king
2020-02-28 888095418c902cc94693cba8b45f31bb79cdf818
2020-02-28
25个文件已修改
4个文件已添加
914 ■■■■ 已修改文件
src/api/index.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/comtable.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/comtable.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/formtab/formgroup/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/formtab/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtabtable/index.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/tableshare/actionList/index.jsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/actionform/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/dragelement/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/settingform/index.jsx 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/settingform/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/source.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/card.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.scss 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/formconfig.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/verifycard/index.jsx 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/verifycardprint/index.jsx 309 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/verifycardprint/index.scss 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/printTemplate/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/printTemplate/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js
@@ -162,6 +162,7 @@
    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('')
    param.sign  = md5(values)
    param.t = new Date().getTime()
src/locales/en-US/comtable.js
@@ -51,6 +51,7 @@
  'header.menu.datasource': '数据来源',
  'header.menu.maintable': '主表',
  'header.menu.query': '查询',
  'header.menu.printTemplate': '打印模板',
  'header.form.tabType': '标签类型',
  'header.form.search.placeholder': 'Please add search criteria',
  'header.form.modal.placeholder': 'Please add the form',
@@ -135,6 +136,7 @@
  'header.form.excelIn': 'Excel导入',
  'header.form.excelOut': 'Excel导出',
  'header.form.newpage': '新页面',
  'header.form.newpage.type': '页面类型',
  'header.form.newpage.inner': '新页面(内部)',
  'header.form.newpage.outer': '新页面(外部)',
  'header.form.newpage.url': '页面地址',
@@ -219,6 +221,7 @@
  'header.modal.search.edit': '搜索条件-编辑',
  'header.modal.action.edit': '按钮-编辑',
  'header.modal.action.copy': '按钮-复制',
  'header.modal.form.copy': '表单-复制',
  'header.modal.column.edit': '显示列-编辑',
  'header.modal.colspan.edit': '合并列-编辑',
  'header.modal.gridbtn.edit': '操作列-编辑',
src/locales/zh-CN/comtable.js
@@ -51,6 +51,7 @@
  'header.menu.datasource': '数据来源',
  'header.menu.maintable': '主表',
  'header.menu.query': '查询',
  'header.menu.printTemplate': '打印模板',
  'header.form.tabType': '标签类型',
  'header.form.search.placeholder': '请添加搜索条件',
  'header.form.modal.placeholder': '请添加表单',
@@ -135,6 +136,7 @@
  'header.form.excelIn': '导入Excel',
  'header.form.excelOut': '导出Excel',
  'header.form.newpage': '新页面',
  'header.form.newpage.type': '页面类型',
  'header.form.newpage.inner': '新页面(内部)',
  'header.form.newpage.outer': '新页面(外部)',
  'header.form.newpage.url': '页面地址',
@@ -219,6 +221,7 @@
  'header.modal.search.edit': '搜索条件-编辑',
  'header.modal.action.edit': '按钮-编辑',
  'header.modal.action.copy': '按钮-复制',
  'header.modal.form.copy': '表单-复制',
  'header.modal.column.edit': '显示列-编辑',
  'header.modal.colspan.edit': '合并列-编辑',
  'header.modal.gridbtn.edit': '操作列-编辑',
src/router/index.js
@@ -6,11 +6,13 @@
import asyncLoadComponent from '@/utils/asyncLoadComponent'
const main = asyncLoadComponent(() => import('@/views/main'))
const PrintTemplate = asyncLoadComponent(() => import('@/views/printTemplate'))
const login = asyncLoadComponent(() => import('@/views/login'))
const NotFound = asyncComponent(() => import('@/views/404'))
const routers = [
  {path: '/login', name: 'login', component: login, auth: false},
  {path: '/print/:param', name: 'print', component: PrintTemplate, auth: false},
  {path: '/ssologin/:param', name: 'ssologin', auth: true},
  {path: '/main', name: 'main', component: main, auth: true},
  {path: '/main/:param', name: 'pmain', component: main, auth: true}
src/tabviews/commontable/index.jsx
@@ -119,6 +119,28 @@
      //   config[group] = config[group].filter(tab => permAction[tab.uuid])
      // })
      let _actions = []     // 工具栏按钮
      let _operations = []  // 操作列按钮(存在时)
      config.action.forEach(item => {
        if (item.execMode) {
          item.OpenType = 'funcbutton'
        }
        if (item.position === 'toolbar') {
          _actions.push(item)
        } else if (item.position === 'grid') {
          _operations.push(item)
        }
      })
      if (config.gridBtn && config.gridBtn.display && _operations.length > 0) {
        _columns.push({
          ...config.gridBtn,
          operations: _operations
        })
      }
      // 1、筛选字段集,2、过滤隐藏列及合并列中的字段uuid
      config.columns.forEach(col => {
@@ -157,17 +179,6 @@
          _columns.push(col)
        }
      })
      let _actions = config.action.filter(item => item.position === 'toolbar') // 过滤工具栏按钮
      let _operations = config.action.filter(item => item.position === 'grid') // 添加操作列(存在时)
      if (config.gridBtn && config.gridBtn.display && _operations.length > 0) {
        _columns.push({
          ...config.gridBtn,
          operations: _operations
        })
      }
      
      let _isLinkMain = false // 检查是否有与主表关联的子表
      config.tabgroups.forEach(groupId => {
src/tabviews/formtab/formgroup/index.jsx
@@ -586,7 +586,7 @@
  }
  render() {
    const { groups } = this.props
    const { groups, setting } = this.props
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -598,7 +598,10 @@
      }
    }
    let _width = (setting && setting.width) || 100
    let keys = groups.map(group => group.uuid)
    return (
      <Form {...formItemLayout}>
        <Collapse
@@ -607,7 +610,7 @@
        >
          {groups.map(group =>
            <Panel header={group.label} key={group.uuid}>
              <Row gutter={24}>{this.getFields(group.sublist)}</Row>
              <Row style={{margin: '0 auto', width: _width + '%'}} gutter={24}>{this.getFields(group.sublist)}</Row>
            </Panel>
          )}
        </Collapse>
src/tabviews/formtab/index.jsx
@@ -92,7 +92,7 @@
        return
      }
      let _arrField = []     // 字段集
      let _arrField = [config.setting.primaryKey]     // 字段集 , 默认添加主键
      // if (this.props.param && this.props.param.arr_field) { // 使用显示列字段查询
      //   _arrField = this.props.param.arr_field
src/tabviews/subtable/index.jsx
@@ -154,8 +154,20 @@
        }
      })
      let _actions = config.action.filter(item => item.position === 'toolbar') // 过滤工具栏按钮
      let _operations = config.action.filter(item => item.position === 'grid')  // 添加操作列(存在时)
      let _actions = []     // 工具栏按钮
      let _operations = []  // 操作列按钮(存在时)
      config.action.forEach(item => {
        if (item.execMode) {
          item.OpenType = 'funcbutton'
        }
        if (item.position === 'toolbar') {
          _actions.push(item)
        } else if (item.position === 'grid') {
          _operations.push(item)
        }
      })
      if (config.gridBtn && config.gridBtn.display && _operations.length > 0) {
        _columns.push({
src/tabviews/subtabtable/index.jsx
@@ -134,8 +134,20 @@
        }
      })
      let _actions = config.action.filter(item => item.position === 'toolbar') // 过滤工具栏按钮
      let _operations = config.action.filter(item => item.position === 'grid')  // 添加操作列(存在时)
      let _actions = []     // 工具栏按钮
      let _operations = []  // 操作列按钮(存在时)
      config.action.forEach(item => {
        if (item.execMode) {
          item.OpenType = 'funcbutton'
        }
        if (item.position === 'toolbar') {
          _actions.push(item)
        } else if (item.position === 'grid') {
          _operations.push(item)
        }
      })
      if (config.gridBtn && config.gridBtn.display && _operations.length > 0) {
        _columns.push({
src/tabviews/tableshare/actionList/index.jsx
@@ -155,6 +155,21 @@
        message: '弹窗页面不支持此设置!',
        duration: 10
      })
    } else if (item.OpenType === 'innerpage') {
      let Id = data[0][setting.primaryKey]
      if (item.pageTemplate === 'print') {
        let cloudmsg = '&cuid=' + (sessionStorage.getItem('CloudUserID') || '') + '&csid=' + (sessionStorage.getItem('CloudSessionUid') || '') + '&clid=' + (sessionStorage.getItem('CloudLoginUID') || '') + '&cun=' + (sessionStorage.getItem('CloudUserName') || '')
        let msg = '&uid=' + sessionStorage.getItem('UserID') + '&sid=' + sessionStorage.getItem('SessionUid') + '&lid=' + sessionStorage.getItem('LoginUID') + '&un=' + sessionStorage.getItem('User_Name')
        let src = '#/print/' + window.btoa('ID=' + Id + msg + cloudmsg)
        window.open(src)
      } else {
        notification.warning({
          top: 92,
          message: '页面类型设置错误!',
          duration: 10
        })
      }
    } else if (item.OpenType === 'outerpage') {
      let url = item.url
      if (item.Ot === 'requiredSgl' && setting.primaryKey) {
@@ -185,6 +200,44 @@
   * @description 触发打印
   */
  triggerPrint = (item, data) => {
    console.log(item)
    if (!item.verify || !item.verify.Template || !item.verify.linkUrl) {
      notification.warning({
        top: 92,
        message: '请完善打印验证信息!',
        duration: 15
      })
      return
    }
    new Promise(resolve => {
      let param = {
        func: 's_PrintTemplateMGetData',
        Type: 'Y',
        ID: item.verify.Template
      }
      if (options.cloudServiceApi) {
        param.rduri = options.cloudServiceApi.replace('dostars', 'dostar')
      }
      Api.getLocalConfig(param).then(res => {
        if (res.status) {
          resolve(res)
        } else {
          this.execError(res, item)
          resolve(false)
        }
      })
    }).then(res => {
      console.log(res)
      if (!res) return
    })
    // socket = new WebSocket('ws://127.0.0.1:13529')
    // // 打开Socket
src/templates/comtableconfig/actionform/index.jsx
@@ -596,6 +596,7 @@
            values.linkTab = Utils.getuuid()
          } else if (values.OpenType === 'funcbutton' && values.funcType === 'print') { // 转换打印时打开方式
            values.OpenType = values.execMode
            values.position = 'toolbar'
          }
          if (values.innerFunc === '' && values.sql === '') {
src/templates/comtableconfig/index.jsx
@@ -26,6 +26,7 @@
import VerifyCard from '@/templates/tableshare/verifycard'
import VerifyCardExcelIn from '@/templates/tableshare/verifycardexcelin'
import VerifyCardExcelOut from '@/templates/tableshare/verifycardexcelout'
import VerifyCardPrint from '@/templates/tableshare/verifycardprint'
import MenuForm from '@/templates/tableshare/menuform'
import TabDragElement from '@/templates/tableshare/tabdragelement'
import SourceElement from '@/templates/tableshare/dragelement/source'
@@ -3021,7 +3022,7 @@
          onCancel={() => { this.setState({ profileVisible: false }) }}
          destroyOnClose
        >
          {this.state.card && this.state.card.OpenType !== 'excelIn' && this.state.card.OpenType !== 'excelOut' ?
          {this.state.card && !this.state.card.execMode && this.state.card.OpenType !== 'excelIn' && this.state.card.OpenType !== 'excelOut' ?
            <VerifyCard
              card={this.state.card}
              dict={this.state.dict}
@@ -3029,6 +3030,14 @@
              wrappedComponentRef={(inst) => this.verifyRef = inst}
            /> : null
          }
          {this.state.card && this.state.card.execMode ?
            <VerifyCardPrint
              card={this.state.card}
              dict={this.state.dict}
              columns={this.state.config.columns}
              wrappedComponentRef={(inst) => this.verifyRef = inst}
            /> : null
          }
          {this.state.card && this.state.card.OpenType === 'excelIn' ?
            <VerifyCardExcelIn
              card={this.state.card}
src/templates/formtabconfig/dragelement/index.jsx
@@ -127,8 +127,10 @@
    }
  })
  
  let _width = (setting && setting.width) || 100
  return (
    <div ref={drop} className="ant-row">
    <div ref={drop} className="ant-row" style={type === 'search' ? {margin: '0 auto', width: _width + '%'} : {}}>
      {type === 'action' && cards.map(card => (
        <Card
          key={card.uuid}
src/templates/formtabconfig/index.jsx
@@ -83,11 +83,22 @@
    if (!config) {
      _config = JSON.parse(JSON.stringify(Source.baseConfig))
      _config.isAdd = true
      if (menu && menu.LongParam && menu.LongParam.setting.dataresource) {
      if (menu && menu.LongParam && menu.LongParam.setting) {
        _config.setting.tableName = menu.LongParam.setting.tableName
        _config.setting.primaryKey = menu.LongParam.setting.primaryKey
        _config.setting.dataresource = menu.LongParam.setting.dataresource
        _config.setting.interType = menu.LongParam.setting.interType
        _config.setting.interface = menu.LongParam.setting.interface
        _config.setting.outerFunc = menu.LongParam.setting.outerFunc
        _config.setting.innerFunc = menu.LongParam.setting.innerFunc
        _config.setting.sysInterface = menu.LongParam.setting.sysInterface
      }
    } else {
      _config = config
      if (menu && menu.LongParam && menu.LongParam.setting) {
        _config.setting.primaryKey = menu.LongParam.setting.primaryKey
      }
      _config.groups.forEach(group => {
        group.sublist.forEach(item => {
@@ -551,6 +562,14 @@
    if (modaltype === 'search') {
      this.modalFormRef.handleConfirm().then(res => {
        if (config.setting.primaryKey && config.setting.primaryKey.toLowerCase() === res.field.toLowerCase()) {
          notification.warning({
            top: 92,
            message: '表单中字段名不可与主键重复!',
            duration: 10
          })
          return
        }
        if ( // 更新下拉字典
          (res.type === 'select' || res.type === 'multiselect' || res.type === 'link') &&
          res.resourceType === '0' &&
@@ -1270,13 +1289,19 @@
      }
      // 存在多余的空表单组
      if (_config.groups.length > 1) {
      let _ismutil = _config.groups.length > 1
      let _primary = _config.setting.primaryKey ? _config.setting.primaryKey.toLowerCase() : ''
        _config.groups.forEach(group => {
          if (group.sublist.length === 0) {
        if (_ismutil && group.sublist.length === 0) {
          _config.enabled = false
        }
        let arr = group.sublist.filter(item => item.field.toLowerCase() === _primary)
        if (arr.length > 0) {
            _config.enabled = false
          }
        })
      }
      _config.funcs = [] // 页面及子页面存储过程集
@@ -1928,13 +1953,24 @@
      })
    }
    let _primary = config.setting.primaryKey ? config.setting.primaryKey.toLowerCase() : ''
    let primaryrepeat = false
    config.groups.forEach(group => {
      let arr = group.sublist.filter(item => item.field.toLowerCase() === _primary)
      if (arr.length > 0) {
        primaryrepeat = true
      }
    })
    if (config.setting.datatype === 'query' && config.setting.interType === 'inner' && !config.setting.innerFunc && !config.setting.dataresource) {
      notification.warning({
        top: 92,
        message: '尚未设置数据源,不可启用!',
        duration: 10
      })
    } else if (config.setting.datatype === 'query' && config.setting.primaryKey) {
    } else if (config.setting.datatype === 'query' && !config.setting.primaryKey) {
      notification.warning({
        top: 92,
        message: '尚未设置主键,不可启用!',
@@ -1952,6 +1988,12 @@
        message: '存在多余空表单组,不可启用!',
        duration: 10
      })
    } else if (primaryrepeat) {
      notification.warning({
        top: 92,
        message: '表单字段与主键重复,不可启用!',
        duration: 10
      })
    } else {
      this.setState({
        config: {...config, enabled: !config.enabled}
src/templates/formtabconfig/index.scss
@@ -254,14 +254,14 @@
              }
              .edit {
                position: absolute;
                left: 15px;
                left: calc(34% - 100px);
                top: 5px;
                color: #1890ff;
                cursor: pointer;
                display: none;
              }
              .edit.close {
                left: 40px;
                left: calc(34% - 80px);
                color: #ff4d4f;
              }
            }
src/templates/formtabconfig/settingform/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Radio, Select, Tooltip, Icon, notification } from 'antd'
import { Form, Row, Col, Input, Radio, Select, Tooltip, Icon, notification, InputNumber } from 'antd'
import { formRule } from '@/utils/option.js'
import './index.scss'
@@ -18,7 +18,6 @@
    interType: (this.props.config.setting && this.props.config.setting.interType) || 'inner',
    columns: null,
    interReadonly: false,
    primaryKey: ''
  }
  UNSAFE_componentWillMount() {
@@ -50,28 +49,12 @@
      })
    }
    let primaryKey = _setting.primaryKey
    if (primaryKey) {
      let field = _columns.filter(column => column.field === primaryKey)
      if (field.length !== 1) {
        primaryKey = ''
      }
    }
    if (!primaryKey) {
      _columns.forEach(col => {
        if (col.field.toLowerCase() === 'id') {
          primaryKey = col.field
        }
      })
    }
    this.setState({
      columns: _columns,
      setting: _setting,
      interType: _setting.interType || 'inner',
      interReadonly: _setting.sysInterface === 'true',
      datatype: _setting.datatype || 'maintable',
      primaryKey: primaryKey
      datatype: _setting.datatype || 'maintable'
    })
  }
@@ -152,7 +135,7 @@
  render() {
    const { dict, usefulFields, menu } = this.props
    const { getFieldDecorator } = this.props.form
    const { interType, columns, setting, datatype, primaryKey } = this.state
    const { interType, setting, datatype } = this.state
    const formItemLayout = {
      labelCol: {
@@ -213,22 +196,13 @@
              )}
            </Form.Item>
          </Col>
          {datatype === 'query' ? <Col span={12}>
          <Col span={12}>
            <Form.Item label="主键">
              {getFieldDecorator('primaryKey', {
                initialValue: primaryKey || ''
              })(
                <Select
                  getPopupContainer={() => document.getElementById('commontable-setting-form')}
                >
                  <Select.Option key='unset' value="">未设置</Select.Option>
                  {columns.map((option, index) =>
                    <Select.Option id={option.uuid} title={option.label} key={index} value={option.field}>{option.label}</Select.Option>
                  )}
                </Select>
              )}
                initialValue: setting.primaryKey
              })(<Input placeholder="" autoComplete="off" disabled/>)}
            </Form.Item>
          </Col> : null}
          </Col>
          {datatype === 'query' ? <Col span={12}>
            <Form.Item label={dict['header.form.intertype']}>
              {getFieldDecorator('interType', {
@@ -319,6 +293,13 @@
              })(<Input placeholder="" autoComplete="off" />)}
            </Form.Item>
          </Col> : null}
          <Col span={12}>
            <Form.Item label="宽度">
              {getFieldDecorator('width', {
                initialValue: setting.width || 100
              })(<InputNumber min={10} max={100} precision={0} />)}
            </Form.Item>
          </Col>
        </Row>
      </Form>
    )
src/templates/formtabconfig/settingform/index.scss
@@ -11,4 +11,7 @@
    color: #c49f47;
    margin-right: 3px;
  }
  .ant-input-number {
    width: 100%;
  }
}
src/templates/formtabconfig/source.jsx
@@ -9,17 +9,17 @@
    type: 'FormTab',
    enabled: false,
    setting: {
      tableName: '',
      primaryKey: '',
      dataresource: '',
      // tableName: '',
      // primaryKey: '',
      // dataresource: '',
      datatype: 'query',
      interType: 'inner',
      sysInterface: 'false',
      innerFunc: '',
      interface: '',
      outerFunc: '',
      // interType: 'inner',
      // sysInterface: 'false',
      // innerFunc: '',
      // interface: '',
      // outerFunc: '',
      cols: '2',
      subtabs: []
      width: 100
    },
    tables: [],
    groups: [
src/templates/modalconfig/dragelement/card.jsx
@@ -8,7 +8,7 @@
const { MonthPicker } = DatePicker
const { TextArea } = Input
const Card = ({ id, card, cols, moveCard, findCard, editCard, closeCard, hasDrop }) => {
const Card = ({ id, card, cols, moveCard, findCard, editCard, closeCard, copyCard, hasDrop }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: ItemTypes.form, id, originalIndex },
@@ -40,6 +40,10 @@
  const close = () => {
    closeCard(id)
  }
  const copy = () => {
    copyCard(id)
  }
  let selectval = ''
@@ -113,6 +117,7 @@
      </div>
      <Icon className="edit" type="edit" onClick={edit} />
      <Icon className="edit close" type="close" onClick={close} />
      <Icon className="edit copy" type="copy" onClick={copy} />
    </div>
  )
}
src/templates/modalconfig/dragelement/index.jsx
@@ -40,12 +40,17 @@
  const editCard = id => {
    const { card } = findCard(id)
    handleForm(card)
    handleForm(card, 'edit')
  }
  const closeCard = id => {
    const { card } = findCard(id)
    closeForm(card)
  }
  const copyCard = id => {
    const { card } = findCard(id)
    handleForm(card, 'copy')
  }
  
  const hasDrop = (item) => {
@@ -112,6 +117,7 @@
            moveCard={moveCard}
            editCard={editCard}
            closeCard={closeCard}
            copyCard={copyCard}
            findCard={findCard}
            hasDrop={hasDrop}
          />
src/templates/modalconfig/index.jsx
@@ -48,6 +48,7 @@
    dict: CommonDict,      // 字典
    config: null,          // 页面配置,包括模板类型、模态框设置、添加表名、表单列表
    visible: false,        // 表单编辑模态框,显示控制
    modalType: null,       // 表单编辑类型,编辑或复制
    tableVisible: false,   // 数据表字段列表模态框,显示控制
    tableColumns: [],      // 表格字段名列表
    fields: null,          // 表单,可选字段(去重后)
@@ -372,8 +373,15 @@
   * 2、保存编辑项-card
   * 3、设置编辑参数项-formlist
   */
  handleForm = (card) => {
  handleForm = (_card, type) => {
    const {menu, tabConfig, subTabConfig} = this.props
    let card = JSON.parse(JSON.stringify(_card))
    if (type === 'copy') {
      card.originUuid = card.uuid
      card.uuid = Utils.getuuid()
      card.focus = true
    }
    const { config } = this.state
    let _inputfields = []
@@ -449,6 +457,7 @@
    this.setState({
      visible: true,
      modalType: type,
      card: card,
      formlist: getModalForm(card, _inputfields, _linkableFields, !!this.props.editTab)
    })
@@ -462,6 +471,8 @@
   */
  handleSubmit = () => {
    const {editAction, optionLibs} = this.props
    const { card, modalType } = this.state
    this.formRef.handleConfirm().then(res => {
      let _config = JSON.parse(JSON.stringify(this.state.config))
@@ -479,6 +490,33 @@
        })
      }
      if (modalType === 'copy' && card.originUuid) {
        if (_config.groups.length > 0) {
          _config.groups = _config.groups.map(group => {
            let _index = null
            group.sublist.forEach((item, index) => {
              if (item.uuid === card.originUuid) {
                _index = index
              }
            })
            if (_index !== null) {
              group.sublist.splice(_index + 1, 0, res)
            }
            return group
          })
        } else {
          let _index = null
          _config.fields.forEach((item, index) => {
            if (item.uuid === card.originUuid) {
              _index = index
            }
          })
          _config.fields.splice(_index + 1, 0, res)
        }
      } else {
      if (_config.groups.length > 0) {
        _config.groups.forEach(group => {
          group.sublist = group.sublist.map(item => {
@@ -498,11 +536,14 @@
          }
        })
      }
      }
      
      _config.fields = _config.fields.filter(item => !item.origin)
      this.setState({
        config: _config,
        modalType: null,
        card: null,
        optionLibs: optionLibs,
        visible: false
      })
@@ -551,27 +592,6 @@
      return
    }
    // if (config.setting.display === 'prompt') { // 有需要置空的场景
    //   let _fields = []
    //   if (config.groups.length > 0) {
    //     config.groups.forEach(group => {
    //       _fields = [..._fields, ...group.sublist]
    //     })
    //   } else {
    //     _fields = config.fields
    //   }
    //   let readfields = _fields.filter(item => item.initval || item.initval === 0)
    //   if (readfields.length < _fields.length) {
    //     notification.warning({
    //       top: 92,
    //       message: '以《是否框》显示的弹框,所有表单必须含有默认值!',
    //       duration: 10
    //     })
    //     return
    //   }
    // }
    let _LongParam = ''
    let _config = {...config, tables: this.state.selectedTables}
@@ -612,6 +632,7 @@
        this.setState({
          menuloading: false,
          closeloading: false,
          closeVisible: false,
          originConfig: _config,
          config: _config
        })
@@ -1181,7 +1202,7 @@
          </div>
        </DndProvider>
        <Modal
          title={this.state.dict['header.edit']}
          title={this.state.modalType !== 'copy' ? this.state.dict['header.edit'] : this.state.dict['header.modal.form.copy']}
          visible={this.state.visible}
          width={700}
          onCancel={this.editModalCancel}
src/templates/modalconfig/index.scss
@@ -252,16 +252,20 @@
          }
          .edit {
            position: absolute;
            left: calc(33% - 70px);
            left: calc(33% - 100px);
            top: 0px;
            color: #1890ff;
            cursor: pointer;
            display: none;
          }
          .edit.close {
            left: calc(33% - 45px);
            left: calc(33% - 60px);
            color: #ff4d4f;
          }
          .edit.copy {
            left: calc(33% - 80px);
            color: #26C281;
          }
        }
        .ant-col.textarea2 {
          padding-left: 7px;
src/templates/tableshare/formconfig.js
@@ -326,10 +326,13 @@
    {
      type: 'select',
      key: 'pageTemplate',
      label: Formdict['header.form.pageTemplate'],
      label: Formdict['header.form.newpage.type'],
      initVal: card.pageTemplate || '',
      required: true,
      options: []
      options: [{
        value: 'print',
        text: Formdict['header.menu.printTemplate']
      }]
    },
    {
      type: 'text',
@@ -1012,7 +1015,7 @@
      type: 'radio',
      key: 'required',
      label: Formdict['header.form.field.required'],
      initVal: card.required || 'false',
      initVal: card.required || 'true',
      options: [{
        value: 'true',
        text: Formdict['header.form.true']
src/templates/tableshare/verifycard/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Tabs, Row, Col, Radio, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber, Tooltip, Input, Select } from 'antd'
import { Form, Tabs, Row, Col, Radio, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber, Tooltip } from 'antd'
import moment from 'moment'
import Api from '@/api'
@@ -33,8 +33,6 @@
    orderModular: [],
    orderModularDetail: [],
    voucher: [],
    templates: [],
    selectimg: '',
    voucherDetail: [],
    uniqueColumns: [
      {
@@ -383,7 +381,6 @@
        billcodes: _verify.billcodes || [],
        voucher: _verify.voucher || {enabled: false},
        scripts: _verify.scripts || [],
        Template: _verify.Template || ''
      }
    })
@@ -637,64 +634,6 @@
        voucherDetail: result[1].data
      })
    })
    if (this.props.card.execMode) {
      let _sql = `select ID,Images,PrintTempNO+PrintTempName as PN from sPrintTemplate
        where appkey= @appkey@ and Deleted=0
        union select ID,Images,a.PrintTempNO+PrintTempName as PN
        from (select * from sPrintTemplate where appkey= '' and Deleted=0 ) a
        left join (select PrintTempNO from sPrintTemplate where appkey= @appkey@ and Deleted=0 ) b
        on a.PrintTempNO=b.PrintTempNO
        left join (select Srcid from sPrintTemplate_Log where appkey='' and apicode= @appkey@ and Deleted=0 ) c
        on a.ID=c.Srcid  where b.PrintTempNO is null and c.Srcid is null`
      let param = {
        func: 'sPC_Get_SelectedList',
        LText: Utils.formatOptions(_sql),
        obj_name: 'data',
        arr_field: 'PN,ID,Images'
      }
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
      Api.getSystemConfig(param).then(res => {
        if (res.status) {
          let temps = res.data.map(temp => {
            return {
              value: temp.ID,
              text: temp.PN,
              img: temp.Images
            }
          })
          let Template = this.state.verify.Template
          let selectimg = ''
          let selectTemp = temps.filter(temp => temp.value === Template)[0]
          if (!selectTemp) {
            Template = ''
          } else {
            selectimg = selectTemp.img
          }
          this.setState({
            selectimg: selectimg,
            templates: temps,
            verify: {
              ...this.state.verify,
              Template: Template
            }
          })
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 10
          })
        }
      })
    }
  }
  uniqueChange = (values) => {
@@ -1044,39 +983,7 @@
    })
  }
  changeTemplate = (val) => {
    const { templates } = this.state
    let temp = templates.filter(temp => temp.value === val)[0]
    this.setState({
      selectimg: temp.img
    })
  }
  handleConfirm = () => {
    const { verify } = this.state
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          let _verify = {...verify, ...values}
          resolve(_verify)
        } else {
          notification.warning({
            top: 92,
            message: '链接地址与打印模板不可为空!',
            duration: 10
          })
        }
      })
    })
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const { verify, fields, uniqueColumns, contrastColumns, customColumns, orderColumns, scriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail } = this.state
    const formItemLayout = {
      labelCol: {
@@ -1124,43 +1031,6 @@
                    </Radio.Group>
                  </Form.Item>
                </Col>
                {this.props.card.execMode ? <Col span={8}>
                  <Form.Item label={'链接地址'}>
                    {getFieldDecorator('linkUrl', {
                      initialValue: verify.linkUrl || '127.0.0.1:13529',
                      rules: [
                        {
                          required: true,
                          message: this.props.dict['form.required.input'] + '链接地址!'
                        }
                      ]
                    })(<Input placeholder="" autoComplete="off" />)}
                  </Form.Item>
                </Col> : null}
                {this.props.card.execMode ? <Col span={8}>
                  <Form.Item label={'打印模板'}>
                    {getFieldDecorator('Template', {
                      initialValue: verify.Template || '',
                      rules: [
                        {
                          required: true,
                          message: this.props.dict['form.required.select'] + '打印模板!'
                        }
                      ]
                    })(
                      <Select onChange={this.changeTemplate}>
                        {this.state.templates.map((option, key) =>
                          <Select.Option id={key} key={key} value={option.value}>
                            {option.text}
                          </Select.Option>
                        )}
                      </Select>
                    )}
                  </Form.Item>
                </Col> : null}
                {this.state.selectimg ? <Col span={9}>
                  <img style={{width: '90%', marginBottom: '25px'}} src={this.state.selectimg} alt=""/>
                </Col> : null}
              </Row>
            </Form>
          </TabPane>
src/templates/tableshare/verifycardprint/index.jsx
New file
@@ -0,0 +1,309 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Input, Select } from 'antd'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import './index.scss'
const { TabPane } = Tabs
class VerifyCard extends Component {
  static propTpyes = {
    floor: PropTypes.any,      // 是否为子表
    btnTab: PropTypes.any,     // 表单标签页(按钮)参数
    config: PropTypes.any,     // 表单标签页参数
    dict: PropTypes.object,    // 字典项
    card: PropTypes.object,
    columns: PropTypes.array
  }
  state = {
    verify: {},
    templates: [],
    selectimg: '',
  }
  UNSAFE_componentWillMount() {
    let _verify = this.props.card.verify || {}
    this.setState({
      verify: {
        ..._verify,
        Template: _verify.Template || ''
      }
    })
  }
  componentDidMount() {
    let _sql = `select ID,Images,PrintTempNO+PrintTempName as PN from sPrintTemplate
      where appkey= @appkey@ and Deleted=0
      union select ID,Images,a.PrintTempNO+PrintTempName as PN
      from (select * from sPrintTemplate where appkey= '' and Deleted=0 ) a
      left join (select PrintTempNO from sPrintTemplate where appkey= @appkey@ and Deleted=0 ) b
      on a.PrintTempNO=b.PrintTempNO
      left join (select Srcid from sPrintTemplate_Log where appkey='' and apicode= @appkey@ and Deleted=0 ) c
      on a.ID=c.Srcid  where b.PrintTempNO is null and c.Srcid is null`
    let param = {
      func: 'sPC_Get_SelectedList',
      LText: Utils.formatOptions(_sql),
      obj_name: 'data',
      arr_field: 'PN,ID,Images'
    }
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    Api.getSystemConfig(param).then(res => {
      if (res.status) {
        let temps = res.data.map(temp => {
          return {
            value: temp.ID,
            text: temp.PN,
            img: temp.Images
          }
        })
        let Template = this.state.verify.Template
        let selectimg = ''
        let selectTemp = temps.filter(temp => temp.value === Template)[0]
        if (!selectTemp) {
          Template = ''
        } else {
          selectimg = selectTemp.img
        }
        this.setState({
          selectimg: selectimg,
          templates: temps,
          verify: {
            ...this.state.verify,
            Template: Template
          }
        })
      } else {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 10
        })
      }
    })
  }
  showError = (errorType) => {
    if (errorType === 'S') {
      notification.success({
        top: 92,
        message: '执行成功!',
        duration: 2
      })
    } else if (errorType === 'F') {
      notification.error({
        className: 'notification-custom-error',
        top: 92,
        message: '执行失败!',
        duration: 15
      })
    } else if (errorType === 'N') {
      notification.error({
        top: 92,
        message: '执行失败!',
        duration: 15
      })
    } else if (errorType === 'E') {
      Modal.error({
        title: '执行失败!'
      })
    } else if (errorType === 'NM') {
      message.error('执行失败!')
    }
  }
  timeChange = (val, type) => {
    const { verify } = this.state
    this.setState({
      verify: {...verify, [type]: val}
    })
  }
  changeTemplate = (val) => {
    const { templates } = this.state
    let temp = templates.filter(temp => temp.value === val)[0]
    this.setState({
      selectimg: temp.img
    })
  }
  handleConfirm = () => {
    const { verify } = this.state
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          let _verify = {...verify, ...values}
          resolve(_verify)
        } else {
          notification.warning({
            top: 92,
            message: '链接地址与打印模板不可为空!',
            duration: 10
          })
        }
      })
    })
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const { verify } = 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" onChange={this.tabchange}>
          <TabPane tab="打印验证" key="1">
            <Form {...formItemLayout}>
              <Row gutter={24}>
                <Col span={8}>
                  <Form.Item label={'链接地址'}>
                    {getFieldDecorator('linkUrl', {
                      initialValue: verify.linkUrl || '127.0.0.1:13529',
                      rules: [
                        {
                          required: true,
                          message: this.props.dict['form.required.input'] + '链接地址!'
                        }
                      ]
                    })(<Input placeholder="" autoComplete="off" />)}
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={'打印模板'}>
                    {getFieldDecorator('Template', {
                      initialValue: verify.Template || '',
                      rules: [
                        {
                          required: true,
                          message: this.props.dict['form.required.select'] + '打印模板!'
                        }
                      ]
                    })(
                      <Select onChange={this.changeTemplate}>
                        {this.state.templates.map((option, key) =>
                          <Select.Option id={key} key={key} value={option.value}>
                            {option.text}
                          </Select.Option>
                        )}
                      </Select>
                    )}
                  </Form.Item>
                </Col>
                <Col span={9}>
                  <img style={{width: '90%', marginBottom: '25px'}} src={this.state.selectimg} alt=""/>
                </Col>
              </Row>
            </Form>
          </TabPane>
          <TabPane tab="信息提示" key="7">
            <Form {...formItemLayout}>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                    <span className="errorval"> S </span>
                    <Button onClick={() => {this.showError('S')}} type="primary" size="small">
                      查看
                    </Button>
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={'停留时间'}>
                    <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} />
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                    <span className="errorval"> -1 </span>
                    不提示
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                    <span className="errorval"> N </span>
                    <Button onClick={() => {this.showError('N')}} type="primary" size="small">
                      查看
                    </Button>
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={'停留时间'}>
                    <InputNumber defaultValue={verify.ntime || 15} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                    <span className="errorval"> F </span>
                    <Button onClick={() => {this.showError('F')}} type="primary" size="small">
                      查看
                    </Button>
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={'停留时间'}>
                    <InputNumber defaultValue={verify.ftime || 15} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                    <span className="errorval"> E </span>
                    <Button onClick={() => {this.showError('E')}} type="primary" size="small">
                      查看
                    </Button>
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                    <span className="errorval"> NM </span>
                    <Button onClick={() => {this.showError('NM')}} type="primary" size="small">
                      查看
                    </Button>
                  </Form.Item>
                </Col>
              </Row>
            </Form>
          </TabPane>
        </Tabs>
      </div>
    )
  }
}
export default Form.create()(VerifyCard)
src/templates/tableshare/verifycardprint/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/utils/utils.js
@@ -1029,8 +1029,14 @@
  static getTableFunc (param, menu, config) {
    let form = ''
    let formParam = ''
    let _vars = ['bid', 'pageindex', 'pagesize', 'ordercol', 'ordertype', 'exceltype', 'septmenuno', 'lang', 'debug', 'loginuid', 'sessionuid', 'userid', 'errorcode', 'retmsg']
    let _columns = []
    let primaryKey = config.setting.primaryKey || 'ID'
    if (!_vars.includes(primaryKey.toLowerCase())) {
      _vars.push(primaryKey.toLowerCase())
      formParam = `mchr13k@${primaryKey} nvarchar(50)='',`
    }
    if (config.search && config.search.length > 0) {
      let _fields = new Map()
@@ -1051,7 +1057,11 @@
            }
  
            _fields.set(cell, true)
            if (!_vars.includes(_f.toLowerCase())) {
              _vars.push(_f.toLowerCase())
            formParam = formParam + `mchr13k@${_f} ${type},`
            }
          })
        }
      })
@@ -1073,8 +1083,7 @@
    let Ltext = `create proc ${param.innerFunc}
    ( /*${menu.MenuName}*/
    @BID nvarchar(50)='',
    @${primaryKey} nvarchar(50)='',${formParam}
    @BID nvarchar(50)='',${formParam}
    @PageIndex nvarchar(50)='',
    @PageSize nvarchar(50)='',
    @OrderCol nvarchar(50)='',
@@ -1159,8 +1168,14 @@
  static getfunc (param, btn, menu, config) {
    let form = ''
    let formParam = ''
    let _vars = ['bid', 'septmenuno', 'lang', 'debug', 'loginuid', 'sessionuid', 'userid', 'errorcode', 'retmsg']
    let columns = config.columns
    let primaryKey = config.setting.primaryKey || 'ID'
    if (!_vars.includes(primaryKey.toLowerCase())) {
      _vars.push(primaryKey.toLowerCase())
      formParam = `mchr13k@${primaryKey} nvarchar(50)='',`
    }
    if (param.fields && param.fields.length > 0) {
      let _fields = []
@@ -1174,7 +1189,11 @@
          } else {
            type = 'nvarchar(50)=\'\''
          }
          if (!_vars.includes(item.field.toLowerCase())) {
            _vars.push(item.field.toLowerCase())
          formParam = formParam + `mchr13k@${item.field} ${type},`
          }
          _fields.push(item.field)
        }
@@ -1223,8 +1242,7 @@
    let Ltext = `create proc ${param.funcName}
    ( /*${menu.MenuName}  ${btn.label}*/
    @BID nvarchar(50)='',
    @${primaryKey} nvarchar(50)='',${formParam}
    @BID nvarchar(50)='',${formParam}
    @sEPTMenuNo nvarchar(50)='${param.menuNo}',
    @lang nvarchar(50)='',
    @debug nvarchar(50)='',
src/views/printTemplate/index.jsx
New file
@@ -0,0 +1,14 @@
import React, {Component} from 'react'
import './index.scss'
class PrintTemplate extends Component {
  render () {
    return (
      <div className="print-template">
      </div>
    )
  }
}
export default PrintTemplate
src/views/printTemplate/index.scss
New file
@@ -0,0 +1,5 @@
.print-template {
  display: flex;
  flex: auto;
  min-height: 100%;
}