king
2020-04-09 b9a0e8541f0959db5d848f7b893c8838851ce411
2020-04-09
35个文件已修改
1038 ■■■■ 已修改文件
package-lock.json 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/options.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/main.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/editthdmenu/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/main.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/main.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/setupProxy.js 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/action-type.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/action.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/reducer.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 69 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.jsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtabtable/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/actionList/index.jsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/index.jsx 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/fileupload/index.jsx 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/actionform/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.jsx 95 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/columnform/index.jsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modaleditable/index.jsx 121 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modaleditable/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/billcodeform/index.jsx 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -8025,6 +8025,11 @@
      "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
      "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
    },
    "highlight-words-core": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/highlight-words-core/-/highlight-words-core-1.2.2.tgz",
      "integrity": "sha512-BXUKIkUuh6cmmxzi5OIbUJxrG8OAk2MqoL1DtO3Wo9D2faJg2ph5ntyuQeLqaHJmzER6H5tllCDA9ZnNe9BVGg=="
    },
    "highlightjs": {
      "version": "9.12.0",
      "resolved": "https://registry.npmjs.org/highlightjs/-/highlightjs-9.12.0.tgz",
@@ -10347,6 +10352,11 @@
          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
        }
      }
    },
    "memoize-one": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-4.1.0.tgz",
      "integrity": "sha512-2GApq0yI/b22J2j9rhbrAlsHb0Qcz+7yWxeLG8h+95sl1XPUgeLimQSOdur4Vw7cUhrBHwaUZxWFZueojqNRzA=="
    },
    "memory-fs": {
      "version": "0.4.1",
@@ -13572,6 +13582,16 @@
      "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.1.tgz",
      "integrity": "sha512-V9yoTr6MeZXPPd4nV/05eCBvGH9cGzc52FN8fs0O0TVQ3HYYf1n7EgZVtHbldRq5xU9zEzoXIITjYNIfxDDdUw=="
    },
    "react-highlight-words": {
      "version": "0.16.0",
      "resolved": "https://registry.npmjs.org/react-highlight-words/-/react-highlight-words-0.16.0.tgz",
      "integrity": "sha512-q34TwCSJOL+5pVDv6LUj3amaoyXdNDwd7zRqVAvceOrO9g1haWLAglK6WkGLMNUa3PFN8EgGedLg/k8Gpndxqg==",
      "requires": {
        "highlight-words-core": "1.2.2",
        "memoize-one": "4.1.0",
        "prop-types": "15.7.2"
      }
    },
    "react-is": {
      "version": "16.9.0",
      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz",
package.json
@@ -63,6 +63,7 @@
    "react-dnd": "^9.4.0",
    "react-dnd-html5-backend": "^9.4.0",
    "react-dom": "^16.9.0",
    "react-highlight-words": "^0.16.0",
    "react-redux": "^7.1.1",
    "react-router-dom": "^5.0.1",
    "redux": "^4.0.4",
public/options.js
@@ -2,7 +2,7 @@
  service: 'mkwms',
  appId: '201912040924165801464FF1788654BC5AC73',
  appkey: '20191106103859640976D6E924E464D029CF0',
  mainSystemApi: 'http://sso.mk9h.cn/webapi/dostars',
  mainSystemApi: 'http://cloud.mk9h.cn/webapi/dostars',
  platTitle: '',
  platName: '',
  favicon: '',
src/api/index.js
@@ -13,7 +13,7 @@
  config.method = 'post'
  if (config.url.includes('LoginAndRedirect') || config.url.includes('getjsonresult')) {
    config.data = qs.stringify(config.data)
  } else if (config.url.includes('Upload')) {
  } else if (config.url.includes('Upload') || config.url.includes('doupload')) {
    config.headers = { 'Content-Type': 'multipart/form-data' }
  } else {
    // config.headers.token = sessionStorage.getItem('TOKEN') || ''
@@ -429,6 +429,16 @@
  }
  /**
   * @description 大文件上传
   */
  getLargeFileUpload (param) {
    return axios({
      url: '/webapi/doupload',
      data: param
    })
  }
  /**
   * @description 文件上传
   */
  getFileUpload (param) {
src/assets/css/main.scss
@@ -171,6 +171,10 @@
  z-index: 1090!important;
}
.ant-dropdown {
  z-index: 1090!important;
}
// 确认提示框高度
.ant-modal.ant-modal-confirm {
  top: 38vh;
src/components/header/index.jsx
@@ -15,6 +15,7 @@
  resetEditState,
  resetEditLevel,
  initPermission,
  initMenuPermission,
  logout
} from '@/store/action'
import Api from '@/api'
@@ -371,6 +372,32 @@
    this.getRolesMenu()
  }
  componentDidMount () {
    // 获取角色菜单权限
    Api.getSystemConfig({func: 's_Get_TrdMenu_Role'}).then(result => {
      if (!result) return
      if (result.status) {
        let _permMenus = {}
        if (result.UserRoles) {
          result.UserRoles.forEach(role => {
            role.RoleMenu.forEach(menu => {
              if (!menu.MenuID) return
              _permMenus[menu.MenuID] = true
            })
          })
        }
        this.props.initMenuPermission(_permMenus)
      } else {
        notification.error({
          top: 92,
          message: result.message,
          duration: 15
        })
      }
    })
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
@@ -480,6 +507,7 @@
    resetEditState: (state) => dispatch(resetEditState(state)),
    resetEditLevel: (level) => dispatch(resetEditLevel(level)),
    initPermission: (permRoles, permAction, permFuncField) => dispatch(initPermission(permRoles, permAction, permFuncField)),
    initMenuPermission: (permMenus) => dispatch(initMenuPermission(permMenus)),
    resetState: () => dispatch(resetState()),
    resetDebug: () => dispatch(resetDebug()),
    logout: () => dispatch(logout())
src/components/sidemenu/editthdmenu/index.jsx
@@ -146,7 +146,7 @@
        _menu.supMenuList = this.props.supMenuList
        _menu.fstMenuId = this.state.fstMenuId || ''
        _menu.fstMenuList = this.state.fstMenuList || []
        _menu.roleList = this.state.roleList
        _menu.roleList = this.state.roleList || []
  
        this.setState({
          handleMVisible: true,
@@ -183,7 +183,7 @@
          _menu.supMenuList = this.props.supMenuList
          _menu.fstMenuId = this.state.fstMenuId || ''
          _menu.fstMenuList = this.state.fstMenuList || []
          _menu.roleList = this.state.roleList
          _menu.roleList = this.state.roleList || []
          // 检测模板是否存在
          let _Template = this.state.sysTemplates.filter(temp => temp.type === _menu.PageParam.Template)
@@ -269,7 +269,7 @@
          isSubtable: '', // 是否为主子表
          ParentID: this.props.supMenu.MenuID,
          supMenuList: this.props.supMenuList,
          roleList: this.state.roleList,
          roleList: this.state.roleList || [],
          fstMenuId: this.state.fstMenuId,
          fstMenuList: this.state.fstMenuList,
          menuSort: (this.props.menulist.length + 1) * 10 // 新建菜单设置排序
@@ -443,6 +443,7 @@
    if (!editMenu.fstMenuId) {
      editMenu.fstMenuId = this.state.fstMenuId
      editMenu.fstMenuList = this.state.fstMenuList
      editMenu.roleList = this.state.roleList || []
    }
    if (useType === 'sys' && template.type === 'RolePermission') { // 独立页面
@@ -746,6 +747,7 @@
        delete _menu.loadingFstMenuId
        _menu.fstMenuId = this.state.fstMenuId
        _menu.fstMenuList = this.state.fstMenuList
        _menu.roleList = this.state.roleList || []
        this.setState({
          type: 'edit',
src/locales/en-US/main.js
@@ -6,6 +6,7 @@
  'main.close': '关闭',
  'main.all': 'All',
  'main.cancel': '取消',
  'main.revert.default': '恢复默认设置',
  'main.copy.success': 'Copy success',
  'main.pagination.of': 'of',
  'main.pagination.items': 'items',
src/locales/zh-CN/main.js
@@ -6,6 +6,7 @@
  'main.close': '关闭',
  'main.all': '全部',
  'main.cancel': '取消',
  'main.revert.default': '恢复默认设置',
  'main.copy.success': '复制成功',
  'main.pagination.of': '共',
  'main.pagination.items': '条',
src/setupProxy.js
@@ -24,7 +24,7 @@
    }
  }))
  app.use(proxy('/Upload', { // 登录接口
  app.use(proxy('/Upload', {
    target: `${host}/${service}zh-CN/Home/Upload`,
    secure: false,
    changeOrigin: true,
@@ -33,12 +33,12 @@
    }
  }))
  app.use(proxy('/local', {
    target: 'http://127.0.0.1:8888',
    secure: false,
    changeOrigin: true,
    pathRewrite: {
    '^/local': '/'
    }
  }))
  // app.use(proxy('/local', {
  //   target: 'http://127.0.0.1:8888',
  //   secure: false,
  //   changeOrigin: true,
  //   pathRewrite: {
  //   '^/local': '/'
  //   }
  // }))
}
src/store/action-type.js
@@ -28,5 +28,8 @@
// 初始化按钮权限及创建存储过程可用字段
export const INIT_PERMISSION = 'INIT_PERMISSION'
// 初始化菜单权限
export const INIT_MENUPERMISSION = 'INIT_MENUPERMISSION'
// 退出
export const LOGOUT = 'LOGOUT'
src/store/action.js
@@ -80,6 +80,14 @@
  }
}
// 初始化菜单权限
export const initMenuPermission = (permMenus) => {
  return {
    type: user.INIT_MENUPERMISSION,
    permMenus: permMenus
  }
}
// 退出重置
export const logout = () => {
  return {
src/store/reducer.js
@@ -11,6 +11,7 @@
  refreshTab: null,     // 刷新tabview页面信息
  permRoles: [],
  permAction: {},
  permMenus: {},
  permFuncField: []
}
@@ -97,6 +98,12 @@
        permAction: action.permAction,
        permFuncField: action.permFuncField
      }
    case Type.INIT_MENUPERMISSION:
    // 初始化三级菜单权限
      return {
        ...state,
        permMenus: action.permMenus
      }
    case Type.LOGOUT:
      return {
        selectedMainMenu: '',
src/tabviews/commontable/index.jsx
@@ -68,6 +68,7 @@
    tabParam: null,       // 表单标签参数
    refreshtabs: null,    // 需要刷新的标签集
    confirmLoading: false,// 自定义设置模态框加载中
    revertLoading: false, // 恢复默认设置
    settingVisible: false,// 自定义设置模态框
    triggerBtn: null,     // 点击表格中或快捷键触发的按钮
    tabActive: null       // 标签页展开控制
@@ -77,7 +78,7 @@
   * @description 获取页面配置信息
   */
  async loadconfig () {
    const { permAction, param } = this.props
    const { permAction, permMenus, param } = this.props
    let _param = {
      func: 'sPC_Get_LongParam',
@@ -234,12 +235,14 @@
      })
      // 生成显示列,处理合并列中的字段
      config.columns.forEach(col => {
      config.columns.forEach((col, index) => {
        if (_hideCol.includes(col.uuid)) return
        // if (col.linkThdMenu && !permAction[col.linkThdMenu.MenuID]) {
        //   col.linkThdMenu = ''
        // }
        if (col.linkThdMenu && !permMenus[col.linkThdMenu.MenuID]) {
          col.linkThdMenu = ''
        }
        col.sort = index
        if (col.type === 'colspan' && col.sublist) {
          let _col = JSON.parse(JSON.stringify(col))
@@ -263,15 +266,17 @@
        })
      }
      let valid = true // 搜索条件必填验证
      config.search.forEach(item => {
        if (item.type === 'text' && param && param.searchkey === item.field) {
          item.initval = param.searchval
      let valid = true // 搜索条件必填验证, 初始搜索条件
      let initSearch = config.search.map(item => {
        let _item = JSON.parse(JSON.stringify(item))
        if (_item.type === 'text' && param && param.searchkey === _item.field) {
          _item.initval = param.searchval
        }
        if (item.required === 'true' && !item.initval) {
        if (_item.required === 'true' && !_item.initval) {
          valid = false
        }
        return _item
      })
      if (_curUserConfig) {
@@ -299,7 +304,7 @@
        columns: _columns,
        logcolumns: _logcolumns,
        arr_field: _arrField.join(','),
        search: Utils.initMainSearch(config.search) // 搜索条件初始化(含有时间格式,需要转化)
        search: Utils.initMainSearch(initSearch) // 搜索条件初始化(含有时间格式,需要转化)
      }, () => {
        this.improveSearch()
        if (config.setting.onload !== 'false' && valid) { // 初始化可加载
@@ -1024,7 +1029,8 @@
  controlCustomSetting = () => {
    this.setState({
      settingVisible: true,
      confirmLoading: false
      confirmLoading: false,
      revertLoading: false
    })
  }
@@ -1058,6 +1064,37 @@
    }
    this.props.modifyTabview(tabs)
  }
  settingRevert = () => {
    let param = {
      func: 's_TrdMenu_UserParam_del',
      MenuID: this.props.MenuID
    }
    this.setState({
      revertLoading: true
    })
    Api.getSystemConfig(param).then(result => {
      if (!result.status) {
        this.setState({
          revertLoading: false
        })
        notification.warning({
          top: 92,
          message: result.message,
          duration: 10
        })
        return
      }
      this.setState({
        settingVisible: false,
        revertLoading: false
      }, () => {
        window.GLOB.CacheMap = new Map()
        this.reloadview()
      })
    })
  }
  settingSubmit = () => {
@@ -1303,9 +1340,12 @@
            maskClosable={false}
            width={950}
            visible={this.state.settingVisible}
            onOk={this.settingSubmit}
            onCancel={() => { this.setState({ settingVisible: false }) }}
            confirmLoading={this.state.confirmLoading}
            footer={[
              <Button key="revert" type="danger" loading={this.state.revertLoading} onClick={this.settingRevert}>{this.state.dict['main.revert.default']}</Button>,
              <Button key="cancel" onClick={() => { this.setState({ settingVisible: false }) }}>{this.state.dict['main.cancel']}</Button>,
              <Button key="confirm" type="primary" loading={this.state.confirmLoading} onClick={this.settingSubmit}>{this.state.dict['main.confirm']}</Button>
            ]}
            destroyOnClose
          >
            {this.state.settingVisible ?
@@ -1334,6 +1374,7 @@
    tabviews: state.tabviews,
    refreshTab: state.refreshTab,
    permAction: state.permAction,
    permMenus: state.permMenus,
    permRoles: state.permRoles
  }
}
src/tabviews/subtable/index.jsx
@@ -10,6 +10,7 @@
import enUS from '@/locales/en-US/main.js'
import Utils from '@/utils/utils.js'
import options from '@/store/options.js'
import { modifyTabview } from '@/store/action'
import SubTable from '@/tabviews/zshare/normalTable'
import SubSearch from '@/tabviews/zshare/topSearch'
@@ -88,7 +89,7 @@
   * @description 获取页面配置信息
   */
  async loadconfig () {
    const { permAction, Tab, BID, userConfig } = this.props
    const { permAction, permMenus, Tab, BID, userConfig } = this.props
    let param = {
      func: 'sPC_Get_LongParam',
@@ -207,8 +208,14 @@
      })
      // 生成显示列,处理合并列中的字段
      config.columns.forEach(col => {
      config.columns.forEach((col, index) => {
        if (_hideCol.includes(col.uuid)) return
        if (col.linkThdMenu && !permMenus[col.linkThdMenu.MenuID]) {
          col.linkThdMenu = ''
        }
        col.sort = index
        if (col.type === 'colspan' && col.sublist) {
          let _col = JSON.parse(JSON.stringify(col))
@@ -733,6 +740,34 @@
    })
  }
  linkTrigger = (menu) => {
    const { tabviews, SupMenuID } = this.props
    menu.selected = true
    let index = 0
    let isexit = false
    let tabs = tabviews.map((tab, i) => {
      tab.selected = false
      if (tab.MenuID === SupMenuID) {
        index = i
      } else if (tab.MenuID === menu.MenuID) {
        tab.param = menu.param
        tab.selected = true
        isexit = true
      }
      return tab
    })
    if (!isexit) {
      tabs.splice(index + 1, 0, menu)
    }
    this.props.modifyTabview(tabs)
  }
  popclose = () => {
    this.setState({
      visible: false
@@ -812,6 +847,7 @@
              loading={this.state.loading}
              refreshdata={this.refreshbytable}
              buttonTrigger={this.buttonTrigger}
              linkTrigger={this.linkTrigger}
              handleTableId={this.handleTableId}
            />
          </div> : null
@@ -847,13 +883,17 @@
const mapStateToProps = (state) => {
  return {
    tabviews: state.tabviews,
    permAction: state.permAction,
    permRoles: state.permRoles
    permRoles: state.permRoles,
    permMenus: state.permMenus
  }
}
const mapDispatchToProps = () => {
  return {}
const mapDispatchToProps = (dispatch) => {
  return {
    modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews))
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(SubTabViewTable)
src/tabviews/subtabtable/index.jsx
@@ -156,6 +156,10 @@
      config.columns.forEach(col => {
        if (_hideCol.includes(col.uuid)) return
        if (col.linkThdMenu) {
          col.linkThdMenu = ''
        }
        if (col.type === 'colspan' && col.sublist) {
          let _col = JSON.parse(JSON.stringify(col))
          let subColumn = []
src/tabviews/verupmanage/actionList/index.jsx
@@ -33,7 +33,8 @@
    confirmLoading: false,
    execAction: null,
    loadingUuid: '',
    configMap: {}
    configMap: {},
    loadingNumber: ''
  }
  refreshdata = (item, type) => {
@@ -92,6 +93,10 @@
      confirm({
        title: this.props.dict['main.action.confirm.tip'],
        onOk() {
          _this.setState({
            loadingUuid: item.uuid
          })
          return new Promise(resolve => {
            _this.execSubmit(item, data, resolve)
          })
@@ -365,7 +370,7 @@
      }
      // 循环调用外部接口(包括内部及回调函数)
      this.outerLoopRequest(_params, btn, _resolve)
      this.outerLoopRequest(_params, btn, _resolve, _params.length > 20)
    }
  }
@@ -376,6 +381,10 @@
    if (!params && params.length === 0) return
    let param = params.shift()
    this.setState({
      loadingNumber: params.length || ''
    })
    Api.genericInterface(param).then(res => {
      if (res.status) {
@@ -395,12 +404,18 @@
  /**
   * @description 外部请求循环执行
   */
  outerLoopRequest = (params, btn, _resolve) => {
  outerLoopRequest = (params, btn, _resolve, widthNumber) => {
    if (!params && params.length === 0) return
    let param = params.shift()
    let _outParam = null
    let _localParam = null
    if (widthNumber) {
      this.setState({
        loadingNumber: params.length || ''
      })
    }
    new Promise(resolve => {
      // 内部请求
@@ -476,7 +491,7 @@
            this.execSuccess(btn, response)
            _resolve()
          } else {
            this.outerLoopRequest(params, btn, _resolve)
            this.outerLoopRequest(params, btn, _resolve, widthNumber)
          }
        } else {
          this.execError(response, btn)
@@ -494,7 +509,7 @@
          this.execSuccess(btn, res)
          _resolve()
        } else {
          this.outerLoopRequest(params, btn, _resolve)
          this.outerLoopRequest(params, btn, _resolve, widthNumber)
        }
      } else {
        this.execError(res, btn)
@@ -508,7 +523,7 @@
          this.execSuccess(btn, res)
          _resolve()
        } else {
          this.outerLoopRequest(params, btn, _resolve)
          this.outerLoopRequest(params, btn, _resolve, widthNumber)
        }
      } else {
        this.execError(res, btn)
@@ -547,7 +562,8 @@
    }
    this.setState({
      loadingUuid: ''
      loadingUuid: '',
      loadingNumber: ''
    })
    this.refreshdata(btn, 'success')
@@ -582,7 +598,8 @@
    }
    
    this.setState({
      loadingUuid: ''
      loadingUuid: '',
      loadingNumber: ''
    })
    
    this.refreshdata(btn, 'error')
@@ -636,6 +653,10 @@
    confirm({
      title: this.props.dict['main.action.confirm.tip'],
      onOk() {
        _this.setState({
          loadingUuid: execAction.uuid
        })
        return new Promise(resolve => {
          _this.execSubmit(execAction, tabledata, resolve, result)
        })
@@ -728,31 +749,24 @@
  }
  render() {
    const { loadingUuid } = this.state
    const { loadingUuid, loadingNumber } = this.state
    return (
      <div className="button-list toolbar-button">
        {this.props.actions.map((item, index) => {
          if (loadingUuid === item.uuid) {
            return (
              <Button
                className={'mk-btn mk-' + item.class}
                icon={item.icon}
                key={'action' + index}
                onClick={() => {this.actionTrigger(item)}}
                loading
              >{item.label}</Button>
            )
          } else {
            return (
              <Button
                className={'mk-btn mk-' + item.class}
                icon={item.icon}
                key={'action' + index}
                onClick={() => {this.actionTrigger(item)}}
              >{item.label}</Button>
            )
          let label = item.label
          if (loadingUuid === item.uuid && loadingNumber !== '') {
            label = label + '(' + loadingNumber + ')'
          }
          return (
            <Button
              className={'mk-btn mk-' + item.class}
              icon={item.icon}
              key={'action' + index}
              onClick={() => {this.actionTrigger(item)}}
              loading={loadingUuid === item.uuid}
            >{label}</Button>
          )
        })}
        {this.getModels()}
      </div>
src/tabviews/zshare/actionList/index.jsx
@@ -44,7 +44,8 @@
    loadingUuid: '',
    btnloading: false,
    configMap: {},
    running: false
    running: false,
    loadingNumber: ''
  }
  /**
@@ -73,6 +74,15 @@
   */
  actionTrigger = (item, record) => {
    const { setting, type, Tab, BID } = this.props
    if (this.state.loadingUuid || this.state.visible || this.state.running) {
      notification.warning({
        top: 92,
        message: '任务执行中,请稍后!',
        duration: 5
      })
      return
    }
    if (type === 'sub' && Tab && Tab.supMenu && !BID) {
      notification.warning({
@@ -123,6 +133,10 @@
      confirm({
        title: this.props.dict['main.action.confirm.tip'],
        onOk() {
          _this.setState({
            loadingUuid: item.uuid
          })
          return new Promise(resolve => {
            _this.execSubmit(item, data, resolve)
          })
@@ -1333,7 +1347,7 @@
      }
      // 循环调用外部接口(包括内部及回调函数)
      this.outerLoopRequest(_params, btn, _resolve)
      this.outerLoopRequest(_params, btn, _resolve, _params.length > 20)
      
    } else {
      this.actionSettingError()
@@ -1349,6 +1363,10 @@
    if (!params && params.length === 0) return
    let param = params.shift()
    this.setState({
      loadingNumber: params.length || ''
    })
    Api.genericInterface(param).then(res => {
      if (res.status) {
@@ -1368,11 +1386,17 @@
  /**
   * @description 外部请求循环执行
   */
  outerLoopRequest = (params, btn, _resolve) => {
  outerLoopRequest = (params, btn, _resolve, widthNumber) => {
    if (!params && params.length === 0) return
    let param = params.shift()
    let _outParam = null
    if (widthNumber) {
      this.setState({
        loadingNumber: params.length || ''
      })
    }
    new Promise(resolve => {
      // 内部请求
@@ -1449,7 +1473,7 @@
            this.execSuccess(btn, response)
            _resolve()
          } else {
            this.outerLoopRequest(params, btn, _resolve)
            this.outerLoopRequest(params, btn, _resolve, widthNumber)
          }
        } else {
          this.execError(response, btn)
@@ -1464,7 +1488,7 @@
          this.execSuccess(btn, res)
          _resolve()
        } else {
          this.outerLoopRequest(params, btn, _resolve)
          this.outerLoopRequest(params, btn, _resolve, widthNumber)
        }
      } else {
        this.execError(res, btn)
@@ -1504,7 +1528,8 @@
    this.setState({
      loadingUuid: '',
      running: false
      running: false,
      loadingNumber: ''
    })
    this.refreshdata(btn, 'success')
@@ -1540,7 +1565,8 @@
    
    this.setState({
      loadingUuid: '',
      running: false
      running: false,
      loadingNumber: ''
    })
    
    this.refreshdata(btn, 'error')
@@ -2425,13 +2451,18 @@
        value: _initval
      }
    })
    this.setState({
    _this.setState({
      running: true
    })
    confirm({
      title: this.props.dict['main.action.confirm.tip'],
      onOk() {
        _this.setState({
          loadingUuid: execAction.uuid
        })
        return new Promise(resolve => {
          _this.execSubmit(execAction, tabledata, resolve, result)
        })
@@ -2502,33 +2533,27 @@
  }
  render() {
    const { loadingUuid, btnloading } = this.state
    const { loadingUuid, btnloading, loadingNumber } = this.state
    if (this.props.setting.actionfixed && this.props.type === 'main') { // 按钮是否固定在头部
      return (
        <Affix offsetTop={48}>
          <div className="button-list toolbar-button" id={this.props.MenuID + 'mainaction'}>
            {this.props.actions.map((item, index) => {
              if (loadingUuid === item.uuid) {
                return (
                  <Button
                    className={'mk-btn mk-' + item.class}
                    icon={item.icon}
                    key={'action' + index}
                    onClick={() => {this.actionTrigger(item)}}
                    loading
                  >{item.label}</Button>
                )
              } else {
                return (
                  <Button
                    className={'mk-btn mk-' + item.class}
                    icon={item.icon}
                    key={'action' + index}
                    onClick={() => {this.actionTrigger(item)}}
                  >{item.label}</Button>
                )
              let label = item.label
              if (loadingUuid === item.uuid && loadingNumber !== '') {
                label = label + '(' + loadingNumber + ')'
              }
              return (
                <Button
                  className={'mk-btn mk-' + item.class}
                  icon={item.icon}
                  key={'action' + index}
                  onClick={() => {this.actionTrigger(item)}}
                  loading={loadingUuid === item.uuid}
                >{label}</Button>
              )
            })}
            {this.getModels()}
            {btnloading && <Spin size="large" />}
@@ -2540,26 +2565,20 @@
      return (
        <div className="button-list toolbar-button">
          {this.props.actions.map((item, index) => {
            if (loadingUuid === item.uuid) {
              return (
                <Button
                  className={'mk-btn mk-' + item.class}
                  icon={item.icon}
                  key={'action' + index}
                  onClick={() => {this.actionTrigger(item)}}
                  loading
                >{item.label}</Button>
              )
            } else {
              return (
                <Button
                  className={'mk-btn mk-' + item.class}
                  icon={item.icon}
                  key={'action' + index}
                  onClick={() => {this.actionTrigger(item)}}
                >{item.label}</Button>
              )
            let label = item.label
            if (loadingUuid === item.uuid && loadingNumber !== '') {
              label = label + '(' + loadingNumber + ')'
            }
            return (
              <Button
                className={'mk-btn mk-' + item.class}
                icon={item.icon}
                key={'action' + index}
                onClick={() => {this.actionTrigger(item)}}
                loading={loadingUuid === item.uuid}
              >{label}</Button>
            )
          })}
          {this.getModels()}
          {btnloading && <Spin size="large" />}
src/tabviews/zshare/fileupload/index.jsx
@@ -1,6 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Upload, message, Button, Icon, Progress } from 'antd'
import { Upload, message, Button, Icon, Progress, notification } from 'antd'
import md5 from 'md5'
import Api from '@/api'
import './index.scss'
@@ -62,52 +63,88 @@
  shardupload = (file, shardSize, shardCount, i, fileList) => {
    let start = i * shardSize
    let end = Math.min(file.size, start + shardSize)
    // let param = {
    //   file: file.slice(start, end),
    //   fileMd5: md5(''),
    //   shardingMd5: md5(''),
    //   baseDomain: '',
    //   rootPath: 'Content/images/upload/',
    //   fileName: file.name,
    //   fileExt: file.type.replace('image/', ''),
    //   shardingCnt: shardCount,
    //   shardingNo: i + 1
    // }
    let form = new FormData()
    let pice = file.slice(start, end)
    form.append('file', file.slice(start, end)) //slice方法用于切出文件的一部分
    form.append('RootPath', 'Content/images/upload/')
    form.append('name', file.name)
    form.append('total', shardCount)
    form.append('index', i + 1)
    form.append('file', pice) //slice方法用于切出文件的一部分
    form.append('fileMd5', md5(file))
    form.append('shardingMd5', md5(pice))
    form.append('baseDomain', '')
    form.append('rootPath', 'Content/images/upload/')
    form.append('fileName', file.name)
    form.append('fileExt', file.type.replace('image/', ''))
    form.append('shardingCnt', shardCount)
    form.append('shardingNo', i + 1)
    if (i < shardCount) {
      i++
      Api.getFileUpload(form).then(res => {
        if (res) {
    Api.getLargeFileUpload(form).then(res => {
      if (res.status) {
        if (i < shardCount) {
          i++
          this.setState({
            percent: Math.floor(100 * (i / shardCount))
          })
          this.shardupload(file, shardSize, shardCount, i, fileList)
        }
      })
    } else {
      this.setState({
        percent: 100
      }, () => {
        setTimeout(() => {
          this.setState({
            showprogress: false,
            percent: 0
          })
        }, 200)
      })
    }
      } else {
        fileList = fileList.filter(item => !!item.url)
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      }
    })
    // } else {
    //   this.setState({
    //     percent: 100
    //   }, () => {
    //     setTimeout(() => {
    //       this.setState({
    //         showprogress: false,
    //         percent: 0
    //       })
    //     }, 200)
    //   })
    // }
  }
  beforeUpload = (file, fileList) => {
    let shardSize = 2 * 1024 * 1024
    // let shardSize = 3 * 1024
    if (file.size > shardSize) {
      this.setState({
        showprogress: true,
        percent: 0
      })
      let shardCount = Math.ceil(file.size / shardSize)
      this.shardupload(file, shardSize, shardCount, 0, fileList)
      return false
      // this.setState({
      //   showprogress: true,
      //   percent: 0
      // })
      // let shardCount = Math.ceil(file.size / shardSize)
      // this.shardupload(file, shardSize, shardCount, 0, fileList)
      // return false
      return true
    } else {
      return true
    }
  }
  /**
   * @description 组件销毁,清除state更新
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
@@ -129,7 +166,6 @@
      action: baseUrl,
      method: 'post',
      multiple: true,
      // headers: {'RootPath': 'Content/images/upload/'},
      onChange: this.onChange,
      onRemove: this.onRemove,
      data: this.getExtraData,
src/tabviews/zshare/mutilform/index.jsx
@@ -80,6 +80,8 @@
        _readin = false
      }
      item.initVal = item.initval
      let _fieldlen = item.fieldlength || 50
      if (item.type === 'textarea' || item.type === 'fileupload' || item.type === 'multiselect') {
        _fieldlen = item.fieldlength || 512
@@ -169,6 +171,9 @@
          console.warn('focus error!')
        }
      }
      this.setState({
        loaded: true
      })
    })
  }
@@ -616,6 +621,15 @@
                key: item.field,
                value: _val
              })
            } else if (item.supField && !item.supvalue.includes(this.props.form.getFieldValue(item.supField))) {
              search.push({
                type: this.state.datatype[item.field],
                readonly: this.state.readtype[item.field],
                readin: this.state.readin[item.field],
                fieldlen: this.state.fieldlen[item.field],
                key: item.field,
                value: item.initVal
              })
            }
          })
src/templates/comtableconfig/actionform/index.jsx
@@ -66,6 +66,9 @@
    }, {
      value: 'delete',
      text: this.props.dict['header.form.action.delete']
    }, {
      value: 'custom',
      text: this.props.dict['header.form.custom']
    }]
  }
src/templates/comtableconfig/index.jsx
@@ -505,12 +505,11 @@
                        MenuNo: cell.MenuNo,
                        Ot: cell.Ot,
                        PageParam: cell.PageParam,
                        LinkUrl: cell.LinkUrl
                        LinkUrl: cell.LinkUrl,
                        disabled: cell.MenuID === menu.MenuID
                      }
                    })
                  }
                  submenu.children = submenu.children.filter(cell => cell.MenuID !== menu.MenuID)
                  return submenu
                })
@@ -703,10 +702,12 @@
        let labelrepet = false // 提示文字重复
        let _search = config.search.map(item => {
          if (item.uuid !== res.uuid && item.field === res.field) {
            fieldrepet = true
          } else if (item.uuid !== res.uuid && item.field && item.label === res.label) {
            labelrepet = true
          if (item.uuid !== res.uuid && res.field && item.field) {
            if (item.field === res.field) {
              fieldrepet = true
            } else if (item.label === res.label) {
              labelrepet = true
            }
          }
          if (item.uuid === res.uuid) {
@@ -918,10 +919,12 @@
        let labelrepet = false // 提示文字重复
        let _columns = config.columns.map(item => {
          if (item.uuid !== res.uuid && item.field === res.field) {
            fieldrepet = true
          } else if (item.uuid !== res.uuid && item.field && item.label === res.label) {
            labelrepet = true
          if (item.uuid !== res.uuid && res.field && item.field) {
            if (item.field === res.field) {
              fieldrepet = true
            } else if (item.label === res.label) {
              labelrepet = true
            }
          }
          if (item.uuid === res.uuid) {
@@ -1205,7 +1208,7 @@
    this.menuformRef.handleConfirm().then(res => {
      this.actionFormRef.handleConfirm().then(result => {
        if (!['pop', 'exec', 'prompt'].includes(result) || result.funcType || result.intertype !== 'inner' || result.innerFunc ) {
        if (!['pop', 'exec', 'prompt'].includes(result.OpenType) || result.funcType || result.intertype !== 'inner' || result.innerFunc ) {
          notification.warning({
            top: 92,
            message: '打开方式为 弹窗(表单)、提示框或直接执行,且使用系统函数时,才可以创建接口!',
@@ -1378,6 +1381,7 @@
      })
    } else {
      let _verify = this.verifyRef.state.verify
      let _loading = this.verifyRef.state.updateloading
      if (card.OpenType !== 'excelOut' && _verify.default === 'false' && _verify.scripts.length === 0) {
        notification.warning({
@@ -1408,11 +1412,29 @@
        return item
      })
  
      this.setState({
        profileVisible: false,
        config: config,
        card: '',
      })
      if (_loading) {
        let _this = this
        confirm({
          content: `存在未保存项,确定提交吗?`,
          okText: this.state.dict['header.confirm'],
          cancelText: this.state.dict['header.cancel'],
          onOk() {
            _this.setState({
              profileVisible: false,
              config: config,
              card: '',
            })
          },
          onCancel() {}
        })
      } else {
        this.setState({
          profileVisible: false,
          config: config,
          card: '',
        })
      }
    }
  }
@@ -2860,6 +2882,7 @@
    return (
      <div className="common-table-board">
        {/* <div className="ant-modal-mask"></div> */}
        <DndProvider backend={HTML5Backend}>
          {/* 工具栏 */}
          <div className="tools">
src/templates/formtabconfig/index.jsx
@@ -671,7 +671,7 @@
              if (item.uuid !== res.uuid && item.field === res.field) {
                fieldrepet = true
              } else if (item.uuid !== res.uuid && item.field && item.label === res.label) {
              } else if (item.uuid !== res.uuid && item.label === res.label) {
                labelrepeat = true
              }
            })
@@ -690,7 +690,7 @@
            group.sublist = group.sublist.map(item => {
              if (item.uuid !== res.uuid && item.field === res.field) {
                fieldrepet = true
              } else if (item.uuid !== res.uuid && item.field && item.label === res.label) {
              } else if (item.uuid !== res.uuid && item.label === res.label) {
                labelrepeat = true
              }
src/templates/modalconfig/index.jsx
@@ -525,7 +525,6 @@
    this.formRef.handleConfirm().then(res => {
      let _config = JSON.parse(JSON.stringify(this.state.config))
      if ( // 更新下拉字典
        (res.type === 'select' || res.type === 'multiselect' || res.type === 'link') &&
        res.resourceType === '0' &&
@@ -554,7 +553,7 @@
              if (item.uuid !== res.uuid && item.field === res.field) {
                fieldrepet = true
              } else if (item.uuid !== res.uuid && item.field && item.label === res.label) {
              } else if (item.uuid !== res.uuid && item.label === res.label) {
                labelrepet = true
              }
            })
@@ -574,7 +573,7 @@
            if (item.uuid !== res.uuid && item.field === res.field) {
              fieldrepet = true
            } else if (item.uuid !== res.uuid && item.field && item.label === res.label) {
            } else if (item.uuid !== res.uuid && item.label === res.label) {
              labelrepet = true
            }
          })
@@ -587,7 +586,7 @@
            group.sublist = group.sublist.map(item => {
              if (item.uuid !== res.uuid && item.field === res.field) {
                fieldrepet = true
              } else if (item.uuid !== res.uuid && item.field && item.label === res.label) {
              } else if (item.uuid !== res.uuid && item.label === res.label) {
                labelrepet = true
              }
@@ -602,7 +601,7 @@
          _config.fields = _config.fields.map(item => {
            if (item.uuid !== res.uuid && item.field === res.field) {
              fieldrepet = true
            } else if (item.uuid !== res.uuid && item.field && item.label === res.label) {
            } else if (item.uuid !== res.uuid && item.label === res.label) {
              labelrepet = true
            }
src/templates/subtableconfig/index.jsx
@@ -8,6 +8,7 @@
import moment from 'moment'
import Api from '@/api'
import options from '@/store/options.js'
import zhCN from '@/locales/zh-CN/comtable.js'
import enUS from '@/locales/en-US/comtable.js'
import Utils from '@/utils/utils.js'
@@ -449,11 +450,76 @@
    const { menu } = this.props
    if (card.type !== 'colspan') {
      this.setState({
        modaltype: 'columns',
        card: card,
        formlist: getColumnForm(card, menu.roleList)
      let menulist = menu.fstMenuList.map(item => {
        return {
          value: item.MenuID,
          label: item.text,
          isLeaf: false
        }
      })
      if ((card.type === 'text' || card.type === 'number') && card.linkmenu && card.linkmenu.length > 0) {
        let _param = {
          func: 'sPC_Get_FunMenu',
          ParentID: card.linkmenu[0],
          systemType: options.systemType,
          debug: 'Y'
        }
        this.setState({
          loading: true
        })
        Api.getSystemConfig(_param).then(result => {
          if (result.status) {
            menulist = menulist.map(item => {
              if (item.value === card.linkmenu[0]) {
                item.children = result.data.map(item => {
                  let submenu = {
                    value: item.ParentID,
                    label: item.MenuNameP,
                    children: item.FunMenu.map(cell => {
                      return {
                        value: cell.MenuID,
                        label: cell.MenuName,
                        MenuID: cell.MenuID,
                        MenuName: cell.MenuName,
                        MenuNo: cell.MenuNo,
                        Ot: cell.Ot,
                        PageParam: cell.PageParam,
                        LinkUrl: cell.LinkUrl,
                        disabled: cell.MenuID === menu.MenuID
                      }
                    })
                  }
                  return submenu
                })
              }
              return item
            })
          } else {
            notification.warning({
              top: 92,
              message: result.message,
              duration: 10
            })
          }
          this.setState({
            loading: false,
            modaltype: 'columns',
            card: card,
            formlist: getColumnForm(card, menu.roleList, menulist)
          })
        })
      } else {
        this.setState({
          modaltype: 'columns',
          card: card,
          formlist: getColumnForm(card, menu.roleList, menulist)
        })
      }
    } else {
      this.setState({
        modaltype: 'colspan',
@@ -500,10 +566,12 @@
        let labelrepet = false // 提示文字重复
        let _search = config.search.map(item => {
          if (item.uuid !== res.uuid && item.field === res.field) {
            fieldrepet = true
          } else if (item.uuid !== res.uuid && item.field && item.label === res.label) {
            labelrepet = true
          if (item.uuid !== res.uuid && res.field && item.field) {
            if (item.field === res.field) {
              fieldrepet = true
            } else if (item.label === res.label) {
              labelrepet = true
            }
          }
          if (item.uuid === res.uuid) {
@@ -640,10 +708,12 @@
        let labelrepet = false // 提示文字重复
        let _columns = config.columns.map(item => {
          if (item.uuid !== res.uuid && item.field === res.field) {
            fieldrepet = true
          } else if (item.uuid !== res.uuid && item.field && item.label === res.label) {
            labelrepet = true
          if (item.uuid !== res.uuid && res.field && item.field) {
            if (item.field === res.field) {
              fieldrepet = true
            } else if (item.label === res.label) {
              labelrepet = true
            }
          }
          if (item.uuid === res.uuid) {
@@ -2393,6 +2463,7 @@
          <ColumnForm
            dict={this.state.dict}
            card={this.state.card}
            MenuID={this.props.menu.MenuID}
            inputSubmit={this.handleSubmit}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.columnFormRef = inst}
src/templates/zshare/columnform/index.jsx
@@ -7,6 +7,13 @@
import Api from '@/api'
import './index.scss'
const columnTypeOptions = {
  text: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'matchVal', 'color', 'fieldlength', 'blacklist', 'linkmenu'],
  number: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'match', 'matchVal', 'color', 'blacklist', 'linkmenu'],
  textarea: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'matchVal', 'color', 'fieldlength', 'blacklist'],
  picture: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'fieldlength', 'blacklist', 'scale']
}
class MainSearch extends Component {
  static propTpyes = {
    dict: PropTypes.object,     // 字典项
@@ -25,17 +32,7 @@
    let _type = this.props.formlist.filter(form => form.key === 'type')[0].initVal
    let _menulist = this.props.formlist.filter(form => form.key === 'linkmenu')[0] || ''
    let _options = null
    if (_type === 'text') {
      _options = ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'matchVal', 'color', 'fieldlength', 'blacklist', 'linkmenu']
    } else if (_type === 'number') {
      _options = ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'match', 'matchVal', 'color', 'blacklist', 'linkmenu']
    } else if (_type === 'textarea') {
      _options = ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'matchVal', 'color', 'fieldlength', 'blacklist']
    } else if (_type === 'picture') {
      _options = ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'fieldlength', 'blacklist', 'scale']
    }
    let _options = columnTypeOptions[_type]
    this.setState({
      menulist: _menulist.options || [],
@@ -66,17 +63,7 @@
  typeChange = (key, value) => {
    if (key === 'type') {
      let _options = null
      if (value === 'text') {
        _options = ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'matchVal', 'color', 'fieldlength', 'blacklist', 'linkmenu']
      } else if (value === 'number') {
        _options = ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'match', 'matchVal', 'color', 'blacklist', 'linkmenu']
      } else if (value === 'textarea') {
        _options = ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'matchVal', 'color', 'fieldlength', 'blacklist']
      } else if (value === 'picture') {
        _options = ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'fieldlength', 'blacklist', 'scale']
      }
      let _options = columnTypeOptions[value]
      this.setState({
        formlist: this.props.formlist.map(item => {
@@ -304,12 +291,11 @@
                MenuNo: cell.MenuNo,
                Ot: cell.Ot,
                PageParam: cell.PageParam,
                LinkUrl: cell.LinkUrl
                LinkUrl: cell.LinkUrl,
                disabled: cell.MenuID === MenuID
              }
            })
          }
          submenu.children = submenu.children.filter(cell => cell.MenuID !== MenuID)
          return submenu
        })
src/templates/zshare/formconfig.jsx
@@ -7,7 +7,7 @@
 * @description 获取搜索条件表单配置信息
 * @param {*} card 
 */
export function getSearchForm (card, roleList = []) {
export function getSearchForm (card, roleList) {
  return [
    {
      type: 'text',
@@ -241,7 +241,7 @@
      label: Formdict['header.form.blacklist'],
      initVal: card.blacklist || [],
      required: false,
      options: roleList
      options: roleList || []
    }
  ]
}
src/templates/zshare/modaleditable/index.jsx
@@ -1,6 +1,7 @@
import React, {Component} from 'react'
import { is, fromJS } from 'immutable'
import { Table, Input, Button, Popconfirm, Form, Icon } from 'antd'
import { Table, Input, Button, Popconfirm, Form, Icon, Radio } from 'antd'
import { formRule } from '@/utils/option.js'
import Utils from '@/utils/utils.js'
import './index.scss'
@@ -31,8 +32,13 @@
  }
  save = e => {
    const { record, handleSave } = this.props
    const { record, handleSave, datatype } = this.props
    this.form.validateFields((error, values) => {
      if (datatype === 'number') {
        Object.keys(values).forEach(key => {
          values[key] = parseFloat(values[key])
        })
      }
      handleSave({ ...record, ...values })
      if (error && error[e.currentTarget.id]) {
        return
@@ -43,8 +49,16 @@
  renderCell = form => {
    this.form = form
    const { children, dataIndex, record } = this.props
    const { children, dataIndex, record, datatype } = this.props
    const { editing } = this.state
    let rules = []
    if (datatype === 'number') {
      rules.push({
        pattern: /^(-?\d+)(\.\d+)?$/,
        message: formRule.input.numbermsg
      })
    }
    return editing ? (
      <Form.Item style={{ margin: 0 }}>
@@ -54,6 +68,7 @@
              required: dataIndex === 'Value' || dataIndex === 'Text',
              message: 'NOT NULL.',
            },
            ...rules
          ],
          initialValue: record[dataIndex]
        })(<Input ref={node => (this.input = node)} autoComplete="off" onPressEnter={this.save} onBlur={this.save} />)}
@@ -97,6 +112,7 @@
    let _width = '40%'
    let fields = []
    let dataItem = props.data ? props.data[0] : ''
    if (props.type === 'link') {
      _width = '27%'
@@ -107,23 +123,28 @@
          title: field.label,
          dataIndex: field.field,
          width: _width,
          editable: true
          editable: true,
          datatype: dataItem && typeof(dataItem[field.field]) === 'number' ? 'number' : 'string'
        }
      })
    }
    let columns = [
      {
        title: 'Value',
        dataIndex: 'Value',
        width: _width,
        editable: true
        editable: true,
        datatype: dataItem && typeof(dataItem.Value) === 'number' ? 'number' : 'string'
      },
      {
        title: 'Text',
        dataIndex: 'Text',
        width: _width,
        editable: true
        editable: true,
        datatype: dataItem && typeof(dataItem.Text) === 'number' ? 'number' : 'string'
      },
      ...fields,
      {
@@ -153,17 +174,79 @@
        title: 'ParentID',
        dataIndex: 'ParentID',
        width: '27%',
        editable: true
        editable: true,
        datatype: dataItem && typeof(dataItem.ParentID) === 'number' ? 'number' : 'string'
      })
    }
    this.state = {
      columns: columns,
      columns: columns.map(col => {
        if (col.dataIndex !== 'operation') {
          col = {...col, ...this.getColumnSearchProps(col)}
        }
        return col
      }),
      dataSource: props.data,
      count: props.data.length,
      type: props.type,
      linkSubFields: props.linkSubFields
    }
  }
  getColumnSearchProps = column => ({
    filterDropdown: () => (
      <div style={{ padding: 8 }}>
        <Radio.Group onChange={(e) => this.changeDatatype(column, e)} value={column.datatype}>
          <Radio style={{display: 'block', height: '30px', lineHeight: '30px'}} value="string">
            String
          </Radio>
          <Radio style={{display: 'block', height: '30px', lineHeight: '30px'}} value="number">
            Number
          </Radio>
        </Radio.Group>
      </div>
    ),
    filterIcon: () => (
      <Icon type="swap" style={{ color: column.datatype === 'number' ? '#1890ff' : undefined}} />
    )
  })
  changeDatatype = (column, e) => {
    const { columns, dataSource } = this.state
    let value = e.target.value
    this.setState({
      dataSource: dataSource.map(item => {
        let val = item[column.dataIndex]
        if (value === 'number') {
          try {
            val = parseFloat(val)
            if (isNaN(val)) {
              val = ''
            }
          } catch {
            val = ''
          }
        } else {
          val = '' + val
        }
        item[column.dataIndex] = val
        return item
      }),
      columns: columns.map(col => {
        if (col.dataIndex === column.dataIndex) {
          col.datatype = value
        }
        if (col.dataIndex !== 'operation') {
          col = {...col, ...this.getColumnSearchProps(col)}
        }
        return col
      })
    })
  }
  handleUpDown = (record, direction) => {
@@ -237,6 +320,8 @@
      })
    }
    let dataItem = dataSource ? dataSource[0] : ''
    if (type === 'link') {
      _width = '27%'
    } else if (type === 'select') {
@@ -246,7 +331,8 @@
          title: field.label,
          dataIndex: field.field,
          width: _width,
          editable: true
          editable: true,
          datatype: dataItem && typeof(dataItem[field.field]) === 'number' ? 'number' : 'string'
        }
      })
    }
@@ -256,13 +342,15 @@
        title: 'Value',
        dataIndex: 'Value',
        width: _width,
        editable: true
        editable: true,
        datatype: dataItem && typeof(dataItem.Value) === 'number' ? 'number' : 'string'
      },
      {
        title: 'Text',
        dataIndex: 'Text',
        width: _width,
        editable: true
        editable: true,
        datatype: dataItem && typeof(dataItem.Text) === 'number' ? 'number' : 'string'
      },
      ...fields,
      {
@@ -292,12 +380,18 @@
        title: 'ParentID',
        dataIndex: 'ParentID',
        width: '27%',
        editable: true
        editable: true,
        datatype: dataItem && typeof(dataItem.ParentID) === 'number' ? 'number' : 'string'
      })
    }
    this.setState({
      columns: columns,
      columns: columns.map(col => {
        if (col.dataIndex !== 'operation') {
          col = {...col, ...this.getColumnSearchProps(col)}
        }
        return col
      }),
      dataSource: dataSource,
      type: type
    })
@@ -344,6 +438,7 @@
          editable: col.editable,
          dataIndex: col.dataIndex,
          title: col.title,
          datatype: col.datatype,
          handleSave: this.handleSave,
        })
      }
src/templates/zshare/modaleditable/index.scss
@@ -14,7 +14,7 @@
  .editable-cell-value-wrap {
    cursor: pointer;
    height: 40px;
    width: 100px;
    width: 300px;
    display: table-cell;
    vertical-align: middle;
    word-wrap: break-word;
src/templates/zshare/modalform/index.jsx
@@ -506,9 +506,9 @@
            values.dataSource = ''
            let emptys = []
            if (values.type === 'multiselect' || values.type === 'select') {
              emptys = values.options.filter(op => !(op.Value && op.Text))
              emptys = values.options.filter(op => !((op.Value || op.Value === 0) && (op.Text || op.Text === 0)))
            } else {
              emptys = values.options.filter(op => !(op.Value && op.Text && op.ParentID))
              emptys = values.options.filter(op => !((op.Value || op.Value === 0) && (op.Text || op.Text === 0) && (op.ParentID || op.ParentID === 0)))
            }
            if (emptys.length > 0) {
              isvalid = false
src/templates/zshare/verifycard/billcodeform/index.jsx
@@ -1,7 +1,8 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Form, Row, Col, Select, Button, InputNumber } from 'antd'
import { Form, Row, Col, Select, Button, InputNumber, Input, Tooltip, Icon } from 'antd'
import { formRule } from '@/utils/option.js'
import './index.scss'
@@ -22,7 +23,8 @@
    modularDetail: [],
    funFields: [],
    billFields: [],
    type: '1'
    type: '1',
    TypeCharOne: 'Lp'
  }
  UNSAFE_componentWillMount() {
@@ -84,7 +86,8 @@
        type: '2',
        funFields: _funFields,
        editItem: record,
        modularDetail: _detail
        modularDetail: _detail,
        TypeCharOne: record.TypeCharOne
      }, () => {
        this.props.form.setFieldsValue({
          field: record.field,
@@ -98,13 +101,18 @@
        type: '1',
        funFields: _funFields,
        editItem: record,
        TypeCharOne: record.TypeCharOne
      }, () => {
        this.props.form.setFieldsValue({
        let _form = {
          field: record.field,
          TypeCharOne: record.TypeCharOne,
          Type: record.Type,
          linkField: record.linkField,
        })
          linkField: record.linkField
        }
        if (record.TypeCharOne === 'Lp') {
          _form.mark = record.mark || ''
        }
        this.props.form.setFieldsValue(_form)
      })
    }
  }
@@ -123,11 +131,13 @@
  TypeCharOneChange = (value) => {
    if (value === 'Y' || value === 'n') {
      this.setState({
        type: '2'
        type: '2',
        TypeCharOne: value
      })
    } else {
      this.setState({
        type: '1'
        type: '1',
        TypeCharOne: value
      })
    }
  }
@@ -181,16 +191,20 @@
            funFields: this.props.fields.filter(field => field.type === 'funcvar' && !_usedfields.includes(field.field)),
          })
        })
        this.props.form.setFieldsValue({
          field: '',
        })
        let _form = {
          field: ''
        }
        if (this.state.TypeCharOne === 'Lp') {
          _form.mark = ''
        }
        this.props.form.setFieldsValue(_form)
      }
    })
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const { type } = this.state
    const { type, TypeCharOne } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -205,7 +219,7 @@
    return (
      <Form {...formItemLayout} className="verify-form">
        <Row gutter={24}>
          <Col span={10}>
          <Col span={7}>
            <Form.Item label={this.props.dict['header.form.funcvar']}>
              {getFieldDecorator('field', {
                initialValue: '',
@@ -226,7 +240,7 @@
              )}
            </Form.Item>
          </Col>
          <Col span={10}>
          <Col span={7}>
            <Form.Item label={'类型'}>
              {getFieldDecorator('TypeCharOne', {
                initialValue: 'Lp',
@@ -246,12 +260,7 @@
              )}
            </Form.Item>
          </Col>
          <Col span={4} className="add">
            <Button onClick={this.handleConfirm} type="primary">
              确定
            </Button>
          </Col>
          {type === '1' ? <Col span={10}>
          {type === '1' ? <Col span={7}>
            <Form.Item label={'关联字段'}>
              {getFieldDecorator('linkField', {
                initialValue: '',
@@ -272,20 +281,7 @@
              )}
            </Form.Item>
          </Col> : null}
          {type === '1' ? <Col span={10}>
            <Form.Item label={'位数'}>
              {getFieldDecorator('Type', {
                initialValue: 4,
                rules: [
                  {
                    required: true,
                    message: this.props.dict['form.required.input'] + '位数!'
                  }
                ]
              })(<InputNumber min={1} max={10} precision={0} />)}
            </Form.Item>
          </Col> : null}
          {type === '2' ? <Col span={10}>
          {type === '2' ? <Col span={7}>
            <Form.Item label={'凭证类型'}>
              {getFieldDecorator('ModularCode', {
                initialValue: this.props.modular[0] ? this.props.modular[0].ID : '',
@@ -310,7 +306,25 @@
              )}
            </Form.Item>
          </Col> : null}
          {type === '2' ? <Col span={10}>
          <Col span={3} className="add">
            <Button onClick={this.handleConfirm} type="primary">
              确定
            </Button>
          </Col>
          {type === '1' ? <Col span={7}>
            <Form.Item label={'位数'}>
              {getFieldDecorator('Type', {
                initialValue: 4,
                rules: [
                  {
                    required: true,
                    message: this.props.dict['form.required.input'] + '位数!'
                  }
                ]
              })(<InputNumber min={1} max={10} precision={0} />)}
            </Form.Item>
          </Col> : null}
          {type === '2' ? <Col span={7}>
            <Form.Item label={'凭证标识'}>
              {getFieldDecorator('ModularDetailCode', {
                initialValue: this.state.modularDetail[0] ? this.state.modularDetail[0].ModularDetailCode : '',
@@ -326,7 +340,7 @@
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                >
                  {this.state.modularDetail.map(option =>
                    <Select.Option title={option.CodeName} id={option.ModularDetailCode} key={option.ModularDetailCode} value={option.ModularDetailCode}>
                    <Select.Option style={{whiteSpace: 'unset'}} title={option.CodeName} id={option.ModularDetailCode} key={option.ModularDetailCode} value={option.ModularDetailCode}>
                      {option.CodeName}
                    </Select.Option>
                  )}
@@ -334,6 +348,24 @@
              )}
            </Form.Item>
          </Col> : null}
          {TypeCharOne === 'Lp' ? <Col span={7}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="该标识用于生成行号规则,为空时使用按钮ID">
                <Icon type="question-circle" />
                {'标识'}
              </Tooltip>
            }>
              {getFieldDecorator('mark', {
                initialValue: '',
                rules: [
                  {
                    pattern: /^[a-zA-Z0-9]*$/ig,
                    message: formRule.input.letternummsg
                  }
                ]
              })(<Input placeholder="" autoComplete="off" />)}
            </Form.Item>
          </Col> : null}
        </Row>
      </Form>
    )
src/templates/zshare/verifycard/index.jsx
@@ -27,6 +27,7 @@
  }
  state = {
    updateloading: false, // 修改中
    verify: {},
    fields: [],
    usefulfields: '',
@@ -268,13 +269,13 @@
      {
        title: this.props.dict['header.form.funcvar'],
        dataIndex: 'fieldName',
        width: '13%',
        width: '12%',
        render: (text, record) => (`${record.fieldName || ''}(${record.field})`)
      },
      {
        title: '类型',
        dataIndex: 'billType',
        width: '8%',
        width: '6%',
      },
      {
        title: '凭证类型',
@@ -289,13 +290,13 @@
      {
        title: '关联字段',
        dataIndex: 'linkFieldName',
        width: '12%',
        width: '10%',
        render: (text, record) => (record.linkField ? `${record.linkFieldName || ''}(${record.linkField})` : '')
      },
      {
        title: '位数',
        dataIndex: 'Type',
        width: '8%'
        width: '6%'
      },
      {
        title: '示例',
@@ -324,9 +325,14 @@
        }
      },
      {
        title: '标识',
        dataIndex: 'mark',
        width: '8%'
      },
      {
        title: '状态',
        dataIndex: 'status',
        width: '9%',
        width: '8%',
        render: (text, record) => record.status === 'false' ?
          (
            <div>
@@ -373,6 +379,9 @@
    if (!_invalid) { // 选择行时,失效验证默认开启
      _invalid = card.Ot !== 'notRequired' ? 'true' : 'false'
    }
    if (card.sqlType === 'custom') { // 自定义验证时,不使用默认sql
      _verify.default = 'false'
    }
    _verify.default = _verify.default || 'true'
@@ -641,6 +650,25 @@
    })
  }
  updateChange = () => {
    let _loading = false
    if (this.customForm && this.customForm.state.editItem) {
      _loading = true
    } else if (this.uniqueForm && this.uniqueForm.state.editItem) {
      _loading = true
    } else if (this.orderForm && this.orderForm.state.editItem) {
      _loading = true
    } else if (this.scriptsForm && this.scriptsForm.state.editItem) {
      _loading = true
    } else if (this.contrastForm && this.contrastForm.state.editItem) {
      _loading = true
    }
    this.setState({
      updateloading: _loading
    })
  }
  uniqueChange = (values) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
@@ -659,6 +687,8 @@
    this.setState({
      verify: verify
    }, () => {
      this.updateChange()
    })
  }
@@ -680,6 +710,8 @@
    this.setState({
      verify: verify
    }, () => {
      this.updateChange()
    })
  }
@@ -701,6 +733,8 @@
    this.setState({
      verify: verify
    }, () => {
      this.updateChange()
    })
  }
@@ -722,6 +756,8 @@
    this.setState({
      verify: verify
    }, () => {
      this.updateChange()
    })
  }
@@ -743,6 +779,8 @@
    this.setState({
      verify: verify
    }, () => {
      this.updateChange()
    })
  }
@@ -800,6 +838,10 @@
        }
      }, 10)
    }
    this.setState({
      updateloading: true
    })
  }
  handleStatus = (record, type) => {
@@ -1034,7 +1076,7 @@
          <TabPane tab="基础验证" key="1">
            <Form {...formItemLayout}>
              <Row gutter={24}>
                <Col span={8}>
                {this.props.card.sqlType !== 'custom' ? <Col span={8}>
                  <Form.Item label={
                    <Tooltip placement="bottomLeft" title={'默认sql执行顺序为自定义脚本之前'}>
                      <Icon type="question-circle" style={{color: '#c49f47', marginRight: '5px'}} />
@@ -1046,7 +1088,7 @@
                      <Radio value="false">不执行</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
                </Col> : null}
                <Col span={8}>
                  <Form.Item label={'账期验证'}>
                    <Radio.Group value={verify.accountdate} onChange={(e) => {this.onOptionChange(e, 'accountdate')}}>
src/templates/zshare/verifycard/index.scss
@@ -36,6 +36,10 @@
    .add {
      padding-top: 4px;
    }
    .anticon-question-circle {
      color: #c49f47;
      margin-right: 3px;
    }
  }
  .custom-table .ant-empty {
    margin: 20px 8px!important;
src/utils/utils.js
@@ -907,9 +907,9 @@
        let _lpline = ''
        if (item.TypeCharOne === 'Lp') {
          if (item.linkField === 'BID' && BID) { // 替换bid
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${btn.uuid}'+@BID@,48)`
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
          } else {
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${btn.uuid}'+@${item.linkField},48)`
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${item.linkField},48)`
          }
          _ModularDetailCode = '@ModularDetailCode'
        } else if (item.TypeCharOne === 'BN') {
src/views/login/index.jsx
@@ -189,6 +189,8 @@
          ...systemMsg
        })
        window.GLOB.mainlogo = systemMsg.mainlogo
        if (res.titlelogo && window.GLOB.favicon !== res.titlelogo) {
          let link = document.querySelector("link[rel*='icon']") || document.createElement('link')
          link.type = 'image/x-icon'