king
2021-01-13 23cb54bbb041413ba327d046a4b396267ef2ecfe
2021-01-13
9个文件已修改
12个文件已删除
2996 ■■■■ 已修改文件
src/tabviews/commontable/index.jsx 101 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.jsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/treepage/index.jsx 219 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/settingcomponent/editTable/index.jsx 323 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/settingcomponent/editTable/index.scss 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/settingcomponent/index.jsx 474 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/settingcomponent/index.scss 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/index.jsx 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/index.scss 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/tabcard/actionform/index.jsx 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/tabcard/actionform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/tabcard/columnform/index.jsx 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/tabcard/columnform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/tabcard/index.jsx 570 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/tabcard/index.scss 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/tabcard/printform/index.jsx 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/tabcard/printform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/tabcard/printtypeform/index.jsx 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/verifycard/tabcard/printtypeform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx
@@ -81,10 +81,11 @@
    if (result.status) {
      let config = ''
      let shortcuts = []
      let _curUserConfig = ''
      try { // 配置信息解析
        config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
        config.MenuID = this.props.MenuID
        config.MenuName = MenuName
      } catch (e) {
        console.warn('Parse Failure')
        config = ''
@@ -94,31 +95,37 @@
      if (result.LongParamUser && this.props.menuType !== 'HS') {
        try { // 配置信息解析
          let userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
          userConfig = []
          if (userConfig && !userConfig.version) {
            Object.keys(userConfig).forEach(key => {
              let component = userConfig[key]
          // if (window.GLOB.UserCacheMap.has(_param)) {
          //   return Promise.resolve(window.GLOB.UserCacheMap.get(_param))
          // } else {
          //   param = this.encryptParam(param)
          //   return new Promise(resolve => {
          //     axios({
          //       url: `/webapi/dostars${param.func ? '/' + param.func : ''}`,
          //       data: param
          //     }).then(res => {
          //       if (res.status) {
          //         window.GLOB.UserCacheMap.set(_param, res)
          //       }
          //       resolve(res)
          //     })
          //   })
          // }
          _curUserConfig = userConfig[this.props.MenuID]
              if (!component.action) return
              Object.keys(component.action).forEach(uuid => {
                let item = {uuid: uuid, parentId: key, shortcut: component.action[uuid].shortcut}
                let printer = component.action[uuid].printer
                if (item.shortcut) {
                  item.$shortcut = item.shortcut.join('+')
                  shortcuts.push(item)
                }
                if (printer) {
                  item.printer = printer.defaultPrinter || ''
                  item.printerList = printer.printerList || ''
                  window.GLOB.UserCacheMap.set(key + uuid, item)
                }
              })
            })
          } else if (userConfig) {
            shortcuts = userConfig.action
            userConfig.printers.forEach(item => {
              window.GLOB.UserCacheMap.set(item.parentId + item.uuid, item)
            })
          }
        } catch (e) {
          console.warn('Parse Failure')
        }
      }
      console.log(config)
      console.log(shortcuts)
      // 页面配置解析错误时提示
      if (!config) {
@@ -235,28 +242,6 @@
        }
      }
      if (_curUserConfig) {
        config.action = config.action.map(item => {
          if (_curUserConfig.action[item.uuid]) {
            delete _curUserConfig.action[item.uuid].label
            item = {...item, ..._curUserConfig.action[item.uuid]}
          }
          if (item.OpenType === 'funcbutton' && item.funcType === 'print' && item.verify && item.printer) {
            item.verify.defaultPrinter = item.printer.defaultPrinter || ''
            if (item.verify.printerTypeList && item.printer.printerList) {
              item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
                cell.printer = item.printer.printerList[cell.Value] || ''
                return cell
              })
            }
          }
          return item
        })
      }
      let _arrField = []     // 字段集
      let _columns = []      // 显示列
      let _hideCol = []      // 隐藏及合并列中字段的uuid集
@@ -270,6 +255,22 @@
      config.action.forEach(item => {
        item.logLabel = MenuName + '-' + item.label // 用于sPC_TableData_InUpDe记录操作按钮
        item.$menuId = this.props.MenuID
        if (item.OpenType === 'funcbutton' && item.funcType === 'print' && item.verify) { // 打印机设置
          let _item = window.GLOB.UserCacheMap.get(this.props.MenuID + item.uuid)
          if (_item) {
            item.printer = _item.printer || ''
            item.verify.defaultPrinter = _item.printer || ''
            if (item.verify.printerTypeList && _item.printerList) {
              item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
                cell.printer = _item.printerList[cell.Value] || ''
                return cell
              })
            }
          }
        }
        
        if (item.position === 'toolbar') {
          _actions.push(item)
@@ -403,13 +404,13 @@
      if (!preKey || !keyCode) return
      let _shortcut = preKey + keyCode
      let _shortcut = `${preKey}+${keyCode}`
      shortcuts.some(item => {
        if (item.shortcut === _shortcut) {
        if (item.$shortcut === _shortcut) {
          MKEmitter.emit('triggerBtnId', item.uuid)
          let element = item.parentId ? document.getElementById(item.parentId) : '' // 标签切换
          let element = item.parentId && item.parentId !== this.props.MenuID ? document.getElementById(item.parentId) : '' // 标签切换
          if (element && element.click) {
            element.click()
          }
@@ -686,7 +687,7 @@
   */
  reloadview = () => {
    this.setState({ loadingview: true, viewlost: false, config: {}, setting: null,
      data: null, total: 0, loading: false, pageIndex: 1,
      data: null, total: 0, loading: false, pageIndex: 1, shortcuts: null,
      pageSize: 10, orderBy: '', search: '', BIDs: {}, pickup: false
    }, () => {
      this.loadconfig()
@@ -848,11 +849,11 @@
  render() {
    const { menuType } = this.props
    const { BID, setting, searchlist, pageSize, actions, columns, loadingview, viewlost, pickup, config, chartId, search, selectedData } = this.state
    const { BID, setting, searchlist, pageSize, actions, columns, loadingview, viewlost, pickup, config, chartId, search, selectedData, shortcuts } = this.state
    return (
      <div className="commontable" id={this.state.ContainerId}>
        {loadingview && <Spin size="large" />}
        {loadingview ? <Spin size="large" /> : null}
        {searchlist && searchlist.length ?
          <MainSearch BID={BID} searchlist={searchlist} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null
        }
@@ -964,7 +965,7 @@
          </Tabs>))
        }
        {menuType !== 'HS' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
        {menuType !== 'HS' ? <SettingComponent config={config} dict={this.state.dict} MenuID={this.props.MenuID} permAction={this.props.permAction}/> : null}
        {menuType !== 'HS' && shortcuts ? <SettingComponent config={config} dict={this.state.dict} shortcuts={shortcuts} permAction={this.props.permAction}/> : null}
        {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
      </div>
    )
src/tabviews/commontable/index.scss
@@ -63,18 +63,9 @@
    position: relative;
    .main-pickup {
      position: absolute;
      right: 35px;
      right: 0px;
      top: -22px;
      z-index: 1;
    }
    .custom-control {
      position: absolute;
      z-index: 1;
      right: 0px;
      top: -23px;
      font-size: 18px;
      padding: 3px;
      cursor: pointer;
    }
    >.async-spin {
      line-height: 150px!important;
src/tabviews/custom/index.jsx
@@ -26,6 +26,7 @@
const MainSearch = asyncComponent(() => import('@/tabviews/zshare/topSearch'))
const NormalTable = asyncComponent(() => import('./components/table/normal-table'))
const NormalGroup = asyncComponent(() => import('./components/group/normal-group'))
const SettingComponent = asyncComponent(() => import('@/tabviews/zshare/settingcomponent'))
const PagemsgComponent = asyncComponent(() => import('@/tabviews/zshare/pageMessage'))
class CustomPage extends Component {
@@ -51,6 +52,7 @@
    loading: false,       // 列表数据加载中
    visible: false,       // 标签页控制
    treevisible: false,   // 菜单结构树弹框显示隐藏控制
    shortcuts: null       // 快捷键
  }
  /**
@@ -67,7 +69,7 @@
    if (result.status) {
      let config = ''
      let userConfig = null
      let shortcuts = []
      try { // 配置信息解析
        config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
@@ -79,10 +81,15 @@
      // HS不使用自定义设置
      if (result.LongParamUser && this.props.menuType !== 'HS') {
        try { // 配置信息解析
          userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
          let userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
          if (userConfig) {
            shortcuts = userConfig.action
            userConfig.printers.forEach(item => {
              window.GLOB.UserCacheMap.set(item.parentId + item.uuid, item)
            })
          }
        } catch (e) {
          console.warn('Parse Failure')
          userConfig = null
        }
      }
@@ -154,7 +161,7 @@
      this.setState({
        BID: BID,
        userConfig: userConfig,
        shortcuts,
        config,
        mainSearch
      }, () => {
@@ -167,6 +174,10 @@
        } else {
          this.loadmaindata(params)
        }
        if (!this.props.Tab) {
          this.setShortcut()
        }
      })
    } else {
      this.setState({
@@ -177,6 +188,41 @@
        top: 92,
        message: result.message,
        duration: 5
      })
    }
  }
  setShortcut = () => {
    const { shortcuts } = this.state
    if (!shortcuts || shortcuts.length === 0) {
      document.onkeydown = () => {}
      return
    }
    document.onkeydown = (event) => {
      let e = event || window.event
      let keyCode = e.keyCode || e.which || e.charCode
      let preKey = ''
      if (e.ctrlKey) {
        preKey = 'ctrl'
      } else if (e.shiftKey) {
        preKey = 'shift'
      } else if (e.altKey) {
        preKey = 'alt'
      }
      if (!preKey || !keyCode) return
      let _shortcut = `${preKey}+${keyCode}`
      shortcuts.some(item => {
        if (item.$shortcut === _shortcut) {
          MKEmitter.emit('triggerBtnId', item.uuid)
          return true
        }
        return false
      })
    }
  }
@@ -260,6 +306,10 @@
          cell.$tabId = tabId
          cell.$type = 'CustomPage'
          if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 打印机设置
            cell = this.getPrinter(cell, item.uuid)
          }
          return isHS || permAction[cell.uuid]
        })
      }
@@ -281,6 +331,10 @@
              cell.$menuId = item.uuid
              cell.$tabId = tabId
              cell.$type = 'CustomPage'
              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 打印机设置
                cell = this.getPrinter(cell, item.uuid)
              }
            } else if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height && _hasheight) {
              cell.innerHeight = 'auto'
            }
@@ -296,6 +350,10 @@
              cell.$menuId = item.uuid
              cell.$tabId = tabId
              cell.$type = 'CustomPage'
              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 打印机设置
                cell = this.getPrinter(cell, item.uuid)
              }
            } else if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height && _hasheight) {
              cell.innerHeight = 'auto'
            }
@@ -314,6 +372,10 @@
              cell.$menuId = item.uuid
              cell.$tabId = tabId
              cell.$type = 'CustomPage'
              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 打印机设置
                cell = this.getPrinter(cell, item.uuid)
              }
            } else if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height && _hasheight) {
              cell.innerHeight = 'auto'
            }
@@ -331,6 +393,10 @@
            cell.$menuId = item.uuid
            cell.$tabId = tabId
            cell.$type = 'CustomPage'
            if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 打印机设置
              cell = this.getPrinter(cell, item.uuid)
            }
            return isHS || permAction[cell.uuid]
          })
@@ -355,6 +421,24 @@
      
      return true
    })
  }
  getPrinter = (item, parentId) => {
    let _item = window.GLOB.UserCacheMap.get(parentId + item.uuid)
    if (_item) {
      item.printer = _item.printer || ''
      item.verify.defaultPrinter = _item.printer || ''
      if (item.verify.printerTypeList && _item.printerList) {
        item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
          cell.printer = _item.printerList[cell.Value] || ''
          return cell
        })
      }
    }
    return item
  }
  getCols = (cols, roleId, permMenus) => {
@@ -620,6 +704,14 @@
    this.reloadview()
  }
  resetActiveMenu = (menuId) => {
    const { MenuID, Tab } = this.props
    if (MenuID !== menuId || Tab) return
    this.setShortcut()
  }
  UNSAFE_componentWillMount () {
    // 组件加载时,获取菜单数据
    this.loadconfig()
@@ -631,6 +723,7 @@
  componentDidMount () {
    MKEmitter.addListener('reloadMenuView', this.reloadMenuView)
    MKEmitter.addListener('resetActiveMenu', this.resetActiveMenu)
  }
  /**
@@ -641,6 +734,7 @@
      return
    }
    MKEmitter.removeListener('reloadMenuView', this.reloadMenuView)
    MKEmitter.removeListener('resetActiveMenu', this.resetActiveMenu)
  }
  reloadview = () => {
@@ -649,7 +743,8 @@
      loadingview: true,    // 页面加载中
      viewlost: false,      // 页面丢失:1、未获取到配置-页面丢失;2、页面未启用
      config: null,         // 页面配置信息,包括组件等
      loading: false        // 列表数据加载中
      loading: false,       // 列表数据加载中
      shortcuts: null
    }, () => {
      this.loadconfig()
    })
@@ -735,13 +830,14 @@
  render() {
    const { menuType } = this.props
    const { loadingview, viewlost, config, loading } = this.state
    const { loadingview, viewlost, config, loading, shortcuts } = this.state
    return (
      <div className={'custom-page-wrap ' + (loadingview || loading ? 'loading' : '')} id={this.state.ContainerId} style={config ? config.style : null}>
        {(loadingview || loading) ? <Spin className="view-spin" size="large" /> : null}
        <Row>{this.getComponents()}</Row>
        {menuType !== 'HS' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
        {menuType !== 'HS' && shortcuts ? <SettingComponent config={config} dict={this.state.dict} shortcuts={shortcuts} permAction={this.props.permAction}/> : null}
        {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
      </div>
    )
src/tabviews/subtable/index.jsx
@@ -174,31 +174,6 @@
      }
      let chartId = config.charts[0] ? config.charts[0].uuid : ''
      let userConfig = null
      if (window.GLOB.UserCacheMap.has(Tab.uuid)) {
        userConfig = window.GLOB.UserCacheMap.get(Tab.uuid)
      }
      if (userConfig) {
        config.action = config.action.map(item => {
          if (userConfig[item.uuid]) {
            item = {...item, ...userConfig.action[item.uuid]}
          }
          if (item.OpenType === 'funcbutton' && item.funcType === 'print' && item.verify && item.printer) {
            item.verify.defaultPrinter = item.printer.defaultPrinter || ''
            if (item.verify.printerTypeList && item.printer.printerList) {
              item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
                cell.printer = item.printer.printerList[cell.Value] || ''
                return cell
              })
            }
          }
          return item
        })
      }
      // 1、筛选字段集,2、过滤隐藏列及合并列中的字段uuid
      config.columns.forEach(col => {
@@ -260,6 +235,20 @@
        item.logLabel = Tab.label + '-' + item.label // 用于sPC_TableData_InUpDe记录操作按钮
        item.$menuId = this.props.MenuID
        if (item.OpenType === 'funcbutton' && item.funcType === 'print' && item.verify) { // 打印机设置
          let _item = window.GLOB.UserCacheMap.get(Tab.uuid + item.uuid)
          if (_item) {
            item.verify.defaultPrinter = _item.printer || ''
            if (item.verify.printerTypeList && _item.printerList) {
              item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
                cell.printer = _item.printerList[cell.Value] || ''
                return cell
              })
            }
          }
        }
        if (item.position === 'toolbar') {
          _actions.push(item)
        } else if (item.position === 'grid') {
src/tabviews/treepage/index.jsx
@@ -2,7 +2,7 @@
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import { is, fromJS } from 'immutable'
import { notification, Spin, Tabs, Icon, Modal, Button, Tree, Row, Col, Card, Input, Empty } from 'antd'
import { notification, Spin, Tabs, Icon, Tree, Row, Col, Card, Input, Empty } from 'antd'
import Api from '@/api'
import zhCN from '@/locales/zh-CN/main.js'
@@ -15,8 +15,8 @@
import NotFount from '@/components/404'
import './index.scss'
const VerifyCard = asyncComponent(() => import('@/tabviews/zshare/verifycard'))
const SubTable = asyncSpinComponent(() => import('@/tabviews/subtable'))
const SettingComponent = asyncComponent(() => import('@/tabviews/zshare/settingcomponent'))
const PagemsgComponent = asyncComponent(() => import('@/tabviews/zshare/pageMessage'))
const { TabPane } = Tabs
@@ -39,8 +39,6 @@
    viewlost: false,      // 页面丢失:1、未获取到配置-页面丢失;2、页面未启用
    lostmsg: '',          // 页面丢失时的提示信息
    config: {},           // 页面配置信息,包括按钮、搜索、显示列、标签等
    userConfig: null,     // 用户自定义设置
    userParam: null,      // 保存用户编辑中的配置
    setting: null,        // 页面全局设置:数据源、按钮及显示列固定、主键等
    treedata: null,       // 列表数据集
    treeNodes: null,      // 列表数据集
@@ -49,10 +47,9 @@
    visible: false,       // 弹框显示隐藏控制
    confirmLoading: false,// 自定义设置模态框加载中
    revertLoading: false, // 恢复默认设置
    settingVisible: false,// 自定义设置模态框
    tabActive: null,      // 标签页展开控制
    expandedKeys: [],     // 展开的树节点
    selectedKeys: [],     // 选中的树节点
    shortcuts: null       // 快捷键
  }
  /**
@@ -69,11 +66,12 @@
    if (result.status) {
      let config = ''
      let userConfig = null
      let _curUserConfig = ''
      let shortcuts = []
      try { // 配置信息解析
        config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
        config.MenuID = this.props.MenuID
        config.MenuName = this.props.MenuName
      } catch (e) {
        console.warn('Parse Failure')
        config = ''
@@ -81,11 +79,15 @@
      
      if (result.LongParamUser) {
        try { // 配置信息解析
          userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
          _curUserConfig = userConfig[this.props.MenuID]
          let userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
          if (userConfig) {
            shortcuts = userConfig.action
            userConfig.printers.forEach(item => {
              window.GLOB.UserCacheMap.set(item.parentId + item.uuid, item)
            })
          }
        } catch (e) {
          console.warn('Parse Failure')
          userConfig = null
        }
      }
@@ -118,12 +120,6 @@
        )
      })
      if (_curUserConfig) {
        config.setting = {...config.setting, ..._curUserConfig.setting}
        config.easyCode = _curUserConfig.easyCode || config.easyCode || ''
      }
      let _tabActive = {} // 筛选展开的tab页
      let _tabgroups = []
      config.tabgroups.forEach(group => {
@@ -131,7 +127,6 @@
        _group.sublist = _group.sublist.filter(tab => tab.level === 0)
        if (_group.sublist.length > 0) {
          _tabActive[_group.uuid] = _group.sublist[0].uuid
          _tabgroups.push(_group)
        }
      })
@@ -182,10 +177,9 @@
        BID: param && param.BID ? param.BID : '',
        loadingview: false,
        config: config,
        tabActive: _tabActive,
        userConfig: userConfig,
        setting: config.setting,
        tabgroups: _tabgroups
        tabgroups: _tabgroups,
        shortcuts
      }, () => {
        this.loadmaindata()
        this.setShortcut()
@@ -204,8 +198,12 @@
  }
  setShortcut = () => {
    const { userConfig, config } = this.state
    if (!userConfig) return
    const { shortcuts } = this.state
    if (!shortcuts || shortcuts.length === 0) {
      document.onkeydown = () => {}
      return
    }
    document.onkeydown = (event) => {
      let e = event || window.event
@@ -220,45 +218,21 @@
        preKey = 'alt'
      }
      if (!preKey) return
      if (!preKey || !keyCode) return
      let triggerId = ''
      let _shortcut = `${preKey}+${keyCode}`
      Object.keys(userConfig).some(key => {
        if (key === this.props.MenuID || !userConfig[key].action) return false
      shortcuts.some(item => {
        if (item.$shortcut === _shortcut) {
          MKEmitter.emit('triggerBtnId', item.uuid)
        let _actions = userConfig[key].action
        Object.keys(_actions).some(btnkey => {
          let item = _actions[btnkey]
          if (Array.isArray(item.shortcut) && preKey === item.shortcut[0] && keyCode === item.shortcut[1]) {
            e.preventDefault()
            triggerId = btnkey
            let _groupId = ''
            let _ActiveTabId = ''
            config.tabgroups.forEach(group => {
              let _tab = group.sublist.filter(tab => tab.uuid === key)[0]
              if (!_tab) return
              _groupId = group.uuid
              _ActiveTabId = _tab.uuid
            })
            this.setState({
              tabActive: {...this.state.tabActive, [_groupId]: _ActiveTabId}
            }, () => {
              MKEmitter.emit('triggerBtnId', triggerId)
            })
          let element = item.parentId ? document.getElementById(item.parentId) : '' // 标签切换
          if (element && element.click) {
            element.click()
          }
            return true
          }
          return false
        })
        if (triggerId) return true
        return false
      })
    }
@@ -428,14 +402,12 @@
    if (selected) {
      let _tabgroups = []
      let _tabActive = {}
      config.tabgroups.forEach(group => {
        let _group = fromJS(group).toJS()
        _group.sublist = _group.sublist.filter(tab => (!tab.level && tab.level !== 0) || tab.level === _data.level)
        if (_group.sublist.length > 0) {
          _tabActive[_group.uuid] = _group.sublist[0].uuid
          _tabgroups.push(_group)
        }
      })
@@ -444,7 +416,6 @@
      this.handleTableId('mainTable', _data.key, _data)
      this.setState({
        tabgroups: _tabgroups,
        tabActive: _tabActive,
        expandedKeys: _expandedKeys,
        selectedKeys: [_data.key]
      })
@@ -464,12 +435,12 @@
      loadingview: true,
      viewlost: false,
      config: {},
      userConfig: null,
      setting: null,
      treedata: null,
      treeNodes: null,
      loading: false,
      BIDs: {},
      shortcuts: null,
      expandedKeys: [],
      selectedKeys: []
    }, () => {
@@ -489,99 +460,6 @@
        [type]: id,
        [type + 'data']: data
      }
    })
  }
  controlCustomSetting = () => {
    this.setState({
      settingVisible: true,
      confirmLoading: false,
      revertLoading: false
    })
  }
  changeMenuParam = (param) => {
    this.setState({userParam: param})
  }
  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: 5
        })
        return
      }
      this.setState({
        settingVisible: false,
        revertLoading: false
      }, () => {
        window.GLOB.CacheMap = new Map()
        this.reloadview()
      })
    })
  }
  settingSubmit = () => {
    const { userParam } = this.state
    let _LongParam = ''
    try {
      _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(userParam)))
    } catch (e) {
      notification.warning({
        top: 92,
        message: '编译错误',
        duration: 5
      })
      return
    }
    let easyCode = userParam[this.props.MenuID] ? userParam[this.props.MenuID].easyCode : ''
    let param = {
      func: 'sPC_TrdMenu_UserParam',
      MenuID: this.props.MenuID,
      EasyCode: easyCode || '',
      LongParam: _LongParam
    }
    this.setState({
      confirmLoading: true
    })
    Api.getSystemConfig(param).then(result => {
      if (!result.status) {
        this.setState({
          confirmLoading: false
        })
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
        return
      }
      this.setState({
        settingVisible: false,
        confirmLoading: false
      }, () => {
        window.GLOB.CacheMap = new Map()
        this.reloadview()
      })
    })
  }
@@ -668,7 +546,7 @@
  render() {
    const { menuType } = this.props
    const { setting, loadingview, viewlost, config, userConfig, tabActive, tabgroups, treeNodes, treedata, expandedKeys, selectedKeys } = this.state
    const { setting, loadingview, viewlost, config, tabgroups, treeNodes, treedata, expandedKeys, selectedKeys, shortcuts } = this.state
    return (
      <div className="tree-page" id={this.state.ContainerId}>
@@ -705,11 +583,11 @@
          </Col>
          <Col span={24 - setting.width}>
            {tabgroups.map(group => (
              <Tabs activeKey={tabActive[group.uuid]} key={group.uuid} onChange={(key) => this.setState({tabActive: {...tabActive, [group.uuid]: key}})}>
              <Tabs key={group.uuid} >
                {group.sublist.map(_tab => {
                  return (
                    <TabPane tab={
                      <span>
                      <span id={_tab.uuid}>
                        {_tab.icon ? <Icon type={_tab.icon} /> : null}
                        {_tab.label}
                      </span>
@@ -719,7 +597,6 @@
                          Tab={_tab}
                          MenuID={_tab.linkTab}
                          mainSearch={null}
                          userConfig={userConfig ? userConfig[_tab.uuid] : null}
                          SupMenuID={this.props.MenuID}
                          ContainerId={this.state.ContainerId}
                          BID={this.state.BIDs[_tab.supMenu] || ''}
@@ -734,33 +611,7 @@
          </Col>
        </Row> : null}
        {menuType !== 'HS' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
        {/* 按钮使用系统存储过程时,验证信息模态框 */}
        <Modal
          wrapClassName="common-table-custom-modal"
          title={'自定义设置'}
          maskClosable={false}
          width={950}
          visible={this.state.settingVisible}
          onCancel={() => { this.setState({ settingVisible: false }) }}
          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.submit']}</Button>
          ]}
          destroyOnClose
        >
          {this.state.settingVisible ?
            <VerifyCard
              MenuID={this.props.MenuID}
              MenuName={this.props.MenuName}
              permAction={this.props.permAction}
              config={this.state.config}
              userConfig={this.state.userConfig}
              columns={[]}
              handleParam={this.changeMenuParam}
            /> : null
          }
        </Modal>
        {menuType !== 'HS' && shortcuts ? <SettingComponent config={config} dict={this.state.dict} shortcuts={shortcuts} permAction={this.props.permAction}/> : null}
        {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
      </div>
    )
src/tabviews/zshare/settingcomponent/editTable/index.jsx
@@ -1,7 +1,7 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Table, Form, Icon, Select, Cascader, notification, message } from 'antd'
// import { fromJS } from 'immutable'
import { Table, Form, Icon, Select, Cascader } from 'antd'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
@@ -9,40 +9,42 @@
let eTDict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
const EditableContext = React.createContext()
const shortkeycode = {
  65: 'A', 66: 'B', 67: 'C', 68: 'D', 69: 'E', 70: 'F', 71: 'G', 72: 'H', 73: 'I', 74: 'J', 75: 'K', 76: 'L', 77: 'M',
  78: 'N', 79: 'O', 80: 'P', 81: 'Q', 82: 'R', 83: 'S', 84: 'T', 85: 'U', 86: 'V', 87: 'W', 88: 'X', 89: 'Y', 90: 'Z'
}
class EditableCell extends Component {
class CustomEditableCell extends Component {
  getInput = () => {
    const { inputType, options } = this.props
    const { inputType, options, record } = this.props
    if (inputType === 'select') {
      let _options = []
      if (record.$port) {
        _options = window.GLOB.UserCacheMap.get(record.$port)
      }
      return (
        <Select>
          {options.map((item, i) => (<Select.Option key={i} value={item.value}> {item.text} </Select.Option>))}
        <Select allowClear>
          {_options.map((item, i) => (<Select.Option key={i} title={item.value} value={item.value}> {item.text} </Select.Option>))}
        </Select>
      )
    } else if (inputType === 'cascader') {
      return (
        <Cascader options={options} placeholder=""/>
        <Cascader allowClear options={options} placeholder=""/>
      )
    }
  }
  renderCell = (form) => {
    const { getFieldDecorator } = form
    const { editing, dataIndex, title, record, children, className, required, inputType } = this.props
    const { editing, editable, dataIndex, record, children, className } = this.props
    return (
      <td className={className}>
        {editing ? (
        {editing && editable ? (
          <Form.Item style={{ margin: 0 }}>
            {getFieldDecorator(dataIndex, {
              rules: [
                {
                  required: required,
                  message: ['number', 'text', 'input'].includes(inputType) ? `${eTDict['form.required.input']} ${title}!` : `${eTDict['form.required.select']} ${title}!`,
                }
              ],
              initialValue: record[dataIndex],
              initialValue: record[dataIndex] || '',
            })(this.getInput())}
          </Form.Item>
        ) : (
@@ -57,10 +59,9 @@
  }
}
class EditTable extends Component {
class CustomEditTable extends Component {
  static propTpyes = {
    data: PropTypes.any,            // 数据列表
    columns: PropTypes.array,       // 显示列
    onChange: PropTypes.func        // 数据变化
  }
@@ -68,14 +69,29 @@
    data: [],
    editingKey: '',
    visible: false,
    columns: []
    columns: [{
      title: '名称',
      dataIndex: 'label',
      width: '25%'
    }, {
      title: '快捷键',
      dataIndex: 'shortcut',
      inputType: 'cascader',
      editable: true,
      options: [],
      width: '25%',
      render: (text, record) => {
        if (!text) return ''
        return text[0] + '+' + shortkeycode[text[1]]
  }
  UNSAFE_componentWillMount () {
    const { data } = this.props
    let columns = fromJS(this.props.columns).toJS()
    columns.push({
    }, {
      title: '打印机',
      dataIndex: 'printer',
      inputType: 'select',
      editable: true,
      options: [],
      width: '25%'
    }, {
      title: '操作',
      dataIndex: 'operation',
      width: '140px',
@@ -99,11 +115,81 @@
          </div>
        )
      }
    }],
    printTypeColumns: [
      {
        title: '打印类型',
        dataIndex: 'Text',
        width: '26.1%'
      },
      {
        title: '打印机',
        dataIndex: 'printer',
        inputType: 'select',
        editable: true,
        options: [],
      },
      {
        title: '操作',
        dataIndex: 'operation',
        width: '153px',
        render: (text, record) => {
          const { editingKey } = this.state
          const editable = this.isEditing(record)
          return editable ? (
            <div style={{textAlign: 'center', minWidth: '110px'}}>
              <EditableContext.Consumer>
                {form => (
                  <span onClick={() => this.save(form, record.uuid, record.parentId)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}>
                    {eTDict['model.save']}
                  </span>
                )}
              </EditableContext.Consumer>
              <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.uuid)}>{eTDict['model.cancel']}</span>
            </div>
          ) : (
            <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px'}}>
              <span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><Icon type="edit" /></span>
            </div>
          )
        }
      }
    ]
  }
  UNSAFE_componentWillMount () {
    const { data } = this.props
    let keys = ['shift', 'ctrl', 'alt']
    let _options = []
    keys.forEach(item => {
      let _op = {
        value: item,
        label: item,
        children: []
      }
      Object.keys(shortkeycode).forEach(key => {
        if (item === 'ctrl' && ['65', '67', '68', '86', '70', '72', '83'].includes(key)) return
        if (item === 'alt' && key === '65') return
        _op.children.push({
          value: +key,
          label: shortkeycode[key]
        })
      })
      _options.push(_op)
    })
    this.setState({
      data: data || [],
      columns
      data: data,
      columns: this.state.columns.map(item => {
        if (item.dataIndex === 'shortcut') {
          item.options = _options
        }
        return item
      })
    })
  }
@@ -111,81 +197,6 @@
  cancel = () => {
    this.setState({ editingKey: '' })
  }
  copy = (item) => {
    const { type } = this.props
    const { data } = this.state
    if (!data || data.length === 0) {
      message.warning('未获取到配置信息')
      return
    }
    let msg = { key: type }
    if (item) {
      msg.type = 'line'
      msg.data = item
    } else {
      msg.type = 'array'
      msg.data = data
    }
    try {
      msg = window.btoa(window.encodeURIComponent(JSON.stringify(msg)))
    } catch {
      console.warn('Stringify Failure')
      msg = ''
    }
    if (msg) {
      let oInput = document.createElement('input')
      oInput.value = msg
      document.body.appendChild(oInput)
      oInput.select()
      document.execCommand('Copy')
      document.body.removeChild(oInput)
      message.success('复制成功。')
    }
  }
  onSave = (record) => {
    const { columns } = this.state
    const newData = [...this.state.data]
    const index = newData.findIndex(item => record.uuid === item.uuid)
    if (index === -1) {
      notification.warning({
        top: 92,
        message: '数据错误,无法找到行ID!',
        duration: 5
      })
      return
    }
    let unique = true
    columns.forEach(col => {
      if (col.unique !== true || !unique) return
      let _index = newData.findIndex(item => record.uuid !== item.uuid && record[col.dataIndex] === item[col.dataIndex])
      if (_index > -1) {
        notification.warning({
          top: 92,
          message: col.title + '不可重复!',
          duration: 5
        })
        unique = false
      }
    })
    if (!unique) return
    newData.splice(index, 1, record)
    this.setState({ data: newData, editingKey: '' }, () => {
      this.props.onChange(newData)
    })
  }
  handleDelete = (uuid) => {
@@ -199,48 +210,38 @@
    })
  }
  save(form, uuid) {
    const { columns } = this.state
  save(form, uuid, parentId) {
    form.validateFields((error, row) => {
      if (error) {
        return;
      }
      const newData = [...this.state.data]
      const index = newData.findIndex(item => uuid === item.uuid)
      let unique = true
      columns.forEach(col => {
        if (col.unique !== true || !unique) return
      let newData = null
        let _index = newData.findIndex(item => uuid !== item.uuid && row[col.dataIndex] === item[col.dataIndex])
        if (_index > -1) {
          notification.warning({
            top: 92,
            message: col.title + '不可重复!',
            duration: 5
          })
          unique = false
      if (parentId) {
        newData = this.state.data.map(item => {
          if (parentId === item.uuid) {
            item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
              if (uuid === cell.uuid) {
                cell = {...cell, ...row}
        }
              return cell
      })
      if (!unique) return
      if (index > -1) {
        const item = newData[index]
        newData.splice(index, 1, {
          ...item,
          ...row,
        })
        this.setState({ data: newData, editingKey: '' }, () => {
          this.props.onChange(newData)
          }
          return item
        })
      } else {
        newData.push(row);
        newData = this.state.data.map(item => {
          if (uuid === item.uuid) {
            item = {...item, ...row}
          }
          return item
        })
      }
        this.setState({ data: newData, editingKey: '' }, () => {
          this.props.onChange(newData)
        })
      }
    })
  }
@@ -248,25 +249,10 @@
    this.setState({ editingKey: uuid })
  }
  moveRow = (dragIndex, hoverIndex) => {
    const { editingKey } = this.state
    let _data = fromJS(this.state.data).toJS()
    if (editingKey) return
    _data.splice(hoverIndex, 0, ..._data.splice(dragIndex, 1))
    this.setState({
      data: _data
    }, () => {
      this.props.onChange(_data)
    })
  }
  render() {
    let components = {
      body: {
        cell: EditableCell
        cell: CustomEditableCell
      }
    }
    
@@ -279,30 +265,53 @@
          inputType: col.inputType,
          dataIndex: col.dataIndex,
          options: col.options || [],
          required: col.required !== false ? true : false,
          title: col.title,
          editable: col.dataIndex === 'shortcut' || record.funcType === 'print',
          editing: this.isEditing(record),
          onSave: this.onSave,
        }),
      }
    })
    const printTypeColumns = this.state.printTypeColumns.map(col => {
      if (!col.editable) return col
      return {
        ...col,
        onCell: record => ({
          record,
          inputType: col.inputType,
          dataIndex: col.dataIndex,
          options: [],
          title: col.title,
          editable: true,
          editing: this.isEditing(record),
        }),
      }
    })
    return (
      <EditableContext.Provider value={this.props.form}>
        <div className="modal-edit-table">
        <div className="modal-custom-edit-table">
          <Table
            bordered
            rowKey="uuid"
            components={components}
            dataSource={this.state.data}
            columns={columns}
            rowClassName="editable-row"
            rowClassName={(record) => 'editable-row' + (record.$expanded ? ' print' : '')}
            pagination={false}
            onRow={(record, index) => ({
              index,
              moveAble: !this.state.editingKey,
              moveRow: this.moveRow,
            })}
            expandedRowRender={record => (
              record.$expanded ?
                <Table
                  bordered
                  rowKey="key"
                  size="small"
                  components={components}
                  rowClassName="editable-row"
                  dataSource={record.verify.printerTypeList}
                  columns={printTypeColumns}
                  pagination={false}
                /> : null
            )}
          />
        </div>
      </EditableContext.Provider>
@@ -310,4 +319,4 @@
  }
}
export default Form.create()(EditTable)
export default Form.create()(CustomEditTable)
src/tabviews/zshare/settingcomponent/editTable/index.scss
@@ -1,14 +1,9 @@
.modal-edit-table {
.modal-custom-edit-table {
  .editable-row {
    .ant-form-explain {
      position: absolute;
      font-size: 12px;
      margin-top: -4px;
    }
    .color-sketch-block {
      width: 200px;
      position: relative;
      top: 8px;
    }
    .ant-select {
      width: 100%;
@@ -18,6 +13,24 @@
    }
    > td:last-child {
      padding: 0px;
    }
  }
  .ant-table-expanded-row {
    td[colspan="4"] {
      padding: 10px;
      .ant-table-wrapper {
        margin: 0;
        .ant-table-body {
          margin: 0;
        }
      }
    }
  }
  .editable-row:not(.print) {
    .ant-table-row-expand-icon-cell {
      div {
        display: none;
      }
    }
  }
@@ -36,12 +49,6 @@
    .primary {
      color: #1890ff;
    }
    .copy {
      color: #26C281;
    }
    .danger {
      color: #ff4d4f;
    }
    span:last-child {
      margin-right: 0px;
    }
@@ -53,35 +60,6 @@
    }
    .primary {
      color: rgba(0, 0, 0, .25);
    }
    .danger {
      color: rgba(0, 0, 0, .25);
    }
    .copy {
      color: rgba(0, 0, 0, .25);
    }
  }
  .ant-empty {
    margin: 0;
  }
  tr.drop-over-downward td {
    border-bottom: 2px dashed #1890ff;
  }
  tr.drop-over-upward td {
    border-top: 2px dashed #1890ff;
  }
  .copy-control {
    display: inline-block;
    position: absolute;
    right: 10px;
    top: 2px;
    .anticon-copy {
      margin-right: 7px;
      color: #26C281;
    }
    .anticon-snippets {
      color: purple;
    }
  }
}
src/tabviews/zshare/settingcomponent/index.jsx
@@ -1,24 +1,28 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Button, Modal, notification } from 'antd'
import { Button, Modal, notification, Spin, Empty } from 'antd'
import Api from '@/api'
import MKEmitter from '@/utils/events.js'
import UtilsUpdate from '@/utils/utils-update.js'
import options from '@/store/options.js'
import asyncComponent from '@/utils/asyncSpinComponent'
import './index.scss'
const VerifyCard = asyncComponent(() => import('@/tabviews/zshare/verifycard'))
const EditTable = asyncComponent(() => import('./editTable'))
class CustomSetting extends Component {
  static propTpyes = {
    dict: PropTypes.any,              // 字典表
    reloadview: PropTypes.func,       // 页面刷新
    dict: PropTypes.object,           // 字典表
    config: PropTypes.object,         // 页面配置信息
    shortcuts: PropTypes.any,         // 自定义设置
    permAction: PropTypes.object,     // 按钮权限
  }
  state = {
    userParam: null,       // 保存用户编辑中的配置
    visible: false,        // 模态框控制
    components: null,      // 组件集合
    revertLoading: false,  // 恢复默认设置
    confirmLoading: false, // 自定义设置模态框加载中
  }
@@ -27,61 +31,351 @@
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  controlCustomSetting = () => {
  trigger = () => {
    const { config } = this.props
    this.setState({
      visible: true,
      confirmLoading: false,
      revertLoading: false
    })
    // let deffers = []
    // config.tabgroups.forEach(group => {
    //   group.sublist.forEach(tab => {
    //     deffers.push(new Promise(resolve => {
    //       let param = {
    //         func: 'sPC_Get_LongParam',
    //         MenuID: tab.linkTab
    //       }
    //       Api.getCacheConfig(param).then(res => {
    //         res.tab = tab
    //         resolve(res)
    //       })
    //     }))
    //   })
    // })
    // if (deffers.length > 0) {
    //   Promise.all(deffers).then(result => {
    //     let errors = result.filter(res => !res.status)
    //     if (errors.length > 0) {
    //       notification.warning({
    //         top: 92,
    //         message: errors[0].message,
    //         duration: 5
    //       })
    //       this.setState({
    //         loading: false
    //       })
    //       return
    //     }
    //     let roleId = sessionStorage.getItem('role_id') || '' // 角色ID
    //     result.forEach(res => {
    //       if (!res.LongParam) return
    //       let subconfig = ''
    //       let subUserConfig = userConfig ? userConfig[res.tab.uuid] : ''
    //     }
    if (config.Template === 'CommonTable' || config.Template === 'TreePage') {
      this.getPageConfig()
    } else if (config.Template === 'CustomPage') {
      this.getCustomPageConfig()
    } else {
      notification.warning({
        top: 92,
        message: '配置信息格式错误!',
        duration: 5
      })
    }
  }
  changeMenuParam = (param) => {
    this.setState({userParam: param})
  getCustomPageConfig = () => {
    const { shortcuts } = this.props
    let config = fromJS(this.props.config).toJS()
    let userConfig = {}
    let printbtns = []
    let _components = []
    shortcuts.forEach(item => {
      userConfig[item.uuid] = item
    })
    let filterComponent = (components) => {
      components.forEach(item => {
        if (item.type === 'tabs') {
          item.subtabs.forEach(tab => {
            filterComponent(tab.components)
          })
          return
        } else if (item.type === 'group') {
          filterComponent(item.components)
          return
        }
        let _comp = {title: item.name, uuid: item.uuid, action: []}
        item.action && item.action.forEach(cell => {
          cell.$expanded = false
          if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
            cell.$port = cell.verify ? cell.verify.linkUrl : ''
            if (cell.verify && cell.verify.printerTypeList) {
              cell.verify.printerTypeList = cell.verify.printerTypeList.map(_cell => {
                _cell.parentId = cell.uuid
                _cell.$port = cell.$port
                return _cell
              })
              cell.$expanded = true
            }
            printbtns.push(cell)
          }
          _comp.action.push({...cell, ...(userConfig[cell.uuid] || {})})
        })
        if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) {
          item.subcards.forEach(card => {
            card.elements && card.elements.forEach(cell => {
              if (cell.eleType !== 'button') return
              cell.$expanded = false
              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
                cell.$port = cell.verify ? cell.verify.linkUrl : ''
                if (cell.verify && cell.verify.printerTypeList) {
                  cell.verify.printerTypeList = cell.verify.printerTypeList.map(_cell => {
                    _cell.parentId = cell.uuid
                    _cell.$port = cell.$port
                    return _cell
                  })
                  cell.$expanded = true
                }
                printbtns.push(cell)
              }
              _comp.action.push({...cell, ...(userConfig[cell.uuid] || {})})
            })
            card.backElements && card.backElements.forEach(cell => {
              if (cell.eleType !== 'button') return
              cell.$expanded = false
              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
                cell.$port = cell.verify ? cell.verify.linkUrl : ''
                if (cell.verify && cell.verify.printerTypeList) {
                  cell.verify.printerTypeList = cell.verify.printerTypeList.map(_cell => {
                    _cell.parentId = cell.uuid
                    _cell.$port = cell.$port
                    return _cell
                  })
                  cell.$expanded = true
                }
                printbtns.push(cell)
              }
              _comp.action.push({...cell, ...(userConfig[cell.uuid] || {})})
            })
          })
        } else if (item.type === 'table' && item.subtype === 'normaltable') {
          item.cols && item.cols.forEach(col => {
            if (col.type !== 'action') return
            col.elements && col.elements.forEach(cell => {
              cell.$expanded = false
              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
                cell.$port = cell.verify ? cell.verify.linkUrl : ''
                if (cell.verify && cell.verify.printerTypeList) {
                  cell.verify.printerTypeList = cell.verify.printerTypeList.map(_cell => {
                    _cell.parentId = cell.uuid
                    _cell.$port = cell.$port
                    return _cell
                  })
                  cell.$expanded = true
                }
                printbtns.push(cell)
              }
              _comp.action.push({...cell, ...(userConfig[cell.uuid] || {})})
            })
          })
        }
        if (_comp.action.length > 0) {
          _components.push(_comp)
        }
      })
    }
    filterComponent(config.components)
    this.setState({components: _components})
    this.getPrinter(printbtns)
  }
  getPageConfig = () => {
    const { shortcuts, permAction } = this.props
    let config = fromJS(this.props.config).toJS()
    let userConfig = {}
    let components = []
    let _component = { title: '主表', uuid: config.MenuID, action: [] }
    let printbtns = []
    shortcuts.forEach(item => {
      userConfig[item.uuid] = item
    })
    config.action && config.action.forEach(item => {
      item.$expanded = false
      if (item.OpenType === 'funcbutton' && item.funcType === 'print') {
        item.$port = item.verify ? item.verify.linkUrl : ''
        printbtns.push(item)
        if (item.verify && item.verify.printerTypeList && item.verify.printerTypeList.length > 0) {
          item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
            cell.parentId = item.uuid
            cell.$port = item.$port
            return cell
          })
          item.$expanded = true
        }
      }
      _component.action.push({...item, ...(userConfig[item.uuid] || {})})
    })
    if (_component.action.length > 0) {
      components.push(_component)
    }
    let deffers = []
    config.tabgroups && config.tabgroups.forEach(group => {
      group.sublist.forEach(tab => {
        deffers.push(new Promise(resolve => {
          let param = {
            func: 'sPC_Get_LongParam',
            MenuID: tab.linkTab
          }
          Api.getCacheConfig(param).then(res => {
            res.tab = tab
            resolve(res)
          })
        }))
      })
    })
    if (deffers.length > 0) {
      Promise.all(deffers).then(result => {
        let errors = result.filter(res => !res.status)
        if (errors.length > 0) {
          notification.warning({
            top: 92,
            message: errors[0].message,
            duration: 5
          })
          return
        }
        result.forEach(res => {
          if (!res.LongParam) return
          let subconfig = ''
          try {
            subconfig = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
          } catch (e) {
            console.warn('Parse Failure')
            subconfig = ''
          }
          if (!subconfig || !subconfig.enabled) return
          subconfig = UtilsUpdate.updateSubTable(subconfig)
          let _comp = {title: res.tab.label, uuid: res.tab.uuid, action: []}
          subconfig.action.forEach(item => {
            if (!permAction[item.uuid]) return
            item.$expanded = false
            if (item.OpenType === 'funcbutton' && item.funcType === 'print') {
              let _item = window.GLOB.UserCacheMap.get(res.tab.uuid + item.uuid)
              item.printer = _item ? (_item.printer || '') : ''
              item.$port = item.verify ? item.verify.linkUrl : ''
              if (item.verify && item.verify.printerTypeList) {
                item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
                  cell.parentId = item.uuid
                  cell.$port = item.$port
                  cell.printer = _item && _item.printerList ? (_item.printerList[cell.Value] || '') : ''
                  return cell
                })
                item.$expanded = true
              }
              printbtns.push(item)
            }
            _comp.action.push({...item, ...(userConfig[item.uuid] || {})})
          })
          if (_comp.action.length > 0) {
            components.push(_comp)
          }
        })
        this.setState({components})
        this.getPrinter(printbtns)
      })
    } else {
      this.setState({components})
      this.getPrinter(printbtns)
    }
  }
  getPrinter = (printbtns) => {
    let links = []
    printbtns.forEach(item => {
      if (!item.verify || !item.verify.linkUrl) {
        notification.warning({
          top: 92,
          message: '按钮《' + item.label + '》设置错误!',
          duration: 5
        })
      } else if (!links.includes(item.verify.linkUrl)) {
        links.push(item.verify.linkUrl)
        let socket = null
        socket = new WebSocket('ws://' + item.verify.linkUrl)
        // 打开Socket
        socket.onopen = () =>{
          let request  = {
            requestID: '',
            version: '',
            cmd: 'getPrinters'
          }
          socket.send(JSON.stringify(request))
        }
        // 监听消息
        socket.onmessage = (event) => {
          let data = ''
          try {
            data = JSON.parse(event.data)
          } catch {
            data = ''
          }
          if (data && data.cmd === 'getPrinters' && (data.status === true || data.status === 'success')) {
            let _printers = []
            let _printer = data.printers[0]
            if (_printer && typeof(_printer) === 'string') {
              _printers = Array.from(new Set(data.printers))
              _printers = _printers.map(print => {
                return {
                  value: print,
                  text: print
                }
              })
            } else if (_printer && typeof(_printer) === 'object') {
              _printers = data.printers.map(p => p.name)
              _printers = Array.from(new Set(_printers))
              _printers = _printers.map(print => {
                return {
                  value: print,
                  text: print
                }
              })
            }
            window.GLOB.UserCacheMap.set(item.verify.linkUrl, _printers)
          } else if (data && data.cmd === 'getPrinters') {
            notification.warning({
              top: 92,
              message: data.message,
              duration: 5
            })
          }
        }
        socket.onerror = () => {
          notification.warning({
            top: 92,
            message: '无法连接到:' + item.verify.linkUrl,
            duration: 5
          })
        }
      }
    })
  }
  settingRevert = () => {
    const { config } = this.props
    let param = {
      func: 's_TrdMenu_UserParam_del',
      MenuID: this.props.MenuID
      MenuID: config.MenuID
    }
    this.setState({
      revertLoading: true
@@ -99,22 +393,50 @@
        })
        return
      }
      Api.deleteMenuStorage(config.MenuID).then(() => {
      this.setState({
        visible: false,
        revertLoading: false
      }, () => {
        window.GLOB.CacheMap = new Map()
        this.props.reloadview()
          MKEmitter.emit('reloadMenuView', config.MenuID)
        })
      })
    })
  }
  settingSubmit = () => {
    const { userParam } = this.state
    let _LongParam = ''
    const { config } = this.props
    const { components } = this.state
    let _LongParam = {version: '1.0', action: [], printers: []}
    components.forEach(com => {
      com.action.forEach(item => {
        if (item.shortcut && item.shortcut.length > 0) {
          _LongParam.action.push({uuid: item.uuid, parentId: com.uuid, shortcut: item.shortcut, $shortcut: item.shortcut.join('+')})
        }
        if (item.funcType === 'print' && (item.printer || item.verify.printerTypeList)) {
          let printerList = {}
          if (item.verify.printerTypeList) {
            item.verify.printerTypeList.forEach(cell => {
              printerList[cell.Value] = cell.printer || ''
            })
          }
          _LongParam.printers.push({
            uuid: item.uuid,
            parentId: com.uuid,
            printer: item.printer || '',
            printerList
          })
        }
      })
    })
    try {
      _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(userParam)))
      _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_LongParam)))
    } catch (e) {
      notification.warning({
        top: 92,
@@ -124,12 +446,10 @@
      return
    }
    let easyCode = userParam[this.props.MenuID] ? userParam[this.props.MenuID].easyCode : ''
    let param = {
      func: 'sPC_TrdMenu_UserParam',
      MenuID: this.props.MenuID,
      EasyCode: easyCode || '',
      MenuID: config.MenuID,
      EasyCode: config.easyCode || '',
      LongParam: _LongParam
    }
@@ -150,19 +470,33 @@
        return
      }
      Api.deleteMenuStorage(this.props.MenuID).then(() => {
      Api.deleteMenuStorage(config.MenuID).then(() => {
        this.setState({
          visible: false,
          confirmLoading: false
        }, () => {
          window.GLOB.CacheMap = new Map()
          this.props.reloadview()
          MKEmitter.emit('reloadMenuView', config.MenuID)
        })
      })
    })
  }
  onChange = (list, parentId) => {
    const { components } = this.state
    this.setState({
      components: components.map(item => {
        if (item.uuid === parentId) {
          item.action = list
        }
        return item
      })
    })
  }
  render() {
    const { components, visible } = this.state
    
    return (
      <div className="page-setting-wrap">
@@ -170,15 +504,14 @@
          icon="setting"
          shape="circle"
          className="page-setting"
          onClick={this.handleviewconfig}
          onClick={this.trigger}
        /> : null}
        {/* <Icon className="custom-control" type="setting" onClick={this.controlCustomSetting} /> */}
        <Modal
          wrapClassName="common-table-custom-modal"
          wrapClassName="custom-setting-modal"
          title={'自定义设置'}
          maskClosable={false}
          width={950}
          visible={this.state.visible}
          visible={visible}
          onCancel={() => { this.setState({ visible: false }) }}
          footer={[
            <Button key="revert" type="danger" loading={this.state.revertLoading} onClick={this.settingRevert}>{this.props.dict['main.revert.default']}</Button>,
@@ -187,17 +520,14 @@
          ]}
          destroyOnClose
        >
          {this.state.visible ?
            <VerifyCard
              MenuID={this.props.MenuID}
              MenuName={this.props.MenuName}
              permAction={this.props.permAction}
              config={this.props.config}
              userConfig={this.props.userConfig}
              columns={this.props.columns}
              handleParam={this.changeMenuParam}
            /> : null
          }
          {components && components.length > 0 ? components.map(item => (
            <div key={item.uuid}>
              <p className="component-title">{item.title}</p>
              <EditTable data={item.action} onChange={(list) => this.onChange(list, item.uuid)}/>
            </div>
          )) : null}
          {components && components.length === 0 ? <Empty /> : null}
          {!components ? <Spin size="large" /> : null}
        </Modal>
      </div>
    )
src/tabviews/zshare/settingcomponent/index.scss
@@ -2,13 +2,23 @@
  .page-setting {
    position: fixed;
    z-index: 2;
    bottom: 110px;
    bottom: 65px;
    right: 30px;
    width: 40px;
    height: 40px;
  }
}
.common-table-custom-modal {
.custom-popview {
  .page-setting-wrap {
    display: none;
  }
}
.page-message-wrap:has(.page-message) + .page-setting-wrap {
  .page-setting {
    bottom: 110px;
  }
}
.custom-setting-modal {
  .ant-modal {
    top: 50px;
    padding-bottom: 5px;
@@ -16,8 +26,24 @@
      max-height: calc(100vh - 190px);
      min-height: 250px;
      overflow-y: auto;
      padding-top: 0px;
      position: relative;
      .ant-spin {
        position: absolute;
        left: calc(50% - 22px);
        top: 100px;
      }
      .ant-empty {
        margin: 15vh 8px;
        margin-top: 30px;
      }
      .component-title {
        font-size: 16px;
        display: inline-block;
        margin: 20px 0px 10px 0px;
        padding: 0 10px;
        border-bottom: 2px solid #1890ff;
      }
    }
    .ant-modal-body::-webkit-scrollbar {
src/tabviews/zshare/verifycard/index.jsx
File was deleted
src/tabviews/zshare/verifycard/index.scss
File was deleted
src/tabviews/zshare/verifycard/tabcard/actionform/index.jsx
File was deleted
src/tabviews/zshare/verifycard/tabcard/actionform/index.scss
src/tabviews/zshare/verifycard/tabcard/columnform/index.jsx
File was deleted
src/tabviews/zshare/verifycard/tabcard/columnform/index.scss
src/tabviews/zshare/verifycard/tabcard/index.jsx
File was deleted
src/tabviews/zshare/verifycard/tabcard/index.scss
File was deleted
src/tabviews/zshare/verifycard/tabcard/printform/index.jsx
File was deleted
src/tabviews/zshare/verifycard/tabcard/printform/index.scss
src/tabviews/zshare/verifycard/tabcard/printtypeform/index.jsx
File was deleted
src/tabviews/zshare/verifycard/tabcard/printtypeform/index.scss