king
2020-01-15 abf582fbe18c20ab4f01458a9209878c77fea9c0
2020-01-15
11个文件已修改
1712 ■■■■■ 已修改文件
src/templates/comtableconfig/actionform/index.jsx 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 299 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/settingform/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/source.jsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/tabdragelement/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/tabform/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/actionform/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.jsx 1117 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/source.jsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/editcard/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/formconfig.js 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/actionform/index.jsx
@@ -167,10 +167,15 @@
    }
  }
  // 打开方式或显示位置变化
  /**
   * @description 下拉切换
   * 1、打开方式切换,重置可见表单和表单值
   * 2、显示位置切换,重置选择行
   * 3、切换标签类型,重置可选标签
   */
  openTypeChange = (key, value) => {
    if (key === 'OpenType') {
      let _options = null
      let _options = []
      if (value === 'innerpage') {
        _options = ['label', 'Ot', 'OpenType', 'pageTemplate', 'icon', 'class', 'position']
      } else if (value === 'outerpage') {
@@ -192,64 +197,57 @@
          _options = ['label', 'position', 'OpenType', 'intertype', 'innerFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'method']
        }
      }
      let _fieldval = {}
      let _formlist = this.state.formlist.map(item => {
        item.hidden = !_options.includes(item.key)
        if (item.hidden) return item
        if (item.key === 'intertype') {
          _fieldval.intertype = this.state.interType
        } else if (item.key === 'Ot') {
          if (value === 'innerpage' || this.state.position === 'grid') {
            item.options = this.state.reqOptionSgl
            _fieldval.Ot = 'requiredSgl'
          } else if (['outerpage', 'blank', 'tab', 'popview'].includes(value)) {
            item.options = this.state.reqOptions
            _fieldval.Ot = 'requiredSgl'
          } else {
            item.options = this.state.reqOptionsMutil
          }
        } else if (item.key === 'sqlType') {
          if (['prompt', 'exec'].includes(value)) {
            item.options = this.state.deleteOptions
          } else {
            item.options = this.state.insertUpdateOptions
          }
          _fieldval.sqlType = ''
        }
        return item
      })
      this.setState({
        openType: value,
        formlist: this.state.formlist.map(item => {
          if (_options) {
            item.hidden = !_options.includes(item.key)
            if (item.key === 'intertype') {
              item.initVal = this.state.interType
            }
          }
          if (item.key === 'Ot') {
            if (value === 'innerpage' || this.state.position === 'grid') {
              item.options = this.state.reqOptionSgl
              item.initVal = 'requiredSgl'
            } else if (['outerpage', 'blank', 'tab', 'popview'].includes(value)) {
              item.options = this.state.reqOptions
              item.initVal = 'requiredSgl'
            } else {
              item.options = this.state.reqOptionsMutil
            }
            item.hidden = true
          } else if (item.key === 'sqlType') {
            if (['prompt', 'exec'].includes(value)) {
              item.options = this.state.deleteOptions
            } else {
              item.options = this.state.insertUpdateOptions
            }
            item.initVal = ''
            item.hidden = true
          }
          return item
        })
        formlist: _formlist
      }, () => {
        if (['excelIn', 'excelOut'].includes(value)) return
        this.setState({
          formlist: this.state.formlist.map(item => {
            if (item.key === 'Ot') {
              item.hidden = false
            } else if (item.key === 'sqlType' && ['prompt', 'exec', 'pop'].includes(value)) {
              item.hidden = false
            }
            return item
          })
        })
        this.props.form.setFieldsValue(_fieldval)
      })
    } else if (key === 'position') {
      let _fieldval = {}
      this.setState({
        position: value,
        formlist: this.state.formlist.map(item => {
          if (item.key === 'Ot') {
            if (this.state.openType === 'innerpage' || value === 'grid') {
              item.options = this.state.reqOptionSgl
              item.initVal = 'requiredSgl'
              item.hidden = true
              _fieldval.Ot = 'requiredSgl'
            } else if (['outerpage', 'blank', 'tab', 'popview'].includes(this.state.openType)) {
              item.options = this.state.reqOptions
              item.initVal = 'requiredSgl'
              item.hidden = true
              _fieldval.Ot = 'requiredSgl'
            } else {
              item.options = this.state.reqOptionsMutil
            }
@@ -257,17 +255,11 @@
          return item
        })
      }, () => {
        this.setState({
          formlist: this.state.formlist.map(item => {
            if (item.key === 'Ot') {
              item.hidden = false
            }
            return item
          })
        })
        this.props.form.setFieldsValue(_fieldval)
      })
    } else if (key === 'tabType') {
      let _tabs = this.props.tabs.filter(tab => tab.type === value)
      let _fieldval = {}
      this.setState({
        formlist: this.state.formlist.map(item => {
@@ -279,20 +271,12 @@
              },
              ..._tabs
            ]
            item.initVal = ''
            item.hidden = true
            _fieldval.linkTab = ''
          }
          return item
        })
      }, () => {
        this.setState({
          formlist: this.state.formlist.map(item => {
            if (item.key === 'linkTab') {
              item.hidden = false
            }
            return item
          })
        })
        this.props.form.setFieldsValue(_fieldval)
      })
    }
  }
@@ -306,10 +290,12 @@
      } else {
        _options = ['label', 'position', 'OpenType', 'intertype', 'innerFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'method']
      }
      this.setState({
        interType: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          if (item.key === 'interface') {
            item.readonly = false
          } else if (item.key === 'sysInterface') {
src/templates/comtableconfig/index.jsx
@@ -47,8 +47,6 @@
  state = {
    dict: CommonDict,        // 字典
    config: null,            // 页面配置
    visible: false,          // 搜索条件、按钮、显示列,模态框显示控制
    modalTitle: '',          // 模态框的标题
    tableVisible: false,     // 数据表字段模态框
    addType: '',             // 添加类型-搜索条件或显示列
    tableColumns: [],        // 表格显示列
@@ -67,7 +65,7 @@
    originMenu: null,        // 原始菜单
    originActions: null,     // 原始按钮信息,使用已有用户模板
    delActions: [],          // 删除按钮列表
    copyActions: [],         // 删除按钮列表
    copyActions: [],         // 复制按钮组
    funcLoading: false,      // 存储过程创建中
    showColumnName: false,   // 显示列字段名控制
    tabviews: [],            // 所有标签页
@@ -349,10 +347,13 @@
    this.setState({
      modaltype: type === 'copy' ? 'actionCopy' : 'actionEdit',
      card: card,
      formlist: getActionForm(card, functip, this.state.config, this.props.permFuncField)
      formlist: getActionForm(card, functip, this.state.config, this.props.permFuncField, 'main')
    })
  }
  /**
   * @description 显示列与合并列编辑,获取表单信息
   */
  handleColumn = (card) => {
    if (card.type !== 'colspan') {
      this.setState({
@@ -368,6 +369,9 @@
    }
  }
  /**
   * @description 标签编辑,筛选可选的下级标签与已关联的下级标签
   */
  handleTab = (card) => {
    const { config } = this.state
@@ -386,12 +390,12 @@
      let _tabMap = new Map()
      let _usedTabMap = new Map()
      config[nextTabId].forEach(tab => { // 下级所有的标签
      config[nextTabId].forEach(tab => {        // 下级所有的标签
        menus.push(tab)
        _tabMap.set(tab.uuid, true)
      })
      config[card.groupId].forEach(tab => { // 同级标签已选的下级标签
      config[card.groupId].forEach(tab => {     // 同级标签已选的下级标签
        if (tab.uuid === card.uuid) return
        tab.subtabs.forEach(subtab => {
@@ -403,7 +407,7 @@
        _usedTabMap.set(subtab, true)
      })
      subtabs = subtabs.filter(tab => _tabMap.has(tab.uuid) && !_usedTabMap.has(tab.uuid))
      subtabs = subtabs.filter(tabId => _tabMap.has(tabId) && !_usedTabMap.has(tabId))
      menus = menus.filter(tab => !_usedTabMap.has(tab.uuid))
    } else {
      subtabs = []
@@ -474,6 +478,9 @@
    })
  }
  /**
   * @description 操作列编辑
   */
  handleGridBtn = () => {
    this.setState({
      modaltype: 'gridbtn'
@@ -484,7 +491,7 @@
   * @description 搜索、按钮、显示列修改后提交保存
   * 1、搜索条件保存
   * 2、按钮包括正常编辑和复制,复制时,末尾添加,如按钮为表单(保存至数据库),复制按钮id存于复制列表(点击不保存时删除)
   * 3、添加或编辑列,保存时,如按钮位置设置为表格,则修改操作列显示状态
   * 3、如按钮位置设置为表格,则修改操作列显示状态
   */
  handleSubmit = () => {
    const { menu } = this.props
@@ -557,7 +564,7 @@
        // 判断是否存在操作列
        let _hasGridbtn = _action.filter(act => act.position === 'grid').length > 0
        let _gridBtn = {...config.gridBtn}
        let _gridBtn = config.gridBtn
        if (_gridBtn) {
          _gridBtn.display = _hasGridbtn
@@ -605,20 +612,14 @@
      })
    } else if (modaltype === 'tabs') {
      this.tabsFormRef.handleConfirm().then(res => {
        let isupdate = false
        let _tabgroup = config[res.values.groupId].map(item => {
          if (item.uuid === res.values.uuid) {
            isupdate = true
            return res.values
          } else {
            return item
          }
        })
        _tabgroup = _tabgroup.filter(item => !item.origin)
        if (!isupdate) { // 操作不是修改,添加元素至列表
          _tabgroup.push(res.values)
        }
        this.setState({
          config: {...config, [res.values.groupId]: _tabgroup},
@@ -628,6 +629,9 @@
    }
  }
  /**
   * @description 取消保存,如果元素为新添元素,则从序列中删除
   */
  editModalCancel = () => {
    const { config, card, modaltype } = this.state
@@ -642,6 +646,9 @@
      } else if (modaltype === 'columns' || modaltype === 'colspan') {
        let _columns = config.columns.filter(item => item.uuid !== card.uuid)
        _config = {...config, columns: _columns}
      } else if (modaltype === 'tabs') {
        let _tabgroup = config[card.groupId].filter(item => item.uuid !== card.uuid)
        _config = {...config, [card.groupId]: _tabgroup}
      } else {
        _config = config
      }
@@ -664,7 +671,7 @@
   */
  creatFunc = () => {
    const { menu } = this.props
    let _config = JSON.parse(JSON.stringify(this.state.config))
    const { config } = this.state
    this.actionFormRef.handleConfirm().then(res => {
      let btn = res         // 按钮信息
@@ -719,11 +726,11 @@
              let _param = {
                funcName: btn.innerFunc,
                name: _config.setting.tableName || '',
                name: config.setting.tableName || '',
                fields: fields,
                menuNo: menu.MenuNo
              }
              newLText = Utils.formatOptions(Utils.getfunc(_param, btn, menu, _config))
              newLText = Utils.formatOptions(Utils.getfunc(_param, btn, menu, config))
              DelText = Utils.formatOptions(Utils.dropfunc(_param.funcName))
              resolve(true)
            } else {
@@ -738,18 +745,17 @@
        } else {
          let _param = {
            funcName: btn.innerFunc,
            name: _config.setting.tableName || '',
            name: config.setting.tableName || '',
            fields: '',
            menuNo: menu.MenuNo
          }
          newLText = Utils.formatOptions(Utils.getfunc(_param, btn, menu, _config))
          newLText = Utils.formatOptions(Utils.getfunc(_param, btn, menu, config))
          DelText = Utils.formatOptions(Utils.dropfunc(_param.funcName))
          resolve(true)
        }
      }).then(res => {
        // 获取云端及本地,是否已存在该存储过程的信息
        if (res === false) return res
        if (res !== false) return false
        let sysDefer = new Promise(resolve => {
          Api.getSystemConfig({
@@ -918,34 +924,24 @@
          return
        }
        let isupdate = false
        _config.action = _config.action.map(item => {
        let _action = config.action.map(item => {
          if (item.uuid === btn.uuid) {
            isupdate = true
            return btn
          } else {
            return item
          }
        })
        _config.action = _config.action.filter(item => !item.origin)
        _action = _action.filter(item => !item.origin)
        // 判断是否存在操作列
        let _hasGridbtn = _action.filter(act => act.position === 'grid').length > 0
        let _gridBtn = config.gridBtn
        if (!isupdate) { // 操作不是修改,添加元素至列表
          _config.action.push(btn)
        }
        let gridbtn = _config.action.filter(act => act.position === 'grid')
        let _display = false
        if (gridbtn.length > 0) {
          _display = true
        }
        if (_config.gridBtn) {
          _config.gridBtn.display = _display
        if (_gridBtn) {
          _gridBtn.display = _hasGridbtn
        } else {
          _config.gridBtn = {
            display: _display,
          _gridBtn = {
            display: _hasGridbtn,
            Align: 'center',
            IsSort: 'false',
            uuid: Utils.getuuid(),
@@ -958,7 +954,7 @@
        }
        this.setState({
          config: _config,
          config: {...config, action: _action, gridBtn: _gridBtn},
          funcLoading: false
        })
      })
@@ -1187,30 +1183,40 @@
  }
  deleteElement = (element) => {
    const { config } = this.state
    let _this = this
    confirm({
      content: `确定删除<<${element.card.label}>>吗?`,
      okText: this.state.dict['header.confirm'],
      cancelText: this.state.dict['header.cancel'],
      onOk() {
        let _config = JSON.parse(JSON.stringify(_this.state.config))
        let _config = null
        if (element.type === 'tabs') {
          _config[element.card.groupId] = _config[element.card.groupId].filter(item => {
          let _tabgroup = config[element.card.groupId].filter(item => {
            if (item.uuid === element.card.uuid) {
              return false
            } else {
              return true
            }
          })
          _config = {...config, [element.card.groupId]: _tabgroup}
        } else {
          _config[element.type] = _config[element.type].filter(item => {
          let list = config[element.type].filter(item => {
            if (item.uuid === element.card.uuid) {
              return false
            } else {
              return true
            }
          })
          _config = {...config, [element.type]: list}
          // 删除按钮时判断是否存在操作列
          if (element.type === 'action' && _config.gridBtn) {
            _config.gridBtn.display = _config.action.filter(act => act.position === 'grid').length > 0
          }
        }
        _this.setState({
@@ -1315,9 +1321,9 @@
        return
      }
      let btnParam = { // 添加菜单按钮
      let btnParam = {             // 添加菜单按钮
        func: 'sPC_Button_AddUpt',
        Type: 40, // 添加菜单下的按钮
        Type: 40,                  // 添加菜单下的按钮type为40,按钮下的按钮type为60
        ParentID: menu.MenuID,
        MenuNo: res.menuNo,
        Template: menu.PageParam.Template || '',
@@ -1406,7 +1412,7 @@
  }
  /**
   * @description 保存或修改菜单按钮
   * @description 保存或修改菜单按钮集
   */
  submitAction = (btnParam, tabParam) => {
    const { config } = this.state
@@ -1559,6 +1565,9 @@
    })
  }
  /**
   * @description 点击返回时,判断配置保存状态
   */
  cancelConfig = () => {
    const { menu } = this.props
    const { config, originMenu } = this.state
@@ -1613,6 +1622,9 @@
    }
  }
  /**
   * @description 筛选可用字段集
   */
  queryField = (type) => {
    const {selectedTables, tableColumns, config} = this.state
    // 判断是否已选择表名
@@ -1659,7 +1671,12 @@
    })
  }
  /**
   * @description 添加字段集
   */
  addFieldSubmit = () => {
    const {addType, config} = this.state
    // 字段集为空,关闭弹窗
    if (!this.state.fields || this.state.fields.length === 0) {
      this.setState({
@@ -1668,7 +1685,6 @@
      })
    }
    const {addType, config} = this.state
    const textmatch = { // 选择text时匹配规则
      text: 'like',
      number: 'like',
@@ -1690,23 +1706,31 @@
    // 获取已选字段集合
    let cards = this.refs.searchcard.state.selectCards
    if (cards.length === 0) {
      notification.warning({
        top: 92,
        message: '请选择添加字段',
        duration: 10
      })
      return
    }
    let columnsMap = new Map()
    cards.forEach(card => {
      columnsMap.set(card.field, card)
    })
    let items = []
    if (addType === 'search') {
      config.search.forEach(item => {
      let _search = config.search.filter(item => !item.origin)
      // 重置原有搜素条件
      _search = _search.map(item => {
        if (columnsMap.has(item.field)) {
          let cell = columnsMap.get(item.field)
          if (cell.selected && cell.type === item.type) { // 数据未修改
            items.push(item)
          } else if (cell.selected) { // 数据类型修改
            if (cell.type === 'text') {
              item.match = textmatch[cell.datatype]
            } else if (cell.type === 'select') {
          if (cell.type !== item.type) { // 数据类型修改
            if (cell.type === 'select') {
              item.match = selectmatch[cell.datatype]
            } else if (cell.type === 'daterange') {
              item.match = datematch[cell.datatype]
@@ -1717,101 +1741,95 @@
            
            item.type = cell.type
            item.initval = ''
            items.push(item)
          }
          columnsMap.delete(item.field)
        } else if (!item.origin) {
          items.push(item)
        }
        return item
      })
      let _columns = [...columnsMap.values()]
      // 顺序添加新增搜索
      _columns.forEach(item => {
        if (item.selected) {
          let _match = ''
          if (item.type === 'text') {
            _match = textmatch[item.datatype]
          } else if (item.type === 'select') {
            _match = selectmatch[item.datatype]
          } else if (item.type === 'daterange') {
            _match = datematch[item.datatype]
          } else {
            item.type = 'text'
            _match = textmatch[item.datatype]
          }
          let newcard = {
            uuid: Utils.getuuid(),
            label: item.label,
            field: item.field,
            initval: '',
            type: item.type,
            resourceType: '0',
            setAll: 'false',
            options: [],
            dataSource: '',
            linkField: '',
            valueField: '',
            valueText: '',
            orderBy: '',
            orderType: 'asc',
            match: _match,
            display: 'dropdown'
          }
          items.push(newcard)
        let _match = ''
        if (item.type === 'select') {
          _match = selectmatch[item.datatype]
        } else if (item.type === 'daterange') {
          _match = datematch[item.datatype]
        } else {
          _match = textmatch[item.datatype]
        }
        let newcard = {
          uuid: Utils.getuuid(),
          label: item.label,
          field: item.field,
          initval: '',
          type: item.type || 'text',
          resourceType: '0',
          setAll: 'false',
          options: [],
          orderType: 'asc',
          match: _match,
          display: 'dropdown'
        }
        _search.push(newcard)
      })
      this.setState({
        config: {...config, search: _search}
      })
    } else {
      config.columns.forEach(item => {
      let _columns = config.columns.filter(item => !item.origin)
      // 重置原有显示列类型
      _columns = _columns.map(item => {
        if (columnsMap.has(item.field)) {
          let cell = columnsMap.get(item.field)
          if (cell.selected) {
            items.push(item)
          if (cell.type) {
            item.type = cell.type
          }
          columnsMap.delete(item.field)
        } else if (!item.origin) {
          items.push(item)
        }
        return item
      })
      let _columns = [...columnsMap.values()]
      let _cols = [...columnsMap.values()]
      _columns.forEach(item => {
        if (item.selected) {
          let newcard = {
            uuid: Utils.getuuid(),
            Align: 'left',
            label: item.label,
            field: item.field,
            Hide: 'false',
            IsSort: item.type === 'picture' ? 'false' : 'true',
            type: item.type,
            Width: 120
          }
          items.push(newcard)
      // 添加显示列
      _cols.forEach(item => {
        let newcard = {
          uuid: Utils.getuuid(),
          Align: 'left',
          label: item.label,
          field: item.field,
          Hide: 'false',
          IsSort: item.type === 'picture' ? 'false' : 'true',
          type: item.type,
          Width: 120
        }
        _columns.push(newcard)
      })
      this.setState({
        config: {...config, columns: _columns}
      })
    }
    this.setState({
      [addType + 'loading']: true,
      config: {...config, [addType]: items}
    }, () => {
      notification.success({
        top: 92,
        message: '操作成功',
        duration: 2
      })
      this.setState({
        [addType + 'loading']: false
      })
    notification.success({
      top: 92,
      message: '操作成功',
      duration: 2
    })
  }
  /**
   * @description 表名切换时,添加表名,新增时查询表相关字段
   */
  onTableChange = (value) => {
    const {tables, selectedTables, tableColumns} = this.state
@@ -1867,6 +1885,9 @@
    }
  }
  /**
   * @description 删除表名以及表相关字段
   */
  deleteTable = (table) => {
    const {selectedTables, tableColumns} = this.state
@@ -1876,12 +1897,18 @@
    })
  }
  /**
   * @description 页面配置信息模态框显示
   */
  changeSetting = () => {
    this.setState({
      settingVisible: true
    })
  }
  /**
   * @description 保存页面配置信息
   */
  settingSave = () => {
    const { menu } = this.props
    const {config} = this.state
@@ -2024,7 +2051,10 @@
    }
  }
  onEnabledChange = (val, e) => {
  /**
   * @description 页面启用停止切换
   */
  onEnabledChange = () => {
    const { config } = this.state
    let tabinvalid = true
@@ -2055,6 +2085,9 @@
    }
  }
  /**
   * @description 显示隐藏显示列字段名
   */
  onColumnNameChange = () => {
    const { showColumnName } = this.state
@@ -2063,6 +2096,9 @@
    })
  }
  /**
   * @description 增加标签页分组
   */
  addTabGroup = () => {
    let _this = this
    let _config = JSON.parse(JSON.stringify(this.state.config))
@@ -2085,6 +2121,9 @@
    })
  }
  /**
   * @description 删除标签页分组
   */
  delTabGroup = (groupId) => {
    let _this = this
    let _config = JSON.parse(JSON.stringify(this.state.config))
@@ -2106,6 +2145,9 @@
    })
  }
  /**
   * @description 选择不保存时,如有复制按钮,则删除
   */
  notsave = () => {
    this.state.copyActions.forEach(item => {
      let _param = {
@@ -2120,7 +2162,8 @@
  render () {
    const { modaltype } = this.state
    const configAction = this.state.config.action.filter(_action =>
      !_action.origin && (_action.OpenType === 'pop' || _action.OpenType === 'popview' || _action.OpenType === 'blank' || _action.OpenType === 'tab')
      !_action.origin && (_action.OpenType === 'pop' || _action.OpenType === 'popview')
      // !_action.origin && (_action.OpenType === 'pop' || _action.OpenType === 'popview' || _action.OpenType === 'blank' || _action.OpenType === 'tab')
    )
    let configTabs = []
@@ -2405,7 +2448,7 @@
            wrappedComponentRef={(inst) => this.columnFormRef = inst}
          />
        </Modal>
        {/* 合并列编辑 */}
        {/* 操作列编辑 */}
        <Modal
          title={this.state.dict['header.modal.gridbtn.edit']}
          visible={modaltype === 'gridbtn'}
src/templates/comtableconfig/settingform/index.jsx
@@ -81,7 +81,6 @@
  }
  selectChange = (val) => {
    // let _order = this.props.form.getFieldValue('order')
    this.props.form.setFieldsValue({
      order: `${val} desc`
    })
src/templates/comtableconfig/source.jsx
@@ -35,11 +35,6 @@
        resourceType: '0',
        setAll: 'false',
        options: [],
        dataSource: '',
        linkField: '',
        valueField: '',
        valueText: '',
        orderBy: '',
        orderType: 'asc',
        match: 'like',
        display: 'dropdown'
@@ -53,11 +48,6 @@
        resourceType: '0',
        setAll: 'false',
        options: [],
        dataSource: '',
        linkField: '',
        valueField: '',
        valueText: '',
        orderBy: '',
        orderType: 'asc',
        match: 'equal',
        display: 'dropdown'
@@ -71,11 +61,6 @@
        resourceType: '0',
        setAll: 'false',
        options: [],
        dataSource: '',
        linkField: '',
        valueField: '',
        valueText: '',
        orderBy: '',
        orderType: 'asc',
        match: 'greater',
        display: 'dropdown'
@@ -87,21 +72,13 @@
        uuid: Utils.getuuid(),
        label: 'add',
        intertype: 'inner',
        innerFunc: '',
        interface: '',
        method: 'POST',
        outerFunc: '',
        sql: '',
        sqlType: '',
        callbackFunc: '',
        Ot: 'notRequired',
        position: 'toolbar',
        execSuccess: 'grid',
        execError: 'never',
        errorTime: 15,
        OpenType: 'pop',
        pageTemplate: '',
        url: '',
        icon: 'plus',
        class: 'green',
        verify: null
@@ -110,21 +87,13 @@
        uuid: Utils.getuuid(),
        label: 'update',
        intertype: 'inner',
        innerFunc: '',
        interface: '',
        method: 'POST',
        outerFunc: '',
        sql: '',
        sqlType: '',
        callbackFunc: '',
        Ot: 'requiredSgl',
        position: 'grid',
        execSuccess: 'grid',
        execError: 'never',
        errorTime: 15,
        OpenType: 'pop',
        pageTemplate: '',
        url: '',
        icon: 'form',
        class: 'purple',
        verify: null
@@ -133,21 +102,13 @@
        uuid: Utils.getuuid(),
        label: 'delete',
        intertype: 'inner',
        innerFunc: '',
        interface: '',
        method: 'POST',
        outerFunc: '',
        sql: '',
        sqlType: '',
        callbackFunc: '',
        Ot: 'required',
        position: 'toolbar',
        execSuccess: 'grid',
        execError: 'never',
        errorTime: 15,
        OpenType: 'prompt',
        pageTemplate: '',
        url: '',
        icon: 'delete',
        class: 'red',
        verify: null
src/templates/comtableconfig/tabdragelement/index.jsx
@@ -52,6 +52,7 @@
      newcard.subtabs = []
      newcard.supMenu = ''
      newcard.groupId = groupId
      newcard.focus = true
      
      let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0
      if (target) {
src/templates/comtableconfig/tabform/index.jsx
@@ -51,6 +51,19 @@
    })
  }
  componentDidMount () {
    const { card } = this.props
    if (card.focus) {
      try {
        let _form = document.getElementById('label')
        _form.select()
      } catch {
        console.warn('表单focus失败!')
      }
    }
  }
  /**
   * @description 标签页类型切换
   */
src/templates/subtableconfig/actionform/index.jsx
@@ -458,7 +458,6 @@
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          values.id = this.props.card.id
          values.uuid = this.props.card.uuid
          values.verify = this.props.card.verify || null
@@ -480,10 +479,7 @@
              duration: 10
            })
          } else {
            resolve({
              type: 'action',
              values
            })
            resolve(values)
          }
        } else {
          reject(err)
src/templates/subtableconfig/index.jsx
@@ -6,7 +6,13 @@
import HTML5Backend from 'react-dnd-html5-backend'
import { Button, Card, Modal, Collapse, notification, Spin, Select, List, Icon, Empty, Switch, Tooltip } from 'antd'
import moment from 'moment'
import Api from '@/api'
import zhCN from '@/locales/zh-CN/comtable.js'
import enUS from '@/locales/en-US/comtable.js'
import Utils from '@/utils/utils.js'
import { getSearchForm, getActionForm, getColumnForm } from '@/templates/tableshare/formconfig'
import ActionForm from './actionform'
import SettingForm from './settingform'
import SearchForm from '@/templates/tableshare/searchform'
@@ -18,9 +24,6 @@
import VerifyCard from '@/templates/tableshare/verifycard'
import MenuForm from '@/templates/tableshare/menuform'
import SourceElement from '@/templates/tableshare/dragelement/source'
import zhCN from '@/locales/zh-CN/comtable.js'
import enUS from '@/locales/en-US/comtable.js'
import Utils from '@/utils/utils.js'
import Source from './source'
import './index.scss'
@@ -50,10 +53,8 @@
    menuformlist: null,      // 基本信息表单字段
    formlist: null,          // 搜索条件、按钮、显示列表单字段
    formtemp: '',            // 表单类型,显示列、按钮、搜索条件
    modaltype: '',           // 模态框类型,控制模态框显示
    card: null,              // 编辑元素
    searchloading: false,    // 搜索条件加载中
    actionloading: false,    // 按钮加载中
    columnsloading: false,   // 显示列加载中
    menuloading: false,      // 菜单保存中
    menucloseloading: false, // 菜单关闭时,选择保存
    loading: false,          // 加载中,页面spin
@@ -64,6 +65,7 @@
    originConfig: null,      // 原配置
    originActions: null,     // 原始按钮信息,使用已有用户模板
    delActions: [],          // 删除按钮列表
    copyActions: [],         // 复制按钮组
    funcLoading: false,      // 存储过程创建中
    showColumnName: false,   // 显示列字段名控制
    tabviews: [],            // 所有标签页
@@ -267,682 +269,79 @@
    }
  }
  /**
   * @description 元素添加或拖动时顺序变化
   */
  handleList = (type, list, card) => {
    const { config } = this.state
    if (list.length > config[type].length) {
      list = list.filter(item => !item.origin)
      this.setState({
        [type + 'loading']: true,
        config: {...config, [type]: list }
      }, () => {
        // 刷新对应的配置信息
        this.setState({
          [type + 'loading']: false
        })
        if (type === 'search') {
          this.handleSearch(card)
        } else if (type === 'action') {
          this.handleAction(card)
        } else if (type === 'columns') {
          this.handleColumn(card)
        }
      })
    } else {
      this.setState({config: {...config, [type]: list}})
      if (type === 'search') {
        this.handleSearch(card)
      } else if (type === 'action') {
        this.handleAction(card)
      } else if (type === 'columns') {
        this.handleColumn(card)
      }
    }
    this.setState({config: {...config, [type]: list}})
  }
  /**
   * @description 搜索条件编辑,获取搜索条件表单信息
   */
  handleSearch = (card) => {
    this.setState({
      visible: true,
      formtemp: 'search',
      modalTitle: '编辑-搜索条件',
      modaltype: 'search',
      card: card,
      formlist: [
        {
          type: 'text',
          key: 'label',
          label: this.state.dict['header.form.name'],
          initVal: card.label,
          required: true,
          readonly: false
        },
        {
          type: 'text',
          key: 'field',
          label: this.state.dict['header.form.field'],
          initVal: card.field,
          tooltip: '字段名可以使用逗号分隔,进行多字段综合搜索,注:综合搜索仅在文本类型时有效',
          tooltipClass: 'middle',
          required: true,
          readonly: false
        },
        {
          type: 'select',
          key: 'type',
          label: this.state.dict['header.form.type'],
          initVal: card.type,
          required: true,
          options: [{
            value: 'text',
            text: this.state.dict['header.form.text']
          }, {
            value: 'select',
            text: this.state.dict['header.form.select']
          }, {
            value: 'multiselect',
            text: this.state.dict['header.form.multiselect']
          }, {
            value: 'link',
            text: this.state.dict['header.form.link']
          }, {
            value: 'date',
            text: this.state.dict['header.form.dateday']
          }, {
            value: 'dateweek',
            text: this.state.dict['header.form.dateweek']
          }, {
            value: 'datemonth',
            text: this.state.dict['header.form.datemonth']
          }, {
            value: 'daterange',
            text: this.state.dict['header.form.daterange']
          }]
        },
        {
          type: 'text',
          key: 'initval',
          label: this.state.dict['header.form.initval'],
          initVal: card.initval,
          required: false
        },
        {
          type: 'radio',
          key: 'resourceType',
          label: this.state.dict['header.form.resourceType'],
          initVal: card.resourceType || '0',
          required: true,
          options: [{
            value: '0',
            text: this.state.dict['header.form.custom']
          }, {
            value: '1',
            text: this.state.dict['header.form.datasource']
          }]
        },
        {
          type: 'radio',
          key: 'setAll',
          label: this.state.dict['header.form.setAll'],
          initVal: card.setAll || 'false',
          options: [{
            value: 'true',
            text: this.state.dict['header.form.true']
          }, {
            value: 'false',
            text: this.state.dict['header.form.false']
          }]
        },
        {
          type: 'textarea',
          key: 'dataSource',
          label: this.state.dict['header.form.datasource'],
          initVal: card.dataSource || '',
          required: true,
          readonly: false
        },
        {
          type: 'options',
          key: 'options',
          label: '',
          initVal: card.options || [],
          required: true,
          readonly: false
        },
        {
          type: 'text',
          key: 'linkField',
          label: this.state.dict['header.form.linkField'],
          initVal: card.linkField || '',
          required: true,
          readonly: false
        },
        {
          type: 'text',
          key: 'valueField',
          label: this.state.dict['header.form.valueField'],
          initVal: card.valueField || '',
          required: true,
          readonly: false
        },
        {
          type: 'text',
          key: 'valueText',
          label: this.state.dict['header.form.valueText'],
          initVal: card.valueText || '',
          required: true,
          readonly: false
        },
        {
          type: 'text',
          key: 'orderBy',
          label: this.state.dict['header.form.orderBy'],
          initVal: card.orderBy || '',
          required: false,
          readonly: false
        },
        {
          type: 'select',
          key: 'orderType',
          label: this.state.dict['header.form.orderType'],
          initVal: card.orderType || 'asc',
          options: [{
            value: 'asc',
            text: this.state.dict['header.form.asc']
          }, {
            value: 'desc',
            text: this.state.dict['header.form.desc']
          }]
        },
        {
          type: 'select',
          key: 'match',
          label: this.state.dict['header.form.match'],
          initVal: card.match || 'like',
          required: true,
          options: [{
            value: 'like',
            text: 'like'
          }, {
            value: 'equal',
            text: 'equal'
          }, {
            value: 'greater',
            text: '>'
          }, {
            value: 'less',
            text: '<'
          }, {
            value: 'greaterequal',
            text: '>='
          }]
        },
        {
          type: 'select',
          key: 'display',
          label: this.state.dict['header.form.display'],
          initVal: card.display || 'dropdown',
          required: true,
          options: [{
            value: 'dropdown',
            text: this.state.dict['header.form.dropdown']
          }, {
            value: 'button',
            text: this.state.dict['header.form.button']
          }]
        }
      ]
      formlist: getSearchForm(card)
    })
  }
  /**
   * @description 按钮编辑,获取按钮表单信息
   */
  handleAction = (card, type) => {
    let ableField = this.props.permFuncField.join(', ')
    let functip = <div>
      <p style={{marginBottom: '5px'}}>{this.state.dict['header.modal.func.innerface'].replace('@ableField', ableField)}</p>
      <p>{this.state.dict['header.modal.func.outface']}</p>
    </div>
    this.setState({
      visible: true,
      formtemp: 'action',
      modalTitle: type === 'copy' ? '复制-按钮' : '编辑-按钮',
      modaltype: type === 'copy' ? 'actionCopy' : 'actionEdit',
      card: card,
      formlist: [
        {
          type: 'text',
          key: 'label',
          label: this.state.dict['header.form.name'],
          initVal: card.label,
          required: true,
          readonly: false
        },
        {
          type: 'select',
          key: 'OpenType',
          label: this.state.dict['header.form.openType'],
          initVal: card.OpenType,
          required: true,
          options: [{
            value: 'pop',
            text: this.state.dict['header.form.popform']
          }, {
            value: 'prompt',
            text: this.state.dict['header.form.prompt']
          }, {
            value: 'exec',
            text: this.state.dict['header.form.exec']
          }, {
            value: 'excelIn',
            text: this.state.dict['header.form.excelIn']
          }, {
            value: 'excelOut',
            text: this.state.dict['header.form.excelOut']
          }, {
            value: 'popview',
            text: this.state.dict['header.form.popview']
          }]
        }, {
          type: 'select',
          key: 'tabType',
          label: this.state.dict['header.form.tabType'],
          initVal: card.tabType || 'SubTable',
          required: true,
          options: [{
            value: 'SubTable',
            text: this.state.dict['header.menu.tab.subtable']
          }]
        },
        {
          type: 'select',
          key: 'linkTab',
          label: '关联标签',
          initVal: card.linkTab || '',
          required: false,
          options: []
        },
        {
          type: 'radio',
          key: 'intertype',
          label: this.state.dict['header.form.intertype'],
          initVal: card.intertype,
          required: true,
          options: [{
            value: 'inner',
            text: this.state.dict['header.form.interface.inner']
          }, {
            value: 'outer',
            text: this.state.dict['header.form.interface.outer']
          }]
        },
        {
          type: 'text',
          key: 'innerFunc',
          label: this.state.dict['header.form.innerFunc'],
          initVal: card.innerFunc,
          tooltip: <div>
            <p>内部接口: 可自定义数据处理函数,函数名称需以{ableField}等字符开始;未设置时会调用系统函数,使用系统函数需完善数据源及操作类型;</p>
            <p>外部接口: 可自定义数据处理函数,提交数据经过内部函数处理后,传入外部接口,未设置时,数据会直接传入外部接口。</p>
          </div>,
          fields: this.props.permFuncField,
          tooltipClass: 'middle',
          required: false,
          readonly: false
        },
        {
          type: 'radio',
          key: 'sysInterface',
          label: this.state.dict['header.form.sysInterface'],
          initVal: card.sysInterface || 'false',
          required: true,
          options: [{
            value: 'true',
            text: this.state.dict['header.form.true']
          }, {
            value: 'false',
            text: this.state.dict['header.form.false']
          }]
        },
        {
          type: 'text',
          key: 'outerFunc',
          label: this.state.dict['header.form.outerFunc'],
          initVal: card.outerFunc,
          required: false,
          readonly: false
        },
        {
          type: 'text',
          key: 'interface',
          label: this.state.dict['header.form.interface'],
          initVal: card.sysInterface === 'true' ? (window.GLOB.mainSystemApi || window.GLOB.subSystemApi) : card.interface,
          required: true,
          readonly: card.sysInterface === 'true'
        },
        {
          type: 'text',
          key: 'callbackFunc',
          label: this.state.dict['header.form.callbackFunc'],
          initVal: card.callbackFunc,
          required: false,
          readonly: false
        },
        {
          type: 'select',
          key: 'position',
          label: this.state.dict['header.form.position'],
          initVal: card.position || 'toolbar',
          required: true,
          options: [{
            value: 'toolbar',
            text: this.state.dict['header.form.toolbar']
          }, {
            value: 'grid',
            text: this.state.dict['header.form.grid']
          }]
        },
        {
          type: 'select',
          key: 'Ot',
          label: this.state.dict['header.form.isRequired'],
          initVal: card.Ot || 'requiredSgl',
          required: true,
          options: []
        },
        {
          type: 'select',
          key: 'execSuccess',
          label: this.state.dict['header.form.execSuccess'],
          initVal: card.execSuccess || 'never',
          required: true,
          options: [{
            value: 'never',
            text: this.state.dict['header.form.refresh.never']
          }, {
            value: 'grid',
            text: this.state.dict['header.form.refresh.grid']
          }, {
            value: 'view',
            text: this.state.dict['header.form.refresh.view']
          }]
        },
        {
          type: 'select',
          key: 'execError',
          label: this.state.dict['header.form.execError'],
          initVal: card.execError || 'never',
          required: true,
          options: [{
            value: 'never',
            text: this.state.dict['header.form.refresh.never']
          }, {
            value: 'grid',
            text: this.state.dict['header.form.refresh.grid']
          }, {
            value: 'view',
            text: this.state.dict['header.form.refresh.view']
          }]
        },
        {
          type: 'select',
          key: 'popClose',
          label: this.state.dict['header.form.popClose'],
          initVal: card.popClose || 'never',
          required: true,
          options: [{
            value: 'never',
            text: this.state.dict['header.form.refresh.never']
          }, {
            value: 'maingrid',
            text: this.state.dict['header.form.refresh.maingrid']
          }, {
            value: 'subgrid',
            text: this.state.dict['header.form.refresh.subgrid']
          }]
        },
        {
          type: 'select',
          key: 'icon',
          label: this.state.dict['header.form.icon'],
          initVal: card.icon,
          required: false,
          options: []
        },
        {
          type: 'select',
          key: 'class',
          label: this.state.dict['header.form.class'],
          initVal: card.class,
          required: false,
          options: []
        },
        {
          type: 'text',
          key: 'sql',
          label: this.state.dict['header.form.datasource'],
          initVal: card.sql || this.state.config.setting.tableName || '',
          tooltip: this.state.dict['header.form.actionhelp.datasource'],
          required: false
        },
        {
          type: 'select',
          key: 'sqlType',
          label: this.state.dict['header.form.action.type'],
          initVal: card.sqlType || '',
          tooltip: this.state.dict['header.form.actionhelp.sqlType'],
          required: false,
          options: []
        }
      ]
      formlist: getActionForm(card, functip, this.state.config, this.props.permFuncField, 'subtable')
    })
  }
  /**
   * @description 显示列与合并列编辑,获取表单信息
   */
  handleColumn = (card) => {
    if (card.type !== 'colspan') {
      this.setState({
        visible: true,
        formtemp: 'columns',
        modalTitle: '编辑-显示列',
        modaltype: 'columns',
        card: card,
        formlist: [
          {
            type: 'text',
            key: 'label',
            label: this.state.dict['header.form.name'],
            initVal: card.label,
            required: true
          },
          {
            type: 'text',
            key: 'field',
            label: this.state.dict['header.form.field'],
            initVal: card.field,
            required: true,
            readonly: false
          },
          {
            type: 'select',
            key: 'type',
            label: this.state.dict['header.form.type'],
            initVal: card.type,
            required: true,
            options: [{
              value: 'text',
              text: this.state.dict['header.form.text']
            }, {
              value: 'picture',
              text: this.state.dict['header.form.picture']
            }, {
              value: 'number',
              text: this.state.dict['header.form.number']
            }, {
              value: 'textarea',
              text: this.state.dict['header.form.textarea']
            }]
          },
          {
            type: 'select',
            key: 'Align',
            label: this.state.dict['header.form.align'],
            initVal: card.Align,
            required: true,
            options: [{
              value: 'left',
              text: this.state.dict['header.form.alignLeft']
            }, {
              value: 'right',
              text: this.state.dict['header.form.alignRight']
            }, {
              value: 'center',
              text: this.state.dict['header.form.alignCenter']
            }]
          },
          {
            type: 'radio',
            key: 'Hide',
            label: this.state.dict['header.form.Hide'],
            initVal: card.Hide,
            required: true,
            options: [{
              value: 'true',
              text: this.state.dict['header.form.true']
            }, {
              value: 'false',
              text: this.state.dict['header.form.false']
            }]
          },
          {
            type: 'radio',
            key: 'IsSort',
            label: this.state.dict['header.form.IsSort'],
            initVal: card.IsSort,
            required: true,
            options: [{
              value: 'true',
              text: this.state.dict['header.form.true']
            }, {
              value: 'false',
              text: this.state.dict['header.form.false']
            }]
          },
          {
            type: 'number',
            key: 'Width',
            min: 1,
            max: 1000,
            decimal: 0,
            label: this.state.dict['header.form.columnWidth'],
            initVal: card.Width,
            required: true
          },
          {
            type: 'number',
            key: 'decimal',
            min: 0,
            max: 18,
            decimal: 0,
            label: this.state.dict['header.form.decimal'],
            initVal: card.decimal,
            required: false
          },
          {
            type: 'select',
            key: 'format',
            label: this.state.dict['header.form.format'],
            initVal: card.format || '',
            options: [{
              value: '',
              text: this.state.dict['header.form.empty']
            }, {
              value: 'thdSeparator',
              text: this.state.dict['header.form.thdSeparator']
            }],
            required: false
          },
          {
            type: 'text',
            key: 'prefix',
            label: this.state.dict['header.form.prefix'],
            initVal: card.prefix || '',
            required: false,
            readonly: false
          },
          {
            type: 'text',
            key: 'postfix',
            label: this.state.dict['header.form.postfix'],
            initVal: card.postfix || '',
            // tooltip: '后缀值设置为"\\n",表示换行',
            tooltipClass: 'middle',
            required: false,
            readonly: false
          },
          {
            type: 'select',
            key: 'match',
            label: this.state.dict['header.form.match'],
            initVal: card.match || '',
            options: [{
              value: '',
              text: this.state.dict['header.form.empty']
            }, {
              value: '>',
              text: '>'
            }, {
              value: '<',
              text: '<'
            }, {
              value: '>=',
              text: '>='
            }, {
              value: '<=',
              text: '<='
            }],
            required: false
          },
          {
            type: 'text',
            key: 'matchVal',
            min: -Infinity,
            max: Infinity,
            decimal: 0,
            label: this.state.dict['header.form.matchVal'],
            initVal: card.matchVal || '',
            required: false,
            readonly: false
          },
          {
            type: 'select',
            key: 'color',
            label: this.state.dict['header.form.color'],
            initVal: card.color || '',
            options: [{
              value: '',
              text: this.state.dict['header.form.empty']
            }, {
              value: 'red',
              text: '红色(内容)'
            }, {
              value: 'redbg',
              text: '红色(背景)'
            }, {
              value: 'orange',
              text: '橙色(内容)'
            }, {
              value: 'orangebg',
              text: '橙色(背景)'
            }, {
              value: 'green',
              text: '绿色(内容)'
            }, {
              value: 'greenbg',
              text: '绿色(背景)'
            }],
            required: false
          }
        ]
        formlist: getColumnForm(card)
      })
    } else {
      this.setState({
        visible: true,
        formtemp: 'columns',
        modaltype: 'colspan',
        card: card
      })
    }
  }
  /**
   * @description 操作列编辑
   */
  handleGridBtn = () => {
    this.setState({
      visible: true,
      formtemp: 'gridbtn',
      modalTitle: '编辑-操作列',
      modaltype: 'gridbtn'
    })
  }
@@ -953,14 +352,41 @@
   * 3、添加或编辑列,保存时,如按钮位置设置为表格,则修改操作列显示状态
   */
  handleSubmit = () => {
    const { card } = this.state
    let _config = JSON.parse(JSON.stringify(this.state.config))
    const { card, config, modaltype } = this.state
    if (this.state.formtemp !== 'gridbtn') {
      this.formRef.handleConfirm().then(res => {
        let isupdate = false
    if (modaltype === 'search') {
      this.searchFormRef.handleConfirm().then(res => {
        let _search = config.search.map(item => {
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
        _search = _search.filter(item => !item.origin)
        if (res.type === 'action' && card.originCard && res.values.OpenType === 'pop') {
        this.setState({
          config: {...config, search: _search},
          modaltype: ''
        })
      })
    } else if (modaltype === 'actionEdit' || modaltype === 'actionCopy') {
      this.actionFormRef.handleConfirm().then(res => {
        let _action = config.action.map(item => {
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
        _action = _action.filter(item => !item.origin)
        if (modaltype === 'actionCopy') {
          _action.push(res)
        }
        // 复制按钮前后皆为表单时,复制表单配置信息,id存于复制列表
        if (res.OpenType === 'pop' && card.originCard && card.originCard.OpenType === 'pop') {
          Api.getSystemConfig({
            func: 'sPC_Get_LongParam',
            MenuID: card.originCard.uuid
@@ -968,11 +394,11 @@
            if (result.status && result.LongParam) {
              let param = {
                func: 'sPC_ButtonParam_AddUpt',
                ParentID: _config.uuid,
                MenuID: res.values.uuid,
                MenuNo: _config.tabNo,
                ParentID: config.uuid,
                MenuID: res.uuid,
                MenuNo: config.tabNo,
                Template: 'Modal',
                MenuName: res.values.label,
                MenuName: res.label,
                PageParam: JSON.stringify({Template: 'Modal'}),
                LongParam: result.LongParam
              }
@@ -983,73 +409,97 @@
                    message: response.message,
                    duration: 10
                  })
                } else {
                  this.setState({
                    copyActions: [...this.state.copyActions, res.uuid]
                  })
                }
              })
            }
          })
        }
        _config[res.type] = _config[res.type].map(item => {
          if (item.uuid === res.values.uuid) {
            isupdate = true
            return res.values
        // 判断是否存在操作列
        let _hasGridbtn = _action.filter(act => act.position === 'grid').length > 0
        let _gridBtn = config.gridBtn
        if (_gridBtn) {
          _gridBtn.display = _hasGridbtn
        } else {
          _gridBtn = {
            display: _hasGridbtn,
            Align: 'center',
            IsSort: 'false',
            uuid: Utils.getuuid(),
            label: this.state.dict['header.form.column.action'],
            type: 'action',
            style: 'button',
            show: 'horizontal',
            Width: 120
          }
        }
        this.setState({
          config: {...config, action: _action, gridBtn: _gridBtn},
          modaltype: ''
        })
      })
    } else if (modaltype === 'columns' || modaltype === 'colspan') {
      this.columnFormRef.handleConfirm().then(res => {
        let _columns = config.columns.map(item => {
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
        _config[res.type] = _config[res.type].filter(item => !item.origin)
        if (!isupdate) { // 操作不是修改,添加元素至列表
          _config[res.type].push(res.values)
        }
        if (res.type === 'action') {
          let gridbtn = _config.action.filter(act => act.position === 'grid')
          let _display = false
          if (gridbtn.length > 0) {
            _display = true
          }
          if (_config.gridBtn) {
            _config.gridBtn.display = _display
          } else {
            _config.gridBtn = {
              display: _display,
              Align: 'center',
              IsSort: 'false',
              uuid: Utils.getuuid(),
              label: this.state.dict['header.form.column.action'],
              type: 'action',
              style: 'button',
              show: 'horizontal',
              Width: 120
            }
          }
        }
        this.setState({
          config: _config,
          searchloading: true,
          actionloading: true,
          columnsloading: true,
          visible: false
        }, () => {
          this.setState({
            searchloading: false,
            actionloading: false,
            columnsloading: false,
          })
        })
      })
    } else {
      this.formRef.handleConfirm().then(res => {
        _config.gridBtn = res
        _columns = _columns.filter(item => !item.origin)
        this.setState({
          config: _config,
          visible: false
          config: {...config, columns: _columns},
          modaltype: ''
        })
      })
    } else if (modaltype === 'gridbtn') {
      this.gridBtnFormRef.handleConfirm().then(res => {
        this.setState({
          config: {...config, gridBtn: res},
          modaltype: ''
        })
      })
    }
  }
  /**
   * @description 取消保存,如果元素为新添元素,则从序列中删除
   */
  editModalCancel = () => {
    const { config, card, modaltype } = this.state
    if (card.focus) {
      let _config = null
      if (modaltype === 'search') {
        let _search = config.search.filter(item => item.uuid !== card.uuid)
        _config = {...config, search: _search}
      } else if (modaltype === 'actionEdit') {
        let _action = config.action.filter(item => item.uuid !== card.uuid)
        _config = {...config, action: _action}
      } else if (modaltype === 'columns' || modaltype === 'colspan') {
        let _columns = config.columns.filter(item => item.uuid !== card.uuid)
        _config = {...config, columns: _columns}
      } else {
        _config = config
      }
      this.setState({
        card: null,
        config: _config,
        modaltype: ''
      })
    } else {
      this.setState({
        card: null,
        modaltype: ''
      })
    }
  }
@@ -1061,7 +511,7 @@
    let _config = JSON.parse(JSON.stringify(this.state.config))
    this.formRef.handleConfirm().then(res => {
      let btn = res.values  // 按钮信息
      let btn = res  // 按钮信息
      let newLText = ''     // 创建存储过程sql
      let DelText = ''      // 删除存储过程sql
      let isExit = false    // 存储过程是否存在
@@ -1311,10 +761,8 @@
          return
        }
        let isupdate = false
        _config.action = _config.action.map(item => {
          if (item.uuid === btn.uuid) {
            isupdate = true
            return btn
          } else {
            return item
@@ -1322,23 +770,14 @@
        })
        _config.action = _config.action.filter(item => !item.origin)
        if (!isupdate) { // 操作不是修改,添加元素至列表
          _config.action.push(btn)
        }
        let gridbtn = _config.action.filter(act => act.position === 'grid')
        let _display = false
        if (gridbtn.length > 0) {
          _display = true
        }
        // 判断是否存在操作列
        let _hasGridbtn = _config.action.filter(act => act.position === 'grid').length > 0
        if (_config.gridBtn) {
          _config.gridBtn.display = _display
          _config.gridBtn.display = _hasGridbtn
        } else {
          _config.gridBtn = {
            display: _display,
            display: _hasGridbtn,
            Align: 'center',
            IsSort: 'false',
            uuid: Utils.getuuid(),
@@ -1352,12 +791,7 @@
        this.setState({
          config: _config,
          actionloading: true,
          funcLoading: false
        }, () => {
          this.setState({
            actionloading: false
          })
        })
      })
    })
@@ -1644,12 +1078,7 @@
    this.setState({
      profileVisible: false,
      config: config,
      card: '',
      actionloading: true
    }, () => {
      this.setState({
        actionloading: false
      })
      card: ''
    })
  }
@@ -1735,21 +1164,11 @@
        if (response.status) {
          this.setState({
            config: _config,
            originConfig: _config,
            searchloading: true,
            actionloading: true,
            columnsloading: true
            originConfig: _config
          }, () => {
            this.setState({
              searchloading: false,
              actionloading: false,
              columnsloading: false
            }, () => {
              this.setState({
                menuloading: false,
                menucloseloading: false
              })
              menuloading: false,
              menucloseloading: false
            })
            this.submitAction(btnParam)
          })
@@ -2255,11 +1674,6 @@
      this.setState({
        config: {...config, setting: res},
        settingVisible: false,
        columnsloading: true
      }, () => {
        this.setState({
          columnsloading: false
        })
      })
    })
  }
@@ -2370,6 +1784,7 @@
  }
  render () {
    const { modaltype } = this.state
    const configAction = this.state.config.action.filter(_action =>
      !_action.origin && (_action.OpenType === 'pop' || _action.OpenType === 'popview' || _action.OpenType === 'blank' || _action.OpenType === 'tab')
    )
@@ -2478,7 +1893,6 @@
            <Card title={'标签(子表)页面配置'} bordered={false} extra={
              <div>
                <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={this.state.config.enabled} onChange={this.onEnabledChange} />
                {/* <Button type="primary" onClick={this.changeTemplate}>{this.state.dict['header.menu.template.change']}</Button> */}
                <Button type="primary" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['header.save']}</Button>
                <Button onClick={this.cancelConfig}>{this.state.dict['header.return']}</Button>
              </div>
@@ -2488,111 +1902,134 @@
                <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《搜索》中,选择对应搜索框拖至此处添加;或点击按钮《添加搜索条件》批量添加,选择批量添加时,需提前选择使用表。">
                  <Icon type="question-circle" />
                </Tooltip>
                {!this.state.searchloading ?
                  <DragElement
                    type="search"
                    list={this.state.config.search}
                    handleList={this.handleList}
                    handleMenu={this.handleSearch}
                    deleteMenu={this.deleteElement}
                    placeholder={this.state.dict['header.form.search.placeholder']}
                  /> : null
                }
                <DragElement
                  type="search"
                  list={this.state.config.search}
                  handleList={this.handleList}
                  handleMenu={this.handleSearch}
                  deleteMenu={this.deleteElement}
                  placeholder={this.state.dict['header.form.search.placeholder']}
                />
              </div>
              <div className="action-list">
                <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《按钮》中,选择对应类型的按钮拖至此处添加,如选择按钮类型为表单、新标签页等含有配置页面的按钮,可在左侧工具栏-按钮-可配置按钮处,点击按钮完成相关配置。注:当设置按钮显示位置为表格时,显示列会增加操作列。">
                  <Icon type="question-circle" />
                </Tooltip>
                {!this.state.actionloading ?
                  <DragElement
                    type="action"
                    list={this.state.config.action}
                    handleList={this.handleList}
                    handleMenu={this.handleAction}
                    copyElement={(val) => this.handleAction(val, 'copy')}
                    deleteMenu={this.deleteElement}
                    profileMenu={this.profileAction}
                    placeholder={this.state.dict['header.form.action.placeholder']}
                  /> : null
                }
                <DragElement
                  type="action"
                  list={this.state.config.action}
                  handleList={this.handleList}
                  handleMenu={this.handleAction}
                  copyElement={(val) => this.handleAction(val, 'copy')}
                  deleteMenu={this.deleteElement}
                  profileMenu={this.profileAction}
                  placeholder={this.state.dict['header.form.action.placeholder']}
                />
              </div>
              <div className="column-list">
                <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《显示列》中,选择对应类型的显示列拖至此处添加;或点击《添加显示列》按钮批量添加,选择批量添加时,需提前选择使用表。注:添加合并列时,需设置可选列。">
                  <Icon type="question-circle" />
                </Tooltip>
                <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showColumnName} onChange={this.onColumnNameChange} />
                {!this.state.columnsloading ?
                  <DragElement
                    type="columns"
                    list={this.state.config.columns}
                    setting={this.state.config.setting}
                    gridBtn={this.state.config.gridBtn}
                    handleList={this.handleList}
                    handleMenu={this.handleColumn}
                    deleteMenu={this.deleteElement}
                    handleGridBtn={this.handleGridBtn}
                    showfield={this.state.showColumnName}
                    placeholder={this.state.dict['header.form.column.placeholder']}
                  /> : null
                }
                <DragElement
                  type="columns"
                  list={this.state.config.columns}
                  setting={this.state.config.setting}
                  gridBtn={this.state.config.gridBtn}
                  handleList={this.handleList}
                  handleMenu={this.handleColumn}
                  deleteMenu={this.deleteElement}
                  handleGridBtn={this.handleGridBtn}
                  showfield={this.state.showColumnName}
                  placeholder={this.state.dict['header.form.column.placeholder']}
                />
              </div>
            </Card>
          </div>
        </DndProvider>
        {/* 编辑搜索条件、按钮、显示列 */}
        {/* 编辑搜索条件 */}
        <Modal
          title={this.state.modalTitle}
          visible={this.state.visible}
          title={this.state.dict['header.modal.search.edit']}
          visible={modaltype === 'search'}
          width={700}
          onCancel={() => { this.setState({ visible: false }) }}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <SearchForm
            dict={this.state.dict}
            card={this.state.card}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.searchFormRef = inst}
          />
        </Modal>
        {/* 编辑按钮:复制、编辑 */}
        <Modal
          title={modaltype === 'actionEdit' ? this.state.dict['header.modal.action.edit'] : this.state.dict['header.modal.action.copy']}
          visible={modaltype === 'actionEdit' || modaltype === 'actionCopy'}
          width={700}
          onCancel={this.editModalCancel}
          footer={[
            this.state.formtemp === 'action' ?
            <Button key="delete" className="mk-btn mk-purple" onClick={this.creatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button> : null,
            <Button key="cancel" onClick={() => { this.setState({ visible: false }) }}>{this.state.dict['header.cancel']}</Button>,
            modaltype === 'actionEdit' ? <Button key="delete" className="mk-btn mk-purple" onClick={this.creatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button> : null,
            <Button key="cancel" onClick={this.editModalCancel}>{this.state.dict['header.cancel']}</Button>,
            <Button key="confirm" type="primary" onClick={this.handleSubmit}>{this.state.dict['header.confirm']}</Button>
          ]}
          destroyOnClose
        >
          {this.state.formtemp === 'search' ?
            <SearchForm
              dict={this.state.dict}
              formlist={this.state.formlist}
              card={this.state.card}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'action' ?
            <ActionForm
              dict={this.state.dict}
              card={this.state.card}
              tabs={this.state.tabviews}
              formlist={this.state.formlist}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'columns' && this.state.card.type !== 'colspan' ?
            <ColumnForm
              dict={this.state.dict}
              card={this.state.card}
              formlist={this.state.formlist}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'columns' && this.state.card.type === 'colspan' ?
            <ColspanForm
              dict={this.state.dict}
              card={this.state.card}
              columns={this.state.config.columns}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'gridbtn' ?
            <GridBtnForm
              dict={this.state.dict}
              card={this.state.config.gridBtn}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          <ActionForm
            dict={this.state.dict}
            card={this.state.card}
            tabs={this.state.tabviews}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.actionFormRef = inst}
          />
        </Modal>
        {/* 显示列编辑 */}
        <Modal
          title={this.state.dict['header.modal.column.edit']}
          visible={modaltype === 'columns'}
          width={700}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <ColumnForm
            dict={this.state.dict}
            card={this.state.card}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.columnFormRef = inst}
          />
        </Modal>
        {/* 合并列编辑 */}
        <Modal
          title={this.state.dict['header.modal.colspan.edit']}
          visible={modaltype === 'colspan'}
          width={700}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <ColspanForm
            dict={this.state.dict}
            card={this.state.card}
            columns={this.state.config.columns}
            wrappedComponentRef={(inst) => this.columnFormRef = inst}
          />
        </Modal>
        {/* 操作列编辑 */}
        <Modal
          title={this.state.dict['header.modal.gridbtn.edit']}
          visible={modaltype === 'gridbtn'}
          width={700}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <GridBtnForm
            dict={this.state.dict}
            card={this.state.config.gridBtn}
            wrappedComponentRef={(inst) => this.gridBtnFormRef = inst}
          />
        </Modal>
        {/* 根据字段名添加显示列及搜索条件 */}
        <Modal
src/templates/subtableconfig/source.jsx
@@ -36,11 +36,6 @@
        resourceType: '0',
        setAll: 'false',
        options: [],
        dataSource: '',
        linkField: '',
        valueField: '',
        valueText: '',
        orderBy: '',
        orderType: 'asc',
        match: 'like',
        display: 'dropdown'
@@ -54,11 +49,6 @@
        resourceType: '0',
        setAll: 'false',
        options: [],
        dataSource: '',
        linkField: '',
        valueField: '',
        valueText: '',
        orderBy: '',
        orderType: 'asc',
        match: 'equal',
        display: 'dropdown'
@@ -72,11 +62,6 @@
        resourceType: '0',
        setAll: 'false',
        options: [],
        dataSource: '',
        linkField: '',
        valueField: '',
        valueText: '',
        orderBy: '',
        orderType: 'asc',
        match: 'greater',
        display: 'dropdown'
@@ -88,13 +73,7 @@
        uuid: Utils.getuuid(),
        label: 'add',
        intertype: 'inner',
        innerFunc: '',
        interface: '',
        method: 'POST',
        outerFunc: '',
        sql: '',
        sqlType: '',
        callbackFunc: '',
        Ot: 'notRequired',
        position: 'toolbar',
        execSuccess: 'grid',
@@ -109,13 +88,7 @@
        uuid: Utils.getuuid(),
        label: 'update',
        intertype: 'inner',
        innerFunc: '',
        interface: '',
        method: 'POST',
        outerFunc: '',
        sql: '',
        sqlType: '',
        callbackFunc: '',
        Ot: 'requiredSgl',
        position: 'grid',
        execSuccess: 'grid',
@@ -130,13 +103,7 @@
        uuid: Utils.getuuid(),
        label: 'delete',
        intertype: 'inner',
        innerFunc: '',
        interface: '',
        method: 'POST',
        outerFunc: '',
        sql: '',
        sqlType: '',
        callbackFunc: '',
        Ot: 'required',
        position: 'toolbar',
        execSuccess: 'grid',
src/templates/tableshare/editcard/index.jsx
@@ -98,18 +98,13 @@
  changeCard = (item) => {
    let cards = JSON.parse(JSON.stringify(this.state.selectCards))
    let isAdd = true
    cards = cards.map(card => {
      if (card.field === item.field) {
        isAdd = false
        return item
      } else {
        return card
      }
    })
    if (isAdd) {
    if (!item.selected) {
      cards = cards.filter(card => card.field !== item.field)
    } else {
      cards.push(item)
    }
    this.setState({
      selectCards: cards
    })
src/templates/tableshare/formconfig.js
@@ -201,7 +201,45 @@
 * @param {*} config         页面配置
 * @param {*} permFuncField  存储过程可用的开始字段
 */
export function getActionForm (card, functip, config, permFuncField) {
export function getActionForm (card, functip, config, permFuncField, type) {
  let openTypeOptions = [{
    value: 'pop',
    text: Formdict['header.form.popform']
  }, {
    value: 'prompt',
    text: Formdict['header.form.prompt']
  }, {
    value: 'exec',
    text: Formdict['header.form.exec']
  }, {
    value: 'excelIn',
    text: Formdict['header.form.excelIn']
  }, {
    value: 'excelOut',
    text: Formdict['header.form.excelOut']
  }, {
    value: 'popview',
    text: Formdict['header.form.popview']
  }]
  if (type === 'main') {
    openTypeOptions = [
      ...openTypeOptions,
      {
        value: 'tab',
        text: Formdict['header.form.tab']
      }, {
        value: 'blank',
        text: Formdict['header.form.blank']
      }, {
        value: 'innerpage',
        text: Formdict['header.form.newpage.inner']
      }, {
        value: 'outerpage',
        text: Formdict['header.form.newpage.outer']
      }
    ]
  }
  return [
    {
      type: 'text',
@@ -217,37 +255,7 @@
      label: Formdict['header.form.openType'],
      initVal: card.OpenType,
      required: true,
      options: [{
        value: 'pop',
        text: Formdict['header.form.popform']
      }, {
        value: 'prompt',
        text: Formdict['header.form.prompt']
      }, {
        value: 'exec',
        text: Formdict['header.form.exec']
      }, {
        value: 'excelIn',
        text: Formdict['header.form.excelIn']
      }, {
        value: 'excelOut',
        text: Formdict['header.form.excelOut']
      }, {
        value: 'popview',
        text: Formdict['header.form.popview']
      }, {
        value: 'tab',
        text: Formdict['header.form.tab']
      }, {
        value: 'blank',
        text: Formdict['header.form.blank']
      }, {
        value: 'innerpage',
        text: Formdict['header.form.newpage.inner']
      }, {
        value: 'outerpage',
        text: Formdict['header.form.newpage.outer']
      }]
      options: openTypeOptions
    }, {
      type: 'select',
      key: 'tabType',