king
2020-12-21 4f2e4e84fd2cdca1407ac06c1b44319518be39b9
2020-12-21
37个文件已修改
728 ■■■■ 已修改文件
src/menu/components/card/cardcellcomponent/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/chartcompile/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/markcolumn/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.jsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/wrapsetting/settingform/index.jsx 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/customscript/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.jsx 99 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/utils.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/calendar/index.jsx 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/data-card/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/prop-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/table-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-bar-line/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-pie/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/tabtransfer/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/normal-table/index.jsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/utils.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/customscript/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.jsx 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.scss 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editcomponent/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/fieldtable/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-datamanage.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx
@@ -544,6 +544,10 @@
    const { elements } = this.state
    if (cards.uuid !== _cards.uuid) return
    let _index = elements.findIndex(cell => cell.uuid === btn.uuid)
    if (_index === -1) return
    let _elements = elements.map(cell => {
      if (cell.uuid === btn.uuid) {
src/menu/components/card/data-card/index.jsx
@@ -106,6 +106,7 @@
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('submitModal', this.handleSave)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -120,6 +121,7 @@
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('submitModal', this.handleSave)
  }
  /**
@@ -238,8 +240,50 @@
    MKEmitter.emit('addButton', card.uuid, newcard)
  }
  setSubConfig = () => {
  setSubConfig = (btn) => {
    const { card } = this.state
    if (btn.OpenType === 'pop') {
      if (!btn.modal) {
        btn.modal = {
          setting: {
            title: btn.label,
            width: 60,
            cols: '2',
            container: 'tab',
            focus: '',
            finish: 'close',
            clickouter: 'unclose',
            display: 'modal'
          },
          tables: [],
          groups: [],
          fields: []
        }
      }
      MKEmitter.emit('changeModal', card, btn)
    }
  }
  handleSave = (_cards, btn, modal) => {
    let card = fromJS(this.state.card).toJS()
    if (card.uuid !== _cards.uuid) return
    let _index = card.action.findIndex(cell => cell.uuid === btn.uuid)
    if (_index === -1) return
    card.action = card.action.map(cell => {
      if (cell.uuid === btn.uuid) {
        cell.modal = modal
      }
      return cell
    })
    this.setState({card})
    this.props.updateConfig(card)
  }
  render() {
@@ -276,7 +320,7 @@
        <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/>
        {card.subcards.map((subcard, index) => (<CardComponent key={subcard.uuid} offset={!index ? offset : 0} MenuType={menu ? menu.MenuType : ''} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        <div style={{clear: 'both'}}></div>
        {card.wrap.pagestyle !== 'switch' && card.setting.laypage === 'true' ? <Pagination total={85} showTotal={total => `共 ${total} 条`} pageSize={20} defaultCurrent={1}/> : null}
        {card.wrap.pagestyle !== 'switch' && card.setting.laypage === 'true' ? <Pagination total={85} size="small" showTotal={total => `共 ${total} 条`} pageSize={20} defaultCurrent={1}/> : null}
      </div>
    )
  }
src/menu/components/card/prop-card/index.jsx
@@ -248,6 +248,7 @@
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
            {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
            {card.wrap.datatype === 'static' ? <Icon style={{color: '#eeeeee', cursor: 'not-allowed'}} type="setting"/> : null}
          </div>
        } trigger="hover">
          <Icon type="tool" />
src/menu/components/chart/antv-bar/chartcompile/index.jsx
@@ -516,7 +516,7 @@
            {plot ? <TabPane tab="颜色设置" key="color">
              <div>
                {datatype === 'statistics' ? <Button className="color-add mk-green" onClick={this.addColor}>{this.props.dict['model.add']}</Button> : null}
                {datatype === 'statistics' ? <EditTable data={plot.colors || []} columns={statColorColumns} onChange={this.changeColor}/> : null}
                {datatype === 'statistics' ? <EditTable actions={['edit', 'move', 'del']} data={plot.colors || []} columns={statColorColumns} onChange={this.changeColor}/> : null}
                {datatype !== 'statistics' ? <EditTable actions={['edit']} data={plot.colors || []} columns={colorColumns} onChange={this.changeColor}/> : null}
              </div>
            </TabPane> : null}
@@ -532,7 +532,7 @@
                </Form>
              </Col>
              <Col style={{fontSize: '12px', color: '#757575', paddingLeft: '10px'}} span={24}>注:使用自定义设置时,显示的坐标轴第一个在左侧,第二个在右侧,多余的不生效;柱形图只可以添加一个(设置多个时,第一个生效)。</Col>
              <EditTable actions={['edit', 'up', 'down']} data={plot.customs || []} columns={cusColumns} onChange={this.changeCustom}/>
              <EditTable actions={['edit', 'move']} data={plot.customs || []} columns={cusColumns} onChange={this.changeCustom}/>
            </TabPane> : null}
          </Tabs>
        </Modal>
src/menu/components/chart/antv-pie/chartcompile/index.jsx
@@ -342,7 +342,7 @@
            {plot ? <TabPane tab="颜色设置" key="color">
              <div>
                <Button className="color-add mk-green" onClick={this.addColor}>{this.props.dict['model.add']}</Button>
                <EditTable data={plot.colors || []} columns={colorColumns} onChange={this.changeColor}/>
                <EditTable actions={['edit', 'move', 'del']} data={plot.colors || []} columns={colorColumns} onChange={this.changeColor}/>
              </div>
            </TabPane> : null}
          </Tabs>
src/menu/components/share/actioncomponent/index.jsx
@@ -58,7 +58,6 @@
   */
  UNSAFE_componentWillReceiveProps (nextProps) {
    const { actionlist } = this.state
    if (!is(fromJS(nextProps.config.action), fromJS(this.props.config.action)) && !is(fromJS(nextProps.config.action), fromJS(actionlist))) {
      this.setState({actionlist: fromJS(nextProps.config.action).toJS()})
    }
src/menu/components/table/normal-table/columns/index.jsx
@@ -2,7 +2,7 @@
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { DndProvider, DragSource, DropTarget } from 'react-dnd'
import { Table, Form, Popover, Icon, Modal, message } from 'antd'
import { Table, Popover, Icon, Modal, message } from 'antd'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
@@ -117,7 +117,7 @@
  }))(HeaderCol),
)
class EditableCell extends Component {
class EditableColumnCell extends Component {
  updateCard = (vals, action) => {
    const { column } = this.props
    this.props.upComponent({...column, elements: vals}, action)
@@ -166,7 +166,7 @@
  }
}
class EditTable extends Component {
class NormalTableColumns extends Component {
  static propTpyes = {
    config: PropTypes.object,       // 配置信息
    updatecolumn: PropTypes.func    // 数据变化
@@ -395,7 +395,7 @@
        cell: DragableHeaderCol
      },
      body: {
        cell: EditableCell
        cell: EditableColumnCell
      }
    }
@@ -476,4 +476,4 @@
  }
}
export default Form.create()(EditTable)
export default NormalTableColumns
src/menu/components/table/normal-table/columns/markcolumn/index.jsx
@@ -313,7 +313,7 @@
          destroyOnClose
        >
          <MarkForm dict={dict} signs={signs} columns={options} markChange={this.markChange}/>
          <EditTable data={marks} columns={markColumns} onChange={(marks) => this.setState({marks})}/>
          <EditTable actions={['edit', 'move', 'del']} data={marks} columns={markColumns} onChange={(marks) => this.setState({marks})}/>
        </Modal>
      </div>
    )
src/menu/components/table/normal-table/index.jsx
@@ -57,9 +57,9 @@
          { origin: true, uuid: Utils.getuuid(), label: 'label', type: 'date', match: 'greater' }
        ],
        action: [
          { origin: true, uuid: Utils.getuuid(), label: '添加', intertype: 'system', OpenType: 'pop', icon: 'plus', class: 'green' },
          { origin: true, uuid: Utils.getuuid(), label: '修改', intertype: 'system', OpenType: 'pop', icon: 'form', class: 'purple' },
          { origin: true, uuid: Utils.getuuid(), label: '删除', intertype: 'system', OpenType: 'prompt', icon: 'delete', class: 'red' }
          { origin: true, uuid: Utils.getuuid(), label: '添加', intertype: 'system', OpenType: 'pop', icon: 'plus', class: 'green', btnstyle: {color: 'rgb(255, 255, 255)', background: 'rgb(38, 194, 129)', marginRight: '15px'} },
          { origin: true, uuid: Utils.getuuid(), label: '修改', intertype: 'system', OpenType: 'pop', icon: 'form', class: 'purple', btnstyle: {color: 'rgb(255, 255, 255)', background: 'rgb(142, 68, 173)', marginRight: '15px'} },
          { origin: true, uuid: Utils.getuuid(), label: '删除', intertype: 'system', OpenType: 'prompt', icon: 'delete', class: 'danger', btnstyle: {color: 'rgb(255, 255, 255)', background: 'rgb(255, 77, 79)', marginRight: '15px'} }
        ],
        name: card.name,
        subtype: card.subtype,
@@ -89,6 +89,7 @@
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('submitModal', this.handleSave)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -103,6 +104,7 @@
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('submitModal', this.handleSave)
  }
  /**
@@ -218,7 +220,49 @@
  }
  setSubConfig = (btn) => {
    const { card } = this.state
    if (btn.OpenType === 'pop') {
      if (!btn.modal) {
        btn.modal = {
          setting: {
            title: btn.label,
            width: 60,
            cols: '2',
            container: 'tab',
            focus: '',
            finish: 'close',
            clickouter: 'unclose',
            display: 'modal'
          },
          tables: [],
          groups: [],
          fields: []
        }
      }
      MKEmitter.emit('changeModal', card, btn)
    }
  }
  handleSave = (_cards, btn, modal) => {
    let card = fromJS(this.state.card).toJS()
    if (card.uuid !== _cards.uuid) return
    let _index = card.action.findIndex(cell => cell.uuid === btn.uuid)
    if (_index === -1) return
    card.action = card.action.map(cell => {
      if (cell.uuid === btn.uuid) {
        cell.modal = modal
      }
      return cell
    })
    this.setState({card})
    this.props.updateConfig(card)
  }
  render() {
src/menu/components/table/normal-table/wrapsetting/settingform/index.jsx
@@ -99,24 +99,6 @@
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="栅格布局,每行等分为24列。">
                  <Icon type="question-circle" />
                  宽度
                </Tooltip>
              }>
                {getFieldDecorator('width', {
                  initialValue: wrap.width || 24,
                  rules: [
                    {
                      required: true,
                      message: this.props.dict['form.required.input'] + '宽度!'
                    }
                  ]
                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit} />)}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label="表格属性">
                {getFieldDecorator('tableType', {
                  initialValue: wrap.tableType
@@ -143,6 +125,24 @@
            </Col>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="栅格布局,每行等分为24列。">
                  <Icon type="question-circle" />
                  宽度
                </Tooltip>
              }>
                {getFieldDecorator('width', {
                  initialValue: wrap.width || 24,
                  rules: [
                    {
                      required: true,
                      message: this.props.dict['form.required.input'] + '宽度!'
                    }
                  ]
                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit} />)}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="双击表格中行,触发的按钮。">
                  <Icon type="question-circle" />
                  双击事件
src/menu/datasource/verifycard/customscript/index.jsx
@@ -9,13 +9,10 @@
class CustomForm extends Component {
  static propTpyes = {
    type: PropTypes.string,         // 菜单类型
    dict: PropTypes.object,         // 字典项
    defaultsql: PropTypes.string,   // 默认sql
    setting: PropTypes.object,      // 设置
    searches: PropTypes.array,      // 搜索条件
    swhere: PropTypes.string,       // where条件
    arr_field: PropTypes.string,    // 列字段
    regoptions: PropTypes.array,    // 正则替换
    systemScripts: PropTypes.array, // 系统脚本
    scriptSubmit: PropTypes.func,   // 脚本验证后提交
    scriptsChange: PropTypes.func   // 脚本验证
@@ -178,6 +175,10 @@
      `
    }
    if (value === 'defaultsql') {
      value = this.props.defaultsql
    }
    _sql = _sql.replace(/\s{6}$/, '')
    _sql = _sql + `/*${option.props.children}*/
    `
@@ -219,7 +220,7 @@
          </Col>
          <Col span={24} className="sqlfield">
            <Form.Item label={'可用字段'}>
              id, bid, loginuid, sessionuid, userid, appkey, time_id{usefulFields ? ', ' + usefulFields : ''}
              id, bid, loginuid, sessionuid, userid, username, fullname, appkey, time_id{usefulFields ? ', ' + usefulFields : ''}
            </Form.Item>
          </Col>
          <Col span={10} style={{width: '43%'}}>
@@ -227,8 +228,9 @@
              <Select
                showSearch
                filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                onChange={this.selectScript}
                onSelect={this.selectScript}
              >
                <Select.Option style={{whiteSpace: 'normal'}} key="default" value="defaultsql">默认sql</Select.Option>
                {systemScripts.map((option, i) =>
                  <Select.Option style={{whiteSpace: 'normal'}} key={i} value={option.value}>{option.name}</Select.Option>
                )}
src/menu/datasource/verifycard/index.jsx
@@ -33,11 +33,8 @@
    loading: false,
    initsql: '',          // sql验证时变量声明及赋值
    usefulfields: '',
    defaultsql: '',         // 默认Sql
    systemScripts: [{
      name: '默认sql',
      value: ''
    }],
    defaultsql: '',       // 默认Sql
    systemScripts: [],
    colColumns: [
      {
        title: '名称',
@@ -227,7 +224,7 @@
        })
        this.setState({
          systemScripts: [...this.state.systemScripts, ..._scripts]
          systemScripts: _scripts
        })
      } else {
        notification.warning({
@@ -372,11 +369,13 @@
              activeKey: val,
              loading: false
            })
            this.getdefaultSql()
          }, () => {             // 验证失败
            this.setState({
              activeKey: val,
              loading: false
            })
            this.getdefaultSql()
          }, true)
        })
      }, () => {
@@ -387,6 +386,7 @@
        activeKey: val,
        loading: false
      })
      this.getdefaultSql()
    } else if (activeKey === 'scripts') {
      let _loading = false
      if (this.scriptsForm && this.scriptsForm.state.editItem) {
@@ -412,6 +412,84 @@
        loading: false
      })
    }
  }
  getdefaultSql = () => {
    const { columns, searches, setting } = this.state
    let defaultsql = ''
    let arr_field = columns.map(col => col.field).join(',')
    let _search = this.formatSearch(searches)
    _search = Utils.joinMainSearchkey(_search)
    _search = _search.replace(/@\$@/ig, '')
    _search = _search ? 'where ' + _search : ''
    if (setting.dataresource) {
      let _dataresource = setting.dataresource
      if (/\s/.test(_dataresource)) {
        _dataresource = '(' + _dataresource + ') tb'
      }
      defaultsql = `select top @pageSize@ ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by @orderBy@) as rows from ${_dataresource} ${_search}) tmptable where rows > (@pageSize@ * (@pageIndex@ - 1)) order by tmptable.rows`
    }
    this.setState({defaultsql})
  }
  /**
   * @description 获取全部搜索条件
   * @param {Array} searches 搜索条件数组
   */
  formatSearch (searches) {
    if (!searches || searches.length === 0) return []
    let newsearches = []
    searches.forEach(search => {
      if (!search.field) return
      let item = {
        key: search.field,
        match: search.match,
        type: search.type,
        label: search.label,
        value: search.initval,
        required: search.required === 'true'
      }
      if (item.type === 'group') {
        let copy = fromJS(item).toJS()
        copy.key = search.datefield
        item.value = search.initval && search.initval[0] ? search.initval[0] : '@$@'
        item.match = '='
        copy.type = 'daterange'
        copy.match = 'between'
        copy.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
        if (search.transfer === 'true') {
          newsearches.push(item)
        }
        newsearches.push(copy)
        return
      } else if (item.type === 'date') {
        item.value = moment().format('YYYY-MM-DD')
      } else if (item.type === 'datemonth') {
        item.value = moment().format('YYYY-MM')
      } else if (item.type === 'dateweek') {
        item.value = [moment().startOf('week').format('YYYY-MM-DD'), moment().endOf('week').format('YYYY-MM-DD')]
      } else if (item.type === 'daterange') {
        item.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
      } else if (item.type === 'multiselect') {
        item.value = ['@$@']
      } else {
        item.value = '@$@'
      }
      newsearches.push(item)
    })
    return newsearches
  }
  submitDataSource = () => {
@@ -542,12 +620,12 @@
  render() {
    const { menu, config } = this.props
    const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches } = this.state
    const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql } = this.state
    return (
      <div id="model-data-source-wrap">
        {loading && <Spin size="large" />}
        <Tabs activeKey={activeKey} className="verify-card-box" onChange={this.changeTab}>
        <Tabs activeKey={activeKey} className="data-source-card-box" onChange={this.changeTab}>
          <TabPane tab="数据源" key="setting">
            <SettingForm
              menu={menu}
@@ -567,7 +645,7 @@
              tableFields={menu.tableFields}
              updatefield={this.updatefields}
            />
            <EditTable data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/>
            <EditTable actions={['edit', 'move', 'copy', 'del']} type="datasourcefield" data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/>
          </TabPane>
          <TabPane tab={
            <span>
@@ -578,6 +656,7 @@
            <CustomScriptsForm
              setting={setting}
              searches={searches}
              defaultsql={defaultsql}
              initsql={this.state.initsql}
              dict={this.props.dict}
              customScripts={scripts}
@@ -586,7 +665,7 @@
              scriptSubmit={this.scriptSubmit}
              wrappedComponentRef={(inst) => this.scriptsForm = inst}
            />
            <EditTable data={scripts} actions={[]} columns={scriptsColumns} onChange={this.changeScripts}/>
            <EditTable actions={['move']} data={scripts} columns={scriptsColumns} onChange={this.changeScripts}/>
          </TabPane>
        </Tabs>
      </div>
src/menu/datasource/verifycard/index.scss
@@ -5,7 +5,10 @@
    top: 220px;
    z-index: 1;
  }
  .verify-card-box {
  .ant-tabs-tabpane {
    position: relative;
  }
  .data-source-card-box {
    .ant-tabs-nav-scroll {
      text-align: center;
    }
@@ -77,5 +80,12 @@
      display: inline-block;
      width: 30px;
    }
    .operation-btn {
      display: inline-block;
      font-size: 16px;
      padding: 0 3px;
      margin-right: 5px;
      cursor: pointer;
    }
  }
}
src/menu/datasource/verifycard/utils.jsx
@@ -34,7 +34,7 @@
    }
    if (_customScript) {
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) select @ErrorCode='',@retmsg =''
        ${_customScript}
      `
    }
@@ -44,6 +44,7 @@
    let _fields = []
    searches.forEach(item => {
      if (!item.field) return
      if (item.datefield) {
        _regoptions.push({
          var: new RegExp('@' + item.datefield, 'ig'),
@@ -108,6 +109,14 @@
        var: new RegExp('@orderBy', 'ig'),
        reg: new RegExp('@orderBy@', 'ig'),
      })
      _regoptions.push({
        var: new RegExp('@UserName', 'ig'),
        reg: new RegExp('@UserName@', 'ig'),
      })
      _regoptions.push({
        var: new RegExp('@FullName', 'ig'),
        reg: new RegExp('@FullName@', 'ig'),
      })
      if (setting.laypage !== 'false') {
        _regoptions.push({
          var: new RegExp('@pageSize', 'ig'),
src/menu/modalconfig/index.scss
@@ -15,6 +15,9 @@
    height: 100%;
    overflow-y: auto;
    padding-bottom: 30px;
    .ant-collapse-borderless {
      background-color: #ffffff;
    }
    .ant-collapse-item {
      border: 0;
    }
src/tabviews/calendar/index.jsx
@@ -327,16 +327,16 @@
    
    let _dataresource = setting.dataresource
    let regoptions = []
    let userName = sessionStorage.getItem('User_Name') || ''
    let fullName = sessionStorage.getItem('Full_Name') || ''
    if (sessionStorage.getItem('isEditState') === 'true') {
      userName = sessionStorage.getItem('CloudUserName') || ''
      fullName = sessionStorage.getItem('CloudFullName') || ''
    }
    if (setting.queryType === 'statistics' || param.custom_script) {
      let allSearch = Utils.getAllSearchOptions(search)
      let userName = sessionStorage.getItem('User_Name') || ''
      let fullName = sessionStorage.getItem('Full_Name') || ''
      if (sessionStorage.getItem('isEditState') === 'true') {
        userName = sessionStorage.getItem('CloudUserName') || ''
        fullName = sessionStorage.getItem('CloudFullName') || ''
      }
      regoptions = allSearch.map(item => {
        return {
          reg: new RegExp('@' + item.key + '@', 'ig'),
@@ -381,7 +381,8 @@
        param.custom_script = param.custom_script.replace(item.reg, item.value)
      })
      param.custom_script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
      param.custom_script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50)
        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}'
        ${param.custom_script}
      `
src/tabviews/custom/components/card/data-card/index.jsx
@@ -125,7 +125,7 @@
      })
      this.setState({sync: false, data: _data})
    } else if (!is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
    } else if (nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
      if (config.setting.syncRefresh === 'true') {
        this.setState({}, () => {
          this.loadData()
@@ -184,9 +184,9 @@
    let searches = fromJS(search).toJS()
    if (mainSearch && mainSearch.length > 0) { // 主表搜索条件
      let keys = searches.map(item => item.key)
      let keys = searches.map(item => item.key.toLowerCase())
      mainSearch.forEach(item => {
        if (!keys.includes(item.key)) {
        if (!keys.includes(item.key.toLowerCase())) {
          searches.push(item)
        }
      })
src/tabviews/custom/components/card/prop-card/index.jsx
@@ -142,7 +142,7 @@
      }
      this.setState({sync: false, data: _data})
    } else if (!is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
    } else if (nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
      if (config.wrap.datatype !== 'static' && config.setting.syncRefresh === 'true') {
        this.setState({}, () => {
          this.loadData()
src/tabviews/custom/components/card/table-card/index.jsx
@@ -138,7 +138,7 @@
      })
      this.setState({sync: false, data: _data})
    } else if (!is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
    } else if (nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
      if (config.setting.syncRefresh === 'true') {
        this.setState({}, () => {
          this.loadData()
src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -218,7 +218,7 @@
      this.setState({sync: false, data: _data}, () => {
        this.handleData()
      })
    } else if (!is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
    } else if (nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
      if (config.setting.syncRefresh === 'true') {
        this.setState({}, () => {
          this.loadData()
src/tabviews/custom/components/chart/antv-pie/index.jsx
@@ -99,7 +99,7 @@
      this.setState({sync: false, data: _data}, () => {
        this.handleData()
      })
    } else if (!is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
    } else if (nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
      if (config.setting.syncRefresh === 'true') {
        this.setState({}, () => {
          this.loadData()
src/tabviews/custom/components/share/tabtransfer/index.jsx
@@ -77,7 +77,7 @@
  UNSAFE_componentWillReceiveProps(nextProps) {
    const { self } = this.state
    
    if (!self && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
    if (!self && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
      this.setState({mainSearch: fromJS(nextProps.mainSearch).toJS()})
    }
  }
@@ -162,11 +162,20 @@
    const { config } = this.props
    let LText_field = []
    let diffUser = false
    let userName = sessionStorage.getItem('User_Name') || ''
    let fullName = sessionStorage.getItem('Full_Name') || ''
    if (sessionStorage.getItem('isEditState') === 'true') {
      userName = sessionStorage.getItem('CloudUserName') || ''
      fullName = sessionStorage.getItem('CloudFullName') || ''
    }
    let _LText = params.map((item, index) => {
      let _script = item.script
      if (index === 0) {
        _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
        _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50)
          select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}'
          ${_script}
        `
      }
@@ -229,7 +238,9 @@
  }
  resetSearch = (search) => {
    this.setState({mainSearch: search})
    this.setState({mainSearch: null}, () => {
      this.setState({mainSearch: search})
    })
  }
  getComponents = () => {
src/tabviews/custom/components/table/normal-table/index.jsx
@@ -121,6 +121,7 @@
   * @param { String }  repage 表格是否重置页码
   */
  async loadmaindata (reset, repage) {
    const { mainSearch } = this.props
    const { setting, config, arr_field, search, orderBy, BID, pageIndex, pageSize } = this.state
    let requireFields = search.filter(item => item.required && (!item.value || item.value.length === 0))
@@ -146,12 +147,22 @@
      return
    }
    let searches = fromJS(search).toJS()
    if (mainSearch && mainSearch.length > 0) { // 主表搜索条件
      let keys = searches.map(item => item.key.toLowerCase())
      mainSearch.forEach(item => {
        if (!keys.includes(item.key.toLowerCase())) {
          searches.push(item)
        }
      })
    }
    this.setState({
      loading: true
    })
    let _orderBy = orderBy || setting.order
    let param = UtilsDM.getQueryDataParams(setting, arr_field, search, _orderBy, pageIndex, pageSize, BID, this.props.menuType)
    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, this.props.menuType)
    if (param.func === 'sPC_Get_TableData') {
      param.menuname = config.name || ''
@@ -189,14 +200,25 @@
   * @description 获取单行数据
   */ 
  async loadmainLinedata (id) {
    const { mainSearch } = this.props
    const { setting, config, arr_field, search, orderBy, BID, pageIndex, pageSize } = this.state
    let searches = fromJS(search).toJS()
    if (mainSearch && mainSearch.length > 0) { // 主表搜索条件
      let keys = searches.map(item => item.key.toLowerCase())
      mainSearch.forEach(item => {
        if (!keys.includes(item.key.toLowerCase())) {
          searches.push(item)
        }
      })
    }
    this.setState({
      loading: true
    })
    let _orderBy = orderBy || setting.order
    let param = UtilsDM.getQueryDataParams(setting, arr_field, search, _orderBy, pageIndex, pageSize, BID, this.props.menuType, id)
    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, this.props.menuType, id)
    if (param.func === 'sPC_Get_TableData') {
      param.menuname = config.name || ''
@@ -244,6 +266,7 @@
   * @description 获取合计字段值
   */
  getStatFieldsValue = () => {
    const { mainSearch } = this.props
    const { setting, config, search, BID, orderBy, statFields } = this.state
    if (setting.supModule && !BID) { // BID 不存在时,不做查询
@@ -260,8 +283,18 @@
      return
    }
    let searches = fromJS(search).toJS()
    if (mainSearch && mainSearch.length > 0) { // 主表搜索条件
      let keys = searches.map(item => item.key.toLowerCase())
      mainSearch.forEach(item => {
        if (!keys.includes(item.key.toLowerCase())) {
          searches.push(item)
        }
      })
    }
    let _orderBy = orderBy || setting.order
    let param = UtilsDM.getStatQueryDataParams(setting, statFields, search, _orderBy, BID, this.props.menuType)
    let param = UtilsDM.getStatQueryDataParams(setting, statFields, searches, _orderBy, BID, this.props.menuType)
    if (param.func === 'sPC_Get_TableData') {
      param.menuname = config.name || ''
@@ -438,7 +471,7 @@
      })
      this.setState({sync: false, data: _data})
    } else if (!is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
    } else if (nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
      if (config.setting.syncRefresh === 'true') {
        this.setState({}, () => {
          this.reloadtable()
src/tabviews/custom/index.jsx
@@ -482,11 +482,20 @@
    const { config } = this.state
    let LText_field = []
    let diffUser = false
    let userName = sessionStorage.getItem('User_Name') || ''
    let fullName = sessionStorage.getItem('Full_Name') || ''
    if (sessionStorage.getItem('isEditState') === 'true') {
      userName = sessionStorage.getItem('CloudUserName') || ''
      fullName = sessionStorage.getItem('CloudFullName') || ''
    }
    let _LText = params.map((item, index) => {
      let _script = item.script
      if (index === 0) {
        _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
        _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50)
          select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}'
          ${_script}
        `
      }
@@ -619,7 +628,9 @@
  }
  resetSearch = (search) => {
    this.setState({mainSearch: search})
    this.setState({mainSearch: null}, () => {
      this.setState({mainSearch: search})
    })
  }
  getComponents = () => {
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -837,7 +837,7 @@
              清空Excel列
            </Button>
            <Col style={{fontSize: '12px', color: '#757575', paddingLeft: '10px'}} span={24}>注:数值类型(int 或 decimal),内容为必填;最大值和最小值在类型为数值时有效。</Col>
            <EditTable data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
            <EditTable actions={['edit', 'move', 'copy', 'del']} type="excelincolumn" data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
          </TabPane>
          {card.intertype === 'system' ? <TabPane tab={
            <span>
@@ -846,7 +846,7 @@
            </span>
          } key="unique">
            <UniqueForm fields={verify.columns} dict={this.props.dict} uniqueChange={this.uniqueChange}/>
            <EditTable data={verify.uniques} columns={uniqueColumns} onChange={this.changeUniques}/>
            <EditTable actions={['edit', 'move', 'del']} data={verify.uniques} columns={uniqueColumns} onChange={this.changeUniques}/>
          </TabPane> : null}
          {card.intertype === 'system' ? <TabPane tab={
            <span>
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -421,7 +421,7 @@
            <Button className="excel-col-add mk-red" title="清空Excel列" onClick={this.clearField}>
              清空Excel列
            </Button>
            <EditTable data={verify.columns} columns={excelColumns} onChange={(columns) => this.setState({verify: {...verify, columns}})}/>
            <EditTable actions={['edit', 'move', 'copy', 'del']} type="exceloutcolumn" data={verify.columns} columns={excelColumns} onChange={(columns) => this.setState({verify: {...verify, columns}})}/>
          </TabPane>
          {card.intertype === 'system' ? <TabPane tab={
            <span>
src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx
@@ -22,7 +22,7 @@
    }
    if (_customScript) {
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) select @ErrorCode='',@retmsg =''
        ${_customScript}
      `
    }
src/templates/sharecomponent/settingcomponent/settingform/utils.jsx
@@ -18,7 +18,7 @@
    })
    if (_customScript) {
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) select @ErrorCode='',@retmsg =''
        ${_customScript}
      `
    }
src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx
@@ -18,7 +18,7 @@
    })
    if (_customScript) {
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) select @ErrorCode='',@retmsg =''
        ${_customScript}
      `
    }
src/templates/zshare/customscript/index.jsx
@@ -407,7 +407,7 @@
            </Col>
          </Row>
        </Form>
        <EditTable data={scripts} actions={[]} columns={scriptsColumns} onChange={this.changeScripts}/>
        <EditTable data={scripts} actions={['move']} columns={scriptsColumns} onChange={this.changeScripts}/>
      </div>
    )
  }
src/templates/zshare/editTable/index.jsx
@@ -2,9 +2,11 @@
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { DndProvider, DragSource, DropTarget } from 'react-dnd'
import { Table, Input, InputNumber, Popconfirm, Form, Icon, Select, Radio, Cascader, notification } from 'antd'
import { Table, Input, InputNumber, Popconfirm, Form, Icon, Select, Radio, Cascader, notification, message, Modal } from 'antd'
import Utils from '@/utils/utils.js'
import ColorSketch from '@/mob/colorsketch'
import PasteForm from '@/templates/zshare/pasteform'
import CusSwitch from './cusSwitch'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
@@ -161,6 +163,7 @@
  state = {
    data: [],
    editingKey: '',
    visible: false,
    columns: []
  }
@@ -168,9 +171,17 @@
    const { data, actions } = this.props
    let columns = fromJS(this.props.columns).toJS()
    if (!actions || actions.length > 0) {
    if (actions && (actions.includes('edit') || actions.includes('copy') || actions.includes('del'))) {
      columns.push({
        title: eTDict['model.operation'],
        title: (<div>
          {eTDict['model.operation']}
          {actions.includes('copy') ? (
            <span className="copy-control">
              <Icon type="copy" onClick={() => this.copy()} />
              <Icon type="snippets" onClick={this.paste} />
            </span>
          ) : null}
        </div>),
        dataIndex: 'operation',
        width: '140px',
        render: (text, record) => {
@@ -189,15 +200,16 @@
            </div>
          ) : (
            <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px'}}>
              {!actions || actions.includes('edit') ? <span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><Icon type="edit" /></span> : null}
              {(!actions || actions.includes('del')) && editingKey === '' ? <Popconfirm
              {actions.includes('edit') ? <span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><Icon type="edit" /></span> : null}
              {actions.includes('copy') ? <span className="copy" onClick={() => {editingKey === '' && this.copy(record)}}><Icon type="copy" /></span> : null}
              {actions.includes('del') && editingKey === '' ? <Popconfirm
                overlayClassName="popover-confirm"
                title={eTDict['model.query.delete']}
                onConfirm={() => this.handleDelete(record.uuid)
              }>
                <span className="danger"><Icon type="delete" /></span>
              </Popconfirm> : null}
              {(!actions || actions.includes('del')) && editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null}
              {actions.includes('del') && editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null}
            </div>
          )
        }
@@ -234,6 +246,108 @@
  cancel = () => {
    this.setState({ editingKey: '' })
  }
  copy = (item) => {
    const { type } = this.props
    const { data } = this.state
    if (!data || data.length === 0) {
      message.warning('未获取到配置信息')
      return
    }
    let msg = { key: type }
    if (item) {
      msg.type = 'line'
      msg.data = item
    } else {
      msg.type = 'array'
      msg.data = data
    }
    try {
      msg = window.btoa(window.encodeURIComponent(JSON.stringify(msg)))
    } catch {
      console.warn('Stringify Failure')
      msg = ''
    }
    if (msg) {
      let oInput = document.createElement('input')
      oInput.value = msg
      document.body.appendChild(oInput)
      oInput.select()
      document.execCommand('Copy')
      document.body.removeChild(oInput)
      message.success('复制成功。')
    }
  }
  paste = () => {
    this.setState({visible: true})
  }
  pasteSubmit = () => {
    const { type } = this.props
    const { columns } = this.state
    let data = fromJS(this.state.data).toJS()
    this.pasteFormRef.handleConfirm().then(res => {
      if (res.key !== type) {
        message.warning('配置信息格式错误!')
        return
      }
      if (res.type === 'line') {
        let unique = true
        res.data.uuid = Utils.getuuid()
        columns.forEach(col => {
          if (col.unique !== true || !unique) return
          let _index = data.findIndex(item => res.data[col.dataIndex] === item[col.dataIndex])
          if (_index > -1) {
            notification.warning({
              top: 92,
              message: col.title + '不可重复!',
              duration: 5
            })
            unique = false
          }
        })
        if (!unique) return
        data.unshift(res.data)
        this.setState({ data, editingKey: '', visible: false }, () => {
          this.props.onChange(data)
        })
      } else if (res.type === 'array') {
        res.data.forEach(cell => {
          let unique = true
          cell.uuid = Utils.getuuid()
          columns.forEach(col => {
            if (col.unique !== true || !unique) return
            let _index = data.findIndex(item => cell[col.dataIndex] === item[col.dataIndex])
            if (_index > -1) {
              unique = false
            }
          })
          if (!unique) return
          data.unshift(cell)
        })
        this.setState({ data, editingKey: '', visible: false }, () => {
          this.props.onChange(data)
        })
      }
      message.success('粘贴成功。')
    })
  }
  onSave = (record) => {
@@ -357,7 +471,7 @@
        cell: EditableCell
      }
    }
    if (!actions || actions.length === 0 || actions.includes('down') || actions.includes('up')) {
    if (actions.includes('move')) {
      components.body.row = DragableBodyRow
    }
    
@@ -400,6 +514,18 @@
              })}
            />
          </DndProvider>
          {/* 信息粘贴 */}
          <Modal
            title={eTDict['header.form.paste']}
            visible={this.state.visible}
            width={600}
            maskClosable={false}
            onOk={this.pasteSubmit}
            onCancel={() => {this.setState({visible: false})}}
            destroyOnClose
          >
            <PasteForm dict={eTDict} wrappedComponentRef={(inst) => this.pasteFormRef = inst}/>
          </Modal>
        </div>
      </EditableContext.Provider>
    )
src/templates/zshare/editTable/index.scss
@@ -36,6 +36,9 @@
    .primary {
      color: #1890ff;
    }
    .copy {
      color: #26C281;
    }
    .danger {
      color: #ff4d4f;
    }
@@ -54,6 +57,9 @@
    .danger {
      color: rgba(0, 0, 0, .25);
    }
    .copy {
      color: rgba(0, 0, 0, .25);
    }
  }
  .ant-empty {
    margin: 0;
@@ -64,5 +70,19 @@
  tr.drop-over-upward td {
    border-top: 2px dashed #1890ff;
  }
  .copy-control {
    display: inline-block;
    position: absolute;
    right: 10px;
    top: 2px;
    .anticon-copy {
      margin-right: 7px;
      color: #26C281;
    }
    .anticon-snippets {
      color: purple;
    }
  }
}
src/templates/zshare/editcomponent/index.jsx
@@ -312,10 +312,7 @@
          onCancel={() => {this.setState({pasteVisible: false})}}
          destroyOnClose
        >
          <PasteForm
            dict={dict}
            wrappedComponentRef={(inst) => this.pasteFormRef = inst}
          />
          <PasteForm dict={dict} wrappedComponentRef={(inst) => this.pasteFormRef = inst}/>
        </Modal>
      </div>
    )
src/templates/zshare/modalform/fieldtable/index.jsx
@@ -117,7 +117,7 @@
    return (
      <div className="modal-card-field-table">
        {data.length < 3 ? <Icon className="add-row" type="plus" onClick={this.handleAdd} /> : null}
        <EditTable data={data} columns={columns} onChange={this.changeData}/>
        <EditTable actions={['edit', 'move', 'del']} data={data} columns={columns} onChange={this.changeData}/>
      </div>
    )
  }
src/templates/zshare/verifycard/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Tabs, Row, Col, Radio, Button, Table, Select, Popconfirm, Icon, notification, Modal, message, InputNumber, Tooltip, Typography } from 'antd'
import { Form, Tabs, Row, Col, Radio, Button, Select, Popconfirm, Icon, notification, Modal, message, InputNumber, Tooltip, Typography } from 'antd'
import moment from 'moment'
import Api from '@/api'
@@ -273,10 +273,8 @@
        width: '15%',
        dataIndex: 'operation',
        render: (text, record) =>
          (<div>
          (<div style={{textAlign: 'center'}}>
            <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record, 'customverify')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
            <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'customverify', 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
            <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'customverify', 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
            <span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record, 'customverify')} style={{color: '#8E44AD'}}><Icon type="swap" /></span>
            <Popconfirm
              overlayClassName="popover-confirm"
@@ -344,10 +342,8 @@
        width: '20%',
        dataIndex: 'operation',
        render: (text, record) =>
          (<div>
          (<div style={{textAlign: 'center'}}>
            <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
            <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'scripts', 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
            <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'scripts', 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
            <span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record, 'scripts')} style={{color: '#8E44AD'}}><Icon type="swap" /></span>
            <Popconfirm
              overlayClassName="popover-confirm"
@@ -447,10 +443,8 @@
        width: '15%',
        dataIndex: 'operation',
        render: (text, record) =>
          (<div>
          (<div style={{textAlign: 'center'}}>
            <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record, 'ordercode')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
            <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'ordercode', 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
            <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'ordercode', 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
            <span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record, 'ordercode')} style={{color: '#8E44AD'}}><Icon type="swap" /></span>
            <Popconfirm
              overlayClassName="popover-confirm"
@@ -1119,66 +1113,6 @@
    this.setState({ verify })
  }
  handleUpDown = (record, type, direction) => {
    let verify = fromJS(this.state.verify).toJS()
    let index = 0
    if (type === 'customverify') {
      verify.customverifys = verify.customverifys.filter((item, i) => {
        if (item.uuid === record.uuid) {
          index = i
        }
        return item.uuid !== record.uuid
      })
      if ((index === 0 && direction === 'up') || (index === verify.customverifys.length && direction === 'down')) {
        return
      }
      if (direction === 'up') {
        verify.customverifys.splice(index - 1, 0, record)
      } else {
        verify.customverifys.splice(index + 1, 0, record)
      }
    } else if (type === 'ordercode') {
      verify.billcodes = verify.billcodes.filter((item, i) => {
        if (item.uuid === record.uuid) {
          index = i
        }
        return item.uuid !== record.uuid
      })
      if ((index === 0 && direction === 'up') || (index === verify.billcodes.length && direction === 'down')) {
        return
      }
      if (direction === 'up') {
        verify.billcodes.splice(index - 1, 0, record)
      } else {
        verify.billcodes.splice(index + 1, 0, record)
      }
    } else if (type === 'scripts') {
      verify.scripts = verify.scripts.filter((item, i) => {
        if (item.uuid === record.uuid) {
          index = i
        }
        return item.uuid !== record.uuid
      })
      if ((index === 0 && direction === 'up') || (index === verify.scripts.length && direction === 'down')) {
        return
      }
      if (direction === 'up') {
        verify.scripts.splice(index - 1, 0, record)
      } else {
        verify.scripts.splice(index + 1, 0, record)
      }
    }
    this.setState({ verify })
  }
  voucherChange = (voucher) => {
    const { verify } = this.state
@@ -1462,7 +1396,7 @@
            </span>
          } key="2x">
            <ContrastForm dict={this.props.dict} contrastChange={this.contrastChange}/>
            <EditTable data={verify.contrasts} columns={contrastColumns} onChange={(contrasts) => this.setState({verify: {...verify, contrasts}})}/>
            <EditTable actions={['edit', 'move', 'copy', 'del']} type="contrastverify" data={verify.contrasts} columns={contrastColumns} onChange={(contrasts) => this.setState({verify: {...verify, contrasts}})}/>
          </TabPane>
          <TabPane tab={
            <span>
@@ -1478,14 +1412,7 @@
              customChange={this.customChange}
              wrappedComponentRef={(inst) => this.customForm = inst}
            />
            <Table
              bordered
              rowKey="uuid"
              className="custom-table"
              dataSource={verify.customverifys}
              columns={customColumns}
              pagination={false}
            />
            <EditTable actions={['move']} data={verify.customverifys} columns={customColumns} onChange={(customverifys) => {this.setState({verify: {...verify, customverifys}})}}/>
          </TabPane>
          <TabPane tab={
            <span>
@@ -1504,14 +1431,7 @@
              orderChange={this.orderChange}
              wrappedComponentRef={(inst) => this.orderForm = inst}
            />
            <Table
              bordered
              rowKey="uuid"
              className="custom-table"
              dataSource={verify.billcodes}
              columns={orderColumns}
              pagination={false}
            />
            <EditTable actions={['move']} data={verify.billcodes} columns={orderColumns} onChange={(billcodes) => {this.setState({verify: {...verify, billcodes}})}}/>
          </TabPane>
          <TabPane tab={
            <span>
@@ -1525,7 +1445,7 @@
              dict={this.props.dict}
              uniqueChange={this.uniqueChange}
            />
            <EditTable data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
            <EditTable actions={['edit', 'move', 'del']} data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
          </TabPane>
          <TabPane tab={
            <span>
@@ -1560,14 +1480,7 @@
              scriptsChange={this.scriptsChange}
              wrappedComponentRef={(inst) => this.scriptsForm = inst}
            />
            <Table
              bordered
              rowKey="uuid"
              className="custom-table"
              dataSource={verify.scripts}
              columns={scriptsColumns}
              pagination={false}
            />
            <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/>
          </TabPane>
          <TabPane tab="信息提示" key="7">
            <Form {...formItemLayout}>
src/utils/utils-datamanage.js
@@ -89,11 +89,20 @@
      default_sql: setting.execute ? 'true' : 'false'
    }
    let userName = sessionStorage.getItem('User_Name') || ''
    let fullName = sessionStorage.getItem('Full_Name') || ''
    if (sessionStorage.getItem('isEditState') === 'true') {
      userName = sessionStorage.getItem('CloudUserName') || ''
      fullName = sessionStorage.getItem('CloudFullName') || ''
    }
    let _dataresource = setting.dataresource
    let _customScript = ''
    
    if (setting.customScript) {
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50)
        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}'
        ${setting.customScript}
      `
    }
src/views/menudesign/index.jsx
@@ -227,6 +227,7 @@
          })
        } else if (item.type === 'table' && item.subtype === 'normaltable') {
          item.action && item.action.forEach(btn => {
            if (btn.origin) return
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
@@ -246,8 +247,24 @@
    return buttons
  }
  filterConfig = (components) => {
    return components.map(item => {
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
          tab.components = this.filterConfig(tab.components)
        })
      } else if (item.type === 'table' && item.subtype === 'normaltable') {
        item.search = item.search.filter(a => !a.origin)
        item.action = item.action.filter(a => !a.origin)
        item.cols = item.cols.filter(a => !a.origin)
      }
      return item
    })
  }
  submitConfig = () => {
    const { config, openEdition } = this.state
    const { openEdition } = this.state
    let config = fromJS(this.state.config).toJS()
    if (config.MenuType === 'billPrint' && (!config.firstCount || !config.everyPCount)) {
      notification.warning({
@@ -271,6 +288,8 @@
      })
      return
    }
    config.components = this.filterConfig(config.components)
    if (config.enabled && this.verifyConfig()) {
      config.enabled = false
@@ -406,7 +425,12 @@
        
        if (res.status) {
          this.setState({
            menuloading: false
            menuloading: false,
            config: {...config, components: []}
          }, () => {
            this.setState({
              config: {...this.state.config, components: this.state.oriConfig.components}
            })
          })
          notification.success({
            top: 92,