king
2023-10-13 ab262bbe2c64ba086a14f181e5a27eba4b46b555
2023-10-13
21个文件已修改
2个文件已删除
2个文件已添加
1769 ■■■■ 已修改文件
src/menu/components/share/actioncomponent/index.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastecomponent/index.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/editColumn/formconfig.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/index.jsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.jsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modulecell/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/index.scss 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/searchform/index.jsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/datatable/index.jsx 502 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/datatable/index.scss 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/modaleditable/index.jsx 519 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/modaleditable/index.scss 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemproc/proc/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemproc/transfer/index.jsx 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemproc/transfer/index.scss 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/source.jsx 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.jsx
@@ -407,10 +407,11 @@
            btn.style = item.style || {}
            if (btn.class) {
              if (btn.class !== item.class || btn.show !== item.show || !btn.style.color || (item.focus && !btn.style.color)) {
                if (btn.show === 'icon') {
                  btn.style.color = color[btn.class]
                  btn.style.backgroundColor = 'transparent'
                } else if (btn.class === 'default') {
                // if (btn.show === 'icon') {
                //   btn.style.color = color[btn.class]
                //   btn.style.backgroundColor = 'transparent'
                // }
                if (btn.class === 'default') {
                  btn.style.color = 'rgba(0, 0, 0, 0.65)'
                  btn.style.backgroundColor = '#fff'
                  btn.style.borderColor = '#d9d9d9'
@@ -419,6 +420,7 @@
                  btn.style.color = color[_c]
                  btn.style.backgroundColor = '#fff'
                  btn.style.borderColor = color[_c]
                  btn.style.borderWidth = '1px'
                } else if (btn.class === 'gray') {
                  btn.style.color = 'rgba(0, 0, 0, 0.65)'
                  btn.style.backgroundColor = color[btn.class]
src/menu/components/share/pastecomponent/index.jsx
@@ -170,11 +170,23 @@
        let keys = config.cols.map(col => (col.field || '$empty'))
        let cols = []
        res.cols.forEach(col => {
          if (!keys.includes(col.field)) {
            config.cols.push(col)
          if (!col.field || !keys.includes(col.field)) {
            cols.push(col)
          }
        })
        if (cols.length === 0) {
          notification.warning({
            top: 92,
            message: '显示列已存在!',
            duration: 5
          })
          return
        } else {
          config.cols.push(...cols)
        }
      }
      this.props.updateConfig(config, type)
src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
@@ -33,6 +33,12 @@
    value: 'number',
    text: '数字'
  }, {
    value: 'custom',
    text: '自定义列'
  }, {
    value: 'formula',
    text: '公式'
  }, {
    value: 'picture',
    text: '图片'
  }, {
@@ -45,14 +51,8 @@
    value: 'textarea',
    text: '多行文本'
  }, {
    value: 'custom',
    text: '自定义列'
  }, {
    value: 'colspan',
    text: '合并列'
  }, {
    value: 'formula',
    text: '公式'
  }, {
    value: 'index',
    text: '序号'
src/menu/components/table/base-table/index.scss
@@ -47,6 +47,9 @@
      padding-top: 10px;
      min-height: 55px;
    }
    button {
      min-width: 60px;
    }
  }
  .model-menu-action-list:not(.length0):not(.length1):not(.length2):not(.length3):not(.length4):not(.length5):not(.length6):not(.length7):not(.length8):not(.length9) {
    margin-bottom: 20px;
src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
@@ -25,18 +25,18 @@
    value: 'number',
    text: '数字'
  }, {
    value: 'textarea',
    text: '多行文本'
  }, {
    value: 'custom',
    text: '自定义列'
  }, {
    value: 'colspan',
    text: '合并列'
  }, {
    value: 'formula',
    text: '公式'
  }, {
    value: 'textarea',
    text: '多行文本'
  }, {
    value: 'colspan',
    text: '合并列'
  }, {
    value: 'index',
    text: '序号'
  }]
src/menu/components/table/edit-table/columns/editColumn/index.jsx
@@ -382,8 +382,19 @@
        className = 'text-area'
        let linkSubFields = this.record.linkSubField || []
        let columns = []
        columns.push({ title: 'Value', key: 'Value', strict: true })
        columns.push({ title: 'Text', key: 'Text' })
        linkSubFields.forEach(field => {
          if (field === 'Value' || field === 'Text') return
          columns.push({ title: transfield[field] || field, key: field })
        })
      
        content = <EditTable type={'select'} module="form" transfield={transfield} linkSubFields={linkSubFields} onChange={this.changeOptions}/>
        content = <EditTable columns={columns} module="form" onChange={this.changeOptions}/>
      }
      fields.push(
@@ -403,6 +414,29 @@
      )
    })
    return fields
  }
  transfer = (options) => {
    if (options.length === 0) return options
    let isNumber = true
    options.forEach(item => {
      if (!item.Value || isNaN(item.Value)) {
        isNumber = false
      }
    })
    if (isNumber) {
      return options.map(item => {
        item.Value = +item.Value
        return item
      })
    } else {
      return options.map(item => {
        item.Value = item.Value + ''
        return item
      })
    }
  }
  handleSubmit = () => {
@@ -431,6 +465,32 @@
          cols.forEach(col => {
            values.formula = values.formula.replace(col.reg, col.value)
          })
        } else if (values.type === 'text' && values.editable === 'true' && values.editType === 'select') {
          if (values.resourceType === '0') {
            values.options = values.options || []
            values.options = this.transfer(values.options)
            if (values.options.filter(op => op.Text === '').length > 0) {
              notification.warning({
                top: 92,
                message: '提示文本(Text)不可为空!',
                duration: 5
              })
              return
            } else {
              let arr = values.options.map(m => m.Value)
              let _arr = Array.from(new Set(arr))
              if (arr.length > _arr.length) {
                notification.warning({
                  top: 92,
                  message: 'Value值不可重复!',
                  duration: 5
                })
                return
              }
            }
          }
        }
        if (values.dataSource && /\s/.test(values.dataSource)) {
src/menu/components/table/edit-table/index.scss
@@ -6,7 +6,7 @@
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 100px;
  .model-table-search-list {
    padding: 10px 0px 15px;
    min-height: 65px;
@@ -73,6 +73,9 @@
      padding-top: 10px;
      min-height: 55px;
    }
    button {
      min-width: 60px;
    }
  }
  .ant-btn.mk-link {
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
@@ -40,6 +40,12 @@
    value: 'number',
    text: '数字'
  }, {
    value: 'custom',
    text: '自定义列'
  }, {
    value: 'formula',
    text: '公式'
  }, {
    value: 'picture',
    text: '图片'
  }, {
@@ -52,14 +58,8 @@
    value: 'textarea',
    text: '多行文本'
  }, {
    value: 'custom',
    text: '自定义列'
  }, {
    value: 'colspan',
    text: '合并列'
  }, {
    value: 'formula',
    text: '公式'
  }, {
    value: 'index',
    text: '序号'
src/menu/components/table/normal-table/columns/index.jsx
@@ -37,6 +37,32 @@
    this.props.updateCol({...column, marks: vals})
  }
  copycolumn = () => {
    const { column } = this.props
    let oInput = document.createElement('input')
    let val = {
      copyType: 'cols',
      cols: [column]
    }
    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
    if (srcid) {
      val.$srcId = srcid
    }
    oInput.value = window.btoa(window.encodeURIComponent(JSON.stringify(val)))
    document.body.appendChild(oInput)
    oInput.select()
    document.execCommand('Copy')
    oInput.className = 'oInput'
    oInput.style.display = 'none'
    message.success('复制成功。')
    document.body.removeChild(oInput)
  }
  shouldComponentUpdate (nextProps, nextState) {
    if (this.props.rowSpan !== nextProps.rowSpan || this.props.colSpan !== nextProps.colSpan) {
@@ -76,6 +102,7 @@
            {column.type === 'custom' ? <PlusOutlined className="plus" title="添加元素" onClick={() => this.props.addElement(column)} /> : null}
            {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="添加按钮" onClick={() => this.props.addElement(column, 'button')} /> : null}
            <EditOutlined className="edit" title="编辑" onClick={() => this.props.editColumn(column)} />
            <CopyOutlined title="复制显示列" style={{color: '#26C281'}} onClick={this.copycolumn} />
            {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
            {column.type === 'custom' ? <FontColorsOutlined className="style" title="调整样式" onClick={() => this.props.changeStyle(column)}/> : null}
            <DeleteOutlined className="close" title="删除" onClick={this.deleteCol} />
@@ -597,6 +624,12 @@
    })
  }
  addColumns = () => {
    const { config } = this.props
    MKEmitter.emit('addColumns', config.uuid)
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
@@ -623,6 +656,7 @@
    return (
      <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType} ${config.wrap.mode || ''} table-vertical-${config.wrap.vertical || ''} table-col-${columns.length}`} id={tableId}>
        <div className="col-control">
          <PlusOutlined style={{color: '#26C281'}} title="添加列" onClick={this.addColumns}/>
          <CopyOutlined title="复制显示列" onClick={this.copycolumn} />
          <MarkColumn columns={fields} type="line" marks={lineMarks} onSubmit={this.updateLineMarks} />
          <FileSyncOutlined title="同步字段集" onClick={this.syncfield} />
src/menu/components/table/normal-table/index.jsx
@@ -92,6 +92,7 @@
  componentDidMount () {
    MKEmitter.addListener('completeSave', this.completeSave)
    MKEmitter.addListener('addColumns', this.addColumns)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -106,6 +107,7 @@
      return
    }
    MKEmitter.removeListener('completeSave', this.completeSave)
    MKEmitter.removeListener('addColumns', this.addColumns)
  }
  completeSave = () => {
@@ -210,12 +212,16 @@
    this.updateComponent(_card)
  }
  addColumns = () => {
    let card = fromJS(this.state.card).toJS()
  addColumns = (id) => {
    const { card } = this.state
    card.cols.push({ focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text' })
    if (id && id !== card.uuid) return
    this.setState({card})
    let _card = fromJS(card).toJS()
    _card.cols.push({ focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text' })
    this.setState({card: _card})
  }
  addSearch = () => {
@@ -365,7 +371,7 @@
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <PlusOutlined className="plus" title="添加列" onClick={this.addColumns}/>
            <PlusOutlined className="plus" title="添加列" onClick={() => this.addColumns()}/>
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
            <PlusSquareOutlined className="plus" title="添加按钮" onClick={this.addButton}/>
            <NormalForm title="表格设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
src/menu/components/table/normal-table/index.scss
@@ -73,6 +73,9 @@
      padding-top: 10px;
      min-height: 55px;
    }
    button {
      min-width: 60px;
    }
  }
  .ant-btn.mk-link {
src/menu/modulecell/index.jsx
@@ -93,13 +93,13 @@
        children: [
          { subType: 'text', text: '文本', type: 'col', $init: true },
          { subType: 'number', text: '数字', type: 'col', $init: true },
          { subType: 'custom', text: '自定义列', type: 'col', $init: true },
          { subType: 'formula', text: '公式', type: 'col', $init: true },
          { subType: 'picture', text: '图片', type: 'col', $init: true },
          { subType: 'video', text: '视频', type: 'col', $init: true },
          { subType: 'link', text: '链接', type: 'col', $init: true },
          { subType: 'textarea', text: '多行文本', type: 'col', $init: true },
          { subType: 'custom', text: '自定义列', type: 'col', $init: true },
          { subType: 'colspan', text: '合并列', type: 'col', $init: true },
          { subType: 'formula', text: '公式', type: 'col', $init: true },
          { subType: 'index', text: '序号', type: 'col', $init: true }
        ]
      }
src/tabviews/zshare/actionList/index.scss
@@ -1,17 +1,21 @@
.button-list.toolbar-button {
  position: relative;
  padding: 15px 0px 0px;
  background: #ffffff;
  min-height: 55px;
  background: transparent;
  button {
    min-width: 65px;
    min-width: 60px;
    margin-right: 15px;
    margin-bottom: 10px!important;
    overflow: hidden;
    min-height: 28px;
    height: auto;
  }
  .ant-btn-icon-only {
    width: auto;
    padding: 0 15px;
  }
  .loading-skeleton {
    background: -webkit-gradient(linear,left top,right top,color-stop(25%,#f5f5f5),color-stop(37%,#ffffff),color-stop(63%,#f5f5f5));
src/tabviews/zshare/topSearch/index.scss
@@ -1,5 +1,5 @@
.mk-search-wrap {
  background: #ffffff;
  // background: #ffffff;
  .mk-search-col {
    display: inline-block;
src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -12,7 +12,6 @@
const ColorSketch = asyncComponent(() => import('@/mob/colorsketch'))
const FieldsTable = asyncComponent(() => import('@/templates/zshare/modalform/fieldtable'))
const DataTable = asyncComponent(() => import('@/templates/zshare/modalform/datatable'))
const EditTable = asyncComponent(() => import('@/templates/zshare/modalform/modaleditable'))
const groupOptions = [
@@ -190,6 +189,14 @@
      }
    } else if (type === 'checkcard') {
      reRequired.fields = false
      reOptions.multiple = [{
        value: 'false',
        text: '单选'
      }, {
        value: 'true',
        text: '多选'
      }]
      if (this.record.display === 'picture') {
        if (this.record.resourceType === '0') {        // 自定义资源
          shows.push('options', 'fields', 'picratio')
@@ -203,6 +210,20 @@
          shows.push('dataSource', 'cardValField', 'colorField', 'fields', 'orderBy', 'orderType', 'database')
        }
      } else {
        let appType = sessionStorage.getItem('appType')
        if (appType === '') {
          reOptions.multiple = [{
            value: 'false',
            text: '单选'
          }, {
            value: 'true',
            text: '多选'
          }, {
            value: 'dropdown',
            text: '下拉菜单'
          }]
        }
        reRequired.fields = true
        if (this.record.resourceType === '0') {        // 自定义资源
          shows.push('options', 'fields', 'selectStyle', 'border')
@@ -349,6 +370,9 @@
        this.record.match = 'like'
        _fieldval.match = 'like'
      }
    } else if (key === 'display') {
      this.record.multiple = 'false'
      _fieldval.multiple = 'false'
    } else if (key === 'items') {
      let _initval = this.props.form.getFieldValue('initval')
      if (_initval && !value.includes(_initval[0])) {
@@ -552,12 +576,44 @@
        let type = this.record.type
        
        if (type !== 'checkcard') {
          content = <EditTable type={type} module="search" transfield={{}} linkSubFields={[]} onChange={this.changeOptions}/>
          let columns = []
          if (type === 'link') {
            columns.push({ title: 'ParentID', key: 'ParentID', strict: true })
          }
          columns.push({ title: 'Value', key: 'Value', strict: true })
          columns.push({ title: 'Text', key: 'Text' })
          content = <EditTable columns={columns} module="search" onChange={this.changeOptions}/>
        } else {
          if (this.record.linkField) {
            type = 'link'
          }
          content = <DataTable type={type} multiple={this.record.multiple} display={this.record.display} linkSubFields={[]} transfield={{}} fields={this.record.fields || []} onChange={this.changeOptions}/>
          let columns = []
          let fields = this.record.fields || []
          let keys = ['ParentID', 'pid']
          if (type === 'link') {
            columns.push({ title: 'ParentID', key: 'ParentID', strict: true })
          } else if (this.record.multiple === 'dropdown' && this.record.display === 'text') {
            columns.push({ title: 'pid', key: 'pid', strict: true })
          }
          columns.push({ title: 'Value', key: '$value', strict: true })
          if (this.record.display === 'picture') {
            columns.push({ title: 'url', key: '$url', type: 'file' })
          } else if (this.record.display === 'color') {
            columns.push({ title: 'Color', key: '$color' })
          }
          fields.forEach(item => {
            keys.push(item.field)
            columns.push({ title: item.field, key: item.field })
          })
          content = <EditTable columns={columns} onChange={this.changeOptions}/>
        }
      } else if (item.type === 'fields') {
        span = 24
src/templates/zshare/formconfig.jsx
@@ -560,6 +560,7 @@
      key: 'dataSource',
      label: '数据源',
      initVal: card.dataSource || '',
      tooltip: '数据权限替换符 $@ -> /* 或 \'\'、 @$ -> */ 或 \'\'',
      required: true
    },
    {
@@ -2924,6 +2925,7 @@
      key: 'dataSource',
      label: '数据源',
      initVal: card.dataSource || '',
      tooltip: '数据权限替换符 $@ -> /* 或 \'\'、 @$ -> */ 或 \'\'',
      placeholder: '系统变量:mk_departmentcode、mk_organization、mk_user_type。公共值:@ID@、@BID@。',
      required: true,
      readonly: false
src/templates/zshare/modalform/datatable/index.jsx
File was deleted
src/templates/zshare/modalform/datatable/index.scss
File was deleted
src/templates/zshare/modalform/index.jsx
@@ -15,7 +15,6 @@
const { TextArea } = Input
const ColorSketch = asyncComponent(() => import('@/mob/colorsketch'))
const FieldsTable = asyncComponent(() => import('./fieldtable'))
const DataTable = asyncComponent(() => import('./datatable'))
const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
const modalTypeOptions = {
@@ -457,13 +456,13 @@
            this.record.options = this.record.options.map(cell => {
              cell.Value = cell.Value || cell.$value || ''
              cell.Text = cell[field] || ''
              delete cell.$value
              return cell
            })
          } else {
            this.record.options = this.record.options.map(cell => {
              cell.Value = cell.Value || cell.$value || ''
              delete cell.$value
              return cell
            })
          }
@@ -778,7 +777,21 @@
              linkSubFields = []
            }
          }
          content = <EditTable type={type} module="form" transfield={transfield} linkSubFields={linkSubFields} onChange={this.changeOptions}/>
          let columns = []
          if (type === 'link') {
            columns.push({ title: 'ParentID', key: 'ParentID', strict: true })
          }
          columns.push({ title: 'Value', key: 'Value', strict: true })
          columns.push({ title: 'Text', key: 'Text' })
          linkSubFields.forEach(field => {
            if (field === 'Value' || field === 'Text') return
            columns.push({ title: transfield[field] || field, key: field })
          })
          content = <EditTable columns={columns} module="form" onChange={this.changeOptions}/>
        } else {
          if (this.record.multiple === 'true') {
            linkSubFields = []
@@ -786,7 +799,34 @@
          if (this.record.linkField) {
            type = 'link'
          }
          content = <DataTable type={type} display={this.record.display} linkSubFields={linkSubFields} transfield={transfield} fields={this.record.fields || []} onChange={this.changeOptions}/>
          let columns = []
          let fields = this.record.fields || []
          let keys = ['ParentID', 'pid']
          if (type === 'link') {
            columns.push({ title: 'ParentID', key: 'ParentID', strict: true })
          }
          columns.push({ title: 'Value', key: '$value', strict: true })
          if (this.record.display === 'picture') {
            columns.push({ title: 'url', key: '$url', type: 'file' })
          } else if (this.record.display === 'color') {
            columns.push({ title: 'Color', key: '$color' })
          }
          fields.forEach(item => {
            keys.push(item.field)
            columns.push({ title: item.field, key: item.field })
          })
          linkSubFields.forEach(m => {
            if (keys.includes(m)) return
            columns.push({ title: transfield[m] || m, key: m })
          })
          content = <EditTable columns={columns} onChange={this.changeOptions}/>
        }
      } else if (item.type === 'fields') {
        span = 24
@@ -836,7 +876,7 @@
    let isNumber = true
    options.forEach(item => {
      if (!/^([0-9]|[1-9]\d{0,2})$/.test(item.Value)) {
      if (!item.Value || isNaN(item.Value)) {
        isNumber = false
      }
    })
src/templates/zshare/modalform/modaleditable/index.jsx
@@ -1,106 +1,138 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Table, Input, Popconfirm, Form, message } from 'antd'
import { ArrowUpOutlined, ArrowDownOutlined, DeleteOutlined, PlusOutlined, SwapOutlined } from '@ant-design/icons'
import { DndProvider, DragSource, DropTarget } from 'react-dnd'
import { Table, Input, Popconfirm, message } from 'antd'
import { DeleteOutlined, PlusOutlined, SwapOutlined, DragOutlined } from '@ant-design/icons'
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const EditableContext = React.createContext()
const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent'))
const EditableRow = ({ form, index, ...props }) => (
  <EditableContext.Provider value={form}>
    <tr {...props} />
  </EditableContext.Provider>
class MoveTd extends React.Component {
  render() {
    const { connectDragSource, connectDropTarget } = this.props
    return connectDragSource(
      connectDropTarget(<td className="mk-move-col"><DragOutlined /></td>),
    )
  }
}
const rowSource = {
  beginDrag(props) {
    return {
      index: props.index,
    }
  }
}
const rowTarget = {
  drop(props, monitor) {
    const dragIndex = monitor.getItem().index
    const hoverIndex = props.index
    if (dragIndex === hoverIndex) {
      return
    }
    props.moveRow(dragIndex, hoverIndex)
    monitor.getItem().index = hoverIndex
  },
}
const DragableTd = DropTarget('td', rowTarget, connect => ({
  connectDropTarget: connect.dropTarget(),
}))(
  DragSource('td', rowSource, (connect, monitor) => ({
    connectDragSource: connect.dragSource(),
    // isDragging: monitor.isDragging()
  }))(MoveTd),
)
const EditableFormRow = Form.create()(EditableRow)
class EditableCell extends Component {
  state = {
    editing: false
    editing: false,
    value: ''
  }
  toggleEdit = () => {
    const editing = !this.state.editing
    this.setState({ editing }, () => {
      if (editing && this.input && this.input.select) {
  trigger = () => {
    const { dataIndex, record } = this.props
    this.setState({ editing: true, value: record[dataIndex] }, () => {
      if (this.input && this.input.select) {
        this.input.select()
      } else if (editing && this.input && this.input.focus) {
      } else if (this.input && this.input.focus) {
        this.input.focus()
      }
    })
  }
  save = e => {
    const { record, handleSave } = this.props
    this.form.validateFields((error, values) => {
      handleSave({ ...record, ...values })
      if (error && error[e.currentTarget.id]) {
        return
      }
      this.toggleEdit()
    })
  save = () => {
    const { record, handleSave, dataIndex } = this.props
    const { value } = this.state
    handleSave({ ...record, [dataIndex]: value })
    this.setState({ editing: false, value: '' })
  }
  renderCell = form => {
    this.form = form
    const { children, dataIndex, record } = this.props
  changeUrl = (val) => {
    const { record, handleSave, dataIndex } = this.props
    handleSave({ ...record, [dataIndex]: val })
  }
  renderCell = () => {
    const { dataIndex, inputType, record } = this.props
    const { editing } = this.state
    return editing ? (
      <Form.Item style={{ margin: '0 -5px 0 -5px' }}>
        {form.getFieldDecorator(dataIndex, {
          rules: [
            {
              required: dataIndex === 'Text',
              message: '不可为空.',
            }
          ],
          initialValue: record[dataIndex]
        })(<Input ref={node => (this.input = node)} autoComplete="off" onPressEnter={this.save} onBlur={this.save} />)}
      </Form.Item>
    ) : (
      <div
        className="editable-cell-value-wrap"
        onClick={this.toggleEdit}
      >
        {children}
      </div>
    )
    if (inputType === 'file') {
      return <SourceComponent initialValue={record[dataIndex]} type="" onChange={this.changeUrl} placement="right"/>
    }
    if (!editing) {
      return (
        <div
          className="editable-cell-value-wrap"
          onClick={this.trigger}
        >
          {record[dataIndex]}
        </div>
      )
    } else {
      return <Input ref={node => (this.input = node)} defaultValue={record[dataIndex]} autoComplete="off" onChange={(e) => this.setState({value: e.target.value})} onPressEnter={this.save} onBlur={this.save} />
    }
  }
  render() {
    const {
      editable,
      dataIndex,
      title,
      record,
      index,
      handleSave,
      children,
      ...restProps
    } = this.props
    const { editable, dataIndex, index } = this.props
    if (dataIndex === '$move') {
      return (<DragableTd key={index} {...this.props} />)
    }
    if (editable) {
      return (
        <td>{this.renderCell()}</td>
      )
    }
    return (
      <td {...restProps}>
        {editable ? (
          <EditableContext.Consumer style={{padding: 0}}>{this.renderCell}</EditableContext.Consumer>
        ) : (
          children
        )}
      </td>
      <td {...this.props}/>
    )
  }
}
class EditTable extends Component {
  static propTpyes = {
    type: PropTypes.string,         // 表单类型
    module: PropTypes.string,       // 元素类型
    linkSubFields: PropTypes.array, // 关联字段
    transfield: PropTypes.object,   // 表单字段名称
    onChange: PropTypes.func        // 数据变化
    type: PropTypes.any,
    module: PropTypes.string,
    columns: PropTypes.array,
    onChange: PropTypes.func
  }
  state = {
@@ -110,38 +142,40 @@
  }
  UNSAFE_componentWillMount () {
    const { linkSubFields, type } = this.props
    let data = this.props['data-__meta'].initialValue || []
    const { columns } = this.getColumns(type, linkSubFields, data)
    const { columns, value } = this.props
    let data = value || []
    this.setState({
      columns: columns,
      dataSource: data,
      columns: this.getColumns(),
      dataSource: data.map(item => {
        columns.forEach(n => {
          if (item[n.key] !== undefined) return
          item[n.key] = ['ParentID', '$url', '$color', '$value'].includes(n.key) ? '' : item.Text || ''
        })
        return item
      }),
      count: data.length
    })
  }
  handleUpDown = (record, direction) => {
  moveRow = (dragId, hoverId) => {
    const { dataSource } = this.state
    let index = 0
    let _data = dataSource.filter((item, i) => {
      if (item.key === record.key) {
        index = i
    let dragIndex = -1
    let hoverIndex = -1
    dataSource.forEach((item, i) => {
      if (item.key === dragId) {
        dragIndex = i
      } else if (item.key === hoverId) {
        hoverIndex = i
      }
      return item.key !== record.key
    })
    if ((index === 0 && direction === 'up') || (index === dataSource.length - 1 && direction === 'down')) {
      return
    }
    if (dragIndex === -1 || hoverIndex === -1) return
    if (direction === 'up') {
      _data.splice(index - 1, 0, record)
    } else {
      _data.splice(index + 1, 0, record)
    }
    let _data = fromJS(dataSource).toJS()
    _data.splice(hoverIndex, 0, ..._data.splice(dragIndex, 1))
    this.setState({
      dataSource: _data
@@ -150,13 +184,14 @@
    })
  }
  handleHide = (record) => {
  handleHide = (key) => {
    let _data = this.state.dataSource.map(item => {
      if (item.key === record.key) {
      if (item.key === key) {
        item.Hide = !item.Hide
      }
      return item
    })
    this.setState({
      dataSource: _data
    }, () => {
@@ -164,7 +199,7 @@
    })
  }
  handleDelete = key => {
  handleDelete = (key) => {
    const { dataSource } = this.state
    let _data = dataSource.filter(item => item.key !== key)
@@ -173,22 +208,26 @@
    })
  }
  handleAdd = (e) => {
    e.stopPropagation()
    const { linkSubFields } = this.props
  handleAdd = () => {
    const { columns } = this.props
    const { count, dataSource } = this.state
    const newData = {
      key: Utils.getuuid(),
      Value: `${count}`,
      Text: `${count}`,
      ParentID: ''
    }
    linkSubFields.forEach(m => {
      newData[m] = newData[m] || ''
    let item = { key: Utils.getuuid() }
    columns.forEach(m => {
      item[m.key] = ''
    })
    let _data = [...dataSource, newData]
    if (item.Value === '') {
      item.Value = `${count + 1}`
    }
    if (item.$value === '') {
      item.$value = `${count + 1}`
    }
    item.Text = `${count + 1}`
    let _data = [...dataSource, item]
    this.setState({
      dataSource: _data,
@@ -199,18 +238,49 @@
  }
  handleSave = row => {
    const { type } = this.props
    const { columns, type } = this.props
    const newData = [...this.state.dataSource]
    const index = newData.findIndex(item => row.key === item.key)
    const item = newData[index]
    if (type === 'link') {
      if (newData.filter(m => row.key !== m.key && row.Value === m.Value && row.ParentID === m.ParentID).length > 0) {
        message.warning('相同ParentID下,此Value值已存在!')
      }
    if (type === 'proc') {
      // if (!row.origin || /^\s+$/.test(row.origin)) {
      //   message.warning(columns[0].title + '为空时无效!')
      // }
    } else {
      if (newData.filter(m => row.key !== m.key && row.Value === m.Value).length > 0) {
        message.warning('此Value值已存在!')
      let val = ''
      let repeat = false
      let _type = ''
      columns.forEach(col => {
        if (!col.strict) return
        if (col.key === 'ParentID') {
          _type = 'mutil'
        }
        val += row[col.key]
      })
      newData.forEach(item => {
        if (row.key === item.key) return
        let _val = ''
        columns.forEach(col => {
          if (!col.strict) return
          _val += item[col.key]
        })
        if (val === _val) {
          repeat = true
        }
      })
      if (repeat) {
        if (_type === 'mutil') {
          message.warning('相同ParentID下,此Value值已存在!')
        } else {
          message.warning('此Value值已存在!')
        }
      }
    }
@@ -223,112 +293,83 @@
    })
  }
  getColumns = (type, linkSubFields, dataSource) => {
    const { transfield } = this.props
  getColumns = () => {
    const { columns } = this.props
    let _dataSource = fromJS(dataSource).toJS()
    let fields = []
    let subFields = linkSubFields.filter(m => m !== 'Value' && m !== 'Text')
    if (subFields.length > 0) {
      _dataSource = _dataSource.map(data => {
        subFields.forEach(n => {
          if (data[n] !== undefined) return
          data[n] = data.Text || ''
        })
        return data
    let fields = [{
      title: ' ',
      width: '60px',
      dataIndex: '$move',
      onCell: (record) => ({
        index: record.key,
        dataIndex: '$move',
        moveRow: this.moveRow
      })
      fields = subFields.map(field => {
        return {
          title: transfield[field] || field,
          $title: transfield[field] || field,
          dataIndex: field,
    }]
    columns.forEach(n => {
      let col = {
        title: n.title,
        dataIndex: n.key,
        onCell: record => ({
          record,
          editable: true,
        }
      })
    }
    let columns = [
      {
        title: 'Value',
        $title: 'Value',
        dataIndex: 'Value',
        editable: true
      },
      {
        title: 'Text',
        $title: 'Text',
        dataIndex: 'Text',
        editable: true
      },
      ...fields,
      {
        title: '操作',
        align: 'center',
        width: '20%',
        dataIndex: 'operation',
        render: (text, record) =>
          this.state.dataSource.length >= 1 ? (
            <div style={{fontSize: '15px'}}>
              <span className="operation-btn" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><ArrowUpOutlined /></span>
              <span className="operation-btn" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><ArrowDownOutlined /></span>
              <span className="operation-btn" title="显示/隐藏" onClick={() => this.handleHide(record)} style={{color: 'rgb(142, 68, 173)'}}><SwapOutlined /></span>
              <Popconfirm
                title="确定删除吗?"
                overlayClassName="popover-confirm"
                onConfirm={() => this.handleDelete(record.key)
              }>
                <span style={{color: '#ff4d4f', cursor: 'pointer'}}><DeleteOutlined /></span>
              </Popconfirm>
            </div>
          ) : null,
          inputType: n.type || 'text',
          dataIndex: n.key,
          handleSave: this.handleSave
        })
      }
    ]
    if (type === 'link') {
      columns.unshift({
        title: 'ParentID',
        $title: 'ParentID',
        dataIndex: 'ParentID',
        editable: true
      })
    }
      if (n.width) {
        col.width = n.width
      }
      if (n.fixed) {
        delete col.onCell
      }
    return {
      columns: columns.map(col => {
        if (col.dataIndex !== 'operation') {
          col.title = <div>
            {col.$title}
      fields.push(col)
    })
    fields.push({
      title: '操作',
      align: 'center',
      width: '110px',
      dataIndex: 'operation',
      render: (text, record) =>
        (
          <div style={{fontSize: '15px'}}>
            <span className="operation-btn" title="显示/隐藏" onClick={() => this.handleHide(record.key)} style={{color: 'rgb(142, 68, 173)'}}><SwapOutlined /></span>
            <Popconfirm
              title="确定删除吗?"
              overlayClassName="popover-confirm"
              onConfirm={() => this.handleDelete(record.key)
            }>
              <span style={{color: '#ff4d4f', cursor: 'pointer'}}><DeleteOutlined /></span>
            </Popconfirm>
          </div>
        }
        return col
      }),
      dataSource: _dataSource
    }
        )
    })
    return fields
  }
  handleEmpty = (e) => {
    e.stopPropagation()
    const { linkSubFields, module } = this.props
  handleEmpty = () => {
    const { columns, module } = this.props
    const { dataSource } = this.state
    if (dataSource.filter(item => item.Value === '').length > 0) {
      message.warning('Value为空已存在!')
      return
    }
    const newData = {
      key: Utils.getuuid(),
      Value: '',
      Text: module === 'form' ? '空' : '全部',
      ParentID: ''
    }
    linkSubFields.forEach(m => {
      newData[m] = newData[m] || ''
    let item = { key: Utils.getuuid() }
    columns.forEach(m => {
      item[m.key] = ''
    })
    let _data = [newData, ...dataSource]
    item.Text = module === 'form' ? '空' : '全部'
    let _data = [item, ...dataSource]
    this.setState({
      dataSource: _data,
@@ -337,65 +378,57 @@
    })
  }
  resetColumn = (type, linkSubFields) => {
    const { columns, dataSource } = this.getColumns(type, linkSubFields, this.state.dataSource)
  resetColumn = () => {
    const { columns, value } = this.props
    let data = fromJS(value).toJS().map(item => {
      columns.forEach(n => {
        if (item[n.key] !== undefined) return
        item[n.key] = ['ParentID', '$url', '$color', '$value'].includes(n.key) ? '' : item.Text || ''
      })
      return item
    })
    if (!is(fromJS(dataSource), fromJS(this.state.dataSource))) {
      this.setState({
        columns,
        dataSource
      }, () => {
        this.props.onChange(dataSource)
      })
    } else {
      this.setState({
        columns
      })
    }
    this.setState({
      columns: this.getColumns(),
      dataSource: data,
      count: data.length
    }, () => {
      this.props.onChange(data)
    })
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    if (!is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) || this.props.type !== nextProps.type) {
      this.resetColumn(nextProps.type, nextProps.linkSubFields)
    if (!is(fromJS(this.props.columns), fromJS(nextProps.columns))) {
      this.setState({}, () => {
        this.resetColumn()
      })
    }
  }
  render() {
    const { module } = this.props
    const { dataSource } = this.state
    const { dataSource, columns } = this.state
    const components = {
      body: {
        row: EditableFormRow,
        cell: EditableCell
      }
    }
    const columns = this.state.columns.map(col => {
      if (!col.editable) {
        return col
      }
      return {
        ...col,
        onCell: record => ({
          record,
          editable: col.editable,
          dataIndex: col.dataIndex,
          title: col.title,
          handleSave: this.handleSave
        })
      }
    })
    return (
      <div className="common-modal-edit-table">
        <span className="add-row add-row-empty" onClick={this.handleEmpty}>{module === 'form' ? '空' : '全部'}</span>
        {module ? <span className="add-row add-row-empty" onClick={this.handleEmpty}>{module === 'form' ? '空' : '全部'}</span> : null}
        <PlusOutlined className="add-row" onClick={this.handleAdd} />
        <Table
          components={components}
          rowClassName={(record) => record.Hide ? 'editable-row hide' : 'editable-row'}
          bordered
          dataSource={dataSource}
          columns={columns}
          pagination={false}
        />
        <DndProvider>
          <Table
            components={components}
            rowClassName={(record) => record.Hide ? 'editable-row hide' : 'editable-row'}
            bordered
            dataSource={dataSource}
            columns={columns}
            pagination={false}
          />
        </DndProvider>
      </div>
    )
  }
src/templates/zshare/modalform/modaleditable/index.scss
@@ -15,6 +15,15 @@
    color: #1890ff;
    cursor: pointer;
  }
  .mk-move-col {
    text-align: center;
    font-size: 16px;
    cursor: move;
    color: #c8c8c8;
  }
  .mk-source-wrap {
    min-width: 150px;
  }
  .ant-table-thead > tr > th {
    padding: 10px 16px;
    position: relative;
@@ -23,7 +32,6 @@
      position: absolute;
      right: 12px;
      font-size: 14px;
      // top: 12px;
      color: #b8b8b8;
    }
  }
@@ -52,7 +60,7 @@
    }
  }
  .operation-btn {
    margin-right: 10px;
    margin-right: 15px;
    cursor: pointer;
  }
  .editable-row.hide {
src/views/systemproc/proc/index.jsx
@@ -6,6 +6,7 @@
import Utils from '@/utils/utils.js'
import Api from '@/api'
import CodeMirror from '@/templates/zshare/codemirror'
import Transfer from '../transfer'
import './index.scss'
const { confirm } = Modal
@@ -379,6 +380,7 @@
              {!inputing ? <Search placeholder="请输入存储过程名称" defaultValue={procName} disabled={loading} enterButton="确定" onSearch={this.search}/> : null}
            </div>
            <div className="action-wrap">
              {!procName || loading || !content ? null : <Transfer procName={procName} content={content} />}
              <Button key="save" className="mk-btn mk-green" disabled={loading} onClick={() => this.save()}>保存</Button>
              <Button key="prev" className="mk-btn mk-primary" disabled={!procName || loading} onClick={this.prev}>上一版本</Button>
              <Button key="next" className="mk-btn mk-primary" disabled={!procName || loading} onClick={this.next}>下一版本</Button>
src/views/systemproc/transfer/index.jsx
New file
@@ -0,0 +1,289 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { DndProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import { Button, Modal, notification, Form, Select } from 'antd'
import Utils from '@/utils/utils.js'
import Api from '@/api'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const EditTable = asyncComponent(() => import('@/templates/zshare/modalform/modaleditable'))
class TransferWrap extends Component {
  static propTpyes = {
    MenuID: PropTypes.string
  }
  state = {
    visible: false,
    loading: false,
    VersionName: '',
    translist: [],
    options: []
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  verifySubmit = () => {
    const { content, procName } = this.props
    const { VersionName, options } = this.state
    let value = content.replace(/^(\s*)|(\s*)$/ig, '')
    if (!VersionName) {
      notification.warning({
        top: 92,
        message: '请选择传输号',
        duration: 5
      })
      return
    } else if (!value) {
      notification.warning({
        top: 92,
        message: '存储过程不可为空',
        duration: 5
      })
      return
    }
    let regs = []
    options.forEach(item => {
      if (item.origin && !/^\s+$/.test(item.origin) && item.origin !== item.value) {
        regs.push({reg: new RegExp(item.origin, 'g'), value: item.value})
      }
    })
    regs.forEach(item => {
      value = value.replace(item.reg, item.value)
    })
    let chars = [
      {key: 'drop', reg: /(^|\s)drop\s/ig},
      {key: 'alter', reg: /(^|\s)alter\s/ig},
      {key: 'object', reg: /(^|\s)object(\s|\()/ig},
      {key: 'kill', reg: /(^|\s)kill\s/ig},
      {key: '--', reg: /--/ig},
      {key: ',,', reg: /,,/ig}
    ]
    let error = ''
    if (!/create(\s+)proc/ig.test(value)) {
      error = '脚本中必须使用create proc'
    }
    chars.forEach(char => {
      if (!error && char.reg.test(value)) {
        error = '不可使用' + char.key
      }
    })
    if (error) {
      notification.warning({
        top: 92,
        message: error,
        duration: 5
      })
      return
    }
    let dropfunc = `IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('${procName}') AND type in (N'P', N'PC'))  mdrpk PROCEDURE ${procName}`
    let dropParam = {
      func: 's_sVersionDetail_Add',
      BID: VersionName,
      VType: 'VSQL',
      VSQL: window.btoa(window.encodeURIComponent(dropfunc))
    }
    let addParam = {
      func: 's_sVersionDetail_Add',
      BID: VersionName,
      VType: 'VSQL',
      VSQL: window.btoa(window.encodeURIComponent(value))
    }
    this.setState({
      loading: true
    })
    Api.genericInterface(dropParam).then(result => {
      if (!result.status) {
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
        this.setState({
          loading: false
        })
        return
      }
      delete result.status
      delete result.message
      delete result.ErrCode
      delete result.ErrMesg
      result.func = 's_sVersionDetail_CloudAdd'
      Api.genericInterface(addParam).then(res => {
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
          this.setState({
            loading: false
          })
          return
        }
        delete res.status
        delete res.message
        delete res.ErrCode
        delete res.ErrMesg
        res.func = 's_sVersionDetail_CloudAdd'
        Api.getCloudConfig(result).then(re => {
          if (!re.status) {
            notification.warning({
              top: 92,
              message: re.message,
              duration: 5
            })
            this.setState({
              loading: false
            })
            return
          }
          Api.getCloudConfig(res).then(r => {
            if (!r.status) {
              notification.warning({
                top: 92,
                message: r.message,
                duration: 5
              })
              this.setState({
                loading: false
              })
              return
            } else {
              notification.success({
                top: 92,
                message: '添加成功!',
                duration: 3
              })
              this.setState({
                loading: false,
                visible: false
              })
            }
          })
        })
      })
    })
  }
  getTransList = () => {
    const { content } = this.props
    let value = content.replace(/^(\s*)|(\s*)$/ig, '')
    if (!value) {
      notification.warning({
        top: 92,
        message: '存储过程不可为空',
        duration: 5
      })
      return
    }
    let param = {
      func: 's_get_sVersion',
      dataM: 'Y',
      PageSize: 9999,
      PageIndex: 1,
      OrderCol: 'ID desc'
    }
    let options = []
    let list = value.match(/\s+[a-z0-9_]+\.(dbo)?\./ig)
    list && list.forEach(str => {
      str = str.replace(/^\s/, '')
      options.push({
        key: Utils.getuuid(),
        origin: str,
        value: str
      })
    })
    this.setState({
      options: options,
      VersionName: '',
      visible: true,
      loading: false
    })
    Api.getCloudConfig(param).then(result => {
      if (result.status) {
        this.setState({
          translist: result.data
        })
      } else {
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
      }
    })
  }
  changeOptions = (value) => {
    this.setState({options: value})
  }
  render () {
    const { visible, loading, translist, options } = this.state
    const columns = [{ title: '原信息', key: 'origin', width: '50%', fixed: true }, { title: '替换为', width: '50%', key: 'value' }]
    return (
      <>
        <Button icon="pull-request" className="mk-border-green" onClick={this.getTransList}>传输号</Button>
        <Modal
          title="加入传输号"
          wrapClassName="proc-transfer"
          visible={visible}
          width={900}
          maskClosable={false}
          okText="确定"
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          confirmLoading={loading}
          destroyOnClose
        >
          <Form.Item label="传输号">
            <Select onChange={(val) => this.setState({VersionName: val})}>
              {translist.map(option =>
                <Select.Option key={option.VersionName} value={option.VersionName}>{`${option.ProgramName}(${option.VersionName})`}</Select.Option>
              )}
            </Select>
          </Form.Item>
          {options.length > 0 ? <DndProvider backend={HTML5Backend}>
            <Form.Item label="替换项">
              <EditTable type="proc" columns={columns} value={options} onChange={this.changeOptions}/>
            </Form.Item>
          </DndProvider> : null}
        </Modal>
      </>
    )
  }
}
export default TransferWrap
src/views/systemproc/transfer/index.scss
New file
@@ -0,0 +1,18 @@
.proc-transfer {
  .ant-form-item {
    display: flex;
    .ant-form-item-control-wrapper {
      flex: 10;
      .ant-select {
        width: 300px;
      }
    }
  }
  .operation-btn {
    display: none;
  }
  .add-row {
    display: none;
  }
}
src/views/tabledesign/source.jsx
@@ -186,6 +186,18 @@
    },
    {
      type: 'col',
      label: '自定义列',
      subType: 'custom',
      $init: true
    },
    {
      type: 'col',
      label: '公式',
      subType: 'formula',
      $init: true
    },
    {
      type: 'col',
      label: '图片',
      subType: 'picture',
      $init: true
@@ -210,20 +222,8 @@
    },
    {
      type: 'col',
      label: '自定义列',
      subType: 'custom',
      $init: true
    },
    {
      type: 'col',
      label: '合并列',
      subType: 'colspan',
      $init: true
    },
    {
      type: 'col',
      label: '公式',
      subType: 'formula',
      $init: true
    },
    {