king
2021-12-29 2245384d97d69e36d09cd6baa877e50a81d9aff9
2021-12-29
30个文件已修改
2846 ■■■■ 已修改文件
src/components/mkIcon/index.scss 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/index.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/options.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/options.jsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/normal-form/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modalconfig/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/data-card/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/prop-card/index.jsx 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkCheckCard/index.jsx 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkRadio/index.jsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/actionform/index.jsx 979 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/datatable/index.jsx 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/datatable/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/fieldtable/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 997 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/modaleditable/index.jsx 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/modaleditable/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/mkIcon/index.scss
@@ -13,7 +13,17 @@
    padding: 0 10px;
    border-left: 1px solid #d9d9d9;
  }
  .anticon.trigger::after {
    content: ' ';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
  }
  .close.anticon {
    position: relative;
    z-index: 1;
    float: right;
    margin-top: 8px;
    margin-right: 8px;
src/components/normalform/modalform/index.jsx
@@ -197,10 +197,17 @@
      this.setState({
        formlist: this.state.formlist.map(cell => {
          if (cell.field) {
            return map.get(cell.field)
          if (!cell.field) return cell
          let item = map.get(cell.field)
          if (item && item.linkField) {
            let supInitVal = this.record[item.linkField] || ''
            item.options = item.oriOptions.filter(option => option.ParentID === supInitVal)
          }
          return cell
          return item || cell
        })
      })
    }
src/index.js
@@ -131,12 +131,6 @@
    let _href = window.location.href.split('#')[0]
    if (localStorage.getItem(_href + 'lang')) {
      sessionStorage.setItem('lang', localStorage.getItem(_href + 'lang'))
    } else {
      sessionStorage.setItem('lang', config.defaultLang !== 'en-US' ? 'zh-CN' : 'en-US')
    }
    let _systemMsg = localStorage.getItem(_href + 'system')
    if (_systemMsg) {
@@ -196,6 +190,19 @@
      GLOB.service = config.service
    }
    let mark = sessionStorage.getItem('system_mark')
    let _mark = `sys_${GLOB.service.replace('/', '') || 'service'}`
    if (mark && mark !== _mark) {
      sessionStorage.clear()
    }
    sessionStorage.setItem('system_mark', _mark)
    if (localStorage.getItem(_href + 'lang')) {
      sessionStorage.setItem('lang', localStorage.getItem(_href + 'lang'))
    } else {
      sessionStorage.setItem('lang', config.defaultLang !== 'en-US' ? 'zh-CN' : 'en-US')
    }
    Object.defineProperty(GLOB, 'appId', {
      writable: false,
      value: GLOB.appId
src/menu/components/card/cardcomponent/options.jsx
@@ -86,9 +86,9 @@
    {
      type: 'text',
      field: 'primaryId',
      label: '主键值',
      label: '静态主键值',
      initval: setting.primaryId || '',
      tooltip: '设置一个属性卡静态ID,向其他组件传递的指定静态ID值',
      tooltip: '设置一个属性卡静态ID,向其他组件传递的指定静态ID值,主键为动态值时无效。',
      required: false,
      forbid: subtype !== 'propcard'
    },
src/menu/components/card/data-card/options.jsx
@@ -64,9 +64,10 @@
      tooltip: '选择静态值,无需配置数据源。',
      required: false,
      options: [
        {value: 'dynamic', label: '动态'},
        {value: 'static', label: '静态'},
        {value: 'dynamic', label: '动态', priKeyType: 'static'},
        {value: 'static', label: '静态', priKeyType: 'static'},
      ],
      linkFields: ['priKeyType'],
      controlFields: [
        {field: 'goback', values: ['dynamic']},
        {field: 'supModule', values: ['static']},
@@ -102,8 +103,25 @@
        {field: 'checkAll', values: ['checkbox']},
        {field: 'selected', values: ['radio', 'checkbox']},
        {field: 'selStyle', values: ['radio', 'checkbox']},
        {field: 'priKeyType', values: ['radio', 'checkbox']},
      ],
      forbid: subtype === 'tablecard'
    },
    {
      type: 'radio',
      field: 'priKeyType',
      label: '主键',
      initval: wrap.priKeyType || 'static',
      tooltip: '拼接值为动态主键与用户自定义的静态主键使用逗号拼接。',
      required: false,
      linkField: 'datatype',
      options: [
        {ParentID: 'static', value: 'static', label: '静态值'},
        {ParentID: 'dynamic', value: 'static', label: '静态值'},
        {ParentID: 'dynamic', value: 'dynamic', label: '动态值'},
        {ParentID: 'dynamic', value: 'joint', label: '拼接值'},
      ],
      forbid: subtype !== 'propcard'
    },
    {
      type: 'radio',
@@ -114,7 +132,7 @@
      options: [
        {value: 'false', label: '无'},
        {value: 'init', label: '初始化'},
        {value: 'always', label: '数据加载', disabled: subtype === 'propcard'},
        {value: 'always', label: '数据加载'},
      ]
    },
    {
@@ -224,6 +242,19 @@
      forbid: subtype !== 'propcard' || appType !== 'mob'
    },
    {
      type: 'radio',
      field: 'empty',
      label: '空值隐藏',
      initval: wrap.empty || 'show',
      tooltip: '当查询数据为空时,隐藏该组件。',
      required: false,
      options: [
        {value: 'show', label: '否'},
        {value: 'hidden', label: '是'},
      ],
      forbid: subtype !== 'datacard'
    },
    {
      type: 'cascader',
      field: 'supModule',
      label: '上级组件',
src/menu/components/form/normal-form/index.jsx
@@ -434,10 +434,7 @@
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = [{
      field: '',
      label: '空'
    }]
    let _linksupFields = []
    let standardform = null
    let uniq = new Map()
@@ -478,6 +475,7 @@
      }
      
      if (!['select', 'link', 'radio', 'checkcard'].includes(item.type)) return
      if (item.type === 'checkcard' && item.multiple === 'true') return // 选项卡多选
      if (item.field && !uniq.has(item.field)) {
        uniq.set(item.field, true)
src/menu/components/form/tab-form/index.jsx
@@ -426,10 +426,7 @@
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = [{
      field: '',
      label: '空'
    }]
    let _linksupFields = []
    let standardform = null
    let uniq = new Map()
@@ -470,6 +467,7 @@
      }
      
      if (!['select', 'link', 'radio', 'checkcard'].includes(item.type)) return
      if (item.type === 'checkcard' && item.multiple === 'true') return // 选项卡多选
      if (item.field && !uniq.has(item.field)) {
        uniq.set(item.field, true)
src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -659,7 +659,7 @@
            if (values.intertype === 'system' && setting.interType !== 'system') {
              notification.warning({
                top: 92,
                message: '表格数据查询未使用数据源,导出Excel使用内部接口时,需自定义内部函数!',
                message: '表格数据查询未使用系统函数,导出Excel不可使用系统函数!',
                duration: 5
              })
              return
src/menu/modalconfig/index.jsx
@@ -114,10 +114,7 @@
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = [{
      field: '',
      label: '空'
    }]
    let _linksupFields = []
    let standardform = null
    let uniq = new Map()
@@ -148,6 +145,7 @@
      }
      if (!['select', 'link', 'radio', 'checkcard'].includes(item.type)) return
      if (item.type === 'checkcard' && item.multiple === 'true') return // 选项卡多选
      if (item.field && !uniq.has(item.field)) {
        uniq.set(item.field, true)
src/mob/modalconfig/index.jsx
@@ -117,10 +117,7 @@
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = [{
      field: '',
      label: '空'
    }]
    let _linksupFields = []
    let standardform = null
    let uniq = new Map()
@@ -151,6 +148,7 @@
      }
      if (!['select', 'link', 'radio', 'checkcard'].includes(item.type)) return
      if (item.type === 'checkcard' && item.multiple === 'true') return // 选项卡多选
      if (item.field && !uniq.has(item.field)) {
        uniq.set(item.field, true)
src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -657,7 +657,9 @@
      
      let _data = [data]
      if (data.$$type === 'extendCard' || data.$$empty) {
      if (data.$$type === 'extendCard') {
        _data = data.$$selectedData || []
      } else if (data.$$empty) {
        _data = []
      } else if (card.$sync) {
        _data = this.props.syncData
src/tabviews/custom/components/card/data-card/index.jsx
@@ -670,6 +670,8 @@
  render() {
    const { config, precards, nextcards, loading, data, pageIndex, total, card, activeKey, BID, BData, selectedData, selectKeys } = this.state
    if (config.wrap.empty === 'hidden' && (!data || data.length === 0)) return null
    let _total = 0
    let switchable = false
    if (config.wrap.pagestyle === 'switch' && config.pageable && config.setting.laypage && total > config.setting.pageSize && data) {
@@ -713,7 +715,7 @@
            {offset ? <Col span={offset} style={{height: '10px'}}> </Col> : null}
            {precards.map((item, index) => (
              <Col key={'pre' + index} className="extend-card" span={item.setting.width || 6}>
                <CardItem card={item} cards={config} data={{$$BID: BID, $$BData: BData, $$type: 'extendCard'}}/>
                <CardItem card={item} cards={config} data={{$$BID: BID, $$BData: BData, $$selectedData: selectedData, $$type: 'extendCard'}}/>
              </Col>
            ))}
            {data && data.map((item, index) => (
@@ -723,7 +725,7 @@
            ))}
            {nextcards.map((item, index) => (
              <Col key={'next' + index} className="extend-card" span={item.setting.width || 6}>
                <CardItem card={item} cards={config} data={{$$BID: BID, $$BData: BData, $$type: 'extendCard'}}/>
                <CardItem card={item} cards={config} data={{$$BID: BID, $$BData: BData, $$selectedData: selectedData, $$type: 'extendCard'}}/>
              </Col>
            ))}
          </Row>
src/tabviews/custom/components/card/prop-card/index.jsx
@@ -31,7 +31,8 @@
    sync: false,               // 是否统一请求数据
    data: {},                  // 数据
    timer: null,               // 定时器时间间隔
    BData: ''
    BData: '',
    selected: 'false',
  }
  UNSAFE_componentWillMount () {
@@ -63,6 +64,9 @@
    if (_data) {
      _data.$$BID = BID || ''
      _data.$$BData = BData || ''
      if (_config.setting && _config.setting.primaryKey) {
        _data.$$uuid = _data[_config.setting.primaryKey] || ''
      }
    }
    _config.columns.forEach(item => {
@@ -105,15 +109,12 @@
      _config.subcards[0].offset = offset
    }
    if (_config.subcards[0] && (_config.wrap.selected === 'always' || _config.wrap.selected === 'init')) {
      setTimeout(() => {
        this.checkTopLine()
      }, 200)
    }
    _config.wrap.selStyle = _config.wrap.selStyle || 'active'
    _config.wrap.priKeyType = _config.wrap.priKeyType || 'static'
    let selected = _config.wrap.selected || 'false'
    this.setState({
      selected,
      sync: _sync,
      data: _data,
      BID: BID || '',
@@ -123,6 +124,10 @@
    }, () => {
      if (_config.wrap.datatype !== 'static' && _config.setting && _config.setting.sync !== 'true' && _config.setting.onload === 'true') {
        this.loadData()
      } else if ((!_sync || _config.wrap.priKeyType === 'static') && selected !== 'false') {
        setTimeout(() => {
          this.checkTopLine()
        }, 200)
      }
    })
  }
@@ -152,23 +157,28 @@
   * @description 图表数据更新,刷新内容
   */
  UNSAFE_componentWillReceiveProps (nextProps) {
    const { sync, config, BID, BData } = this.state
    const { sync, config, BID, BData, selected } = this.state
    if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
      let _data = { $$empty: true }
      if (nextProps.data && nextProps.data[config.dataName]) {
        _data = nextProps.data[config.dataName]
        if (_data && Array.isArray(_data)) {
          _data = _data[0]
        _data = nextProps.data[config.dataName] || {}
        if (Array.isArray(_data)) {
          _data = _data[0] || {}
        }
      }
      if (_data) {
        _data.$$BID = BID || ''
        _data.$$BData = BData || ''
      }
      _data.$$BID = BID || ''
      _data.$$BData = BData || ''
      _data.$$uuid = _data[config.setting.primaryKey] || ''
      this.setState({sync: false, data: _data})
      this.setState({sync: false, data: _data}, () => {
        if (config.wrap.priKeyType !== 'static' && selected !== 'false') {
          setTimeout(() => {
            this.checkTopLine()
          }, 200)
        }
      })
    } else if ( config.setting.syncRefresh && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
      this.setState({}, () => {
        this.loadData()
@@ -177,13 +187,23 @@
  }
  checkTopLine = () => {
    const { config, data } = this.state
    const { config, data, selected } = this.state
    if (!config.subcards[0]) return
    this.setState({
      activeKey: 0
      activeKey: 0,
      selected: selected === 'init' ? 'false' : selected
    })
    MKEmitter.emit('resetSelectLine', config.uuid, (config.subcards[0].setting.primaryId || ''), data)
    let primaryId = config.subcards[0].setting.primaryId || ''
    if (config.wrap.priKeyType === 'dynamic') {
      primaryId = data.$$uuid || ''
    } else if (config.wrap.priKeyType === 'joint') {
      primaryId = (data.$$uuid || '') + ',' + primaryId
    }
    MKEmitter.emit('resetSelectLine', config.uuid, primaryId, data)
  }
  handleTimer = () => {
@@ -282,7 +302,7 @@
  async loadData (hastimer) {
    const { mainSearch, menuType } = this.props
    const { config, arr_field, BID, BData } = this.state
    const { config, arr_field, BID, BData, selected } = this.state
    if (config.wrap.datatype === 'static') {
      this.setState({
@@ -324,10 +344,15 @@
      _data.$$BID = BID || ''
      _data.$$BData = BData
      _data.$$uuid = _data[config.setting.primaryKey] || ''
      this.setState({
        data: _data,
        loading: false
      }, () => {
        if (config.wrap.priKeyType !== 'static' && selected !== 'false') {
          this.checkTopLine()
        }
      })
      if (config.timer && config.clearField) {
@@ -358,7 +383,14 @@
      activeKey: index
    })
    MKEmitter.emit('resetSelectLine', config.uuid, (item.setting.primaryId || ''), data)
    let primaryId = item.setting.primaryId || ''
    if (config.wrap.priKeyType === 'dynamic') {
      primaryId = data.$$uuid || ''
    } else if (config.wrap.priKeyType === 'joint') {
      primaryId = (data.$$uuid || '') + ',' + primaryId
    }
    MKEmitter.emit('resetSelectLine', config.uuid, primaryId, data)
  }
  render() {
src/tabviews/zshare/mutilform/index.jsx
@@ -56,18 +56,23 @@
    let check = action.setting.formType === 'check'
    formlist = formlist.filter(item => {
      if (item.supField && item.supvalue) { // 多层表单控制
      if (item.supField) { // 多层表单控制
        let supvals = []
        item.supvalue.split(',').forEach(val => {
          supvals.push(val)
          if (/^([-]?(0|[1-9][0-9]*)(\.[0-9]+)?)$/.test(val)) {
            supvals.push(+val)
          }
        })
        if (item.supvalue) {
          item.supvalue.split(',').forEach(val => {
            supvals.push(val)
            if (/^([-]?(0|[1-9][0-9]*)(\.[0-9]+)?)$/.test(val)) {
              supvals.push(+val)
            }
          })
        } else {
          supvals.push('')
        }
        controlFields[item.supField] = controlFields[item.supField] || []
        controlFields[item.supField].push({field: item.field, values: supvals})
      }
      if (item.type === 'link') {
      // if (item.type === 'link') {
      if (item.linkField) {
        linkFields[item.linkField] = linkFields[item.linkField] || []
        linkFields[item.linkField].push({field: item.field, uuid: item.uuid})
      }
@@ -317,7 +322,8 @@
      if (!cell.field || !fieldMap.has(cell.field)) return cell
      let item = fieldMap.get(cell.field)
      if (item.type === 'link') {
      // if (item.type === 'link') {
      if (item.linkField) {
        item.supInitVal = ''
        if (fieldMap.has(item.linkField)) {
@@ -585,7 +591,7 @@
            _cell = {..._cell, ...cell}
          }
  
          if (item.type === 'link') {
          if (item.linkField) {
            _cell.ParentID = cell[item.linkField] === undefined ? '' : cell[item.linkField]
          }
          if (item.subFields) {
@@ -603,9 +609,11 @@
        item.oriOptions = [...item.oriOptions, ...options]
        if (item.type === 'link') {
        // if (item.type === 'link') {
        if (item.linkField) {
          item.options = item.oriOptions.filter(option => option.ParentID === item.supInitVal || option.value === '')
        } else if (['select', 'radio', 'checkbox', 'checkcard', 'multiselect'].includes(item.type)) {
        // } else if (['select', 'radio', 'checkbox', 'checkcard', 'multiselect'].includes(item.type)) {
        } else {
          item.options = item.oriOptions
        }
      }
@@ -722,7 +730,7 @@
        } else if (item.type === 'checkbox') {
          content = (<MKCheckbox config={item} onChange={(val) => this.recordChange({[item.field]: val})}/>)
        } else if (item.type === 'radio') {
          content = (<MKRadio config={item} onChange={(val) => this.recordChange({[item.field]: val}, item)}/>)
          content = (<MKRadio config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)}/>)
        } else if (item.type === 'date' || item.type === 'datemonth' || item.type === 'datetime') {
          content = (<MKDatePicker config={item} onChange={(val) => this.recordChange({[item.field]: val})} />)
        } else if (item.type === 'fileupload') {
src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
@@ -1,5 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Col, Row } from 'antd'
import MKEmitter from '@/utils/events.js'
@@ -12,26 +13,94 @@
  }
  state = {
    selectKeys: null
    selectKeys: null,
    config: null,
    options: []
  }
  UNSAFE_componentWillMount() {
    const { config } = this.props
    let selectKeys = config.initval
    if (config.multiple === 'true') {
      selectKeys = config.initval ? config.initval.split(',') : []
    }
    this.setState({
      config: fromJS(config).toJS(),
      options: fromJS(config.options).toJS(),
      selectKeys: selectKeys
    })
  }
  componentDidMount () {
    const { config } = this.state
    if (config.multiple !== 'true' && config.linkField) {
      MKEmitter.addListener('mkFP', this.mkFormHandle)
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    const { config } = this.props
    if (!is(fromJS(config.oriOptions), fromJS(nextProps.config.oriOptions))) {
      this.setState({
        selectKeys: config.initval ? config.initval.split(',') : []
        config: fromJS(nextProps.config).toJS(),
        options: fromJS(nextProps.config.options).toJS()
      })
    } else {
      this.setState({
        selectKeys: config.initval
    }
  }
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('mkFP', this.mkFormHandle)
  }
  mkFormHandle = (uuid, parentId, level) => {
    if (uuid !== this.state.config.uuid) return
    const { config } = this.state
    let options = config.oriOptions.filter(option => option.ParentID === parentId)
    let _option = options[0] && !options[0].$disabled ? options[0] : null
    let val = _option ? _option.$value : ''
    this.setState({
      options,
      value: val
    })
    let other = {}
    if (config.subFields && _option) {
      config.subFields.forEach((n, i) => {
        other[n.field] = _option[n.field]
        setTimeout(() => {
          MKEmitter.emit('mkFC', 'input', n.uuid, _option[n.field])
        }, i * 5)
      })
    }
    this.props.onChange(val, other)
    if (level < 7 && config.linkFields) {
      config.linkFields.forEach((m, i) => {
        setTimeout(() => {
          MKEmitter.emit('mkFP', m.uuid, val, level + 1)
        }, (i + 1) * 70)
      })
    }
  }
  changeCard = (item) => {
    const { config } = this.props
    const { selectKeys } = this.state
    const { selectKeys, config } = this.state
    if (config.readonly || item.$disabled) return
@@ -71,8 +140,8 @@
  }
  getCards = () => {
    const { display, width, options, fields, ratio, multiple, backgroundColor, borderColor } = this.props.config
    const { selectKeys } = this.state
    const { selectKeys, options, config } = this.state
    const { display, width, fields, ratio, multiple, backgroundColor, borderColor } = config
    let paddingTop = '100%'
    if (ratio === '4:3') {
@@ -127,7 +196,7 @@
  }
  render() {
    const { config } = this.props
    const { config } = this.state
    return (
      <div className={'check-card-form-box' + (config.readonly ? ' readonly' : '')}>
src/tabviews/zshare/mutilform/mkRadio/index.jsx
@@ -1,6 +1,9 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Radio } from 'antd'
import MKEmitter from '@/utils/events.js'
class MKRadio extends Component {
  static propTpyes = {
@@ -9,27 +12,132 @@
  }
  state = {
    defaultValue: this.props.config.initval
    value: '',
    config: null,
    options: []
  }
  onChange = (e) => {
    let value = e.target.value
    this.props.onChange(value)
  UNSAFE_componentWillMount () {
    const { config } = this.props
    let value = config.initval
    if (value) {
      let option = null
      option= config.oriOptions[0]
      if (typeof(value) === 'string' && option && typeof(option.value) === 'number') {
        value = +value
        if (isNaN(value)) {
          value = config.initval
        }
      }
    }
    this.setState({
      config: fromJS(config).toJS(),
      options: fromJS(config.options).toJS(),
      value,
    })
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    const { config } = this.state
    if (!is(fromJS(config.oriOptions), fromJS(nextProps.config.oriOptions))) {
      this.setState({
        config: fromJS(nextProps.config).toJS(),
        options: fromJS(nextProps.config.options).toJS()
      })
      if (typeof(config.initval) === 'string' && config.initval.indexOf('$first') > -1) {
        this.setState({
          value: nextProps.config.initval,
        })
      }
    }
  }
  componentDidMount () {
    MKEmitter.addListener('mkFP', this.mkFormHandle)
  }
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('mkFP', this.mkFormHandle)
  }
  mkFormHandle = (uuid, parentId, level) => {
    if (uuid !== this.state.config.uuid) return
    const { config } = this.state
    let options = config.oriOptions.filter(option => option.ParentID === parentId || option.value === '')
    let _option = options[0] && !options[0].$disabled ? options[0] : null
    let val = _option ? _option.value : ''
    this.setState({
      options,
      value: val
    })
    let other = {}
    if (config.subFields && _option) {
      config.subFields.forEach((n, i) => {
        other[n.field] = _option[n.field]
        setTimeout(() => {
          MKEmitter.emit('mkFC', 'input', n.uuid, _option[n.field])
        }, i * 5)
      })
    }
    this.props.onChange(val, other)
    if (level < 7 && config.linkFields) {
      config.linkFields.forEach((m, i) => {
        setTimeout(() => {
          MKEmitter.emit('mkFP', m.uuid, val, level + 1)
        }, (i + 1) * 70)
      })
    }
  }
  onChange = (val) => {
    const { config } = this.state
    let other = {}
    if (config.subFields) {
      let option = this.state.options.filter(m => m.value === val)[0]
      option && config.subFields.forEach((n, i) => {
        other[n.field] = option[n.field]
        setTimeout(() => {
          MKEmitter.emit('mkFC', 'input', n.uuid, option[n.field])
        }, i * 5)
      })
    }
    if (config.linkFields) {
      config.linkFields.forEach((m, i) => {
        setTimeout(() => {
          MKEmitter.emit('mkFP', m.uuid, val, 0)
        }, (i + 1) * 100)
      })
    }
    this.props.onChange(val, other)
    this.setState({value: val})
  }
  render() {
    const { config } = this.props
    const { defaultValue } = this.state
    const { value, options, config } = this.state
    return (
      <Radio.Group defaultValue={defaultValue} disabled={config.readonly} onChange={this.onChange}>
        {config.options.map(option => <Radio key={option.key} disabled={option.$disabled} value={option.value}>{option.label}</Radio>)}
      <Radio.Group value={value} disabled={config.readonly} onChange={(e) => this.onChange(e.target.value)}>
        {options.map(option => <Radio key={option.key} disabled={option.$disabled} value={option.value}>{option.label}</Radio>)}
      </Radio.Group>
    )
  }
src/templates/formtabconfig/index.jsx
@@ -430,10 +430,7 @@
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = [{
      value: '',
      text: '空'
    }]
    let _linksupFields = []
    let _formfields = []
    // 设置下拉菜单可关联字段
src/templates/modalconfig/index.jsx
@@ -195,10 +195,7 @@
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = [{
      field: '',
      label: '空'
    }]
    let _linksupFields = []
    let standardform = null
    let uniq = new Map()
@@ -228,7 +225,8 @@
        _tabIndex++
      }
      if (!['select', 'link', 'radio', ''].includes(item.type)) return
      if (!['select', 'link', 'radio', 'checkcard'].includes(item.type)) return
      if (item.type === 'checkcard' && item.multiple === 'true') return // 选项卡多选
      if (item.field && !uniq.has(item.field)) {
        uniq.set(item.field, true)
src/templates/sharecomponent/actioncomponent/actionform/index.jsx
@@ -4,7 +4,7 @@
import { Form, Row, Col, Input, Select, Radio, notification, Tooltip, InputNumber, Cascader } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import { btnClasses, formRule } from '@/utils/option.js'
import { formRule } from '@/utils/option.js'
import asyncComponent from '@/utils/asyncComponent'
import Utils from '@/utils/utils.js'
import './index.scss'
@@ -19,7 +19,7 @@
  excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'icon', 'class', 'sheet', 'execSuccess', 'execError'],
  excelOut: ['label', 'OpenType', 'intertype', 'icon', 'class', 'execSuccess', 'execError', 'pagination', 'search'],
  popview: ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'tabType', 'linkTab', 'popClose', 'display', 'ratio', 'clickouter'],
  tab: ['label', 'Ot', 'OpenType', 'icon', 'class', 'position'],
  tab: ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'linkmenu'],
  innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'icon', 'class', 'position'],
  funcbutton: ['label', 'OpenType', 'funcType', 'icon', 'class']
}
@@ -30,21 +30,11 @@
    setting: PropTypes.object,   // 页面设置
    formlist: PropTypes.any,     // 表单信息
    card: PropTypes.any,         // 按钮信息
    tabs: PropTypes.array,       // 所有标签页
    inputSubmit: PropTypes.any   // 回车提交事件
  }
  state = {
    formlist: null,  // 表单信息
    openType: null,  // 打开方式
    interType: null, // 接口类型:内部、外部
    funcType: null,  // 功能类型
    position: null,  // 按钮位置
    procMode: null,  // 外部接口参数处理方式
    control: '',
    display: '',
    pageTemplate: null,
    Ot: null,
    requireOptions: [{
      value: 'notRequired',
      text: this.props.dict['header.form.notRequired']
@@ -93,77 +83,33 @@
    }]
  }
  record = {}
  
  UNSAFE_componentWillMount () {
    const { card } = this.props
    this.props.formlist.forEach(item => {
      this.record[item.key] = item.initVal
    })
    let _opentype = card.OpenType               // 打开方式
    // let _tabType = card.tabType || 'SubTable'   // 按钮为弹窗(标签)时,标签的类型
    let _intertype = card.intertype || 'system' // 接口类型
    let _procMode = card.procMode || 'system'   // 参数处理方式
    let _funcType = card.funcType || ''         // 功能按钮默认类型
    let _pageTemplate = card.pageTemplate       // 新页面类型
    let _Ot = card.Ot || 'requiredSgl'
    let control = card.control || ''
    let _display = card.display || 'modal'
    let { shows, reOptions, reTypes, reRequired, reReadonly } = this.getMutilOptions()
    if (_opentype === 'outerpage') {
      card.pageTemplate = 'custom'
      _opentype = 'innerpage'
    }
    let _tabs = this.props.tabs.filter(tab => tab.type === 'SubTable')
    let _options = this.getOptions(_opentype, _intertype, _funcType, _pageTemplate, _procMode, _Ot, control, _display)
    this.setState({
      display: _display,
      control: control,
      Ot: _Ot,
      openType: _opentype,
      pageTemplate: _pageTemplate,
      interType: _intertype,
      procMode: _procMode,
      position: card.position || 'toolbar',
      funcType: _funcType,
      formlist: this.props.formlist.map(item => {
        if (item.key === 'class') {
          item.options = btnClasses
        } else if (item.key === 'innerFunc' && _procMode === 'inner') {
          item.required = true
        } else if (item.key === 'intertype') {
          let iscustom = ['pop', 'prompt', 'exec'].includes(_opentype)
          item.options = this.state.interTypeOptions.filter(op => (iscustom || op.value !== 'custom'))
        } else if (item.key === 'Ot') {
          if (card.position === 'grid' || _pageTemplate === 'pay') { // 行级按钮、支付按钮,只能选单行
            item.options = this.state.requireOptions.filter(op => ['requiredSgl'].includes(op.value))
          } else if (_opentype === 'innerpage' && _pageTemplate === 'billprint') {
            item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl', 'required'].includes(op.value))
          } else if (['innerpage', 'tab', 'popview', 'excelIn'].includes(_opentype)) {
            item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
          } else if (card.sqlType === 'insert') {
            item.options = this.state.requireOptions.filter(op => ['notRequired'].includes(op.value))
          } else {
            item.options = this.state.requireOptions
          }
        } else if (item.key === 'sqlType') {
          if (['prompt', 'exec'].includes(_opentype)) {
            item.options = this.state.deleteOptions
          } else {
            item.options = this.state.insertUpdateOptions
          }
        } else if (item.key === 'linkTab') {
          item.options = [
            {
              value: '',
              text: '新建'
            },
            ..._tabs
          ]
        } else if (item.key === 'OpenType') {
          item.initVal = _opentype
        item.hidden = !shows.includes(item.key)
        item.initVal = this.record[item.key]
        if (reOptions[item.key]) {
          item.options = reOptions[item.key]
        }
        if (reTypes[item.key]) {
          item.type = reTypes[item.key]
        }
        if (reRequired[item.key] !== undefined) {
          item.required = reRequired[item.key]
        }
        if (reReadonly[item.key] !== undefined) {
          item.readonly = reReadonly[item.key]
        }
        item.hidden = !_options.includes(item.key)
        return item
      })
    })
@@ -182,342 +128,344 @@
    }
  }
  getOptions = (_opentype, _intertype, _funcType, _pageTemplate, _procMode, _Ot, _control, _display) => {
    let _options = fromJS(actionTypeOptions[_opentype]).toJS() // 选项列表
    if (_opentype === 'innerpage') {         // 新页面,可选模板(自定义时,可填入外部链接)
      if (_pageTemplate === 'custom') {
        _options.push('url', 'joint')
      } else if (_pageTemplate === 'billprint') {
        _options.push('printTemp')
  getMutilOptions = () => {
    const { requireOptions } = this.state
    let openType = this.record.OpenType
    let Ot = this.record.Ot
    let shows = fromJS(actionTypeOptions[openType] || []).toJS()
    let reOptions = {}
    let reTypes = {}
    let reRequired = {}
    let reReadonly = {}
    if (openType === 'pop' || openType === 'prompt' || openType === 'exec') {
      let intertype = this.record.intertype
      reOptions.intertype = this.state.interTypeOptions
      if (intertype === 'custom') {
        shows.push('procMode', 'interface', 'callbackType', 'cbTable', 'proInterface', 'method', 'cross')
        if (this.record.procMode === 'system') {
          shows.push('sql', 'sqlType')
        } else {
          reRequired.innerFunc = true
          shows.push('innerFunc')
        }
        reReadonly.interface = false
        reRequired.interface = true
      } else if (intertype === 'outer') {
        shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc', 'output')
        reRequired.innerFunc = false
        if (this.record.sysInterface === 'false') {
          reReadonly.interface = false
          reRequired.interface = true
        } else {
          reReadonly.interface = true
          reRequired.interface = false
        }
      } else if (intertype === 'inner') {
        shows.push('innerFunc', 'output')
        reRequired.innerFunc = true
      } else {
        shows.push('sql', 'sqlType', 'output')
      }
    } else if (_opentype === 'tab') {         // 标签页
      if (this.props.card.tabTemplate !== 'FormTab') {
        _options.push('linkmenu')
      if (this.record.sqlType === 'insert') {
        reOptions.Ot = requireOptions.filter(op => op.value === 'notRequired')
      } else {
        reOptions.Ot = requireOptions
      }
    } else if (_opentype === 'excelOut') {    // 导入导出
      if (_intertype === 'outer') {
        _options.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc')
      } else if (_intertype === 'inner') {
        _options.push('innerFunc')
      if (openType === 'prompt' || openType === 'exec') {
        reOptions.sqlType = this.state.deleteOptions
      } else {
        reOptions.sqlType = this.state.insertUpdateOptions
      }
    } else if (_opentype === 'excelIn') {    // 导入导出
      if (_intertype === 'outer') {
        _options.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
      } else if (_intertype === 'inner') {
        _options.push('innerFunc')
    } else if (openType === 'excelIn') {
      reOptions.intertype = this.state.interTypeOptions.filter(op => op.value !== 'custom')
      reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
      if (this.record.intertype === 'outer') {
        shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
        reRequired.innerFunc = false
        if (this.record.sysInterface === 'false') {
          reReadonly.interface = false
          reRequired.interface = true
        } else {
          reReadonly.interface = true
          reRequired.interface = false
        }
      } else if (this.record.intertype === 'inner') {
        shows.push('innerFunc')
        reRequired.innerFunc = true
      }
    } else if (_opentype === 'funcbutton') {
    } else if (openType === 'excelOut') {
      reOptions.intertype = this.state.interTypeOptions.filter(op => op.value !== 'custom')
      if (this.record.intertype === 'outer') {
        shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc')
        reRequired.innerFunc = false
        if (this.record.sysInterface === 'false') {
          reReadonly.interface = false
          reRequired.interface = true
        } else {
          reReadonly.interface = true
          reRequired.interface = false
        }
      } else if (this.record.intertype === 'inner') {
        shows.push('innerFunc')
        reRequired.innerFunc = true
      }
    } else if (openType === 'popview') {
      reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
      if (this.record.display === 'drawer') {
        shows.push('placement')
      }
    } else if (openType === 'tab') {
      reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
      reRequired.linkmenu = true
    } else if (openType === 'innerpage') {
      reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
      if (this.record.pageTemplate === 'custom') {
        shows.push('url', 'joint')
      } else if (this.record.pageTemplate === 'billprint') {
        shows.push('printTemp')
        reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl', 'required'].includes(op.value))
      } else if (this.record.pageTemplate === 'pay' || this.record.pageTemplate === 'print' || this.record.pageTemplate === 'billprintTemp') {
        reOptions.Ot = requireOptions.filter(op => op.value === 'requiredSgl')
      }
    } else if (openType === 'funcbutton') {
      reOptions.intertype = this.state.interTypeOptions.filter(op => op.value !== 'custom')
      reOptions.Ot = requireOptions
      let _funcType = this.record.funcType
      if (_funcType === 'print') {
        _options.push('execMode', 'intertype', 'Ot', 'execSuccess', 'execError')
        if (_intertype === 'outer') {
          _options.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
        } else if (_intertype === 'inner') {
          _options.push('innerFunc')
        shows.push('execMode', 'intertype', 'Ot', 'execSuccess', 'execError', 'resetPageIndex')
        if (this.record.intertype === 'outer') {
          shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
          reRequired.innerFunc = false
          if (this.record.sysInterface === 'false') {
            reReadonly.interface = false
            reRequired.interface = true
          } else {
            reReadonly.interface = true
            reRequired.interface = false
          }
        } else if (this.record.intertype === 'inner') {
          shows.push('innerFunc')
          reRequired.innerFunc = true
        }
      } else if (_funcType === 'closetab') {
        _options.push('refreshTab')
        shows.push('refreshTab')
      }
    } else if (_opentype === 'popview') {
      if (_display === 'drawer') {
        _options.push('placement')
      }
    }
    if (this.record.position === 'grid') { // 表格中按钮只能选单行
      reOptions.Ot = requireOptions.filter(op => op.value === 'requiredSgl')
    }
    if (Ot !== 'notRequired') {
      reOptions.control = [
        { value: '', text: '无' },
        { value: 'disabled', text: '禁用' },
        { value: 'hidden', text: '隐藏' },
        { value: 'parent', text: '上级' }
      ]
    } else {
      if (_intertype === 'custom') {
        _options.push('procMode', 'interface', 'callbackType', 'cbTable', 'proInterface', 'method', 'cross')
        if (_procMode === 'system') {
          _options.push('sql', 'sqlType')
        } else {
          _options.push('innerFunc')
        }
      } else if (_intertype === 'outer') {
        _options.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
      } else if (_intertype === 'inner') {
        _options.push('innerFunc', 'preFunc')
      } else {
        _options.push('sql', 'sqlType')
      }
      reOptions.control = [
        { value: '', text: '无' },
        { value: 'parent', text: '上级' }
      ]
    }
    shows.push('control')
    if (this.record.control === 'parent') {
      reTypes.controlField = 'text'
    } else {
      reTypes.controlField = 'select'
    }
    if (this.record.control) {
      shows.push('controlField', 'controlVal')
    }
    if (_options.includes('execSuccess') || _options.includes('popClose')) {
      _options.push('resetPageIndex')
    return {
      shows,
      reOptions,
      reTypes,
      reRequired,
      reReadonly
    }
    if (_Ot !== 'notRequired' && _opentype !== 'excelOut') {
      _options.push('control')
      if (_control) {
        _options.push('controlField', 'controlVal')
      }
    }
    return _options
  }
  /**
   * @description 切换
   */
  optionChange = (key, value) => {
    const { openType, funcType, procMode, Ot, control, display } = this.state
    const { card } = this.props
    this.record[key] = value
    let _fieldval = {}
    if (key === 'OpenType') {
      let _options = this.getOptions(value, 'system', '', this.state.pageTemplate, 'system', Ot, control, 'modal')
      let _fieldval = {}
      let _formlist = this.state.formlist.map(item => {
        item.hidden = !_options.includes(item.key)
      this.record.intertype = 'system'
      this.record.procMode = 'system'
      this.record.display = 'modal'
      this.record.position = 'toolbar'
      this.record.pageTemplate = ''
      this.record.funcType = ''
      this.record.sqlType = ''
        if (item.key === 'intertype') {
          let iscustom = ['pop', 'prompt', 'exec'].includes(value)
          item.options = this.state.interTypeOptions.filter(op => (iscustom || op.value !== 'custom'))
        } else if (item.key === 'control') {
          item.initVal = control
        } else if (item.key === 'display') {
          item.initVal = 'modal'
        }
      if (value === 'pop' || value === 'prompt' || value === 'exec') {
        _fieldval.intertype = 'system'
        _fieldval.sqlType = ''
      } else if (value === 'excelIn') {
        _fieldval.intertype = 'system'
        _fieldval.Ot = 'notRequired'
        _fieldval.label = this.props.dict['model.form.excelIn']
        _fieldval.class = 'dgreen'
        this.record.Ot = 'notRequired'
        this.record.label = this.props.dict['model.form.excelIn']
        this.record.class = 'dgreen'
      } else if (value === 'excelOut') {
        _fieldval.intertype = 'system'
        _fieldval.label = this.props.dict['model.form.excelOut']
        _fieldval.class = 'dgreen'
        this.record.Ot = 'notRequired'
        this.record.label = this.props.dict['model.form.excelOut']
        this.record.class = 'dgreen'
      } else if (value === 'popview') {
        _fieldval.display = 'modal'
        _fieldval.Ot = 'requiredSgl'
        _fieldval.popClose = 'grid'
        this.record.display = 'modal'
        this.record.Ot = 'requiredSgl'
        this.record.popClose = 'grid'
      } else if (value === 'tab') {
        _fieldval.Ot = 'requiredSgl'
        this.record.Ot = 'requiredSgl'
      } else if (value === 'innerpage') {
        _fieldval.Ot = 'requiredSgl'
        this.record.Ot = 'requiredSgl'
      }
      if (value === 'excelIn') {
        _fieldval.label = this.props.dict['model.form.excelIn']
        _fieldval.class = 'border-dgreen'
      } else if (value === 'excelOut') {
        _fieldval.label = this.props.dict['model.form.excelOut']
        _fieldval.class = 'dgreen'
        _fieldval.control = ''
        this.record.control = ''
      }
        if (item.hidden) return item
      if (_fieldval.Ot === 'notRequired') {
        this.record.control = ''
        _fieldval.control = ''
      }
        if (item.key === 'intertype') {
          _fieldval.intertype = 'system'
        } else if (item.key === 'Ot') {
          if (this.state.position === 'grid' || this.state.pageTemplate === 'pay') {
            item.options = this.state.requireOptions.filter(op => ['requiredSgl'].includes(op.value))
            _fieldval.Ot = 'requiredSgl'
          } else if (value === 'innerpage' && this.state.pageTemplate === 'billprint') {
            item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl', 'required'].includes(op.value))
            _fieldval.Ot = 'requiredSgl'
          } else if (['innerpage', 'tab', 'popview'].includes(value)) {
            item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
            _fieldval.Ot = 'requiredSgl'
          } else if (value === 'excelIn') {
            item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
            _fieldval.Ot = 'notRequired'
          } else {
            item.options = this.state.requireOptions
          }
        } 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,
        funcType: '',
        intertype: 'system',
        procMode: 'system',
        display: 'modal',
        formlist: _formlist
      }, () => {
        if (value === 'excelIn') {
          _fieldval.label = this.props.dict['model.form.excelIn']
          _fieldval.class = 'border-dgreen'
        } else if (value === 'excelOut') {
          _fieldval.label = this.props.dict['model.form.excelOut']
          _fieldval.class = 'dgreen'
        }
        this.props.form.setFieldsValue(_fieldval)
      })
      if (!['funcbutton', 'excelIn', 'excelOut'].includes(value)) {
        _fieldval.position = 'toolbar'
      }
    } else if (key === 'position') {
      let _fieldval = {}
      this.setState({
        position: value,
        formlist: this.state.formlist.map(item => {
          if (item.key === 'Ot') {
            if (value === 'grid' || this.state.pageTemplate === 'pay') {
              item.options = this.state.requireOptions.filter(op => ['requiredSgl'].includes(op.value))
              _fieldval.Ot = 'requiredSgl'
            } else if (openType === 'innerpage' && this.state.pageTemplate === 'billprint') {
              item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl', 'required'].includes(op.value))
              _fieldval.Ot = 'requiredSgl'
            } else if (['innerpage', 'tab', 'popview'].includes(openType)) {
              item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
              _fieldval.Ot = 'requiredSgl'
            } else {
              item.options = this.state.requireOptions
            }
          }
          return item
        })
      }, () => {
        this.props.form.setFieldsValue(_fieldval)
      })
      if (value === 'grid') {
        _fieldval.Ot = 'requiredSgl'
        this.record.Ot = 'requiredSgl'
      } else if (['pop', 'prompt', 'exec'].includes(this.record.OpenType) && this.record.sqlType === 'insert') {
        _fieldval.Ot = 'notRequired'
        this.record.Ot = 'notRequired'
      }
    } else if (key === 'funcType') {
      let _options = this.getOptions('funcbutton', this.state.interType, value, card.pageTemplate, procMode, Ot, control, display)
      let _fieldval = {}
      if (value === 'print') {
        _fieldval.label = '打印'
      } else if (value === 'closetab') {
        _fieldval.label = '关闭'
      }
      this.setState({
        funcType: value,
        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' && value === 'print') {
            item.options = this.state.requireOptions
          }
          return item
        })
      }, () => {
        this.props.form.setFieldsValue(_fieldval)
      })
    } else if (key === 'sqlType') {
      let _fieldval = {}
      this.setState({
        formlist: this.state.formlist.map(item => {
          if (item.key === 'Ot' && value === 'insert') {
            item.options = this.state.requireOptions.filter(op => ['notRequired'].includes(op.value))
          } else if (item.key === 'Ot') {
            item.options = this.state.requireOptions
          }
          return item
        })
      }, () => {
        if (value === 'insert') {
          _fieldval.label = '添加'
          _fieldval.class = 'green'
          _fieldval.Ot = 'notRequired'
        } else if (value === 'update') {
          _fieldval.label = '修改'
          _fieldval.class = 'purple'
          _fieldval.Ot = 'requiredSgl'
        } else if (value === 'audit') {
          _fieldval.label = '审核'
          _fieldval.class = 'primary'
          _fieldval.Ot = 'requiredSgl'
        } else if (value === 'LogicDelete' || value === 'delete') {
          _fieldval.label = '删除'
          _fieldval.class = 'danger'
          _fieldval.Ot = 'required'
        }
      if (value === 'insert') {
        _fieldval.label = '添加'
        _fieldval.Ot = 'notRequired'
        _fieldval.class = 'green'
      } else if (value === 'update') {
        _fieldval.label = '修改'
        _fieldval.Ot = 'requiredSgl'
        _fieldval.class = 'purple'
      } else if (value === 'audit') {
        _fieldval.label = '审核'
        _fieldval.Ot = 'requiredSgl'
        _fieldval.class = 'primary'
      } else if (value === 'LogicDelete' || value === 'delete') {
        _fieldval.label = '删除'
        _fieldval.Ot = 'requiredSgl'
        _fieldval.class = 'danger'
      }
        this.props.form.setFieldsValue(_fieldval)
      })
      if (this.record.position === 'grid') {
        _fieldval.Ot = 'requiredSgl'
      }
      this.record.label = _fieldval.label
      this.record.Ot = _fieldval.Ot
      this.record.class = _fieldval.class || ''
      if (_fieldval.Ot === 'notRequired') {
        this.record.control = ''
        _fieldval.control = ''
      }
    } else if (key === 'pageTemplate') {
      let _options = this.getOptions('innerpage', this.state.interType, this.state.funcType, value, procMode, Ot, control, display)
      let _fieldval = {}
      this.setState({
        pageTemplate: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          if (item.key === 'Ot') {
            if (value === 'pay') {
              item.options = this.state.requireOptions.filter(op => ['requiredSgl'].includes(op.value))
              _fieldval.Ot = 'requiredSgl'
            } else if (value === 'billprint') {
              item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl', 'required'].includes(op.value))
              _fieldval.Ot = 'requiredSgl'
            } else {
              item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
            }
          }
          return item
        })
      }, () => {
        this.props.form.setFieldsValue(_fieldval)
      })
      if (value === 'pay') {
        _fieldval.Ot = 'requiredSgl'
      } else if (value === 'billprint') {
        _fieldval.Ot = 'requiredSgl'
      }
    } else if (key === 'intertype') {
      let _options = this.getOptions(openType, value, funcType, '', procMode, Ot, control, display)
      this.setState({
        interType: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          if (item.key === 'innerFunc') {
            item.required = value === 'inner'
          } else if (item.key === 'interface') {
            item.readonly = false
          } else if (item.key === 'sysInterface') {
            item.initVal = 'false'
          } else if (item.key === 'Ot') {
            item.options = this.state.requireOptions
          }
          return item
        })
      })
    } else if (key === 'procMode') {
      let _options = this.getOptions(openType, this.state.interType, funcType, '', value, Ot, control, display)
      this.setState({
        procMode: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          if (item.key === 'innerFunc') {
            item.required = true
          }
          return item
        })
      })
    } else if (key === 'Ot') {
      let _options = this.getOptions(openType, this.state.interType, funcType, this.state.pageTemplate, procMode, value, control, display)
      this.setState({
        Ot: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          return item
        })
      })
    } else if (key === 'control') {
      let _options = this.getOptions(openType, this.state.interType, funcType, this.state.pageTemplate, procMode, Ot, value, display)
      this.setState({
        control: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          return item
        })
      })
    } else if (key === 'display') {
      let _options = this.getOptions(openType, this.state.interType, funcType, this.state.pageTemplate, procMode, Ot, control, value)
      this.setState({
        display: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          return item
        })
      })
      this.record.sysInterface = 'false'
    } else if (key === 'sysInterface') {
      if (value === 'true') {
        this.props.form.setFieldsValue({
          interface: window.GLOB.mainSystemApi || ''
        })
        _fieldval.interface = window.GLOB.mainSystemApi || ''
        this.record.interface = window.GLOB.mainSystemApi || ''
      }
      this.setState({
        formlist: this.state.formlist.map(item => {
          if (item.key === 'interface' && value === 'true') {
            item.readonly = true
          } else if (item.key === 'interface') {
            item.readonly = false
          }
          return item
        })
      })
    }
    let { shows, reOptions, reTypes, reRequired, reReadonly } = this.getMutilOptions()
    this.setState({
      formlist: this.state.formlist.map(item => {
        item.hidden = !shows.includes(item.key)
        item.initVal = this.record[item.key]
        if (reOptions[item.key]) {
          item.options = reOptions[item.key]
        }
        if (reTypes[item.key]) {
          item.type = reTypes[item.key]
        }
        if (reRequired[item.key] !== undefined) {
          item.required = reRequired[item.key]
        }
        if (reReadonly[item.key] !== undefined) {
          item.readonly = reReadonly[item.key]
        }
        return item
      })
    }, () => {
      this.props.form.setFieldsValue(_fieldval)
    })
  }
  handleSubmit = (e) => {
@@ -529,208 +477,111 @@
  }
  getFields() {
    const { dict } = this.props
    const { getFieldDecorator } = this.props.form
    const fields = []
    this.state.formlist.forEach((item, index) => {
      if (item.hidden) return
      if (item.type === 'text') { // 文本搜索
        let _rules = []
        if (item.key === 'innerFunc' || item.key === 'preFunc') {
      let span = 12
      let rules = []
      let className = ''
      let content = null
      let initVal = item.initVal || ''
      if (item.type === 'text') {
        rules = [
          { required: item.required, message: dict['form.required.input'] + item.label + '!' }
        ]
        if (item.key === 'innerFunc') {
          let str = '^(' + item.fields.join('|') + ')'
          let _patten = new RegExp(str + formRule.func.innerPattern + '$', 'g')
          _rules = [{
            pattern: _patten,
            message: formRule.func.innerMessage
          }, {
            max: formRule.func.max,
            message: formRule.func.maxMessage
          }]
          rules.push(
            { pattern: _patten, message: formRule.func.innerMessage },
            { max: formRule.func.max, message: formRule.func.maxMessage }
          )
        } else if (item.key === 'outerFunc' || item.key === 'callbackFunc') {
          _rules = [{
            pattern: formRule.func.pattern,
            message: formRule.func.message
          }, {
            max: formRule.func.max,
            message: formRule.func.maxMessage
          }]
          rules.push(
            { pattern: formRule.func.pattern, message: formRule.func.message },
            { max: formRule.func.max, message: formRule.func.maxMessage }
          )
        } else {
          _rules = [{
            max: formRule.input.max,
            message: formRule.input.message
          }]
          rules.push({ max: formRule.input.max, message: formRule.input.message })
        }
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  },
                  ..._rules
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col>
        )
        content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />
      } else if (item.type === 'number') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<InputNumber min={0} max={10000} precision={0} onPressEnter={this.handleSubmit}/>)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') { // 下拉搜索
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  onChange={(value) => {this.optionChange(item.key, value)}}
                  getPopupContainer={() => document.getElementById('winter')}
                >
                  {item.options.map((option, index) =>
                    <Select.Option id={`${index}`} title={option.text} key={`${index}`} value={option.value || option.field}>
                      {option.text || option.label}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'icon') { // 下拉搜索
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <MkEditIcon options={['edit', 'direction', 'normal', 'data', 'hint']} allowClear/>
              )}
            </Form.Item>
          </Col>
        )
        rules = [
          { required: item.required, message: dict['form.required.input'] + item.label + '!' }
        ]
        content = <InputNumber min={item.min} max={item.max} precision={item.precision} />
      } else if (item.type === 'select') {
        rules = [
          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
        ]
        content = <Select
          showSearch
          allowClear={item.allowClear === true}
          filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
          onChange={(value) => {this.optionChange(item.key, value)}}
          getPopupContainer={() => document.getElementById('winter')}
        >
          {item.options.map((option, index) =>
            <Select.Option key={index} value={(option.value || option.field || '')}>
              {(option.text || option.label)}
            </Select.Option>
          )}
        </Select>
      } else if (item.type === 'radio') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Radio.Group onChange={(e) => {this.optionChange(item.key, e.target.value)}} disabled={item.readonly}>
                  {
                    item.options.map(option => {
                      return (
                        <Radio key={option.value} value={option.value}>{option.text}</Radio>
                      )
                    })
                  }
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
        )
        rules = [
          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
        ]
        content = <Radio.Group onChange={(e) => {this.optionChange(item.key, e.target.value)}}>
          {item.options.map(option => <Radio key={option.value} value={option.value}>{option.text}</Radio>)}
        </Radio.Group>
      } else if (item.type === 'cascader') {
        initVal = item.initVal || []
        rules = [
          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
        ]
        content = <Cascader options={item.options || []} expandTrigger="hover" placeholder=""/>
      } else if (item.type === 'icon') {
        rules = [
          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
        ]
        content = <MkEditIcon options={['edit', 'hint', 'direction', 'normal', 'data']} allowClear/>
      } else if (item.type === 'textarea') {
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label} className="textarea">
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<TextArea rows={2} readOnly={item.readonly} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'cascader') { // 多选
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || [],
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Cascader allowClear options={item.options || []} placeholder="" />
              )}
            </Form.Item>
          </Col>
        )
        span = 24
        className = 'textarea'
        rules = [
          { required: item.readonly ? false : item.required, message: dict['form.required.input'] + item.label + '!' }
        ]
        content = <TextArea rows={2} readOnly={item.readonly}/>
      }
      fields.push(
        <Col span={span} key={index}>
          <Form.Item className={className} label={item.tooltip ?
            <Tooltip placement="topLeft" title={item.tooltip}>
              <QuestionCircleOutlined className="mk-form-tip" />
              {item.label}
            </Tooltip> : item.label
          }>
            {getFieldDecorator(item.key, {
              initialValue: initVal,
              rules: rules
            })(content)}
          </Form.Item>
        </Col>
      )
    })
    return fields
  }
@@ -743,10 +594,9 @@
        if (!err) {
          values.uuid = card.uuid
          values.verify = card.verify || null
          values.position = values.position || 'toolbar'
          if (values.OpenType === 'excelIn') {
            values.position = 'toolbar'
          } else if (values.OpenType === 'excelOut') {
          if (values.OpenType === 'excelOut') {
            if (values.intertype === 'system' && setting.interType !== 'system') { // 导出excel需使用查询数据源
              notification.warning({
                top: 92,
@@ -756,12 +606,9 @@
              return
            }
            
            values.position = 'toolbar'
            values.Ot = 'notRequired'
          } else if (values.OpenType === 'popview' && !values.linkTab) { // 没有关联标签(新建时),创建新标签Id
            values.linkTab = Utils.getuuid()
          } else if (values.OpenType === 'funcbutton') { // 转换打印时打开方式
            values.position = 'toolbar'
          } else if (['pop', 'prompt', 'exec'].includes(values.OpenType) && values.verify) {
            if ((values.Ot === 'requiredOnce' || card.Ot === 'requiredOnce') && card.Ot !== values.Ot) {
              values.verify.uniques = []
src/templates/sharecomponent/actioncomponent/index.jsx
@@ -185,7 +185,7 @@
    this.setState({
      visible: true,
      card: card,
      formlist: getActionForm(card, this.props.config, usefulFields, this.props.type, menulist, this.state.printTemps)
      formlist: getActionForm(card, this.props.config, usefulFields, this.props.type, menulist, this.state.printTemps, this.props.tabs)
    })
  }
@@ -895,7 +895,6 @@
          <ActionForm
            dict={dict}
            card={card}
            tabs={this.props.tabs}
            formlist={this.state.formlist}
            inputSubmit={this.handleSubmit}
            setting={config.setting}
src/templates/zshare/editTable/index.jsx
@@ -507,7 +507,7 @@
  }
  render() {
    const { actions } = this.props
    const { actions, indexShow } = this.props
    let components = {
      body: {
@@ -545,12 +545,14 @@
      }
    })
    columns.unshift({
      title: '序号',
      dataIndex: '$index',
      className: 'mk-index',
      width: '60px',
    })
    if (indexShow !== false) {
      columns.unshift({
        title: '序号',
        dataIndex: '$index',
        className: 'mk-index',
        width: '60px',
      })
    }
    const data = this.state.data.map((item, index) => {
      item.$index = index + 1
src/templates/zshare/formconfig.jsx
@@ -1,6 +1,6 @@
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import { formRule } from '@/utils/option.js'
import { formRule, btnClasses } from '@/utils/option.js'
const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
@@ -820,7 +820,7 @@
 * @param {*} usefulFields   存储过程可用的开始字段
 * @param {*} type           按钮类型,用于区分可选的打开方式
 */
export function getActionForm (card, config, usefulFields, type, menulist = [], printTemps = []) {
export function getActionForm (card, config, usefulFields, type, menulist = [], printTemps = [], tabs = []) {
  let columns = (config.columns || []).filter(col => col.field)
  let opentypes = [
@@ -862,6 +862,11 @@
  }
  if (card.popClose === 'view') {
    card.popClose = 'grid'
  }
  if (card.OpenType === 'outerpage') {
    card.pageTemplate = 'custom'
    card.OpenType = 'innerpage'
  }
  let refresh = []
@@ -981,7 +986,6 @@
      initVal: card.innerFunc || '',
      tooltip: `函数名称需以${usefulFields.join(', ')}等字符开始。`,
      fields: usefulFields,
      tooltipClass: 'middle',
      required: card.intertype === 'inner',
      readonly: false
    },
@@ -991,7 +995,13 @@
      label: '关联标签',
      initVal: card.linkTab || '',
      required: false,
      options: []
      options: [
        {
          value: '',
          text: '新建'
        },
        ...tabs
      ]
    },
    {
      type: 'select',
@@ -1246,7 +1256,7 @@
      label: Formdict['model.form.color'],
      initVal: card.class,
      required: false,
      options: []
      options: btnClasses
    },
    {
      type: 'cascader',
@@ -1332,7 +1342,7 @@
      type: 'number',
      key: 'ratio',
      min: 1,
      max: 24,
      max: 3000,
      precision: 0,
      label: '比例',
      initVal: card.ratio || 85,
@@ -1380,7 +1390,6 @@
      initVal: card.preFunc || '',
      tooltip: `函数名称需以${usefulFields.join(', ')}等字符开始;前置函数执行完成后,结果会传入内部函数中,此时内部函数会异步执行;当前置函数返回中ErrCode等于-1时,将不再执行内部函数。`,
      fields: usefulFields,
      tooltipClass: 'middle',
      required: false,
      readonly: false
    },
@@ -2346,6 +2355,16 @@
    _fieldlength = 8000
  }
  let options = card.options || []
  if (['select', 'radio', 'link'].includes(card.type) && card.setAll === 'true') { // 兼容
    options.unshift({
      key: 'empty',
      Value: '',
      Text: card.emptyText || '空',
      ParentID: ''
    })
  }
  return [
    {
      type: 'text',
@@ -2375,7 +2394,6 @@
      type: 'text',
      key: 'initval',
      label: Formdict['header.form.initval'],
      tooltip: '下拉多选与多选框,添加多个初始值请使用“,”号分隔。注:下拉选择、联动菜单或单选框中$first表示选择第一项',
      initVal: card.initval || '',
      required: false
    },
@@ -2492,19 +2510,19 @@
        text: '16:9'
      }]
    },
    {
      type: 'radio',
      key: 'setAll',
      label: '设置空值',
      initVal: card.setAll || 'false',
      options: [{
        value: 'true',
        text: Formdict['model.true']
      }, {
        value: 'false',
        text: Formdict['model.false']
      }]
    },
    // {
    //   type: 'radio',
    //   key: 'setAll',
    //   label: '设置空值',
    //   initVal: card.setAll || 'false',
    //   options: [{
    //     value: 'true',
    //     text: Formdict['model.true']
    //   }, {
    //     value: 'false',
    //     text: Formdict['model.false']
    //   }]
    // },
    {
      type: 'fields',
      key: 'fields',
@@ -2517,7 +2535,7 @@
      type: 'options',
      key: 'options',
      label: '选项',
      initVal: card.options || [],
      initVal: options,
      required: true,
      readonly: false
    },
@@ -2530,12 +2548,27 @@
      readonly: false
    },
    {
      type: 'radio',
      key: 'multiple',
      label: '选择形式',
      initVal: card.multiple || 'false',
      required: true,
      options: [{
        value: 'true',
        text: '多选'
      }, {
        value: 'false',
        text: '单选'
      }]
    },
    {
      type: 'select',
      key: 'linkField',
      label: '关联字段',
      initVal: card.linkField || '',
      required: true,
      readonly: false,
      allowClear: true,
      options: linkableFields
    },
    {
@@ -2583,20 +2616,6 @@
      tooltip: '设置禁用字段,且字段值为true时,选项不可选。',
      required: false,
      readonly: false
    },
    {
      type: 'radio',
      key: 'multiple',
      label: '可多选',
      initVal: card.multiple || 'false',
      required: true,
      options: [{
        value: 'true',
        text: '是'
      }, {
        value: 'false',
        text: '否'
      }]
    },
    {
      type: 'number',
@@ -2726,10 +2745,10 @@
      type: 'number',
      key: 'fieldlength',
      min: 1,
      max: 1000000,
      max: 100000,
      precision: 0,
      label: Formdict['model.form.field'] + Formdict['model.length'],
      tooltip: '文本、下拉框、日期等字段默认长度为50,多行文本与文件上传字段默认长度为512',
      // tooltip: '文本、下拉框、日期等字段默认长度为50,多行文本与文件上传字段默认长度为512',
      initVal: card.fieldlength || _fieldlength,
      required: false
    },
@@ -3179,10 +3198,11 @@
      type: 'select',
      key: 'supField',
      label: '上级表单',
      tooltip: '上级表单为下拉选择、联动菜单、单选框及多选框,添加后该表单显示及隐藏将受上级表单控制,注:受控关系在该表单隐藏时失效。',
      tooltip: '该表单显示或隐藏受上级表单控制。',
      initVal: card.supField || '',
      required: false,
      readonly: false,
      allowClear: true,
      options: linksupFields
    },
    {
@@ -3191,7 +3211,7 @@
      label: '显示值',
      tooltip: '请填写显示值,只有上级表单值与显示值相同时,该表单才会显示,注:1、多个值用逗号分隔;2、上级表单初始值为$first时暂未处理。',
      initVal: card.supvalue || '',
      required: true,
      required: false,
      readonly: false
    },
    {
@@ -3220,14 +3240,14 @@
      initVal: card.placeholder || '',
      required: false
    },
    {
      type: 'text',
      key: 'emptyText',
      label: '空值文本',
      tooltip: '空值的提示文本,选择设置空值时有效,默认值为《空》。',
      initVal: card.emptyText || '',
      required: false
    },
    // {
    //   type: 'text',
    //   key: 'emptyText',
    //   label: '空值文本',
    //   tooltip: '空值的提示文本,选择设置空值时有效,默认值为《空》。',
    //   initVal: card.emptyText || '',
    //   required: false
    // },
    {
      type: 'radio',
      key: 'enter',
@@ -3256,8 +3276,8 @@
    {
      type: 'multiselect',
      key: 'linkSubField',
      label: Formdict['model.form.linkform'],
      tooltip: '在切换选项时会把信息自动填入关联的表单(文本或数字表单)中。注:使用选项卡且设为可多选时无效。',
      label: '填充表单',
      tooltip: '在切换选项时会把信息自动填入关联的表单(文本或数字表单)中。',
      initVal: card.linkSubField || [],
      options: inputfields
    },
src/templates/zshare/modalform/datatable/index.jsx
@@ -144,8 +144,11 @@
class EdiDataTable extends Component {
  static propTpyes = {
    dict: PropTypes.object,         // 字典项
    type: PropTypes.object,         // 数据类型,文本、图片
    transfield: PropTypes.object,   // 字段名称
    type: PropTypes.string,         // 是否为关联表单
    display: PropTypes.string,      // 数据类型,文本、图片
    fields: PropTypes.array,        // 字段集
    linkSubFields: PropTypes.array, // 填充字段
    onChange: PropTypes.func        // 数据变化
  }
@@ -165,7 +168,12 @@
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    if (!is(fromJS(this.props.fields), fromJS(nextProps.fields)) || !is(fromJS(this.props.type), fromJS(nextProps.type))) {
    if (
      !is(fromJS(this.props.fields), fromJS(nextProps.fields)) ||
      !is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) ||
      this.props.display !== nextProps.display ||
      this.props.type !== nextProps.type
    ) {
      this.setState({editingKey: ''}, () => {
        this.setState({
          columns: this.getCloumns()
@@ -175,15 +183,16 @@
  }
  getCloumns = () => {
    const { type, fields } = this.props
    const { display, fields, linkSubFields, transfield, type } = this.props
    let columns = []
    let keys = ['ParentID']
    if (type === 'picture') {
    if (display === 'picture') {
      columns.push({
        title: 'url',
        dataIndex: '$url',
        inputType: 'file',
        width: '40%',
        // width: '40%',
        editable: true,
        render: (text) => {
          if (!text) return ''
@@ -191,11 +200,26 @@
        }
      })
    } else {
      columns = fields.map(item => ({
        title: item.field,
        dataIndex: item.field,
        editable: true,
      }))
      columns = fields.map(item => {
        keys.push(item.field)
        return {
          title: item.field,
          dataIndex: item.field,
          editable: true,
        }
      })
    }
    if (linkSubFields.length > 0) {
      linkSubFields.forEach(m => {
        if (keys.includes(m)) return
        columns.push({
          title: transfield[m] || m,
          dataIndex: m,
          editable: true,
        })
      })
    }
    
    columns.unshift({
@@ -203,6 +227,14 @@
      dataIndex: '$value',
      editable: true,
    })
    if (type === 'link') {
      columns.unshift({
        title: 'ParentID',
        dataIndex: 'ParentID',
        editable: true,
      })
    }
    columns.push({
      title: '操作',
@@ -297,7 +329,7 @@
  }
  handleAdd = () => {
    const { fields, type } = this.props
    const { fields, display } = this.props
    if (this.state.data.length >= 100) {
      notification.warning({
        top: 92,
@@ -307,9 +339,9 @@
      return
    }
    let item = { key: Utils.getuuid(), $value: `${this.state.data.length + 1}` }
    let item = { key: Utils.getuuid(), $value: `${this.state.data.length + 1}`, ParentID: '' }
    if (type === 'picture') {
    if (display === 'picture') {
      item.$url = ''
    } else {
      fields.forEach(f => {
@@ -369,7 +401,7 @@
    })
    let addable = false
    if (this.props.type === 'picture') {
    if (this.props.display === 'picture') {
      addable = true
    } else if (this.props.fields && this.props.fields.length > 0) {
      addable = true
src/templates/zshare/modalform/datatable/index.scss
@@ -32,9 +32,12 @@
    font-size: 16px;
    text-align: center;
    span {
      margin-right: 15px;
      margin-right: 20px;
      cursor: pointer;
    }
    span:last-child {
      margin-right: 0px;
    }
    .primary {
      color: #1890ff;
    }
src/templates/zshare/modalform/fieldtable/index.jsx
@@ -19,6 +19,7 @@
    let data = this.props['data-__meta'].initialValue || []
    this.setState({
      loading: false,
      data: data.map(item => {
        item.uuid = item.uuid || item.key
        return item
@@ -104,21 +105,24 @@
        message: '字段名不可重复!',
        duration: 5
      })
      this.setState({loading: true}, () => {
        this.setState({loading: false})
      })
      return
    }
    Array.from(new Set(fields))
    this.setState({ data }, () => {
      this.props.onChange(data)
    })
  }
  render() {
    const { data, columns } = this.state
    const { data, columns, loading } = this.state
    return (
      <div className="modal-card-field-table">
        {data.length < 3 ? <PlusOutlined className="add-row" onClick={this.handleAdd} /> : null}
        <EditTable actions={['edit', 'move', 'del']} data={data} columns={columns} onChange={this.changeData}/>
        {!loading ? <EditTable indexShow={false} actions={['edit', 'move', 'del']} data={data} columns={columns} onChange={this.changeData}/> : null}
      </div>
    )
  }
src/templates/zshare/modalform/index.jsx
@@ -22,9 +22,9 @@
  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder', 'place', 'marginTop', 'marginBottom'],
  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline', 'place', 'marginTop', 'marginBottom'],
  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom'],
  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'setAll', 'emptyText', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
  checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'fieldlength', 'span', 'labelwidth', 'display', 'tooltip', 'extra', 'width', 'multiple', 'borderColor', 'splitline', 'marginTop', 'marginBottom'],
  checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'display', 'tooltip', 'extra', 'width', 'multiple', 'borderColor', 'splitline', 'marginTop', 'marginBottom'],
  multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'marginTop', 'marginBottom'],
  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom'],
  fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'tooltip', 'extra', 'compress', 'splitline', 'marginTop', 'marginBottom'],
@@ -52,98 +52,46 @@
  }
  state = {
    openType: null,
    resourceType: null,
    supField: '',
    compress: 'false',
    display: 'text',
    enter: '',
    cFields: [],
    formlist: null,
    linkSubFields: null
    transfield: {},
    formlist: null
  }
  UNSAFE_componentWillMount () {
    let formlist = fromJS(this.props.formlist).toJS()
    let type = ''
    let resourceType = ''
    let supField = ''
    let display = ''
    let compress = 'false'
    let enter = ''
    let cFields = []
    let linkSubFields = []
  record = {}
    formlist.forEach(cell => {
      if (cell.key === 'type') {
        type = cell.initVal
      } else if (cell.key === 'compress') {
        compress = cell.initVal
      } else if (cell.key === 'display') {
        display = cell.initVal
      } else if (cell.key === 'enter') {
        enter = cell.initVal
      } else if (cell.key === 'fields') {
        cFields = cell.initVal
      } else if (cell.key === 'resourceType') {
        resourceType = cell.initVal
      } else if (cell.key === 'linkSubField') {
        let arr = []
        linkSubFields = cell.options.filter(option => {
          if (!['Value', 'Text'].includes(option.field) && cell.initVal.includes(option.field) && !arr.includes(option.field)) {
            arr.push(option.field)
            return true
          } else {
            return false
          }
  UNSAFE_componentWillMount () {
    let transfield = {}
    this.props.formlist.forEach(item => {
      this.record[item.key] = item.initVal
      if (item.key === 'linkSubField') {
        item.options.forEach(cell => {
          transfield[cell.field] = cell.label
        })
      } else if (cell.key === 'supField') {
        supField = cell.initVal
      }
    })
    let _options = this.getOptions(type, resourceType, supField, display, enter, compress)
    let { shows, reOptions, reTypes, reRequired, reTooltip } = this.getMutilOptions()
    this.setState({
      enter: enter,
      compress: compress,
      openType: type,
      supField: supField,
      display: display,
      cFields: cFields,
      resourceType: resourceType,
      linkSubFields: linkSubFields,
      formlist: formlist.map(form => {
        if (form.key === 'initval') {
          if (dateOptions.hasOwnProperty(type)) {
            form.options = dateOptions[type]
            form.type = 'select'
          } else if (type === 'switch') {
            form.initVal = !!form.initVal
            form.options = [
              {value: true, text: '开'},
              {value: false, text: '关'}
            ]
            form.type = 'radio'
          }
          if (type === 'number') {
            form.type = 'number'
            form.initVal = form.initVal || 0
            form.required = true
          } else if (type === 'rate') {
            form.type = 'number'
            form.initVal = form.initVal || 0
            form.required = false
          }
        } else if (form.key === 'label') {
          form.required = true
          if (type === 'hint') {
            form.required = false
          }
      transfield,
      formlist: this.props.formlist.map(item => {
        item.show = shows.includes(item.key)
        item.initVal = this.record[item.key]
        if (reOptions[item.key]) {
          item.options = reOptions[item.key]
        }
        if (reTypes[item.key]) {
          item.type = reTypes[item.key]
        }
        if (reRequired[item.key] !== undefined) {
          item.required = reRequired[item.key]
        }
        if (reTooltip[item.key] !== undefined) {
          item.tooltip = reTooltip[item.key]
        }
        form.show = _options.includes(form.key)
        return form
        return item
      })
    })
  }
@@ -161,252 +109,257 @@
    }
  }
  getOptions = (type, resourceType, supField, display, enter, compress) => {
    let _options = ['label', 'field', 'type', 'blacklist', 'writein', ...fromJS(modalTypeOptions[type]).toJS()]
  getMutilOptions = () => {
    let type = this.record.type
    let shows = ['label', 'field', 'type', 'blacklist', 'writein', 'supField', ...fromJS(modalTypeOptions[type] || []).toJS()]
    let reOptions = {}
    let reTypes = {}
    let reRequired = {}
    let reTooltip = {}
    if (type === 'hint') {
      _options = fromJS(modalTypeOptions[type]).toJS()
    } else if (type === 'split') {
      return fromJS(modalTypeOptions[type]).toJS()
    if (type === 'hint' || type === 'split') {
      shows = fromJS(modalTypeOptions[type]).toJS()
    }
    // text number select multiselect link switch checkbox radio checkcard fileupload date datemonth datetime textarea
    // rate color brafteditor funcvar hint split linkMain
    // 通用设置
    reTypes.initval = 'text'
    reRequired.initval = false
    reRequired.label = true
    reRequired.linkField = true
    reTooltip.initval = ''
    if (type === 'text') {
      if (this.record.enter === 'tab' || this.record.enter === 'sub') {
        shows.push('tabField')
      }
    } else if (type === 'number') {
      reTypes.initval = 'number'
      reRequired.initval = true
      if (this.record.enter === 'tab' || this.record.enter === 'sub') {
        shows.push('tabField')
      }
    } else if (['multiselect', 'select', 'link', 'radio', 'checkbox'].includes(type)) {
      if (resourceType === '0') {        // 自定义资源
        _options.push('options')
      } else if (resourceType === '1') { // 数据源
        _options.push('dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'disableField', 'database')
      if (this.record.resourceType === '0') {        // 自定义资源
        shows.push('options')
      } else if (this.record.resourceType === '1') { // 数据源
        shows.push('dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'disableField', 'database')
      }
      if (type === 'select' || type === 'link') {
        if (this.record.enter === 'tab' || this.record.enter === 'sub') {
          shows.push('tabField')
        }
      } else if (type === 'radio') {
        shows.push('linkField')
        reRequired.linkField = false
      }
    } else if (type === 'checkcard') {
      if (display === 'picture') {
        if (resourceType === '0') {        // 自定义资源
          _options.push('options', 'ratio')
        } else if (resourceType === '1') { // 数据源
          _options.push('dataSource', 'cardValField', 'urlField', 'orderBy', 'orderType', 'disableField', 'database', 'ratio')
      if (this.record.display === 'picture') {
        if (this.record.resourceType === '0') {        // 自定义资源
          shows.push('options', 'ratio')
        } else if (this.record.resourceType === '1') { // 数据源
          shows.push('dataSource', 'cardValField', 'urlField', 'orderBy', 'orderType', 'disableField', 'database', 'ratio')
        }
      } else {
        if (resourceType === '0') {        // 自定义资源
          _options.push('options', 'fields', 'backgroundColor')
        } else if (resourceType === '1') { // 数据源
          _options.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'disableField', 'database', 'backgroundColor')
        if (this.record.resourceType === '0') {        // 自定义资源
          shows.push('options', 'fields', 'backgroundColor')
        } else if (this.record.resourceType === '1') { // 数据源
          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'disableField', 'database', 'backgroundColor')
        }
      }
      if (this.record.multiple === 'false') {
        shows.push('linkSubField')
        shows.push('linkField')
        reRequired.linkField = false
      } else {
        reTooltip.initval = '添加多个初始值请使用逗号分隔。'
      }
      if (sessionStorage.getItem('appType') === 'mob') {
        _options.push('hidelabel')
        shows.push('hidelabel')
      }
    } else if (['date', 'datemonth', 'datetime'].includes(type)) {
      reOptions.initval = dateOptions[type]
      reTypes.initval = 'select'
    } else if (type === 'switch') {
      reOptions.initval = [
        {value: true, text: '开'},
        {value: false, text: '关'}
      ]
      reTypes.initval = 'radio'
    } else if (type === 'rate') {
      reTypes.initval = 'number'
    } else if (type === 'hint') {
      reRequired.label = false
    } else if (type === 'fileupload') {
      if (compress === 'true') {
        _options.push('limit', 'rduri', 'proRduri')
      if (this.record.compress === 'true') {
        shows.push('limit', 'rduri', 'proRduri')
      } else {
        _options.push('suffix')
        shows.push('suffix')
      }
    }
    if (type === 'text' || type === 'number' || type === 'select' || type === 'link') {
      if (enter === 'tab' || enter === 'sub') {
        _options.push('tabField')
      }
    if (['multiselect', 'checkbox'].includes(type)) {
      reTooltip.initval = '添加多个初始值请使用逗号分隔。'
    } else if (['select', 'link', 'radio'].includes(type)) {
      reTooltip.initval = '使用$first表示默认选择第一项。'
    }
    if (type !== 'funcvar' && type !== 'linkMain') {
      if (supField) {
        _options.push('supField', 'supvalue')
      } else {
        _options.push('supField')
      }
    if (this.record.supField) {
      shows.push('supvalue')
    }
    return _options
    return {
      shows,
      reOptions,
      reTypes,
      reRequired,
      reTooltip
    }
  }
  openTypeChange = (key, value) => {
  optionChange = (key, value) => {
    let _fieldval = {}
    if (key === 'type') {
      let enter = 'false'
      let fieldValue = {}
      this.record.enter = 'false'
      this.record.initval = ''
      this.record.fieldlength = 50
      _fieldval.initval = ''
      if (value === 'text' || value === 'number') {
        enter = 'sub'
        fieldValue.enter = 'sub'
        this.record.enter = 'sub'
        _fieldval.enter = 'sub'
      } else if (value === 'select' || value === 'link') {
        fieldValue.enter = 'false'
        _fieldval.enter = 'false'
      }
      let _options = this.getOptions(value, this.state.resourceType, this.state.supField, this.state.display, enter, this.state.compress)
      this.setState({
        openType: value,
        enter: enter,
        formlist: this.state.formlist.map(form => {
          form.show = _options.includes(form.key)
          if (form.key === 'initval') {
            form.required = false
            form.initVal = ''
            if (dateOptions.hasOwnProperty(value)) {
              form.options = dateOptions[value]
              form.type = 'select'
            } else if (value === 'switch') {
              form.initVal = false
              form.options = [
                {value: true, text: '开'},
                {value: false, text: '关'}
              ]
              form.type = 'radio'
            } else if (value === 'number') {
              form.type = 'number'
              form.required = true
              form.initVal = 0
            } else if (value === 'rate') {
              form.type = 'number'
              form.required = false
              form.initVal = 0
            } else {
              form.type = 'text'
            }
      if (value === 'number' || value === 'rate') {
        this.record.initval = 0
        _fieldval.initval = 0
      } else if (value === 'switch') {
        this.record.initval = false
        _fieldval.initval = false
      }
            if (form.show) {
              fieldValue.initval = form.initVal
            }
          } else if (form.key === 'fieldlength') {
            form.initVal = 50
            if (value === 'textarea' || value === 'brafteditor') {
              form.initVal = 8000
            } else if (value === 'fileupload' || value === 'multiselect' || value === 'checkbox') {
              form.initVal = 512
            }
      if (['hint', 'split', 'brafteditor', 'funcvar', 'linkMain', 'fileupload'].includes(value)) {
        delete _fieldval.initval
      }
            if (form.show) {
              fieldValue.fieldlength = form.initVal
            }
          } else if (form.key === 'resourceType') {
            form.initVal = this.state.resourceType
      if (value === 'text' || value === 'linkMain' || value === 'checkcard') {
        _fieldval.fieldlength = 50
      } else if (value === 'textarea' || value === 'brafteditor') {
        this.record.fieldlength = 8000
        _fieldval.fieldlength = 8000
      } else if (value === 'fileupload' || value === 'multiselect' || value === 'checkbox') {
        this.record.fieldlength = 512
        _fieldval.fieldlength = 512
      }
            if (form.show) {
              fieldValue.resourceType = form.initVal
            }
          } else if (form.key === 'linkSubField') {
            form.initVal = this.state.linkSubFields.map(_field => _field.field)
      if (value === 'brafteditor') {
        this.record.encryption = 'true'
        _fieldval.encryption = 'true'
      }
            if (form.show) {
              fieldValue.linkSubField = form.initVal
            }
          } else if (form.key === 'label') {
            form.required = true
            if (value === 'hint') {
              form.required = false
            }
          } else if (form.key === 'encryption') {
            if (value === 'brafteditor') {
              fieldValue.encryption = 'true'
            }
          } else if (form.key === 'hidden') {
            if (value === 'linkMain') {
              fieldValue.hidden = 'true'
            }
      if (value === 'linkMain') {
        this.record.hidden = 'true'
        _fieldval.hidden = 'true'
      }
      if (this.record.options.length > 0) {
        if (value === 'checkcard') {
          this.record.options = this.record.options.map(cell => {
            cell.$value = cell.Value || ''
            delete cell.Value
            return cell
          })
          if (this.record.options[0].Text) {
            let key = Utils.getuuid()
            this.record.fields = [{
              $index: 1,
              align: 'left',
              color: 'rgba(0, 0, 0, 0.85)',
              field: 'Text',
              fontSize: 14,
              key: key,
              uuid: key
            }]
          }
          return form
        })
      }, () => {
        this.props.form.setFieldsValue(fieldValue)
      })
    } else if (key === 'supField') {
      this.setState({
        supField: value,
        formlist: this.state.formlist.map(form => {
          if (form.key === 'supvalue' && value) {
            form.show = true
          } else if (form.key === 'supvalue' && !value) {
            form.show = false
        } else if (['multiselect', 'select', 'link', 'radio', 'checkbox'].includes(value)) {
          if (!this.record.options[0].Text && this.record.fields.length > 0) {
            let field = this.record.fields[0].field
            this.record.options = this.record.options.map(cell => {
              cell.Value = cell.Value || cell.$value || ''
              cell.Text = cell[field] || ''
              return cell
            })
          } else {
            this.record.options = this.record.options.map(cell => {
              cell.Value = cell.Value || cell.$value || ''
              return cell
            })
          }
          return form
        })
      })
    }
  }
  multiselectChange = (key, value, options) => {
    if (key === 'linkSubField') {
      let arr = []
      let linkSubField = {}
      options.forEach(option => {
        if (!['Value', 'Text'].includes(option.field) && value.includes(option.field) && !arr.includes(option.field)) {
          arr.push(option.field)
          linkSubField[option.field] = option
        }
      })
      let linkSubFields = []
      value.forEach(item => {
        if (linkSubField[item]) {
          linkSubFields.push(linkSubField[item])
        }
      })
      this.setState({linkSubFields: linkSubFields})
    }
  }
  onChange = (e, key) => {
    const { openType, compress } = this.state
    let value = e.target.value
    if (key === 'resourceType') {
      let _options = this.getOptions(openType, value, this.state.supField, this.state.display, this.state.enter, compress)
      this.setState({
        resourceType: value,
        formlist: this.state.formlist.map(form => {
          form.show = _options.includes(form.key)
          return form
        })
      })
    } else if (key === 'display') {
      let _options = this.getOptions(openType, this.state.resourceType, this.state.supField, value, this.state.enter, compress)
      this.setState({
        display: value,
        formlist: this.state.formlist.map(form => {
          form.show = _options.includes(form.key)
          return form
        })
      })
    } else if (key === 'compress') {
      let _options = this.getOptions(openType, this.state.resourceType, this.state.supField, this.state.display, this.state.enter, value)
      this.setState({
        compress: value,
        formlist: this.state.formlist.map(form => {
          form.show = _options.includes(form.key)
          return form
        })
      })
    } else if (key === 'enter') {
      let _options = this.getOptions(openType, this.state.resourceType, this.state.supField, this.state.display, value, compress)
      this.setState({
        enter: value,
        formlist: this.state.formlist.map(form => {
          form.show = _options.includes(form.key)
          return form
        })
      })
      }
    } else if (key === 'multiple') {
      if (value === 'true') {
        this.props.form.setFieldsValue({fieldlength: 512})
        this.record.fieldlength = 512
        _fieldval.fieldlength = 512
      } else {
        this.props.form.setFieldsValue({fieldlength: 50})
        this.record.fieldlength = 50
        _fieldval.fieldlength = 50
      }
    }
    this.record[key] = value
    let { shows, reOptions, reTypes, reRequired, reTooltip } = this.getMutilOptions()
    this.setState({
      formlist: this.state.formlist.map(item => {
        item.show = shows.includes(item.key)
        item.initVal = this.record[item.key]
        if (reOptions[item.key]) {
          item.options = reOptions[item.key]
        }
        if (reTypes[item.key]) {
          item.type = reTypes[item.key]
        }
        if (reRequired[item.key] !== undefined) {
          item.required = reRequired[item.key]
        }
        if (reTooltip[item.key] !== undefined) {
          item.tooltip = reTooltip[item.key]
        }
        return item
      })
    }, () => {
      this.props.form.setFieldsValue(_fieldval)
    })
  }
  multiselectChange = (key, value) => {
    if (key !== 'linkSubField') return
    this.record[key] = value
  }
  changeField = (data) => {
    this.setState({
      cFields: data,
      formlist: this.state.formlist.map(form => {
        if (form.key === 'fields') {
          form.initVal = data
        }
        return form
      })
    })
    this.record.fields = data || []
  }
  changeOptions = (data) => {
    this.record.options = data || []
  }
  changeVal = (val, type) => {
@@ -447,7 +400,6 @@
      }
    } 
    if (labelwidth) {
      this.props.form.setFieldsValue({labelwidth})
    }
@@ -463,285 +415,162 @@
  getFields() {
    const { getFieldDecorator } = this.props.form
    const { openType } = this.state
    const { dict } = this.props
    const { transfield } = this.state
    const fields = []
    this.state.formlist.forEach((item, index) => {
      if (!item.show || item.forbid) return null
      if (item.type === 'text') { // 文本搜索
        let rules = []
      let span = 12
      let rules = []
      let className = ''
      let content = null
      let initVal = item.initVal || ''
      if (item.type === 'text') {
        rules = [
          { required: item.required, message: dict['form.required.input'] + item.label + '!' }
        ]
        if (item.key === 'field') {
          rules = [{
          rules.push({
            pattern: formRule.field.pattern,
            message: formRule.field.message
          }, {
            max: formRule.field.max,
            message: formRule.field.maxMessage
          }]
          })
        } else {
          rules = [
            {
              max: formRule.input.max,
              message: formRule.input.message
            }
          ]
          rules.push({
            max: formRule.input.max,
            message: formRule.input.message
          })
        }
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  },
                  ...rules
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col>
        )
        content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />
      } else if (item.type === 'number') {
        rules = [
          { required: item.required, message: dict['form.required.input'] + item.label + '!' }
        ]
        initVal = item.initVal
        if (item.max) {
          fields.push(
            <Col span={12} key={index}>
              <Form.Item label={item.tooltip ?
                <Tooltip placement="topLeft" title={item.tooltip}>
                  <QuestionCircleOutlined className="mk-form-tip" />
                  {item.label}
                </Tooltip> : item.label
              }>
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal || 0,
                  rules: [
                    {
                      required: !!item.required,
                      message: this.props.dict['form.required.input'] + item.label + '!'
                    }
                  ]
                })(<InputNumber onChange={(value) => this.changeVal(value, item.key)} min={item.min} max={item.max} precision={item.precision} onPressEnter={this.handleSubmit}/>)}
              </Form.Item>
            </Col>
          )
          content = <InputNumber onChange={(value) => this.changeVal(value, item.key)} min={item.min} max={item.max} precision={item.precision} onPressEnter={this.handleSubmit}/>
        } else {
          fields.push(
            <Col span={12} key={index}>
              <Form.Item label={item.tooltip ?
                <Tooltip placement="topLeft" title={item.tooltip}>
                  <QuestionCircleOutlined className="mk-form-tip" />
                  {item.label}
                </Tooltip> : item.label
              }>
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal,
                  rules: [
                    {
                      required: !!item.required,
                      message: this.props.dict['form.required.input'] + item.label + '!'
                    }
                  ]
                })(<InputNumber onPressEnter={this.handleSubmit}/>)}
              </Form.Item>
            </Col>
          )
          content = <InputNumber onPressEnter={this.handleSubmit}/>
        }
      } else if (item.type === 'select') { // 下拉搜索
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  onChange={(value) => {this.openTypeChange(item.key, value)}}
                  getPopupContainer={() => document.getElementById('modal-fields-form-box')}
                >
                  {item.options.map((option, i) =>
                    <Select.Option key={`${i}`} value={option.value || option.field || ''}>
                      {option.text || option.label}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') {
        rules = [
          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
        ]
        content = <Select
          showSearch
          allowClear={item.allowClear === true}
          filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0}
          onChange={(value) => {this.optionChange(item.key, value)}}
          getPopupContainer={() => document.getElementById('modal-fields-form-box')}
        >
          {item.options.map((option, i) =>
            <Select.Option key={`${i}`} value={option.value || option.field || ''}>
              {option.text || option.label}
            </Select.Option>
          )}
        </Select>
      } else if (item.type === 'multiselect') { // 多选
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal
              })(
                <Select
                  showSearch
                  mode="multiple"
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  onChange={(value) => this.multiselectChange(item.key, value, item.options)}
                >
                  {item.options.map((option, i) =>
                    <Select.Option key={i} value={option.field}>{option.label}</Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
        content = <Select
          showSearch
          mode="multiple"
          filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
          onChange={(value) => this.multiselectChange(item.key, value)}
        >
          {item.options.map((option, i) =>
            <Select.Option key={i} value={option.field}>{option.label}</Select.Option>
          )}
        </Select>
      } else if (item.type === 'radio') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Radio.Group onChange={(e) => {this.onChange(e, item.key)}}>
                  {item.options.map(option => {
                    return (
                      <Radio key={option.value} value={option.value}>{option.text}</Radio>
                    )
                  })}
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
        )
        rules = [
          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
        ]
        content = <Radio.Group onChange={(e) => {this.optionChange(item.key, e.target.value)}}>
          {item.options.map(option => {
            return (
              <Radio key={option.value} value={option.value}>{option.text}</Radio>
            )
          })}
        </Radio.Group>
      } else if (item.type === 'codemirror') {
        fields.push(
          <Col span={24} key={index}>
            <Form.Item className="text-area" label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<CodeMirror />)}
            </Form.Item>
          </Col>
        )
        rules = [
          { required: item.required, message: dict['form.required.input'] + item.label + '!' }
        ]
        span = 24
        className = 'text-area'
        content = <CodeMirror />
      } else if (item.type === 'textarea') {
        fields.push(
          <Col span={24} key={index}>
            <Form.Item className="text-msg" label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<TextArea rows={item.rows || 4} />)}
            </Form.Item>
          </Col>
        )
        span = 24
        className = 'text-msg'
        rules = [
          { required: item.required, message: dict['form.required.input'] + item.label + '!' }
        ]
        content = <TextArea rows={item.rows || 4}/>
      } else if (item.type === 'options') {
        if (openType !== 'checkcard') {
          fields.push(
            <Col span={24} key={index}>
              <Form.Item label={item.label} className="text-area">
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal
                })(<EditTable type={openType} linkSubFields={this.state.linkSubFields}/>)}
              </Form.Item>
            </Col>
          )
        span = 24
        className = 'text-area'
        let type = this.record.type
        let linkSubFields = this.record.linkSubField || []
        if (type !== 'checkcard') {
          if (!['select', 'radio', 'link'].includes(type)) {
            linkSubFields = []
          }
          if (type === 'radio' && this.record.linkField) {
            type = 'link'
          }
          content = <EditTable type={type} transfield={transfield} linkSubFields={linkSubFields} onChange={this.changeOptions}/>
        } else {
          fields.push(
            <Col span={24} key={index}>
              <Form.Item label={item.label} className="text-area">
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal
                })(<DataTable dict={this.props.dict} type={this.state.display} fields={this.state.cFields}/>)}
              </Form.Item>
            </Col>
          )
          if (this.record.multiple === 'true') {
            linkSubFields = []
          }
          if (this.record.linkField) {
            type = 'link'
          }
          content = <DataTable dict={this.props.dict} type={type} display={this.record.display} linkSubFields={linkSubFields} transfield={transfield} fields={this.record.fields || []} onChange={this.changeOptions}/>
        }
      } else if (item.type === 'fields') {
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label} className="text-area">
              {getFieldDecorator(item.key, {
                initialValue: item.initVal
              })(<FieldsTable dict={this.props.dict} onChange={this.changeField}/>)}
            </Form.Item>
          </Col>
        )
        span = 24
        className = 'text-area'
        content = <FieldsTable dict={this.props.dict} onChange={this.changeField}/>
      } else if (item.type === 'color') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label} className="color-form-item">
              {getFieldDecorator(item.key, {
                initialValue: item.initVal
              })(<ColorSketch allowClear={true}/>)}
            </Form.Item>
          </Col>
        )
        className = 'color-form-item'
        content = <ColorSketch allowClear={true}/>
      } else if (item.type === 'icon') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [{
                  required: !!item.required,
                  message: this.props.dict['form.required.select'] + item.label + '!'
                }]
              })(
                <MkEditIcon allowClear />
              )}
            </Form.Item>
          </Col>
        )
        rules = [
          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
        ]
        content = <MkEditIcon allowClear />
      }
      fields.push(
        <Col span={span} key={index}>
          <Form.Item className={className} label={item.tooltip ?
            <Tooltip placement="topLeft" title={item.tooltip}>
              <QuestionCircleOutlined className="mk-form-tip" />
              {item.label}
            </Tooltip> : item.label
          }>
            {getFieldDecorator(item.key, {
              initialValue: initVal,
              rules: rules
            })(content)}
          </Form.Item>
        </Col>
      )
    })
    return fields
@@ -758,23 +587,91 @@
            if (values.resourceType === '0') {
              values.options = values.options || []
              values.dataSource = ''
              let empty = false
              let type = values.type
              if (values.type === 'radio' && values.linkField) {
                type = 'link'
              }
              values.options.forEach(op => {
                if (!((op.Value || op.Value === 0) && (op.Text || op.Text === 0))) {
                  empty = true
                } else if (values.type === 'link' && !(op.ParentID || op.ParentID === 0)) {
                  empty = true
                }
              })
              if (empty) {
              if (values.options.filter(op => op.Text === '').length > 0) {
                notification.warning({
                  top: 92,
                  message: '下拉选项设置错误!',
                  message: '提示文本(Text)不可为空!',
                  duration: 5
                })
                return
              } else if (values.options.filter(op => op.Value === '').length > 1) {
                notification.warning({
                  top: 92,
                  message: 'Value为空最多只可添加一行(在关联菜单中,Value为空时不区分ParentID)!',
                  duration: 5
                })
                return
              } else if (type === 'link') {
                let arr = values.options.map(m => m.ParentID + m.Value)
                let _arr = Array.from(new Set(arr))
                if (arr.length > _arr.length) {
                  notification.warning({
                    top: 92,
                    message: '同一ParentID中,Value值不可重复!',
                    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
                }
              }
            } else {
              values.options = []
            }
          } else if (values.type === 'checkcard') {
            if (values.resourceType === '0') {
              values.options = values.options || []
              let linkSubFields = values.linkSubField || []
              values.options = values.options.map(m => {
                m.ParentID = m.ParentID || ''
                linkSubFields.forEach(n => {
                  m[n] = m[n] || ''
                })
                return m
              })
              let type = values.type
              if (values.linkField) {
                type = 'link'
              }
              if (type === 'link') {
                let arr = values.options.map(m => m.ParentID + m.$value)
                let _arr = Array.from(new Set(arr))
                if (arr.length > _arr.length) {
                  notification.warning({
                    top: 92,
                    message: '同一ParentID中,Value值不可重复!',
                    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
                }
              }
            } else {
              values.options = []
src/templates/zshare/modalform/modaleditable/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Table, Input, Popconfirm, Form, Radio } from 'antd'
import { Table, Input, Popconfirm, Form, Radio, message } from 'antd'
import { ArrowUpOutlined, ArrowDownOutlined, DeleteOutlined, PlusOutlined, SwapOutlined } from '@ant-design/icons'
import { formRule } from '@/utils/option.js'
@@ -40,6 +40,9 @@
      if (datatype === 'number') {
        Object.keys(values).forEach(key => {
          values[key] = parseFloat(values[key])
          if (isNaN(values[key])) {
            values[key] = 0
          }
        })
      }
      handleSave({ ...record, ...values })
@@ -68,8 +71,8 @@
        {form.getFieldDecorator(dataIndex, {
          rules: [
            {
              required: dataIndex === 'Value' || dataIndex === 'Text',
              message: 'NOT NULL.',
              required: dataIndex === 'Text',
              message: '不可为空.',
            },
            ...rules
          ],
@@ -113,94 +116,26 @@
  static propTpyes = {
    type: PropTypes.string,         // 表单类型
    linkSubFields: PropTypes.array, // 关联字段
    transfield: PropTypes.object,   // 表单字段名称
    onChange: PropTypes.func        // 数据变化
  }
  state = {
    columns: [],
    dataSource: [],
    count: 0,
    type: null,
    linkSubFields: []
    count: 0
  }
  UNSAFE_componentWillMount () {
    const { linkSubFields, type } = this.props
    let data = this.props['data-__meta'].initialValue
    let data = this.props['data-__meta'].initialValue || []
    if (!data) {
      data = []
    }
    let fields = []
    let dataItem = data[0] || ''
    if (type === 'select' || type === 'radio' || type === 'link') {
      fields = linkSubFields.map(cell => {
        return {
          title: cell.label,
          dataIndex: cell.field,
          editable: true,
          datatype: dataItem && typeof(dataItem[cell.field]) === 'number' ? 'number' : 'string'
        }
      })
    }
    let columns = [
      {
        title: 'Value',
        dataIndex: 'Value',
        editable: true,
        datatype: dataItem && typeof(dataItem.Value) === 'number' ? 'number' : 'string'
      },
      {
        title: 'Text',
        dataIndex: 'Text',
        editable: true,
        datatype: dataItem && typeof(dataItem.Text) === 'number' ? 'number' : 'string'
      },
      ...fields,
      {
        title: '操作',
        align: 'center',
        width: '20%',
        dataIndex: 'operation',
        render: (text, record) =>
          this.state.dataSource.length >= 1 ? (
            <div>
              <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>
              <Popconfirm
                overlayClassName="popover-confirm"
                onConfirm={() => this.handleDelete(record.key)
              }>
                <span style={{color: '#ff4d4f', cursor: 'pointer'}}><DeleteOutlined /></span>
              </Popconfirm>
            </div>
          ) : null,
      }
    ]
    if (type === 'link') {
      columns.unshift({
        title: 'ParentID',
        dataIndex: 'ParentID',
        editable: true,
        datatype: dataItem && typeof(dataItem.ParentID) === 'number' ? 'number' : 'string'
      })
    }
    const { columns } = this.getColumns(type, linkSubFields, data)
    this.setState({
      columns: columns.map(col => {
        if (col.dataIndex !== 'operation') {
          col = {...col, ...this.getColumnSearchProps(col)}
        }
        return col
      }),
      columns: columns,
      dataSource: data,
      count: data.length,
      type: type,
      linkSubFields: linkSubFields
      count: data.length
    })
  }
@@ -228,13 +163,9 @@
    let _data = dataSource.map(item => {
      let val = item[column.dataIndex]
      if (value === 'number') {
        try {
          val = parseFloat(val)
          if (isNaN(val)) {
            val = ''
          }
        } catch (e) {
          val = ''
        val = parseFloat(val)
        if (isNaN(val)) {
          val = 0
        }
      } else {
        val = '' + val
@@ -302,15 +233,18 @@
  handleAdd = (e) => {
    e.stopPropagation()
    const { type, count, dataSource } = this.state
    const { linkSubFields } = this.props
    const { count, dataSource } = this.state
    const newData = {
      key: Utils.getuuid(),
      Value: `${count}`,
      Text: `${count}`
      Text: `${count}`,
      ParentID: ''
    }
    if (type === 'link') {
      newData.ParentID = `${count}`
    }
    linkSubFields.forEach(m => {
      newData[m] = newData[m] || ''
    })
    let _data = [...dataSource, newData]
@@ -323,9 +257,21 @@
  }
  handleSave = row => {
    const { 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值已存在!')
      }
    } else {
      if (newData.filter(m => row.key !== m.key && row.Value === m.Value).length > 0) {
        message.warning('此Value值已存在!')
      }
    }
    newData.splice(index, 1, {
      ...item,
      ...row
@@ -335,29 +281,35 @@
    })
  }
  resetColumn = (type, linkSubFields) => {
    let dataSource = JSON.parse(JSON.stringify(this.state.dataSource))
    let fields = []
  getColumns = (type, linkSubFields, dataSource) => {
    const { transfield } = this.props
    if ((type === 'select' || type === 'radio') && linkSubFields.length > this.state.linkSubFields) {
      let addcol = linkSubFields.slice(-1)[0]
      dataSource = dataSource.map(data => {
        data[addcol.field] = data.Text
    let _dataSource = fromJS(dataSource).toJS()
    let fields = []
    let dataItem = ''
    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 dataItem = dataSource ? dataSource[0] : ''
      dataItem = _dataSource ? _dataSource[0] : ''
    if (type === 'select' || type === 'radio' || type === 'link') {
      fields = linkSubFields.map(field => {
      fields = subFields.map(field => {
        return {
          title: field.label,
          dataIndex: field.field,
          title: transfield[field] || field,
          dataIndex: field,
          editable: true,
          datatype: dataItem && typeof(dataItem[field.field]) === 'number' ? 'number' : 'string'
          datatype: dataItem && typeof(dataItem[field]) === 'number' ? 'number' : 'string'
        }
      })
    } else {
      dataItem = _dataSource ? _dataSource[0] : ''
    }
    let columns = [
@@ -381,10 +333,11 @@
        dataIndex: 'operation',
        render: (text, record) =>
          this.state.dataSource.length >= 1 ? (
            <div>
            <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>
              <Popconfirm
                title="确定删除吗?"
                overlayClassName="popover-confirm"
                onConfirm={() => this.handleDelete(record.key)
              }>
@@ -404,18 +357,32 @@
      })
    }
    this.setState({
    return {
      columns: columns.map(col => {
        if (col.dataIndex !== 'operation') {
          col = {...col, ...this.getColumnSearchProps(col)}
        }
        return col
      }),
      dataSource: dataSource,
      type: type
    }, () => {
      this.props.onChange(dataSource)
    })
      dataSource: _dataSource
    }
  }
  resetColumn = (type, linkSubFields) => {
    const { columns, dataSource } = this.getColumns(type, linkSubFields, this.state.dataSource)
    if (!is(fromJS(dataSource), fromJS(this.state.dataSource))) {
      this.setState({
        columns,
        dataSource
      }, () => {
        this.props.onChange(dataSource)
      })
    } else {
      this.setState({
        columns
      })
    }
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
src/templates/zshare/modalform/modaleditable/index.scss
@@ -37,7 +37,7 @@
    }
  }
  .operation-btn {
    margin-right: 10px;
    margin-right: 15px;
    cursor: pointer;
  }
  .ant-form-explain {
src/templates/zshare/verifycard/index.jsx
@@ -813,7 +813,11 @@
          if (!item.field || item.writein === 'false') return
          _arr.push(item.field.toLowerCase())
          _form.push(item.field + '=@' + item.field)
          if (item.field.toLowerCase() === 'bid' && item.uuid === 'BID') {
            _form.push(item.field + '=@BID@')
          } else {
            _form.push(item.field + '=@' + item.field)
          }
        })
        if (this.props.card.sqlType === 'audit') {
src/utils/utils.js
@@ -707,15 +707,17 @@
  static getSelectQueryOptions (item) {
    let arrfield = [item.valueField, item.valueText]
    if (item.type === 'link') {
      arrfield.push(item.linkField)
    } else if (item.type === 'checkcard') {
    if (item.type === 'checkcard') {
      arrfield = item.fields.map(f => f.field)
      arrfield.push(item.cardValField)
      if (item.urlField) {
        arrfield.push(item.urlField)
      }
    }
    if (item.linkField) {
      arrfield.push(item.linkField)
    }
    if (['select', 'radio', 'link', 'checkcard'].includes(item.type) && item.linkSubField && item.linkSubField.length > 0) {
      arrfield.push(...item.linkSubField)
    }