king
2024-05-23 9a11e62adeb8d435b52a361eb62d5b59e1deef2a
2024-05-23
25个文件已修改
2个文件已添加
1280 ■■■■■ 已修改文件
public/README.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/options.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/design.scss 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/index.jsx 85 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/index.scss 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/step-form/index.jsx 86 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/step-form/index.scss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.jsx 85 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.scss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/index.jsx 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/debug/index.jsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/formfork/index.jsx 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/formfork/index.scss 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.jsx 92 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.scss 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modalconfig/index.jsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/invoice/index.jsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/README.txt
@@ -14,6 +14,7 @@
nginx             -- 是否开启了nginx服务,值为 true 时开启,如需使用微信模板消息等服务,请先设置nginx服务并开启此配置
debugger          -- 值为 true 时开启调试模式,开启后移动端子应用中会有控制台
licenseKey        -- 许可密钥,在内部网络中使用系统时,会跳过epc验证
storeKey          -- 电子档案本地授权码,使用本地许可密钥时有效
probation         -- 试用期(YYYY-MM-DD),在正式系统中,试用期内调用系统接口的脚本会记录下来
transfer          -- 是否使用转接口,使用转接口时请设置为 true, 使用转接口时,外部接口调用前不会做登录验证
keepPassword      -- 记住密码,默认开启,当值为 false 时禁用
public/options.json
@@ -14,6 +14,7 @@
  "nginx": "true",
  "debugger": false,
  "licenseKey": "",
  "storeKey": "",
  "probation": "",
  "transfer": "false",
  "keepPassword": "true",
src/api/index.js
@@ -865,8 +865,8 @@
    if (script) {
      try {
        // eslint-disable-next-line
        let func = new Function('axios', 'Api', 'param', 'position', 'systemType', script)
        let promise = func(axios, this, param, position, window.GLOB.systemType)
        let func = new Function('axios', 'Api', 'param', 'position', 'systemType', 'notification', script)
        let promise = func(axios, this, param, position, window.GLOB.systemType, notification)
        if (promise instanceof Promise) {
          return promise
src/assets/css/design.scss
@@ -110,3 +110,27 @@
  }
}
// 表单工具
.mk-form-tool {
  float: right;
  padding-right: 15px;
  .anticon {
    margin-right: 15px;
    font-size: 16px;
    cursor: pointer!important;
    position: relative;
    top: 2px;
  }
  .anticon-copy {
    color: #26C281;
  }
  .anticon-swap {
    color: #1890ff;
  }
  .anticon-fork {
    color: purple;
  }
  .anticon-delete {
    color: #f5222d;
  }
}
src/components/header/index.jsx
@@ -578,6 +578,8 @@
          } else {
            Api.updateAppVersion()
            Api.delCacheConfig('all')
            localStorage.removeItem(window.location.href.split('#')[0] + 'AuthCode')
            setTimeout(() => {
              notification.success({
                top: 92,
src/index.js
@@ -254,6 +254,29 @@
    let lang = localStorage.getItem(_href + 'lang') || (config.defaultLang !== 'en-US' ? 'zh-CN' : 'en-US')
    sessionStorage.setItem('lang', lang)
    if (localStorage.getItem(_href + 'files') === md5(_href + 'files')) {
      let d = localStorage.getItem(_href + 'filesDate')
      GLOB.storeFiles = true
      GLOB.storeDate = Math.ceil((new Date(d).getTime() - new Date().getTime()) / 86400000)
    } else if (GLOB.licenseKey && config.storeKey && config.storeKey.length === 16) {
      let d = config.storeKey.slice(0, 8)
      let key = config.storeKey.slice(8)
      let _key = GLOB.appId + GLOB.appkey + 'e_files_key'
      _key = md5(_key.toLowerCase())
      _key = _key.toUpperCase()
      _key = _key.slice(-8)
      if (key === _key) {
        GLOB.storeFiles = true
        let trans = {A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9}
        d = d.split('').map(k => trans[k]).join('')
        d = d.slice(0, 4) + '-' + d.slice(4, 6) + '-' + d.slice(6)
        GLOB.storeDate = Math.ceil((new Date(d).getTime() - new Date().getTime()) / 86400000)
      }
    }
    GLOB.mkActions = {}  // 按钮权限集
    Object.defineProperty(GLOB, 'appId', {
src/menu/components/form/simple-form/index.jsx
@@ -2,7 +2,7 @@
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Modal, Button, Switch, message } from 'antd'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, SwapOutlined, FontColorsOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
@@ -19,6 +19,7 @@
const CardComponent = asyncComponent(() => import('@/templates/modalconfig/dragelement'))
const MobCardComponent = asyncComponent(() => import('@/mob/components/formdragelement'))
const FormAction = asyncComponent(() => import('../formaction'))
// const FormFork = asyncComponent(() => import('@/menu/modalconfig/formfork'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteForms = asyncIconComponent(() => import('@/menu/components/share/pasteforms'))
@@ -346,69 +347,13 @@
   */
  handleForm = (_item) => {
    const { card } = this.state
    let _form = fromJS(_item).toJS()
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = []
    card.subcards[0].fields.forEach((item, i) => {
      if (!item.field || _form.field === item.field) return
      if (['text', 'number', 'textarea', 'select'].includes(item.type)) {
        _inputfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
        _tabfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (['switch', 'check', 'popSelect'].includes(item.type)) {
        _linksupFields.push({
          field: item.field,
          label: item.label
        })
      }
      if (!['select', 'link', 'radio', 'checkcard', 'multiselect'].includes(item.type)) return
      _linksupFields.push({
        field: item.field,
        label: item.label
      })
      if (item.type === 'multiselect' || (item.type === 'checkcard' && item.multiple === 'true')) return
      _linkableFields.push({
        field: item.field,
        label: item.label + '-表单'
      })
    })
    let _fields = _linkableFields.map(cell => cell.field)
    card.columns.forEach(col => {
      if (col.field && !_fields.includes(col.field)) {
        _linkableFields.push({
          field: col.field,
          label: col.label + '-显示列'
        })
      }
    })
    if (_form.linkSubField && _form.linkSubField.length > 0) {
      let fields = _inputfields.map(item => item.field)
      _form.linkSubField = _form.linkSubField.filter(item => fields.includes(item))
    }
    this.setState({
      visible: true,
      editform: _form,
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, card.columns)
      formlist: getModalForm(_form, card.subcards[0].fields, card.columns)
    })
  }
@@ -605,12 +550,22 @@
        <div className={`form-area mk-${card.wrap.formStyle || ''}`}>
          <PlusOutlined className="plus" title="添加表单" onClick={this.addForm}/>
          <FieldsComponent config={card.subcards[0]} type="form" plusFields={this.plusFields} />
          <span style={{color: 'red', marginLeft: '30px', cursor: 'pointer'}} onClick={this.clearGroup}>清空</span>
          <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</Button> : null}
          <div className="mk-form-tool">
            <DeleteOutlined title="清空" onClick={this.clearGroup} />
            {appType !== 'mob' ? <Popover title="切换布局" overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
              <>
                <Button style={{marginRight: '10px'}} onClick={() => this.changecols(1)}>1列</Button>
                <Button style={{marginRight: '10px'}} onClick={() => this.changecols(2)}>2列</Button>
                <Button style={{marginRight: '10px'}} onClick={() => this.changecols(3)}>3列</Button>
                <Button onClick={() => this.changecols(4)}>4列</Button>
              </>
            } trigger="hover">
              <SwapOutlined />
            </Popover> : null}
            {/* <FormFork forms={card.subcards[0].fields}/> */}
            {/* <CopyOutlined title="复制" onClick={this.triggerCopy} /> */}
            <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
          </div>
          <div style={{clear: 'both'}}></div>
          {appType !== 'mob' ? <CardComponent
            list={card.subcards[0].fields}
src/menu/components/form/simple-form/index.scss
@@ -34,14 +34,6 @@
      cursor: pointer;
      padding: 4px 10px;
    }
    >button {
      float: right;
      margin-right: 10px;
    }
    >.mk-cols-change {
      height: 24px;
      padding: 0 10px;
    }
    >.quickly-add {
      display: inline-block;
      margin-left: 10px;
@@ -78,12 +70,12 @@
  //   }
  // }
}
.menu-normal-form-edit-box::after {
.menu-simple-form-edit-box::after {
  display: block;
  content: ' ';
  clear: both;
}
.menu-normal-form-edit-box:hover {
.menu-simple-form-edit-box:hover {
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/form/step-form/index.jsx
@@ -2,7 +2,7 @@
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Modal, Button, Switch, notification, message } from 'antd'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, SwapOutlined, FontColorsOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
@@ -20,6 +20,7 @@
const MobCardComponent = asyncComponent(() => import('@/mob/components/formdragelement'))
const FormTitle = asyncComponent(() => import('../dragtitle'))
const FormAction = asyncComponent(() => import('../formaction'))
// const FormFork = asyncComponent(() => import('@/menu/modalconfig/formfork'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
@@ -447,70 +448,13 @@
   */
  handleForm = (_item) => {
    const { card, group } = this.state
    let _form = fromJS(_item).toJS()
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = []
    group.fields.forEach((item, i) => {
      if (!item.field || _form.field === item.field) return
      if (['text', 'number', 'textarea', 'select'].includes(item.type)) {
        _inputfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
        _tabfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (['switch', 'check', 'popSelect'].includes(item.type)) {
        _linksupFields.push({
          field: item.field,
          label: item.label
        })
      }
      if (!['select', 'link', 'radio', 'checkcard', 'multiselect'].includes(item.type)) return
      _linksupFields.push({
        field: item.field,
        label: item.label
      })
      if (item.type === 'multiselect' || (item.type === 'checkcard' && item.multiple === 'true')) return
      _linkableFields.push({
        field: item.field,
        label: item.label + '-表单'
      })
    })
    let _fields = _linkableFields.map(cell => cell.field)
    card.columns.forEach(col => {
      if (col.field && !_fields.includes(col.field)) {
        _linkableFields.push({
          field: col.field,
          label: col.label + '-显示列'
        })
      }
    })
    if (_form.linkSubField && _form.linkSubField.length > 0) {
      let fields = _inputfields.map(item => item.field)
      _form.linkSubField = _form.linkSubField.filter(item => fields.includes(item))
    }
    this.setState({
      visible: true,
      editform: _form,
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, card.columns)
      formlist: getModalForm(_form, group.fields, card.columns)
    })
  }
@@ -721,12 +665,22 @@
        {group ? <div className={`form-area mk-${card.wrap.formStyle || ''}`}>
          <PlusOutlined className="plus" title="添加表单" onClick={this.addForm}/>
          <FieldsComponent config={group} type="form" plusFields={this.plusFields} />
          <span style={{color: 'red', marginLeft: '30px', cursor: 'pointer'}} onClick={this.clearGroup}>清空</span>
          <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</Button> : null}
          <div className="mk-form-tool">
            <DeleteOutlined title="清空" onClick={this.clearGroup} />
            {appType !== 'mob' ? <Popover title="切换布局" overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
              <>
                <Button style={{marginRight: '10px'}} onClick={() => this.changecols(1)}>1列</Button>
                <Button style={{marginRight: '10px'}} onClick={() => this.changecols(2)}>2列</Button>
                <Button style={{marginRight: '10px'}} onClick={() => this.changecols(3)}>3列</Button>
                <Button onClick={() => this.changecols(4)}>4列</Button>
              </>
            } trigger="hover">
              <SwapOutlined />
            </Popover> : null}
            {/* <FormFork forms={group.fields}/> */}
            {/* <CopyOutlined title="复制" onClick={this.triggerCopy} /> */}
            <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
          </div>
          <div style={{clear: 'both'}}></div>
          {appType !== 'mob' ? <CardComponent
            list={group.fields}
src/menu/components/form/step-form/index.scss
@@ -35,14 +35,6 @@
      cursor: pointer;
      padding: 4px 10px;
    }
    >button {
      float: right;
      margin-right: 10px;
    }
    >.mk-cols-change {
      height: 24px;
      padding: 0 10px;
    }
    >.quickly-add {
      display: inline-block;
      margin-left: 10px;
src/menu/components/form/tab-form/index.jsx
@@ -2,7 +2,7 @@
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Modal, Button, Switch, notification, message } from 'antd'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, SwapOutlined, FontColorsOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
@@ -20,6 +20,7 @@
const MobCardComponent = asyncComponent(() => import('@/mob/components/formdragelement'))
const FormTitle = asyncComponent(() => import('../dragtitle'))
const FormAction = asyncComponent(() => import('../formaction'))
// const FormFork = asyncComponent(() => import('@/menu/modalconfig/formfork'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
@@ -453,69 +454,13 @@
   */
  handleForm = (_item) => {
    const { card, group } = this.state
    let _form = fromJS(_item).toJS()
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = []
    group.fields.forEach((item, i) => {
      if (!item.field || _form.field === item.field) return
      if (['text', 'number', 'textarea', 'select'].includes(item.type)) {
        _inputfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
        _tabfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (['switch', 'check', 'popSelect'].includes(item.type)) {
        _linksupFields.push({
          field: item.field,
          label: item.label
        })
      }
      if (!['select', 'link', 'radio', 'checkcard', 'multiselect'].includes(item.type)) return
      _linksupFields.push({
        field: item.field,
        label: item.label
      })
      if (item.type === 'multiselect' || (item.type === 'checkcard' && item.multiple === 'true')) return
      _linkableFields.push({
        field: item.field,
        label: item.label + '-表单'
      })
    })
    let _fields = _linkableFields.map(cell => cell.field)
    card.columns.forEach(col => {
      if (col.field && !_fields.includes(col.field)) {
        _linkableFields.push({
          field: col.field,
          label: col.label + '-显示列'
        })
      }
    })
    if (_form.linkSubField && _form.linkSubField.length > 0) {
      let fields = _inputfields.map(item => item.field)
      _form.linkSubField = _form.linkSubField.filter(item => fields.includes(item))
    }
    this.setState({
      visible: true,
      editform: _form,
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, card.columns)
      formlist: getModalForm(_form, group.fields, card.columns)
    })
  }
@@ -723,12 +668,22 @@
        {group ? <div className={`form-area mk-${card.wrap.formStyle || ''}`}>
          <PlusOutlined className="plus" title="添加表单" onClick={this.addForm}/>
          <FieldsComponent config={group} type="form" plusFields={this.plusFields} />
          <span style={{color: 'red', marginLeft: '30px', cursor: 'pointer'}} onClick={this.clearGroup}>清空</span>
          <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</Button> : null}
          <div className="mk-form-tool">
            <DeleteOutlined title="清空" onClick={this.clearGroup} />
            {appType !== 'mob' ? <Popover title="切换布局" overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
              <>
                <Button style={{marginRight: '10px'}} onClick={() => this.changecols(1)}>1列</Button>
                <Button style={{marginRight: '10px'}} onClick={() => this.changecols(2)}>2列</Button>
                <Button style={{marginRight: '10px'}} onClick={() => this.changecols(3)}>3列</Button>
                <Button onClick={() => this.changecols(4)}>4列</Button>
              </>
            } trigger="hover">
              <SwapOutlined />
            </Popover> : null}
            {/* <FormFork forms={group.fields}/> */}
            {/* <CopyOutlined title="复制" onClick={this.triggerCopy} /> */}
            <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
          </div>
          <div style={{clear: 'both'}}></div>
          {appType !== 'mob' ? <CardComponent
            list={group.fields}
src/menu/components/form/tab-form/index.scss
@@ -34,14 +34,6 @@
      cursor: pointer;
      padding: 4px 10px;
    }
    >button {
      float: right;
      margin-right: 10px;
    }
    >.mk-cols-change {
      height: 24px;
      padding: 0 10px;
    }
    >.quickly-add {
      display: inline-block;
      margin-left: 10px;
src/menu/components/table/edit-table/columns/tableIn/index.jsx
@@ -104,6 +104,92 @@
            </div>
          )
      },
      {
        dataIndex: 'sqlRender',
        render: (record) => {
          let columns = this.props.config.columns
          let textFields = []
          let numberFields = []
          let dateFields = []
          columns.forEach((col) => {
            if (/Nvarchar/ig.test(col.datatype)) {
              textFields.push(col.field)
            } else if (/Decimal|int/ig.test(col.datatype)) {
              numberFields.push(col.field)
            } else if (/date/ig.test(col.datatype)) {
              dateFields.push(col.field)
            }
          })
          let _sheet = this.state.verify.sheet
          if (window.GLOB.externalDatabase !== null) {
            _sheet = _sheet.replace(/@db@/ig, window.GLOB.externalDatabase)
          }
          let database = _sheet.match(/(.*)\.(.*)\./ig)
          let sheet = _sheet.replace(/(.*)\.(.*)\./ig, '')
          database = database ? (database[0] || '') : ''
          let _fields = record.field.split(',')
          let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
          _fields_ = _fields_.join(' and ')
          let _where = []
          _fields.forEach(f => {
            if (textFields.includes(f)) {
              _where.push(`${f}!=''`)
            } else if (numberFields.includes(f)) {
              _where.push(`${f}!=0`)
            } else if (dateFields.includes(f)) {
              _where.push(`${f}>'1949-10-01'`)
            }
          })
          _where = _where.length ? `where ${_where.join(' and ')} ` : ''
          if (record.verifyType === 'logic' || record.verifyType === 'logic_temp') {
            _fields_ += ' and b.deleted=0'
          }
          let _afields = []
          _fields = _fields.map(f => {
            if (numberFields.includes(f)) {
              _afields.push(`cast(a.${f} as nvarchar(50))`)
              return `cast(${f} as nvarchar(50))`
            } else if (dateFields.includes(f)) {
              _afields.push(`CONVERT(nvarchar(50), a.${f}, 21)`)
              return `CONVERT(nvarchar(50), ${f}, 21)`
            }
            _afields.push(`a.${f}`)
            return f
          })
          let sql = `
          /* 重复性验证 */
          Set @tbid=''
          Select top 1 @tbid=${_fields.join('+\' \'+')} from (select 1 as n,${record.field} from #${sheet} ) a group by ${record.field} having sum(n)>1
          If @tbid!=''
          Begin
            select @ErrorCode='${record.errorCode}',@retmsg=@tbid+' 重复'
            goto aaa
          end
          ${record.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
          Select top 1 @tbid=${_afields.join('+\' \'+')} from ${_where ? `(select * from #${sheet} ${_where})` : `#${sheet}`} a Inner join ${database}${sheet} b on ${_fields_}
          If @tbid!=''
          Begin
            select @ErrorCode='${record.errorCode}',@retmsg=@tbid+' 与已有数据重复'
            goto aaa
          end` : ''}
          `
          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
        }
      }
    ],
    scriptsColumns: [
      {
@@ -611,7 +697,7 @@
            </span>
          } key="unique">
            <UniqueForm fields={fields} uniqueChange={this.uniqueChange}/>
            <EditTable actions={['edit', 'move', 'del']} data={verify.uniques} columns={uniqueColumns} onChange={this.changeUniques}/>
            <EditTable actions={['edit', 'move', 'del', 'sql']} data={verify.uniques} columns={uniqueColumns} onChange={this.changeUniques}/>
          </TabPane>
          <TabPane disabled={verify.intertype !== 'system'} tab={
            <span>
src/menu/debug/index.jsx
@@ -1470,17 +1470,54 @@
    let _uniquesql = ''
    if (btn.uniques && btn.uniques.length > 0) {
      let textFields = []
      let numberFields = []
      let dateFields = []
      btn.columns.forEach((col) => {
        if (/Nvarchar/ig.test(col.type)) {
          textFields.push(col.Column)
        } else if (/Decimal|int/ig.test(col.type)) {
          numberFields.push(col.Column)
        } else if (/date/ig.test(col.type)) {
          dateFields.push(col.Column)
        }
      })
      btn.uniques.forEach(unique => {
        if (unique.status === 'false' || !unique.verifyType) return
        let _fields = unique.field.split(',')
        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
        let _afields = _fields.map(_field => `a.${_field}`)
        _fields_ = _fields_.join(' and ')
        let _where = []
        _fields.forEach(f => {
          if (textFields.includes(f)) {
            _where.push(`${f}!=''`)
          } else if (numberFields.includes(f)) {
            _where.push(`${f}!=0`)
          } else if (dateFields.includes(f)) {
            _where.push(`${f}>'1949-10-01'`)
          }
        })
        _where = _where.length ? `where ${_where.join(' and ')} ` : ''
        if (unique.verifyType === 'logic' || unique.verifyType === 'logic_temp') {
          _fields_ += ' and b.deleted=0'
        }
        let _afields = []
        _fields = _fields.map(f => {
          if (numberFields.includes(f)) {
            _afields.push(`cast(a.${f} as nvarchar(50))`)
            return `cast(${f} as nvarchar(50))`
          } else if (dateFields.includes(f)) {
            _afields.push(`CONVERT(nvarchar(50), a.${f}, 21)`)
            return `CONVERT(nvarchar(50), ${f}, 21)`
          }
          _afields.push(`a.${f}`)
          return f
        })
        _uniquesql += `
      /* 重复性验证 */
@@ -1494,7 +1531,7 @@
      end
      
      ${unique.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
      Select top 1 @tbid=${_afields.join('+\' \'+')} from  #${sheet} a Inner join ${sheet} b on ${_fields_}
      Select top 1 @tbid=${_afields.join('+\' \'+')} from ${_where ? `(select * from #${sheet} ${_where})` : `#${sheet}`} a Inner join ${sheet} b on ${_fields_}
      
      If @tbid!=''
      Begin
@@ -1662,17 +1699,54 @@
    let _uniquesql = ''
    if (btn.uniques && btn.uniques.length > 0) {
      let textFields = []
      let numberFields = []
      let dateFields = []
      columns.forEach((col) => {
        if (/Nvarchar/ig.test(col.datatype)) {
          textFields.push(col.field)
        } else if (/Decimal|int/ig.test(col.datatype)) {
          numberFields.push(col.field)
        } else if (/date/ig.test(col.datatype)) {
          dateFields.push(col.field)
        }
      })
      btn.uniques.forEach(unique => {
        if (unique.status === 'false' || !unique.verifyType) return
        let _fields = unique.field.split(',')
        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
        let _afields = _fields.map(_field => `a.${_field}`)
        _fields_ = _fields_.join(' and ')
        let _where = []
        _fields.forEach(f => {
          if (textFields.includes(f)) {
            _where.push(`${f}!=''`)
          } else if (numberFields.includes(f)) {
            _where.push(`${f}!=0`)
          } else if (dateFields.includes(f)) {
            _where.push(`${f}>'1949-10-01'`)
          }
        })
        _where = _where.length ? `where ${_where.join(' and ')} ` : ''
        if (unique.verifyType === 'logic' || unique.verifyType === 'logic_temp') {
          _fields_ += ' and b.deleted=0'
        }
        let _afields = []
        _fields = _fields.map(f => {
          if (numberFields.includes(f)) {
            _afields.push(`cast(a.${f} as nvarchar(50))`)
            return `cast(${f} as nvarchar(50))`
          } else if (dateFields.includes(f)) {
            _afields.push(`CONVERT(nvarchar(50), a.${f}, 21)`)
            return `CONVERT(nvarchar(50), ${f}, 21)`
          }
          _afields.push(`a.${f}`)
          return f
        })
        _uniquesql += `
      /* 重复性验证 */
@@ -1686,7 +1760,7 @@
      end
      
      ${unique.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
      Select top 1 @tbid=${_afields.join('+\' \'+')} from  #${sheet} a Inner join ${sheet} b on ${_fields_}
      Select top 1 @tbid=${_afields.join('+\' \'+')} from ${_where ? `(select * from #${sheet} ${_where})` : `#${sheet}`} a Inner join ${sheet} b on ${_fields_}
      
      If @tbid!=''
      Begin
src/menu/modalconfig/formfork/index.jsx
New file
@@ -0,0 +1,241 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Modal } from 'antd'
import { ForkOutlined } from '@ant-design/icons'
import './index.scss'
class FormFork extends Component {
  static propTpyes = {
    forms: PropTypes.array
  }
  state = {
    visible: false,
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  trigger = () => {
    const { forms } = this.props
    // let linkSubField = []
    // let supField = []
    // let tabField = []
    // let linkField = []
    let linkFields = {}    // 关联菜单
    let controlFields = {} // 控制表单
    let fieldMap = new Map()
    let formlist = fromJS(forms).toJS()
    formlist.forEach(item => {
      if (item.supField) { // 多层表单控制
        if (['hint', 'split', 'formula'].includes(item.type)) {
          item.field = item.uuid
        }
        let supvals = []
        if (item.supvalue) {
          item.supvalue.split(',').forEach(val => {
            supvals.push(val)
          })
        } else {
          supvals.push('')
        }
        supvals = Array.from(new Set(supvals))
        controlFields[item.supField] = controlFields[item.supField] || []
        controlFields[item.supField].push({field: item.field, values: supvals.join(',')})
      } else {
        delete item.supField
        delete item.supvalue
      }
      if (item.linkField) {
        linkFields[item.linkField] = linkFields[item.linkField] || []
        linkFields[item.linkField].push({field: item.field, label: item.label, uuid: item.uuid})
      } else {
        delete item.linkField
      }
      Object.keys(item).forEach(key => {
        if (!['type', 'uuid', 'field', 'label', 'supField', 'supvalue', 'linkField', 'linkSubField', 'multiple', 'enter', 'tabField'].includes(key)) {
          delete item[key]
        }
      })
      if (!item.field) return
      fieldMap.set(item.field, item)
    })
    Object.keys(controlFields).forEach(key => {
      if (!fieldMap.has(key)) return
      let supItem = fieldMap.get(key)
      let fields = []
      controlFields[key].forEach(item => {
        if (!fieldMap.has(item.field)) return
        item.label = fieldMap.get(item.field).label
        fields.push(item)
      })
      if (fields.length === 0) return
      supItem.controlFields = fields
      fieldMap.set(key, supItem)
    })
    let _f = fromJS([...fieldMap.values()]).toJS()
    _f.forEach(item => {
      // 下级表单控制-字段写入
      if (item.linkSubField && item.linkSubField.length > 0) {
        item.subFields = []
        if ((['select', 'radio', 'link', 'cascader'].includes(item.type) || (item.type === 'checkcard' && item.multiple !== 'true'))) {
          item.linkSubField.forEach(m => {
            let n = fieldMap.get(m)
            if (n && ['text', 'number', 'textarea', 'select'].includes(n.type)) {
              item.subFields.push({
                uuid: n.uuid,
                field: m,
                label: n.label
              })
            }
          })
        } else if (item.type === 'switch') {
          item.linkSubField.forEach(m => {
            let n = fieldMap.get(m)
            if (n && ['text', 'number', 'textarea', 'select'].includes(n.type)) {
              item.subFields.push({
                uuid: n.uuid,
                field: m,
                label: n.label
              })
            }
          })
        } else if (item.type === 'fileupload') {
          item.linkSubField.forEach(m => {
            let n = fieldMap.get(m)
            if (n && ['text', 'number', 'textarea', 'select'].includes(n.type)) {
              item.subFields.push({
                uuid: n.uuid,
                field: m,
                label: n.label
              })
            }
          })
        } else if (item.type === 'popSelect') {
          item.linkSubField.forEach(m => {
            let n = fieldMap.get(m)
            if (n && ['text', 'number', 'textarea', 'select'].includes(n.type)) {
              item.subFields.push({
                uuid: n.uuid,
                field: m,
                label: n.label
              })
            }
          })
        }
        if (item.subFields.length === 0) {
          delete item.subFields
        }
      }
      if (linkFields[item.field]) {
        item.linkFields = linkFields[item.field]
      }
      if (item.enter === 'tab' || item.enter === 'sub') {
        if (item.tabField) {
          if (!fieldMap.has(item.tabField)) {
            delete item.tabField
          } else {
            item.tabLabel = fieldMap.get(item.tabField).label
          }
        }
      } else {
        delete item.tabField
      }
      if (item.supField) {
        if (!fieldMap.has(item.supField)) {
          delete item.supField
          delete item.supvalue
        } else {
          item.supLabel = fieldMap.get(item.supField).label
        }
      }
      if (item.linkField) {
        if (!fieldMap.has(item.linkField)) {
          item.linkLabel = '字段集'
        } else {
          item.linkLabel = fieldMap.get(item.linkField).label
        }
      }
      delete item.enter
      delete item.multiple
      delete item.linkSubField
      // if (!item.controlFields && !item.linkFields && !item.subFields && !item.resubFields)
      fieldMap.set(item.field, item)
    })
    let _t = fromJS([...fieldMap.values()]).toJS()
    _t.forEach(item => {
      if (item.subFields) {
        item.subFields.forEach(cell => {
          let _cell = fieldMap.get(cell.field)
          _cell.resubFields = _cell.resubFields || []
          _cell.resubFields.push({
            uuid: item.uuid,
            field: item.field,
            label: item.label
          })
          fieldMap.set(cell.field, _cell)
        })
      }
    })
    this.setState({
      visible: true
    })
  }
  render() {
    const { visible } = this.state
    return (
      <>
        <ForkOutlined title="表单关系图" onClick={this.trigger}/>
        <Modal
          title="表单关系图"
          wrapClassName="form-fork-modal mk-scroll-modal"
          visible={visible}
          width={900}
          maskClosable={false}
          cancelText="关闭"
          onOk={() => { this.setState({ visible: false })}}
          onCancel={() => { this.setState({ visible: false })}}
          destroyOnClose
        >
        </Modal>
      </>
    )
  }
}
export default FormFork
src/menu/modalconfig/formfork/index.scss
New file
@@ -0,0 +1,14 @@
.form-fork-modal {
  .ant-modal-header {
    text-align: center;
  }
  .ant-modal-body {
    min-height: 350px!important;
  }
  .ant-modal-footer {
    .ant-btn-primary {
      display: none;
    }
  }
}
src/menu/modalconfig/index.jsx
@@ -3,8 +3,8 @@
import { is, fromJS } from 'immutable'
import { DndProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import { Button, Card, Modal, Collapse, Switch, message } from 'antd'
import { SettingOutlined, CopyOutlined } from '@ant-design/icons'
import { Button, Card, Modal, Collapse, Switch, message, Popover } from 'antd'
import { SettingOutlined, CopyOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
import { getModalForm } from '@/templates/zshare/formconfig'
import SourceElement from '@/templates/modalconfig/dragelement/source'
@@ -21,6 +21,7 @@
const TableComponent = asyncComponent(() => import('./tablecomponent'))
const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
const PasteForms = asyncComponent(() => import('@/menu/components/share/pasteforms'))
// const FormFork = asyncComponent(() => import('@/menu/modalconfig/formfork'))
const DragElement = asyncComponent(() => import('@/templates/modalconfig/dragelement'))
const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
@@ -97,81 +98,21 @@
  /**
   * @description 表单编辑
   * 1、显示编辑弹窗-visible
   * 2、保存编辑项-card
   * 3、设置编辑参数项-formlist
   */
  handleForm = (_card) => {
    const { componentConfig, btn } = this.props
    const { config } = this.state
    let card = fromJS(_card).toJS()
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = []
    config.fields.forEach((item, i) => {
      if (!item.field || card.field === item.field) return
      if (['text', 'number', 'textarea', 'select'].includes(item.type)) {
        _inputfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
        _tabfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (['switch', 'check', 'popSelect'].includes(item.type)) {
        _linksupFields.push({
          field: item.field,
          label: item.label
        })
      }
      if (!['select', 'link', 'radio', 'checkcard', 'multiselect'].includes(item.type)) return
      _linksupFields.push({
        field: item.field,
        label: item.label
      })
      if (item.type === 'multiselect' || (item.type === 'checkcard' && item.multiple === 'true')) return
      _linkableFields.push({
        field: item.field,
        label: item.label + '-表单'
      })
    })
    let columns = componentConfig.columns
    if (btn.$sub) {
      columns = componentConfig.subColumns || []
    }
    let _fields = _linkableFields.map(cell => cell.field)
    columns.forEach(col => {
      if (col.field && !_fields.includes(col.field)) {
        _linkableFields.push({
          field: col.field,
          label: col.label + '-显示列'
        })
      }
    })
    if (card.linkSubField && card.linkSubField.length > 0) {
      let fields = _inputfields.map(item => item.field)
      card.linkSubField = card.linkSubField.filter(item => fields.includes(item))
    }
    this.setState({
      visible: true,
      card: card,
      formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, columns)
      formlist: getModalForm(card, config.fields, columns)
    })
  }
@@ -451,7 +392,6 @@
          <div className="setting">
            <Card title="表单配置" bordered={false} extra={
              <div>
                <Button type="danger" onClick={this.clearConfig}>清空</Button>
                <PasteForms type="toolbar" config={config} update={this.pasteFields}/>
                <Button type="primary" id="save-modal-config" loading={saving} onClick={this.submitConfig}>保存</Button>
                <Button onClick={this.cancelConfig}>返回</Button>
@@ -461,12 +401,22 @@
              <div className="ant-modal-content" style={{width: config.setting.width > 100 ? config.setting.width : config.setting.width + '%'}}>
                <div className="ant-modal-header">
                  <div className="ant-modal-title">{config.setting.icon ? <span className={'mk-modal-icon-' + config.setting.iconType} style={{background: config.setting.iconColor || 'unset', color: config.setting.iconColor || 'inherit'}}><MkIcon type={config.setting.icon}/></span> : null}{btn.label}</div>
                  <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</Button>
                  <CopyOutlined title="复制" onClick={this.triggerCopy} />
                  <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
                  <div className="mk-form-tool">
                    <DeleteOutlined title="清空" onClick={this.clearConfig} />
                    <Popover title="切换布局" overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                      <>
                        <Button style={{marginRight: '10px'}} onClick={() => this.changecols(1)}>1列</Button>
                        <Button style={{marginRight: '10px'}} onClick={() => this.changecols(2)}>2列</Button>
                        <Button style={{marginRight: '10px'}} onClick={() => this.changecols(3)}>3列</Button>
                        <Button onClick={() => this.changecols(4)}>4列</Button>
                      </>
                    } trigger="hover">
                      <SwapOutlined />
                    </Popover>
                    {/* <FormFork forms={config.fields}/> */}
                    <CopyOutlined title="复制" onClick={this.triggerCopy} />
                    <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
                  </div>
                </div>
                <div className="ant-modal-body">
                  <div className="modal-form">
src/menu/modalconfig/index.scss
@@ -125,7 +125,8 @@
          z-index: 10;
          background: transparent;
          min-height: 50px;
          padding-right: 80px;
          padding-right: 10px;
          .ant-modal-title {
            display: inline-block;
            height: 22px;
@@ -143,23 +144,6 @@
              text-align: center;
              line-height: 30px;
            }
          }
          .anticon-copy {
            position: absolute;
            top: 18px;
            color: #26C281;
            right: 65px;
            font-size: 16px;
          }
          .ant-switch {
            position: absolute;
            top: 15px;
            right: 10px;
          }
          .mk-cols-change {
            float: right;
            height: 25px;
            margin-right: 10px;
          }
        }
        .ant-modal-close {
src/mob/modalconfig/index.jsx
@@ -106,74 +106,18 @@
  handleForm = (_card) => {
    const { componentConfig, btn } = this.props
    const { config } = this.state
    let card = fromJS(_card).toJS()
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = []
    config.fields.forEach((item, i) => {
      if (!item.field || card.field === item.field) return
      if (['text', 'number', 'textarea', 'select'].includes(item.type)) {
        _inputfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
        _tabfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (item.type === 'switch' || item.type === 'check') {
        _linksupFields.push({
          field: item.field,
          label: item.label
        })
      }
      if (!['select', 'link', 'radio', 'checkcard'].includes(item.type)) return
      _linksupFields.push({
        field: item.field,
        label: item.label
      })
      if (item.type === 'checkcard' && item.multiple === 'true') return
      _linkableFields.push({
        field: item.field,
        label: item.label + '-表单'
      })
    })
    let columns = componentConfig.columns
    if (btn.$sub) {
      columns = componentConfig.subColumns || []
    }
    let _fields = _linkableFields.map(cell => cell.field)
    columns.forEach(col => {
      if (col.field && !_fields.includes(col.field)) {
        _linkableFields.push({
          field: col.field,
          label: col.label + '-显示列'
        })
      }
    })
    if (card.linkSubField && card.linkSubField.length > 0) {
      let fields = _inputfields.map(item => item.field)
      card.linkSubField = card.linkSubField.filter(item => fields.includes(item))
    }
    this.setState({
      visible: true,
      card: card,
      formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, columns)
      formlist: getModalForm(card, config.fields, columns)
    })
  }
src/tabviews/custom/components/module/invoice/index.jsx
@@ -541,6 +541,22 @@
  outBill = () => {
    const { config, BID, saveType } = this.state
    if (window.GLOB.storeFiles) {
      if (!window.GLOB.storeDate || window.GLOB.storeDate < 0) {
        Modal.warning({
          title: `电子档案存储包已过期。`,
          okText: '知道了'
        })
        return
      } else if (window.GLOB.storeDate < 30) {
        notification.warning({
          top: 92,
          message: `电子档案存储包还剩${window.GLOB.storeDate}天。`,
          duration: 5
        })
      }
    }
    if (window.GLOB.systemType === 'production' && !config.billOutBtn.proInterface) {
      notification.warning({
        top: 92,
@@ -797,6 +813,10 @@
    param.data.invoiceTypeCode = trans[param.data.invoiceTypeCode] || ''
    if (window.GLOB.storeFiles) {
      param.store = true
    }
    let url = ''
    if (window.GLOB.systemType === 'production') {
      url = config.billOutBtn.proInterface
src/templates/modalconfig/index.jsx
@@ -216,89 +216,21 @@
  handleForm = (_card) => {
    const { menu, tabConfig, subTabConfig } = this.props
    const { config } = this.state
    let card = fromJS(_card).toJS()
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = []
    config.fields.forEach((item, i) => {
      if (!item.field || card.field === item.field) return
      if (['text', 'number', 'textarea', 'select'].includes(item.type)) {
        _inputfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
        _tabfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (['switch', 'check', 'popSelect'].includes(item.type)) {
        _linksupFields.push({
          field: item.field,
          label: item.label
        })
      }
      if (!['select', 'link', 'radio', 'checkcard', 'multiselect'].includes(item.type)) return
      _linksupFields.push({
        field: item.field,
        label: item.label
      })
      if (item.type === 'multiselect' || (item.type === 'checkcard' && item.multiple === 'true')) return
      _linkableFields.push({
        field: item.field,
        label: item.label + '-表单'
      })
    })
    let _fields = _linkableFields.map(cell => cell.field)
    let columns = []
    if (subTabConfig) {
      subTabConfig.columns.forEach(col => {
        if (col.field && !_fields.includes(col.field)) {
          _linkableFields.push({
            field: col.field,
            label: col.label + '-显示列'
          })
        }
      })
      columns = subTabConfig.columns
    } else if (tabConfig) {
      tabConfig.columns.forEach(col => {
        if (col.field && !_fields.includes(col.field)) {
          _linkableFields.push({
            field: col.field,
            label: col.label + '-显示列'
          })
        }
      })
      columns = tabConfig.columns
    } else if (menu.LongParam) {
      menu.LongParam.columns.forEach(col => {
        if (col.field && !_fields.includes(col.field)) {
          _linkableFields.push({
            field: col.field,
            label: col.label + '-显示列'
          })
        }
      })
    }
    if (card.linkSubField && card.linkSubField.length > 0) {
      let fields = _inputfields.map(item => item.field)
      card.linkSubField = card.linkSubField.filter(item => fields.includes(item))
      columns = menu.LongParam.columns
    }
    this.setState({
      visible: true,
      card: card,
      formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields)
      formlist: getModalForm(card, config.fields, columns)
    })
  }
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -205,6 +205,93 @@
            </div>
          )
      },
      {
        dataIndex: 'sqlRender',
        render: (record) => {
          let columns = this.state.verify.columns
          let textFields = []
          let numberFields = []
          let dateFields = []
          columns.forEach((col) => {
            if (/Nvarchar/ig.test(col.type)) {
              textFields.push(col.Column)
            } else if (/Decimal|int/ig.test(col.type)) {
              numberFields.push(col.Column)
            } else if (/date/ig.test(col.type)) {
              dateFields.push(col.Column)
            }
          })
          let _fields = record.field.split(',')
          let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
          _fields_ = _fields_.join(' and ')
          let _where = []
          _fields.forEach(f => {
            if (textFields.includes(f)) {
              _where.push(`${f}!=''`)
            } else if (numberFields.includes(f)) {
              _where.push(`${f}!=0`)
            } else if (dateFields.includes(f)) {
              _where.push(`${f}>'1949-10-01'`)
            }
          })
          _where = _where.length ? `where ${_where.join(' and ')} ` : ''
          if (record.verifyType === 'logic' || record.verifyType === 'logic_temp') {
            _fields_ += ' and b.deleted=0'
          }
          let _afields = []
          _fields = _fields.map(f => {
            if (numberFields.includes(f)) {
              _afields.push(`cast(a.${f} as nvarchar(50))`)
              return `cast(${f} as nvarchar(50))`
            } else if (dateFields.includes(f)) {
              _afields.push(`CONVERT(nvarchar(50), a.${f}, 21)`)
              return `CONVERT(nvarchar(50), ${f}, 21)`
            }
            _afields.push(`a.${f}`)
            return f
          })
          let _sheet = this.props.card.sheet
          if (window.GLOB.externalDatabase !== null) {
            _sheet = _sheet.replace(/@db@/ig, window.GLOB.externalDatabase)
          }
          let database = _sheet.match(/(.*)\.(.*)\./ig)
          let sheet = _sheet.replace(/(.*)\.(.*)\./ig, '')
          database = database ? (database[0] || '') : ''
          let sql = `
          /* 重复性验证 */
          Set @tbid=''
          Select top 1 @tbid=${_fields.join('+\' \'+')} from (select 1 as n,${record.field} from #${sheet} ${_where}) a group by ${record.field} having sum(n)>1
          If @tbid!=''
          Begin
            select @ErrorCode='${record.errorCode}',@retmsg=@tbid+' 重复'
            goto aaa
          end
          ${record.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
          Select top 1 @tbid=${_afields.join('+\' \'+')} from ${_where ? `(select * from #${sheet} ${_where})` : `#${sheet}`} a Inner join ${database}${sheet} b on ${_fields_}
          If @tbid!=''
          Begin
            select @ErrorCode='${record.errorCode}',@retmsg=@tbid+' 与已有数据重复'
            goto aaa
          end` : ''}
          `
          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
        }
      }
    ],
    scriptsColumns: [
      {
@@ -980,7 +1067,7 @@
            </span>
          } key="unique">
            <UniqueForm fields={verify.columns} uniqueChange={this.uniqueChange}/>
            <EditTable actions={['edit', 'move', 'del', 'status']} data={verify.uniques} columns={uniqueColumns} onChange={this.changeUniques}/>
            <EditTable actions={['edit', 'move', 'del', 'status', 'sql']} data={verify.uniques} columns={uniqueColumns} onChange={this.changeUniques}/>
          </TabPane> : null}
          {card.intertype === 'system' ? <TabPane tab={
            <span>
src/templates/zshare/editTable/index.jsx
@@ -366,7 +366,7 @@
    if (list) {
      Modal.info({
        title: '',
        width: 500,
        width: 700,
        className: 'sql-example',
        icon: null,
        content: list.map((n, index) => <div key={index} dangerouslySetInnerHTML={{ __html: n }}></div>)
src/templates/zshare/formconfig.jsx
@@ -731,13 +731,8 @@
/**
 * @description 获取表单配置信息
 * @param {*} card            // 表单对象
 * @param {*} inputfields     // 可写入表单
 * @param {*} tabfields       // 可切换表单
 * @param {*} linkableFields  // 可关联表单
 * @param {*} linksupFields   // 上级表单
 */
export function getModalForm (card, inputfields = [], tabfields = [], linkableFields, linksupFields, columns = []) {
export function getModalForm (card, fields, columns = []) {
  let appType = sessionStorage.getItem('appType')
  let roleList = sessionStorage.getItem('sysRoles')
  if (roleList) {
@@ -774,6 +769,64 @@
    msgTemps = []
  }
  let inputfields = []
  let tabfields = []
  let linkableFields = []
  let linksupFields = []
  fields.forEach(item => {
    if (!item.field || card.field === item.field) return
    if (['text', 'number', 'textarea', 'select'].includes(item.type)) {
      inputfields.push({
        field: item.field,
        label: item.label
      })
    }
    if (item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
      tabfields.push({
        field: item.field,
        label: item.label
      })
    }
    if (['switch', 'check', 'popSelect'].includes(item.type)) {
      linksupFields.push({
        field: item.field,
        label: item.label
      })
    }
    if (!['select', 'link', 'radio', 'checkcard', 'multiselect'].includes(item.type)) return
    linksupFields.push({
      field: item.field,
      label: item.label
    })
    if (item.type === 'multiselect' || (item.type === 'checkcard' && item.multiple === 'true')) return
    linkableFields.push({
      field: item.field,
      label: item.label + '-表单'
    })
  })
  let _fields = linkableFields.map(cell => cell.field)
  columns.forEach(col => {
    if (col.field && !_fields.includes(col.field)) {
      linkableFields.push({
        field: col.field,
        label: col.label + '-显示列'
      })
    }
  })
  if (card.linkSubField && card.linkSubField.length > 0) {
    let fields = inputfields.map(item => item.field)
    card.linkSubField = card.linkSubField.filter(item => fields.includes(item))
  }
  inputfields = inputfields.map((item, index) => {
    item.label = `${index + 1}、${item.field || ''}(${item.label})`
    return item
src/templates/zshare/verifycard/index.jsx
@@ -86,7 +86,7 @@
        title: '验证类型',
        dataIndex: 'verifyType',
        width: '14%',
        render: (text, record) => record.verifyType === 'logic' ? '逻辑验证' : '物理验证',
        render: (text) => text === 'logic' ? '逻辑验证' : '物理验证',
        inputType: 'select',
        editable: true,
        options: [
@@ -124,7 +124,7 @@
          record.field.split(',').forEach((_field, index) => {
            let _key = _field.toLowerCase()
            _fieldValue.push(`${_key}=${_key === 'bid' ? '@BID@' : ''}`)
            _fieldValue.push(`${_key}=${_key === 'bid' ? '@BID@' : `''`}`)
            _value.push(`${_labels[index] || ''}:xxx`)
          })
src/utils/utils.js
@@ -1134,9 +1134,15 @@
    let _uniquesql = ''
    if (btn.uniques && btn.uniques.length > 0) {
      let textFields = []
      let numberFields = []
      let dateFields = []
      btn.columns.forEach((col) => {
        if (/^Nvarchar/ig.test(col.type)) {
        if (/Nvarchar/ig.test(col.type)) {
          textFields.push(col.Column)
        } else if (/Decimal|int/ig.test(col.type)) {
          numberFields.push(col.Column)
        } else if (/date/ig.test(col.type)) {
          dateFields.push(col.Column)
        }
      })
@@ -1145,13 +1151,17 @@
        let _fields = unique.field.split(',')
        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
        let _afields = _fields.map(_field => `a.${_field}`)
        _fields_ = _fields_.join(' and ')
        let _where = []
        _fields.forEach(f => {
          if (textFields.includes(f)) {
            _where.push(`${f}!=''`)
          } else if (numberFields.includes(f)) {
            _where.push(`${f}!=0`)
          } else if (dateFields.includes(f)) {
            _where.push(`${f}>'1949-10-01'`)
          }
        })
        _where = _where.length ? `where ${_where.join(' and ')} ` : ''
@@ -1159,6 +1169,20 @@
        if (unique.verifyType === 'logic' || unique.verifyType === 'logic_temp') {
          _fields_ += ' and b.deleted=0'
        }
        let _afields = []
        _fields = _fields.map(f => {
          if (numberFields.includes(f)) {
            _afields.push(`cast(a.${f} as nvarchar(50))`)
            return `cast(${f} as nvarchar(50))`
          } else if (dateFields.includes(f)) {
            _afields.push(`CONVERT(nvarchar(50), a.${f}, 21)`)
            return `CONVERT(nvarchar(50), ${f}, 21)`
          }
          _afields.push(`a.${f}`)
          return f
        })
        _uniquesql += `
      /* 重复性验证 */
@@ -1368,17 +1392,54 @@
    let _uniquesql = ''
    if (btn.uniques && btn.uniques.length > 0) {
      let textFields = []
      let numberFields = []
      let dateFields = []
      columns.forEach((col) => {
        if (/Nvarchar/ig.test(col.datatype)) {
          textFields.push(col.field)
        } else if (/Decimal|int/ig.test(col.datatype)) {
          numberFields.push(col.field)
        } else if (/date/ig.test(col.datatype)) {
          dateFields.push(col.field)
        }
      })
      btn.uniques.forEach(unique => {
        if (unique.status === 'false' || !unique.verifyType) return
        let _fields = unique.field.split(',')
        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
        let _afields = _fields.map(_field => `a.${_field}`)
        _fields_ = _fields_.join(' and ')
        let _where = []
        _fields.forEach(f => {
          if (textFields.includes(f)) {
            _where.push(`${f}!=''`)
          } else if (numberFields.includes(f)) {
            _where.push(`${f}!=0`)
          } else if (dateFields.includes(f)) {
            _where.push(`${f}>'1949-10-01'`)
          }
        })
        _where = _where.length ? `where ${_where.join(' and ')} ` : ''
        if (unique.verifyType === 'logic' || unique.verifyType === 'logic_temp') {
          _fields_ += ' and b.deleted=0'
        }
        let _afields = []
        _fields = _fields.map(f => {
          if (numberFields.includes(f)) {
            _afields.push(`cast(a.${f} as nvarchar(50))`)
            return `cast(${f} as nvarchar(50))`
          } else if (dateFields.includes(f)) {
            _afields.push(`CONVERT(nvarchar(50), a.${f}, 21)`)
            return `CONVERT(nvarchar(50), ${f}, 21)`
          }
          _afields.push(`a.${f}`)
          return f
        })
        _uniquesql += `
      /* 重复性验证 */
@@ -1392,7 +1453,7 @@
      end
      
      ${unique.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
      Select top 1 @tbid=${_afields.join('+\' \'+')} from  #${sheet} a Inner join ${database}${sheet} b on ${_fields_}
      Select top 1 @tbid=${_afields.join('+\' \'+')} from ${_where ? `(select * from #${sheet} ${_where})` : `#${sheet}`} a Inner join ${database}${sheet} b on ${_fields_}
      
      If @tbid!=''
      Begin
@@ -1873,7 +1934,7 @@
        if (_key === 'bid' && !_val) { // 表单中没有bid则使用系统bid变量
          _val = BID
        }
        _fieldValue.push(`${_key}='${_val}'`)
        _value.push(`${_labels[index] || ''}:${_val || ''}`)
      })
src/views/login/index.jsx
@@ -464,6 +464,16 @@
            }
            box = box.join(',')
            localStorage.setItem(_authUrl, box)
            if (res.e_files === 'true') {
              localStorage.setItem(_href + 'files', md5(_href + 'files'))
              localStorage.setItem(_href + 'filesDate', res.e_files_end_date)
              window.GLOB.storeFiles = true
              window.GLOB.storeDate = Math.ceil((new Date(res.e_files_end_date).getTime() - new Date().getTime()) / 86400000)
            } else {
              localStorage.removeItem(_href + 'files')
              window.GLOB.storeFiles = false
            }
    
            this.setState({
              auth: true
@@ -477,6 +487,9 @@
            }
          } else {
            localStorage.removeItem(_authUrl)
            localStorage.removeItem(_href + 'files')
            window.GLOB.storeFiles = false
            this.setState({
              auth: false
            })