king
2020-03-10 c39ea1f23d21b070188abcf5f4dd5bdd7b47c1f9
2020-03-10
23个文件已修改
4个文件已添加
1336 ■■■■ 已修改文件
src/api/index.js 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/comtable.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/comtable.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.scss 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/mainTable/index.jsx 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/tableshare/actionList/index.jsx 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/tableshare/topSearch/index.jsx 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/tableshare/topSearch/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/tableshare/verifycard/actionform/index.jsx 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/tableshare/verifycard/actionform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/tableshare/verifycard/index.jsx 368 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/tableshare/verifycard/index.scss 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/settingform/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/dragelement/card.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/dragelement/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/formconfig.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/searchform/index.jsx 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/searchform/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/verifycard/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 63 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/printTemplate/dragelement/index.scss 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/printTemplate/index.jsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/printTemplate/index.scss 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js
@@ -142,8 +142,15 @@
    param.nonc = Utils.getuuid()
    
    let keys = Object.keys(param).sort()
    keys = keys.filter(key => key !== 'rduri')
    let values = keys.map(key => key + param[key]).join('')
    let values = ''
    keys.forEach(key => {
      if (key === 'rduri' || key === 't') return
      if (typeof(param[key]) === 'object') {
        values += key + JSON.stringify(param[key])
      } else {
        values += key + param[key]
      }
    })
    param.sign  = md5(values)
    param.t = new Date().getTime()
@@ -175,8 +182,15 @@
    param.nonc = Utils.getuuid()
    
    let keys = Object.keys(param).sort()
    keys = keys.filter(key => key !== 'rduri')
    let values = keys.map(key => key + param[key]).join('')
    let values = ''
    keys.forEach(key => {
      if (key === 'rduri' || key === 't') return
      if (typeof(param[key]) === 'object') {
        values += key + JSON.stringify(param[key])
      } else {
        values += key + param[key]
      }
    })
    param.sign  = md5(values)
    param.t = new Date().getTime()
@@ -199,8 +213,15 @@
    param.nonc = Utils.getuuid()
    
    let keys = Object.keys(param).sort()
    keys = keys.filter(key => key !== 'rduri')
    let values = keys.map(key => key + param[key]).join('')
    let values = ''
    keys.forEach(key => {
      if (key === 'rduri' || key === 't') return
      if (typeof(param[key]) === 'object') {
        values += key + JSON.stringify(param[key])
      } else {
        values += key + param[key]
      }
    })
    param.sign  = md5(values)
    param.t = new Date().getTime()
@@ -245,8 +266,15 @@
      param.nonc = Utils.getuuid()
      
      let keys = Object.keys(param).sort()
      keys = keys.filter(key => key !== 'rduri')
      let values = keys.map(key => key + param[key]).join('')
      let values = ''
      keys.forEach(key => {
        if (key === 'rduri' || key === 't') return
        if (typeof(param[key]) === 'object') {
          values += key + JSON.stringify(param[key])
        } else {
          values += key + param[key]
        }
      })
      param.sign  = md5(values)
      param.t = new Date().getTime()
@@ -281,8 +309,15 @@
    param.nonc = Utils.getuuid()
    
    let keys = Object.keys(param).sort()
    keys = keys.filter(key => key !== 'rduri' && key !== 't')
    let values = keys.map(key => key + param[key]).join('')
    let values = ''
    keys.forEach(key => {
      if (key === 'rduri' || key === 't') return
      if (typeof(param[key]) === 'object') {
        values += key + JSON.stringify(param[key])
      } else {
        values += key + param[key]
      }
    })
    param.sign  = md5(values)
    param.t = new Date().getTime()
@@ -374,8 +409,15 @@
    param.nonc = Utils.getuuid()
    
    let keys = Object.keys(param).sort()
    keys = keys.filter(key => key !== 'rduri')
    let values = keys.map(key => key + param[key]).join('')
    let values = ''
    keys.forEach(key => {
      if (key === 'rduri' || key === 't') return
      if (typeof(param[key]) === 'object') {
        values += key + JSON.stringify(param[key])
      } else {
        values += key + param[key]
      }
    })
    param.sign  = md5(values)
    param.t = new Date().getTime()
src/locales/en-US/comtable.js
@@ -224,6 +224,7 @@
  'header.form.thawbutton': '解冻按钮',
  'header.form.maxRows': '最大行数',
  'header.form.paste': '粘贴',
  'header.form.ratio': '比例',
  'header.modal.form.edit': '表单-编辑',
  'header.modal.search.edit': '搜索条件-编辑',
  'header.modal.action.edit': '按钮-编辑',
src/locales/zh-CN/comtable.js
@@ -224,6 +224,7 @@
  'header.form.thawbutton': '解冻按钮',
  'header.form.maxRows': '最大行数',
  'header.form.paste': '粘贴',
  'header.form.ratio': '比例',
  'header.modal.form.edit': '表单-编辑',
  'header.modal.search.edit': '搜索条件-编辑',
  'header.modal.action.edit': '按钮-编辑',
src/tabviews/commontable/index.jsx
@@ -13,6 +13,7 @@
import {refreshTabView, modifyTabview} from '@/store/action'
import MainTable from './mainTable'
import VerifyCard from '@/tabviews/tableshare/verifycard'
import MainAction from '@/tabviews/tableshare/actionList'
import MainSearch from '@/tabviews/tableshare/topSearch'
import SubTable from '@/tabviews/subtable'
@@ -54,16 +55,16 @@
    orderBy: '',          // 排序
    search: '',           // 搜索条件数组,使用时需分场景处理
    BIDs: {},             // 上级表id
    setsingle: false,     // 主表单选多选切换
    pickup: false,        // 主表数据隐藏显示切换
    isLinkMain: false,    // 是否存在与主表关联的子表
    popAction: false,     // 弹框页面,按钮信息
    popData: false,       // 弹框页面,所选的表格数据
    visible: false,       // 弹框显示隐藏控制
    treevisible: false,   // 菜单结构树弹框显示隐藏控制
    tabBtn: null,         // 表单标签按钮
    tabParam: null,       // 表单标签参数
    refreshtabs: null     // 需要刷新的标签集
    refreshtabs: null,    // 需要刷新的标签集
    confirmLoading: false,// 自定义设置模态框加载中
    settingVisible: false // 自定义设置模态框
  }
  /**
@@ -79,12 +80,20 @@
    let result = await Api.getSystemCacheConfig(param)
    if (result.status) {
      let config = ''
      let userConfig = ''
      try { // 配置信息解析
        config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
      } catch (e) {
        console.warn('Parse Failure')
        config = ''
      }
      try { // 配置信息解析
        userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
      } catch (e) {
        console.warn('Parse Failure')
        userConfig = ''
      }
      // 页面配置解析错误时提示
@@ -106,18 +115,34 @@
        return
      }
      let _arrField = []     // 字段集
      let _columns = []      // 显示列
      let _logcolumns = []   // 日志显示列
      let _hideCol = []      // 隐藏及合并列中字段的uuid集
      let colMap = new Map() // 用于字段过滤
      // 权限过滤
      config.action = config.action.filter(item => permAction[item.uuid])
      // config.tabgroups.forEach(group => {
      //   if (!config[group]) return
      //   config[group] = config[group].filter(tab => permAction[tab.uuid])
      // })
      if (userConfig) {
        config.setting = {...config.setting, ...userConfig.setting}
        let _actions = {}
        userConfig.action.forEach(item => {
          _actions[item.uuid] = item
        })
        config.action = config.action.map(item => {
          if (_actions[item.uuid]) {
            item = {...item, ..._actions[item.uuid]}
          }
          return item
        })
      }
      let _arrField = []     // 字段集
      let _columns = []      // 显示列
      let _logcolumns = []   // 日志显示列
      let _hideCol = []      // 隐藏及合并列中字段的uuid集
      let colMap = new Map() // 用于字段过滤
      let _actions = []     // 工具栏按钮
      let _operations = []  // 操作列按钮(存在时)
@@ -180,17 +205,6 @@
        }
      })
      let _isLinkMain = false // 检查是否有与主表关联的子表
      config.tabgroups.forEach(groupId => {
        if (!config[groupId] || config[groupId].length === 0) return
        config[groupId].forEach(tab => {
          if (tab.supMenu === 'mainTable') {
            _isLinkMain = true
          }
        })
      })
      this.setState({
        loadingview: false,
        config: config,
@@ -199,18 +213,17 @@
        actions: _actions,
        columns: _columns,
        logcolumns: _logcolumns,
        isLinkMain: _isLinkMain,
        arr_field: _arrField.join(','),
        search: Utils.initMainSearch(config.search) // 搜索条件初始化(含有时间格式,需要转化)
      }, () => {
        this.improveSearch()
        if (config.setting.onload !== 'false') { // 初始化可加载
          this.setState({
            loading: true
          })
          this.loadmaindata()
        }
        this.setShortcut()
      })
    } else {
      this.setState({
@@ -221,6 +234,36 @@
        top: 92,
        message: result.message,
        duration: 10
      })
    }
  }
  setShortcut = () => {
    const { actions } = this.state
    if (!actions) 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'
      }
      let istrigger = false
      actions.forEach(item => {
        if (!item.shortcut || istrigger) return
        if (preKey === item.shortcut && keyCode === item.shortcutkey) {
          e.preventDefault()
          istrigger = true
          this.refs.mainButton.actionTrigger(item)
        }
      })
    }
  }
@@ -551,9 +594,7 @@
      orderBy: '',
      search: '',
      BIDs: {},
      setsingle: false,
      pickup: false,
      isLinkMain: false
      pickup: false
    }, () => {
      this.loadconfig()
    })
@@ -665,22 +706,6 @@
        [type]: id,
        [type + 'data']: data
      }
    })
  }
  /**
   * @description 表格单选多选切换
   */
  checkChange = () => {
    const { setsingle, BIDs } = this.state
    let _BIDs = JSON.parse(JSON.stringify(BIDs))
    _BIDs.mainTable = ''
    this.setState({
      setsingle: !setsingle,
      pickup: false,
      BIDs: _BIDs
    })
  }
  
@@ -831,19 +856,50 @@
    })
  }
  controlCustomSetting = () => {
    this.setState({
      settingVisible: true,
      confirmLoading: false
    })
  }
  settingSubmit = () => {
    this.verifyRef.handleConfirm().then(res => {
      let _LongParam = ''
      try {
        _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(res)))
      } catch (e) {
        notification.warning({
          top: 92,
          message: '编译错误',
          duration: 10
        })
        return
      }
      let param = {
        func: 'sPC_TrdMenu_UserParam',
        MenuID: this.props.MenuID,
        LongParam: _LongParam
      }
      this.setState({
        confirmLoading: true
      })
      Api.getSystemConfig(param).then(result => {
        this.setState({
          settingVisible: false,
          confirmLoading: false
        })
      })
    })
  }
  UNSAFE_componentWillMount () {
    // 组件加载时,获取菜单数据
    this.loadconfig()
  }
  componentDidMount () {
    // document.onkeydown = (event) => {
    //   let e = event || window.event
    //   if(e && e.keyCode === 27) {
    //     console.log(this.props.MenuID)
    //   }
    // }
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
@@ -871,11 +927,11 @@
  }
  render() {
    const { view, setting, searchlist, actions, columns, loadingview, viewlost, setsingle, pickup, isLinkMain, config } = this.state
    const { view, setting, searchlist, actions, columns, loadingview, viewlost, pickup, config } = this.state
    return (
      <div>
        {view === 'commontable' ? <div className={'commontable ' + (isLinkMain ? 'pick-control' : '')} id={this.state.ContainerId}>
        {view === 'commontable' ? <div className="commontable pick-control" id={this.state.ContainerId}>
          {loadingview && <Spin size="large" />}
          {searchlist && searchlist.length > 0 ?
            <MainSearch
@@ -904,18 +960,15 @@
          }
          {columns && setting.onload !== 'false' ?
            <div className="main-table-box">
              {isLinkMain ?
                <div className="pickchange">
                  {setting.tableType === 'checkbox' ? <Switch title="单选切换" checkedChildren="单" unCheckedChildren="多" defaultChecked={setsingle} onChange={this.checkChange} /> : null}
                  {this.state.BIDs.mainTable && (setting.tableType === 'radio' || setsingle) ? <Switch title="收起" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null}
                </div> : null
              <Icon className="custom-control" type="setting" onClick={this.controlCustomSetting} />
              {this.state.data && this.state.data.length > 0 ?
                <Switch title="收起" className="main-pickup" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null
              }
              <MainTable
                ref="mainTable"
                pickup={pickup}
                setting={setting}
                columns={columns}
                setsingle={setsingle}
                dict={this.state.dict}
                data={this.state.data}
                total={this.state.total}
@@ -1010,6 +1063,25 @@
              {this.getTreeNode(config.funcs)}
            </Tree> : null}
          </Modal>
          {/* 按钮使用系统存储过程时,验证信息模态框 */}
          <Modal
            wrapClassName="common-table-custom-modal"
            title={'自定义设置'}
            maskClosable={false}
            width={850}
            visible={this.state.settingVisible}
            onOk={this.settingSubmit}
            onCancel={() => { this.setState({ settingVisible: false }) }}
            confirmLoading={this.state.confirmLoading}
            destroyOnClose
          >
            {this.state.config ?
              <VerifyCard
                config={this.state.config}
                wrappedComponentRef={(inst) => this.verifyRef = inst}
              /> : null
            }
          </Modal>
          {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
        </div> : null}
        {view === 'formtab' ? <FormTab MenuID={this.state.tabBtn.uuid} param={this.state.tabParam} refresh={this.refreshbyformtab}/> : null}
src/tabviews/commontable/index.scss
@@ -50,16 +50,20 @@
  }
  .main-table-box {
    position: relative;
    .pickchange {
    .main-pickup {
      position: absolute;
      right: 0px;
      right: 20px;
      top: -25px;
      .ant-switch {
        z-index: 1;
        float: right;
        margin-right: 20px;
        margin-bottom: 5px;
      }
      z-index: 1;
    }
    .custom-control {
      position: absolute;
      z-index: 1;
      right: 20px;
      top: -55px;
      font-size: 16px;
      padding: 3px;
      cursor: pointer;
    }
  }
  > .ant-tabs {
@@ -106,4 +110,31 @@
      cursor: default;
    }
  }
}
.common-table-custom-modal {
  .ant-modal {
    top: 50px;
    padding-bottom: 5px;
    .ant-modal-body {
      max-height: calc(100vh - 190px);
      overflow-y: auto;
      .ant-empty {
        margin: 15vh 8px;
      }
    }
    .ant-modal-body::-webkit-scrollbar {
      width: 7px;
    }
    .ant-modal-body::-webkit-scrollbar-thumb {
      border-radius: 5px;
      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
      background: rgba(0, 0, 0, 0.13);
    }
    .ant-modal-body::-webkit-scrollbar-track {
      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
      border-radius: 3px;
      border: 1px solid rgba(0, 0, 0, 0.07);
      background: rgba(0, 0, 0, 0);
    }
  }
}
src/tabviews/commontable/mainTable/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
// import { is, fromJS } from 'immutable'
import { Table, message, Affix, Button, Typography } from 'antd'
import './index.scss'
@@ -12,7 +12,6 @@
    MenuID: PropTypes.string,      // 菜单Id
    setting: PropTypes.object,     // 表格全局设置:tableType(表格是否可选、单选、多选)、columnfixed(列固定)、actionfixed(按钮固定)
    pickup: PropTypes.any,         // 数据收起
    setsingle: PropTypes.any,      // 设置单选多选
    columns: PropTypes.array,      // 表格列
    data: PropTypes.any,           // 表格数据
    total: PropTypes.number,       // 总数
@@ -26,13 +25,11 @@
    selectedRowKeys: [],  // 表格中选中行
    pageIndex: 1,         // 初始页面索引
    pageSize: 10,         // 每页数据条数
    columns: null,        // 显示列
    selectId: '',
    isSingleSelect: false
    columns: null         // 显示列
  }
  UNSAFE_componentWillMount () {
    const { columns, setting } = this.props
    const { columns } = this.props
    let _columns = []
    
    columns.forEach(item => {
@@ -50,19 +47,8 @@
    })
    this.setState({
      columns: _columns,
      isSingleSelect: setting.tableType === 'radio'
      columns: _columns
    })
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (!is(fromJS(this.props.setsingle), fromJS(nextProps.setsingle))) {
      this.setState({
        isSingleSelect: nextProps.setsingle,
        selectedRowKeys: [],
        selectId: ''
      })
    }
  }
  getContent = (item, record) => {
@@ -247,8 +233,6 @@
  }
  onSelectChange = selectedRowKeys => {
    if (this.props.pickup) return
    let index = ''
    if (selectedRowKeys.length > 0) {
      index = selectedRowKeys[selectedRowKeys.length - 1]
@@ -266,7 +250,7 @@
    let newkeys = JSON.parse(JSON.stringify(this.state.selectedRowKeys))
    let _re = newkeys.includes(index)
    if (this.props.setting.tableType === 'radio' || this.state.isSingleSelect) {
    if (this.props.setting.tableType === 'radio') {
      this.changedata(index)
      this.setState({ selectedRowKeys: [index] })
    } else {
@@ -301,30 +285,25 @@
      _data = data[index] || ''
    }
    this.setState({
      selectId: _id
    })
    this.props.handleTableId('mainTable', _id, _data)
  }
  resetTable = () => {
    this.setState({
      pageIndex: 1,
      selectId: '',
      selectedRowKeys: []
    })
  }
  render() {
    const { setting, pickup } = this.props
    let { selectedRowKeys, isSingleSelect, selectId } = this.state
    let { selectedRowKeys } = this.state
    let rowSelection = null
    if (setting.tableType) {
      rowSelection = {
        selectedRowKeys,
        type: (setting.tableType === 'radio' || isSingleSelect) ? 'radio' : 'checkbox',
        type: (setting.tableType === 'radio') ? 'radio' : 'checkbox',
        onChange: this.onSelectChange
      }
    }
@@ -345,8 +324,8 @@
    let _data = this.props.data ? this.props.data : []
    if (selectId && pickup && isSingleSelect) {
      _data = _data.filter(item => item[setting.primaryKey] === selectId)
    if (pickup) {
      _data = _data.filter((item, index) => selectedRowKeys.includes(index))
    }
    return (
src/tabviews/subtable/index.jsx
@@ -682,9 +682,6 @@
            gettableselected={this.gettableselected}
          />
        }
        {/* {this.state.data && this.state.data.length > 0 ?
          <Switch title="收起" className="subtable-pickup" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null
        } */}
        {columns ?
          <div className="subtable-box">
            {this.state.data && this.state.data.length > 0 ?
src/tabviews/tableshare/actionList/index.jsx
@@ -11,6 +11,7 @@
import './index.scss'
const { confirm } = Modal
let socket = null
class MainAction extends Component {
  static propTpyes = {
@@ -185,7 +186,25 @@
      if (item.funcType === 'changeuser') {
        this.changeUser(item, data)
      } else if (item.funcType === 'print') {
        this.triggerPrint(item, data)
        if (item.execMode === 'pop') {
          this.setState({
            execAction: item,
            tabledata: data,
            btnloading: true
          }, () => {
            this.improveAction(item)
          })
        } else if (item.execMode === 'prompt') {
          confirm({
            title: this.props.dict['main.action.confirm.tip'],
            onOk() {
              _this.triggerPrint(item, data)
            },
            onCancel() {}
          })
        } else {
          this.triggerPrint(item, data)
        }
      }
    } else {
      notification.warning({
@@ -199,8 +218,10 @@
  /**
   * @description 触发打印
   */
  triggerPrint = (item, data) => {
  triggerPrint = (item, data, formdata) => {
    console.log(item)
    console.log(data)
    console.log(formdata)
    if (!item.verify || !item.verify.Template || !item.verify.linkUrl) {
      notification.warning({
        top: 92,
@@ -224,7 +245,33 @@
      Api.getLocalConfig(param).then(res => {
        if (res.status) {
          resolve(res)
          if (!res.ConfigParam) {
            notification.warning({
              top: 92,
              message: '未获取到打印模板信息!',
              duration: 15
            })
            resolve(false)
          } else {
            let configParam = ''
            try {
              configParam = JSON.parse(window.decodeURIComponent(window.atob(res.ConfigParam)))
            } catch (e) {
              configParam = ''
            }
            if (!configParam) {
              notification.warning({
                top: 92,
                message: '打印模板解析错误!',
                duration: 15
              })
            } else {
              resolve(configParam)
            }
          }
        } else {
          this.execError(res, item)
          resolve(false)
@@ -233,7 +280,87 @@
    }).then(res => {
      console.log(res)
      if (!res) return
      if (!socket || socket.readyState !== 1 || socket.url !== 'ws://' + item.verify.linkUrl) {
        socket = new WebSocket('ws://' + item.verify.linkUrl)
      }
      // 打开Socket
      socket.onopen = () =>{
        if (!item.printer) {
          let request  = {
            requestID: '',
            version: '',
            cmd: 'getPrinters'
          }
          socket.send(JSON.stringify(request))
        } else {
          let printdata = {
            cmd: 'print',
            requestID: '',
            version: '',
            task: {
              taskID: '1',
              preview: false,
              printer: item.printer,
              documents: [
                {
                  documentID: '9890000106027',
                  contents: [
                    {
                      data: {
                        barcode: '12345'
                      },
                      templateURL: '{"Version":"","Title":"1234","Author":"U000000001","Description":"","PrintTempNO":"","PageSetting":{"Width":210,"Height":297,"Left":"0","Right":"0","Top":"0","Bottom":"0","Landscape":false},"PageHeader":[],"ReportHeader":{"Control":[{"Name":"","Type":"barcode","Value":"","Field":"barcode","Left":71,"Top":32,"Width":52,"Height":26,"Rotate":0,"BorderSize":0.1,"BorderColor":"black","Align":"center","VerticalAlign":"middle","BackColor":"white","ForeColor":"black","BarcodeType":"code128","BarcodeWidth":31,"BarcodeHeight":10,"BarcodeLabel":true,"LabelSize":12}]},"ReportFooter":[],"PageFooter":[]}'
                    }
                  ]
                }
              ]
            }
          }
          socket.send(JSON.stringify(printdata))
        }
      }
      // 监听消息
      socket.onmessage = (event) => {
        let data = JSON.parse(event.data)
        if (data.defaultPrinter) {
          let printdata = {
            cmd: 'print',
            requestID: '',
            version: '',
            task: {
              taskID: '1',
              preview: false,
              printer: data.defaultPrinter,
              documents: [
                {
                  documentID: '9890000106027',
                  contents: [
                    {
                      data: {
                        barcode: '12345'
                      },
                      templateURL: '{"Version":"","Title":"1234","Author":"U000000001","Description":"","PrintTempNO":"","PageSetting":{"Width":210,"Height":297,"Left":"0","Right":"0","Top":"0","Bottom":"0","Landscape":false},"PageHeader":[],"ReportHeader":{"Control":[{"Name":"","Type":"barcode","Value":"","Field":"barcode","Left":71,"Top":32,"Width":52,"Height":26,"Rotate":0,"BorderSize":0.1,"BorderColor":"black","Align":"center","VerticalAlign":"middle","BackColor":"white","ForeColor":"black","BarcodeType":"code128","BarcodeWidth":31,"BarcodeHeight":10,"BarcodeLabel":true,"LabelSize":12}]},"ReportFooter":[],"PageFooter":[]}'
                    }
                  ]
                }
              ]
            }
          }
          socket.send(JSON.stringify(printdata))
        }
      }
      socket.onerror = () => {
        notification.warning({
          top: 92,
          message: '无法连接到:' + item.verify.linkUrl,
          duration: 10
        })
      }
    })
@@ -309,6 +436,14 @@
  execSubmit = (btn, data, _resolve, formdata) => {
    const { setting, logcolumns } = this.props
    if (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop') {
      this.setState({
        confirmLoading: false,
        visible: false
      })
      this.triggerPrint(btn, data, formdata)
      return
    }
    if (btn.intertype === 'inner') {
      // 使用内部接口时,内部函数和数据源不可同时为空, 使用系统函数时,类型不可为空
      if (!btn.innerFunc && (!btn.sql || (btn.sql && !btn.sqlType))) {
src/tabviews/tableshare/topSearch/index.jsx
@@ -172,7 +172,7 @@
      if (item.type === 'text') { // 文本搜索
        fields.push(
          <Col span={6} key={index}>
          <Col span={item.ratio || 6} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.field, {initialValue: item.initval })(<Input placeholder="" autoComplete="off" />)}
            </Form.Item>
@@ -180,7 +180,7 @@
        )
      } else if (item.type === 'select') { // 下拉搜索
        fields.push(
          <Col span={6} key={index}>
          <Col span={item.ratio || 6} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.field, {initialValue: item.initval })(
                <Select
@@ -200,7 +200,7 @@
      } else if (item.type === 'multiselect') { // 下拉多选
        let _initval = item.initval ? item.initval.split(',').filter(Boolean) : []
        fields.push(
          <Col span={6} key={index}>
          <Col span={item.ratio || 6} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.field, {initialValue: _initval })(
                <Select
@@ -220,7 +220,7 @@
        )
      } else if (item.type === 'date') { // 时间搜索
        fields.push(
          <Col span={6} key={index}>
          <Col span={item.ratio || 6} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.field, {initialValue: item.initval ? moment().subtract(item.initval, 'days') : null })(
                <DatePicker onChange={this.searchChange} getCalendarContainer={() => document.getElementById(this.state.formId)} />
@@ -230,7 +230,7 @@
        )
      } else if (item.type === 'datemonth') {
        fields.push(
          <Col span={6} key={index}>
          <Col span={item.ratio || 6} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.field, {initialValue: item.initval ? moment().subtract(item.initval, 'month') : null })(
                <MonthPicker onChange={this.searchChange} getCalendarContainer={() => document.getElementById(this.state.formId)} />
@@ -240,7 +240,7 @@
        )
      } else if (item.type === 'dateweek') {
        fields.push(
          <Col span={6} key={index}>
          <Col span={item.ratio || 6} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.field, {initialValue: item.initval ? moment().subtract(item.initval * 7, 'days') : null })(
                <WeekPicker onChange={this.searchChange} getCalendarContainer={() => document.getElementById(this.state.formId)} />
@@ -261,7 +261,7 @@
        }
        fields.push(
          <Col className="daterange" span={6} key={index}>
          <Col className="daterange" span={item.ratio || 6} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.field,
                {
@@ -280,29 +280,18 @@
      }
    })
    if (this.props.searchlist.length >= 4) { // 添加搜索、重置按钮
      fields.push(
        <Col span={this.props.searchlist.length % 4 ? 6 : 24} style={{paddingLeft: '112px', whiteSpace: 'nowrap'}} key="actions">
    fields.push(
      <Col span={6} style={{ whiteSpace: 'nowrap' }} key="actions">
        <Form.Item label={' '} colon={false}>
          <Button type="primary" htmlType="submit">
            {this.props.dict['main.search']}
          </Button>
          <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
            {this.props.dict['main.reset']}
          </Button>
        </Col>
      )
    } else {
      fields.push(
        <Col span={6} style={{ paddingTop: '4px', whiteSpace: 'nowrap' }} key="actions">
          <Button type="primary" htmlType="submit">
            {this.props.dict['main.search']}
          </Button>
          <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
            {this.props.dict['main.reset']}
          </Button>
        </Col>
      )
    }
        </Form.Item>
      </Col>
    )
    
    return fields
  }
@@ -402,8 +391,19 @@
  }
  render() {
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    return (
      <Form className="ant-advanced-search-form top-search" id={this.state.formId} onSubmit={this.handleSearch}>
      <Form {...formItemLayout} className="ant-advanced-search-form top-search" id={this.state.formId} onSubmit={this.handleSearch}>
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
src/tabviews/tableshare/topSearch/index.scss
@@ -10,7 +10,7 @@
    width: calc(100% - 100px);
  }
  .ant-form-item-label {
    width: 100px;
    // width: 100px;
    text-overflow: ellipsis;
  }
  .daterange .ant-calendar-picker-input {
src/tabviews/tableshare/verifycard/actionform/index.jsx
New file
@@ -0,0 +1,188 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Select, Button, Input } from 'antd'
import './index.scss'
class UniqueForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,       // 字典项
    actionChange: PropTypes.func  // 修改函数
  }
  state = {
    editItem: null, // 编辑元素
    shortcut: ''
  }
  edit = (record) => {
    this.setState({
      editItem: record,
      shortcut: record.shortcut || ''
    }, () => {
      let item = {
        label: record.label,
        shortcut: record.shortcut
      }
      if (record.shortcut) {
        item.shortcutkey = record.shortcutkey
      }
      if (record.OpenType === 'funcbutton' && record.funcType === 'print') {
        item.printer = record.printer || ''
      }
      this.props.form.setFieldsValue(item)
    })
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        values.uuid = this.state.editItem ? this.state.editItem.uuid : ''
        this.props.actionChange(values)
        this.setState({
          editItem: null,
          shortcut: ''
        }, () => {
          this.props.form.setFieldsValue({
            shortcut: '',
            label: ''
          })
        })
      }
    })
  }
  shortcutChange = (value) => {
    this.setState({
      shortcut: value
    })
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const { editItem } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    let hasprint = editItem && editItem.OpenType === 'funcbutton' && editItem.funcType === 'print'
    return (
      <Form {...formItemLayout} className="verify-form" id="verifycard1">
        <Row gutter={24}>
          <Col span={7}>
            <Form.Item label={'名称'}>
              {getFieldDecorator('label', {
                initialValue: '',
              })(<Input placeholder="" autoComplete="off" disabled />)}
            </Form.Item>
          </Col>
          {hasprint ?
            <Col span={7}>
              <Form.Item label={'打印机'}>
                {getFieldDecorator('printer', {
                  initialValue: '',
                  rules: [
                    {
                      required: true,
                      message: '请选择打印机!'
                    }
                  ]
                })(
                  <Select>
                    {editItem.printers && editItem.printers.map(option =>
                      <Select.Option id={option.value} title={option.text} key={option.value} value={option.value}>{option.text}</Select.Option>
                    )}
                  </Select>
                )}
              </Form.Item>
            </Col> : null
          }
          <Col span={7}>
            <Form.Item label={'快捷键'}>
              {getFieldDecorator('shortcut', {
                initialValue: ''
              })(
                <Select onChange={(value) => {this.shortcutChange(value)}}>
                  <Select.Option value=""> 空 </Select.Option>
                  <Select.Option value="shift"> shift </Select.Option>
                  <Select.Option value="ctrl"> ctrl </Select.Option>
                  <Select.Option value="alt"> alt </Select.Option>
                </Select>
              )}
            </Form.Item>
          </Col>
          {hasprint ? <Col span={3} className="add">
            <Button onClick={this.handleConfirm} type="primary" className="add-row">
              确定
            </Button>
          </Col> : null}
          {this.state.shortcut ?
            <Col span={7}>
              <Form.Item label={'组合键'}>
                {getFieldDecorator('shortcutkey', {
                  initialValue: '',
                  rules: [
                    {
                      required: true,
                      message: '请选择组合键!'
                    }
                  ]
                })(
                  <Select>
                    <Select.Option value=""> 空 </Select.Option>
                    {this.state.shortcut !== 'alt' ? <Select.Option value={65}> A </Select.Option> : null}
                    <Select.Option value={66}> B </Select.Option>
                    {this.state.shortcut !== 'ctrl' ? <Select.Option value={67}> C </Select.Option> : null}
                    <Select.Option value={68}> D </Select.Option>
                    <Select.Option value={69}> E </Select.Option>
                    <Select.Option value={70}> F </Select.Option>
                    <Select.Option value={71}> G </Select.Option>
                    <Select.Option value={72}> H </Select.Option>
                    <Select.Option value={73}> I </Select.Option>
                    <Select.Option value={74}> J </Select.Option>
                    <Select.Option value={75}> K </Select.Option>
                    <Select.Option value={76}> L </Select.Option>
                    <Select.Option value={77}> M </Select.Option>
                    <Select.Option value={78}> N </Select.Option>
                    <Select.Option value={79}> O </Select.Option>
                    <Select.Option value={80}> P </Select.Option>
                    <Select.Option value={81}> Q </Select.Option>
                    <Select.Option value={82}> R </Select.Option>
                    <Select.Option value={83}> S </Select.Option>
                    <Select.Option value={84}> T </Select.Option>
                    <Select.Option value={85}> U </Select.Option>
                    {this.state.shortcut !== 'ctrl' ? <Select.Option value={86}> V </Select.Option> : null}
                    <Select.Option value={87}> W </Select.Option>
                    <Select.Option value={88}> X </Select.Option>
                    <Select.Option value={89}> Y </Select.Option>
                    <Select.Option value={90}> Z </Select.Option>
                  </Select>
                )}
              </Form.Item>
            </Col> : null
          }
          {!hasprint ? <Col span={3} className="add">
            <Button onClick={this.handleConfirm} type="primary" className="add-row">
              确定
            </Button>
          </Col> : null}
        </Row>
      </Form>
    )
  }
}
export default Form.create()(UniqueForm)
src/tabviews/tableshare/verifycard/actionform/index.scss
src/tabviews/tableshare/verifycard/index.jsx
New file
@@ -0,0 +1,368 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Tabs, Row, Col, Radio, Table, Icon, Select, notification } from 'antd'
import Utils from '@/utils/utils.js'
import ActionForm from './actionform'
import './index.scss'
const { TabPane } = Tabs
const keycode = {
  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 VerifyCard extends Component {
  static propTpyes = {
    config: PropTypes.object     // 页面配置
  }
  state = {
    colColumns: [
      {
        title: '字段名',
        dataIndex: 'field',
        width: '35%'
      },
      {
        title: '操作',
        align: 'center',
        width: '25%',
        dataIndex: 'operation',
        render: (text, record) =>
          (<div>
            <span className="operation-btn" title="编辑" onClick={() => this.handleEdit(record, 'column')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
            <span className="operation-btn" title="上移" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
            <span className="operation-btn" title="下移" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
            <span className="operation-btn" title="状态切换" onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><Icon type="swap" /></span>
          </div>)
      }
    ],
    actionColumns: [
      {
        title: '名称',
        dataIndex: 'label',
        width: '20%'
      },
      {
        title: '快捷键',
        dataIndex: 'shortcut',
        width: '20%'
      },
      {
        title: '组合键',
        dataIndex: 'shortcutkey',
        width: '20%',
        render: (text, record) => keycode[text] || ''
      },
      {
        title: '打印机',
        dataIndex: 'printer',
        width: '20%'
      },
      {
        title: '操作',
        align: 'center',
        width: '20%',
        dataIndex: 'operation',
        render: (text, record) =>
          (<div>
            <span className="operation-btn" title="编辑" onClick={() => this.handleEdit(record, 'action')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
          </div>)
      }
    ]
  }
  UNSAFE_componentWillMount() {
    const { config } = this.props
    this.setState({
      config: JSON.parse(JSON.stringify(config))
    })
  }
  componentDidMount() {
    let printbtns = this.state.config.action.filter(item => item.OpenType === 'funcbutton' && item.funcType === 'print')
    printbtns.forEach(item => {
      if (!item.verify || !item.verify.linkUrl) {
        notification.warning({
          top: 92,
          message: '打印按钮《' + item.label + '》设置错误!',
          duration: 10
        })
      } else {
        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 = JSON.parse(event.data)
          if (data.defaultPrinter) {
            let printers = Array.from(new Set(data.printers))
            let _config = JSON.parse(JSON.stringify(this.state.config))
            _config.action = _config.action.map(cell => {
              if (item.uuid === cell.uuid) {
                cell.printer = cell.printer || data.defaultPrinter
                cell.printers = printers.map(print => {
                  return {
                    value: print,
                    text: print
                  }
                })
              }
              return cell
            })
            this.setState({
              config: _config
            })
          }
        }
        socket.onerror = () => {
          notification.warning({
            top: 92,
            message: '无法连接到:' + item.verify.linkUrl,
            duration: 10
          })
        }
      }
    })
  }
  columnChange = (values) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    if (values.uuid) {
      verify.uniques = verify.uniques.map(item => {
        if (item.uuid === values.uuid) {
          return values
        } else {
          return item
        }
      })
    } else {
      values.uuid = Utils.getuuid()
      verify.uniques.push(values)
    }
    this.setState({
      verify: verify
    })
  }
  actionChange = (values) => {
    let config = JSON.parse(JSON.stringify(this.state.config))
    config.action = config.action.map(item => {
      if (values.uuid === item.uuid) {
        item = {...item, ...values}
      }
      return item
    })
    this.setState({
      config: config
    })
  }
  handleEdit = (record, type) => {
    if (type === 'action') {
      this.actionForm.edit(record)
    } else if (type === 'column') {
      this.uniqueForm.edit(record)
    }
    let node = document.getElementById('verify-card-box-tab').parentNode
    if (node && node.scrollTop) {
      node.scrollTop = 0
    }
  }
  handleStatus = (record) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    record.status = record.status === 'false' ? 'true' : 'false'
    verify.scripts = verify.scripts.map(item => {
      if (item.uuid === record.uuid) {
        return record
      } else {
        return item
      }
    })
    this.setState({
      verify: verify
    })
  }
  handleUpDown = (record, type, direction) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    let index = 0
    verify.customverifys = verify.customverifys.filter((item, i) => {
      if (item.uuid === record.uuid) {
        index = i
      }
      return item.uuid !== record.uuid
    })
    if ((index === 0 && direction === 'up') || (index === verify.customverifys.length && direction === 'down')) {
      return
    }
    if (direction === 'up') {
      verify.customverifys.splice(index - 1, 0, record)
    } else {
      verify.customverifys.splice(index + 1, 0, record)
    }
    this.setState({
      verify: verify
    })
  }
  handleConfirm = () => {
    const { config } = this.state
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          let _config = {}
          _config.setting = values
          _config.action = config.action.map(item => {
            return {
              uuid: item.uuid,
              shortcut: item.shortcut || '',
              shortcutkey: item.shortcutkey || '',
              printer: item.printer || ''
            }
          })
          resolve(_config)
        }
      })
    })
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const { actionColumns, config } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    return (
      <div id="verify-card-box-tab">
        <Tabs defaultActiveKey="1" className="verify-card-box">
          <TabPane tab="基础设置" key="1">
            <Form {...formItemLayout}>
              <Row gutter={24}>
                <Col span={8}>
                  <Form.Item label="固定按钮">
                    {getFieldDecorator('actionfixed', {
                      initialValue: config.setting.actionfixed ? 'true' : 'false'
                    })(
                      <Radio.Group>
                        <Radio value="true">是</Radio>
                        <Radio value="false">否</Radio>
                      </Radio.Group>
                    )}
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label="固定表头">
                    {getFieldDecorator('columnfixed', {
                      initialValue: config.setting.columnfixed ? 'true' : 'false'
                    })(
                      <Radio.Group>
                        <Radio value="true">是</Radio>
                        <Radio value="false">否</Radio>
                      </Radio.Group>
                    )}
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label="表格属性">
                    {getFieldDecorator('tableType', {
                      initialValue: config.setting.tableType || 'checkbox'
                    })(
                      <Select>
                        <Select.Option value="">不可选</Select.Option>
                        <Select.Option value="radio">单选</Select.Option>
                        <Select.Option value="checkbox">多选</Select.Option>
                      </Select>
                    )}
                  </Form.Item>
                </Col>
              </Row>
            </Form>
          </TabPane>
          <TabPane tab="按钮设置" key="action">
            <ActionForm
              dict={this.props.dict}
              actionChange={this.actionChange}
              wrappedComponentRef={(inst) => this.actionForm = inst}
            />
            <Table
              bordered
              rowKey="uuid"
              className="custom-table"
              dataSource={config.action}
              columns={actionColumns}
              pagination={false}
            />
          </TabPane>
        </Tabs>
      </div>
    )
  }
}
export default Form.create()(VerifyCard)
src/tabviews/tableshare/verifycard/index.scss
New file
@@ -0,0 +1,53 @@
.verify-card-box {
  .ant-tabs-nav-scroll {
    text-align: center;
  }
  .ant-tabs-content {
    min-height: 40vh;
  }
  table tr td {
    word-wrap: break-word;
    word-break: break-word;
  }
  .verify-form {
    .ant-input-number {
      width: 100%;
    }
    .sql {
      .ant-col-sm-8 {
        width: 10.5%;
      }
      .ant-col-sm-16 {
        width: 89.5%;
        padding-top: 4px;
      }
    }
    .sqlfield {
      .ant-form-item {
        margin-bottom: 5px;
      }
      .ant-col-sm-8 {
        width: 10.5%;
      }
      .ant-col-sm-16 {
        width: 89.5%;
      }
    }
    .add {
      padding-top: 4px;
    }
  }
  .custom-table .ant-empty {
    margin: 20px 8px!important;
  }
  .errorval {
    display: inline-block;
    width: 30px;
  }
  .operation-btn {
    display: inline-block;
    font-size: 16px;
    padding: 0 5px;
    cursor: pointer;
  }
}
src/templates/comtableconfig/index.scss
@@ -199,7 +199,7 @@
            display: flex;
            margin-bottom: 0px;
            .ant-form-item-label {
              width: 100px;
              // width: 100px;
              height: 40px;
              label {
                width: 100%;
src/templates/comtableconfig/settingform/index.jsx
@@ -295,7 +295,6 @@
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="固定表头">
              {getFieldDecorator('columnfixed', {
src/templates/subtableconfig/index.scss
@@ -199,7 +199,7 @@
            display: flex;
            margin-bottom: 0px;
            .ant-form-item-label {
              width: 100px;
              // width: 100px;
              height: 40px;
              label {
                width: 100%;
src/templates/tableshare/dragelement/card.jsx
@@ -89,10 +89,10 @@
      <div ref={node => drag(drop(node))}>
        {type === 'search' ?
          <div className="ant-row ant-form-item">
            <div className="ant-col ant-form-item-label">
            <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8">
              <label title={card.label}>{card.label}</label>
            </div>
            <div className="ant-col ant-form-item-control-wrapper">
            <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16">
              {card.type === 'text' ?
                <Input style={{marginTop: '4px'}} defaultValue={card.initval} /> : null
              }
src/templates/tableshare/dragelement/index.jsx
@@ -218,7 +218,7 @@
        />
      ))}
      {type === 'search' && cards.map(card => (
        <Col key={card.uuid} span={6}>
        <Col key={card.uuid} span={card.ratio || 6}>
          <Card
            id={`${card.uuid}`}
            type={type}
src/templates/tableshare/formconfig.js
@@ -205,6 +205,16 @@
      }]
    },
    {
      type: 'number',
      key: 'ratio',
      min: 1,
      max: 24,
      label: Formdict['header.form.ratio'],
      tooltip: '每行分为24份,比例可设置为1-24',
      initVal: card.ratio,
      required: false
    },
    {
      type: 'select',
      key: 'quick',
      label: Formdict['header.form.quickadd'],
src/templates/tableshare/searchform/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Select, Icon, Radio, notification, Tooltip } from 'antd'
import { Form, Row, Col, Input, Select, Icon, Radio, notification, Tooltip, InputNumber } from 'antd'
import { dateOptions, matchReg, formRule } from '@/utils/option.js'
import EditTable from '../editable'
import './index.scss'
@@ -32,7 +32,7 @@
    let type = formlist.filter(cell => cell.key === 'type')[0].initVal
    let resourceType = formlist.filter(cell => cell.key === 'resourceType')[0].initVal
    let _options = ['label', 'field', 'initval', 'type', 'match']                // 默认显示项
    let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio']                // 默认显示项
    if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '0') {        // 下拉选择类型、选项为自定义资源
      _options = [..._options, 'resourceType', 'options', 'display', 'quick']
@@ -104,7 +104,7 @@
    const { resourceType } = this.state
    if (key === 'type') {
      let _options = ['label', 'field', 'initval', 'type', 'match']
      let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio']
      if ((value === 'multiselect' || value === 'select' || value === 'link') && resourceType === '0') {        // 下拉选择类型、选项为自定义资源
        _options = [..._options, 'resourceType', 'options', 'display', 'quick']
@@ -189,7 +189,7 @@
    let value = e.target.value
    if (key === 'resourceType') {
      let _options = ['label', 'field', 'initval', 'type', 'match', 'resourceType', 'display']
      let _options = ['label', 'field', 'initval', 'type', 'match', 'resourceType', 'display', 'ratio']
      if (value === '0') {
        _options = [..._options, 'options', 'quick']
@@ -267,6 +267,27 @@
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'number') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || 6,
                rules: [
                  {
                    required: item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<InputNumber min={item.min} max={item.max} precision={0} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') { // 下拉搜索
        fields.push(
          <Col span={12} key={index}>
src/templates/tableshare/searchform/index.scss
@@ -15,4 +15,7 @@
    position: relative;
    left: -3px;
  }
  .ant-input-number {
    width: 100%;
  }
}
src/templates/tableshare/verifycard/index.jsx
@@ -1002,7 +1002,7 @@
    return (
      <div id="verify-card-box-tab">
        <Tabs defaultActiveKey="1" className="verify-card-box" onChange={this.tabchange}>
        <Tabs defaultActiveKey="1" className="verify-card-box">
          <TabPane tab="基础验证" key="1">
            <Form {...formItemLayout}>
              <Row gutter={24}>
src/views/login/index.jsx
@@ -56,45 +56,44 @@
  async loginsubmit (param) {
    // 登录提交
    // let password = this.md5Password(param.password)
    let result = await Api.loginsystem(param.username, param.password)
    if (!result.IsError) {
      Api.getusermsg(param.username, param.password).then(res => {
        if (res.status) {
          sessionStorage.setItem('UserID', res.UserID)
          sessionStorage.setItem('SessionUid', Utils.getuuid())
          sessionStorage.setItem('LoginUID', res.LoginUID)
          sessionStorage.setItem('User_Name', res.UserName)
          sessionStorage.setItem('avatar', res.icon || '')
          localStorage.setItem('lang', param.lang)
    // let result = await Api.loginsystem(param.username, param.password)
    // if (!result.IsError) {
    let res = await Api.getusermsg(param.username, param.password)
    if (res.status) {
      sessionStorage.setItem('UserID', res.UserID)
      sessionStorage.setItem('SessionUid', Utils.getuuid())
      sessionStorage.setItem('LoginUID', res.LoginUID)
      sessionStorage.setItem('User_Name', res.UserName)
      sessionStorage.setItem('avatar', res.icon || '')
      localStorage.setItem('lang', param.lang)
          let _url = window.location.href.split('#')[0]
      let _url = window.location.href.split('#')[0]
          if (param.remember) { // 记住密码时账号密码存入localStorage
            localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify({username: param.username, password: param.password}))))
          } else {
            localStorage.removeItem(_url)
          }
          if (this.props.location.state && this.props.location.state.from.pathname) {
            // 查看是否为其他页面跳转,路径存在时,跳回原页面
            this.props.history.replace(this.props.location.state.from.pathname)
          } else {
            this.props.history.replace('/main')
          }
        } else {
          message.warning(res.message)
          this.setState({
            isDisabled: false
          })
        }
      })
      if (param.remember) { // 记住密码时账号密码存入localStorage
        localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify({username: param.username, password: param.password}))))
      } else {
        localStorage.removeItem(_url)
      }
      if (this.props.location.state && this.props.location.state.from.pathname) {
        // 查看是否为其他页面跳转,路径存在时,跳回原页面
        this.props.history.replace(this.props.location.state.from.pathname)
      } else {
        this.props.history.replace('/main')
      }
    } else {
      message.warning(result.Message)
      message.warning(res.message)
      this.setState({
        isDisabled: false
      })
    }
    // } else {
    //   message.warning(result.Message)
    //   this.setState({
    //     isDisabled: false
    //   })
    // }
  }
  componentDidMount () {
src/views/printTemplate/dragelement/index.scss
@@ -12,6 +12,8 @@
  }
}
.print-area {
  position: relative;
  z-index: 2;
  display: inline-block;
  margin: 0 auto;
  margin-right: 30px;
src/views/printTemplate/index.jsx
@@ -47,10 +47,11 @@
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
    let screenX = e.clientX
    let screenY = e.clientY + scrollTop
    let offsetT = screenY - document.getElementById('darea').offsetTop
    let offsetL = screenX - document.getElementById('darea').offsetLeft
    let cx = Math.floor(offsetL / parseInt(document.getElementById('darea').style.width) * config.width)
    let offsetT = screenY - 75
    let _width = parseInt(document.getElementById('darea').style.width)
    let offsetL = screenX - (document.body.offsetWidth - _width - 30) / 2
    let cx = Math.floor(offsetL / _width * config.width)
    let cy = Math.floor(offsetT / parseInt(document.getElementById('darea').style.height) * config.height)
    return {
@@ -104,10 +105,11 @@
          y -= 4
          height = 8
        }
        if (cx > x && cx < x + width && cy > y && cy < y + height) {
        if (cx >= x && cx <= x + width && cy >= y && cy <= y + height) {
          _selectItem = element
        }
      })
      if (!_selectItem) {
        _selectItem = _config
      } else {
@@ -298,7 +300,14 @@
    document.getElementById('darea').addEventListener('drop', (e) => {
      dropPoint = this.getclickpoint(e)
    })
    this.handleResize()
    window.addEventListener('resize', this.handleResize)
    this.loadconfig()
  }
  handleResize = () => {
    if (document.body.offsetWidth < 1360) {
      document.getElementById('darea').style.width = '600px'
    } else if (document.body.offsetWidth < 1500) {
@@ -306,8 +315,6 @@
    } else if (document.body.offsetWidth < 1920) {
      document.getElementById('darea').style.width = '800px'
    }
    this.loadconfig()
  }
  resetbox = () => {
@@ -381,6 +388,18 @@
        duration: 10
      })
    }
  }
  switchbox = () => {
    const { config } = this.state
    this.setState({
      editItemId: config.uuid,
      editItemType: config.type,
      formlist: getpageform(config)
    }, () => {
      this.resetview()
    })
  }
  /**
@@ -658,22 +677,21 @@
          if (result.status) {
            resolve(Utils.getcloudurl(result.Images))
          } else {
            // notification.warning({
            //   top: 92,
            //   message: result.ErrMesg,
            //   duration: 10
            // })
            // this.setState({
            //   saveloading: false
            // })
            // resolve(false)
            resolve(true)
            notification.warning({
              top: 92,
              message: result.ErrMesg,
              duration: 10
            })
            this.setState({
              saveloading: false
            })
            resolve(false)
          }
        })
      })
    }).then(res => {
      if (!res) return
      param.Images = 'http://css.positecgroup.com/Content/Upload/2020-01-08/2020010810525808769824_U000000001.png'
      param.Images = res
      return Api.getCloudConfig(param)
    }).then(res => {
@@ -710,6 +728,7 @@
              })}
            </Card>
          </aside>
          <div className="switchbox" onClick={this.switchbox}></div>
          <DragElement dropcard={this.dropcard} />
          <aside className="setting">
            {this.state.editItemId ?
src/views/printTemplate/index.scss
@@ -21,6 +21,7 @@
  .tools {
    width: 240px;
    position: fixed;
    z-index: 3;
    top: 47px;
    left: -1px;
    bottom: 0px;
@@ -42,6 +43,7 @@
  .setting {
    width: 300px;
    position: fixed;
    z-index: 3;
    top: 47px;
    right: -1px;
    bottom: 0px;
@@ -88,5 +90,11 @@
      margin-bottom: 10px;
    }
  }
  .switchbox {
    position: absolute;
    left: 240px;
    right: 300px;
    top: 48px;
    bottom: 0px;
  }
}