king
2020-04-17 bf772e586c29b4858366dbad143b1eaeca3c46ed
2020-04-17
35个文件已修改
7个文件已添加
1777 ■■■■ 已修改文件
src/components/sidemenu/config.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tabview/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/formtab/actionList/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/formtab/formgroup/index.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/formtab/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/managetable/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/managetable/secretKeyTable/actionList/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/managetable/secretKeyTable/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/actionList/index.jsx 321 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/actionList/index.scss 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/config.jsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/index.jsx 365 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/index.scss 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/topSearch/index.jsx 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/topSearch/index.scss 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtabtable/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/actionList/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/subtabtable/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/index.jsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/normalTable/index.jsx 71 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/normalTable/index.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/actionform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/settingform/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/actionform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/settingform/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/actionform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/settingform/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/columnform/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customscript/index.jsx 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelin/customscript/index.jsx 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelin/index.jsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 108 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/config.js
@@ -71,6 +71,14 @@
      MenuNo: 'sUsersAppM',
      MenuName: '系统用户管理',
      text: '系统用户管理'
    }, {
      src: '',
      PageParam: {OpenType: 'newtab', Template: 'ScriptTable'},
      type: 'ScriptTable',
      MenuID: '1587005717541lov40vg61q7l1rbveon',
      MenuNo: 's_custom_scriptM',
      MenuName: '自定义脚本',
      text: '自定义脚本'
    }]
  }, {
    MenuID: 'systemManageViewInterface',
src/components/tabview/index.jsx
@@ -19,6 +19,7 @@
const Home = asyncComponent(() => import('@/tabviews/home'))
const CommonTable = asyncComponent(() => import('@/tabviews/commontable'))
const VerupTable = asyncComponent(() => import('@/tabviews/verupmanage'))
const ScriptTable = asyncComponent(() => import('@/tabviews/scriptmanage'))
const TabManage = asyncComponent(() => import('@/tabviews/tabmanage'))
const ManageTable = asyncComponent(() => import('@/tabviews/managetable'))
const Iframe = asyncComponent(() => import('@/tabviews/iframe'))
@@ -103,6 +104,8 @@
      return (<CommonTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
    } else if (view.type === 'VerupTable') {
      return (<VerupTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
    } else if (view.type === 'ScriptTable') {
      return (<ScriptTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
    } else if (view.type === 'TabManage') {
      return (<TabManage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
    } else if (view.type === 'ManageTable') {
src/index.js
@@ -25,8 +25,31 @@
window.GLOB = window.GLOB || {}
if (!(options.systemType === 'local' && window.GLOB.systemType === 'official')) {
if (!(options.systemType === 'local' && window.GLOB.systemType === 'official')) { // 只有业务系统才可以设置为正式系统
  window.GLOB.systemType = 'test'
}
if (options.systemType !== 'local') { // sso,cloud不可设置单点服务器地址
  window.GLOB.mainSystemApi = ''
} else if (options.systemType === 'local' && window.GLOB.mainSystemApi) { // 业务系统
  let systemApi = window.GLOB.mainSystemApi
  if (/^(http|https):\/\//ig.test(systemApi)) {
    let _systemApi = /^(http|https):\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62}|(:[0-9]{1,4}))+\.?/ig.exec(systemApi)
    systemApi = _systemApi ? _systemApi[0] : ''
  } else {
    systemApi = ''
  }
  if (systemApi && systemApi === /^(http|https):\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62}|(:[0-9]{1,4}))+\.?/ig.exec(options.cloudServiceApi)[0]) {
    window.GLOB.dataFormat = true
  }
  if (systemApi) {
    systemApi = systemApi + '/webapi/dostars'
  }
  window.GLOB.mainSystemApi = systemApi
}
let _systemMsg = localStorage.getItem(window.location.href.split('#')[0] + 'system')
@@ -76,14 +99,6 @@
if (window.GLOB.style && option[window.GLOB.style]) {
  document.getElementById('root').className = option[window.GLOB.style]
}
if (process.env.NODE_ENV === 'production') {
  let service = window.GLOB.service ? (/\/$/.test(window.GLOB.service) ? window.GLOB.service : window.GLOB.service + '/') : ''
  window.GLOB.subSystemApi = document.location.origin + '/' + service + 'webapi/dostars'
} else {
  window.GLOB.subSystemApi = 'http://qingqiumarket.cn/mkwms/webapi/dostars'
}
sessionStorage.removeItem('isEditState')
src/tabviews/commontable/index.jsx
@@ -587,13 +587,11 @@
    if (setting.interType === 'inner') {
      param.func = setting.innerFunc
    } else {
      if (setting.sysInterface === 'true') {
        param.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
      } else {
      if (setting.sysInterface === 'true' && window.GLOB.mainSystemApi) {
        param.rduri = window.GLOB.mainSystemApi
      } else if (setting.sysInterface !== 'true') {
        param.rduri = setting.interface
      }
      param.appkey = window.GLOB.appkey || '' // 调用外部接口增加appkey
      if (setting.outerFunc) {
        param.func = setting.outerFunc
@@ -625,8 +623,7 @@
    let param = {
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field,
      appkey: window.GLOB.appkey || ''
      arr_field: arr_field
    }
    
    let _orderBy = orderBy || setting.order
@@ -652,8 +649,6 @@
          value: item.value
        }
      })
      // options.reverse()
      options.forEach(item => {
        _dataresource = _dataresource.replace(item.reg, `'${item.value}'`)
src/tabviews/formtab/actionList/index.jsx
@@ -198,9 +198,9 @@
            res.rduri = btn.interface
          }
        } else {
          if (btn.sysInterface === 'true') {
            res.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          } else {
          if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
            res.rduri = window.GLOB.mainSystemApi
          } else if (btn.sysInterface !== 'true') {
            res.rduri = btn.interface
          }
        }
@@ -208,8 +208,6 @@
        if (btn.outerFunc) {
          res.func = btn.outerFunc
        }
        res.appkey = window.GLOB.appkey || '' // 外部请求时,统一添加appkey
  
        return Api.genericInterface(res)
      }).then(response => {
src/tabviews/formtab/formgroup/index.jsx
@@ -121,7 +121,10 @@
        let _readin = item.readin !== 'false'
        if (item.type === 'funcvar') {
          _readin = false
          item.initval = '' // 初始化为空
        }
        item.initVal = item.initval ? JSON.parse(JSON.stringify(item.initval)) : ''
        let _fieldlen = item.fieldlength || 50
        if (item.type === 'textarea' || item.type === 'fileupload' || item.type === 'multiselect') {
@@ -567,19 +570,26 @@
            if (!item.field) return
            if (item.type === 'funcvar') {
              let _val = item.initval
              if (values.hasOwnProperty(item.field)) {
                _val = values[item.field] === '系统自动生成' ? '' : values[item.field]
              } else if (record.hasOwnProperty(item.field)) {
                _val = record[item.field]
              }
              search.push({
                type: 'funcvar',
                readonly: 'true',
                readin: false,
                fieldlen: this.state.fieldlen[item.field],
                key: item.field,
                value: ''
                value: _val
              })
            } else if (item.hidden === 'true' && item.field !== this.props.setting.primaryKey) {
              let _val = item.initval
              if (record.hasOwnProperty(item.field)) {
                _val = record[item.field]
              }
              search.push({
                type: this.state.datatype[item.field],
                readonly: this.state.readtype[item.field],
@@ -587,6 +597,15 @@
                fieldlen: this.state.fieldlen[item.field],
                key: item.field,
                value: _val
              })
            } else if (item.supField && !item.supvalue.includes(this.props.form.getFieldValue(item.supField))) {
              search.push({
                type: this.state.datatype[item.field],
                readonly: this.state.readtype[item.field],
                readin: this.state.readin[item.field],
                fieldlen: this.state.fieldlen[item.field],
                key: item.field,
                value: item.initVal
              })
            }
          })
@@ -644,7 +663,7 @@
              value: _value
            })
          })
          resolve(search)
          // resolve(search)
        } else {
          reject(err)
        }
src/tabviews/formtab/index.jsx
@@ -373,7 +373,6 @@
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field,
      appkey: window.GLOB.appkey || '',
      ID: primaryId
    }
    
@@ -415,14 +414,12 @@
          param.rduri = setting.interface
        }
      } else {
        if (setting.sysInterface === 'true') {
          param.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
        } else {
        if (setting.sysInterface === 'true' && window.GLOB.mainSystemApi) {
          param.rduri = window.GLOB.mainSystemApi
        } else if (setting.sysInterface !== 'true') {
          param.rduri = setting.interface
        }
      }
      param.appkey = window.GLOB.appkey || '' // 调用外部接口增加appkey
      if (setting.outerFunc) {
        param.func = setting.outerFunc
src/tabviews/managetable/index.jsx
@@ -363,8 +363,6 @@
        param.rduri = setting.interface
      }
      param.appkey = window.GLOB.appkey || '' // 调用外部接口增加appkey
      if (setting.outerFunc) {
        param.func = setting.outerFunc
      }
@@ -395,8 +393,7 @@
    let param = {
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field,
      appkey: window.GLOB.appkey || ''
      arr_field: arr_field
    }
    
    let _orderBy = orderBy || setting.order
@@ -422,8 +419,6 @@
          value: item.value
        }
      })
      // options.reverse()
      options.forEach(item => {
        _dataresource = _dataresource.replace(item.reg, `'${item.value}'`)
@@ -877,6 +872,7 @@
              }
              <MainTable
                ref="mainTable"
                menuType="HS"
                tableId="mainTable"
                pickup={pickup}
                setting={setting}
src/tabviews/managetable/secretKeyTable/actionList/index.jsx
@@ -170,7 +170,7 @@
      ]
    }
    let _number =  Math.floor(Math.random() * 10)
    let _number = Math.floor(Math.random() * 10)
    let keyString = window.btoa(window.encodeURIComponent(JSON.stringify(datalist)))
    let regular = refCodes[_number]
    keyString = keyString.replace(new RegExp(regular.char, 'g'), regular.md5str)
src/tabviews/managetable/secretKeyTable/index.jsx
@@ -220,8 +220,6 @@
        param.rduri = setting.interface
      }
      param.appkey = window.GLOB.appkey || '' // 调用外部接口增加appkey
      if (setting.outerFunc) {
        param.func = setting.outerFunc
      }
@@ -370,6 +368,7 @@
          }
          <SubTable
            ref="subTable"
            menuType="HS"
            tableId={this.props.Tab.uuid}
            pickup={pickup}
            setting={setting}
src/tabviews/scriptmanage/actionList/index.jsx
New file
@@ -0,0 +1,321 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import moment from 'moment'
import { Button, Modal, notification, message } from 'antd'
import MutilForm from '@/tabviews/zshare/mutilform'
import options from '@/store/options.js'
import Utils from '@/utils/utils.js'
import Api from '@/api'
import './index.scss'
const { confirm } = Modal
class MainAction extends Component {
  static propTpyes = {
    BID: PropTypes.string,            // 主表ID
    BData: PropTypes.any,             // 主表数据
    Tab: PropTypes.any,               // 如果当前元素为标签时,tab为标签信息
    type: PropTypes.string,           // 判断当前为主表(main)、子表(sub)、子表标签(subtab)
    MenuID: PropTypes.string,         // 菜单ID
    actions: PropTypes.array,         // 按钮组
    logcolumns: PropTypes.array,      // 显示列
    dict: PropTypes.object,           // 字典项
    setting: PropTypes.any,           // 页面通用设置
    ContainerId: PropTypes.any,       // tab页面ID,用于弹窗控制
    refreshdata: PropTypes.func,      // 执行完成后数据刷新
    gettableselected: PropTypes.func  // 获取表格中数据
  }
  state = {
    visible: false,
    formdata: null,
    tabledata: null,
    confirmLoading: false,
    execAction: null,
    configMap: {}
  }
  refreshdata = (item, type) => {
    this.props.refreshdata(item, type)
  }
  /**
   * @description 触发按钮操作
   */
  actionTrigger = (item, record) => {
    const { setting } = this.props
    let _this = this
    let data = this.props.gettableselected() || []
    if (record) { // 表格中触发按钮
      data = [record]
    }
    if (item.Ot !== 'notRequired' && data.length === 0) {
      // 需要选择行时,校验数据
      notification.warning({
        top: 92,
        message: this.props.dict['main.action.confirm.selectline'],
        duration: 10
      })
      return
    } else if (item.Ot === 'requiredSgl' && data.length !== 1) {
      // 需要选择单行时,校验数据
      notification.warning({
        top: 92,
        message: this.props.dict['main.action.confirm.selectSingleLine'],
        duration: 10
      })
      return
    } else if (item.Ot !== 'notRequired' && !setting.primaryKey) {
      // 需要选择行时,校验是否设置主键
      notification.warning({
        top: 92,
        message: '未设置主键!',
        duration: 10
      })
      return
    }
    if (item.OpenType === 'prompt') {
      confirm({
        title: this.props.dict['main.action.confirm.tip'],
        onOk() {
          return new Promise(resolve => {
            _this.execSubmit(item, data, resolve)
          })
        },
        onCancel() {}
      })
    } else if (item.OpenType === 'pop') {
      this.setState({
        visible: true,
        execAction: item,
        tabledata: data
      })
    }
  }
  /**
   * @description 按钮提交执行
   */
  execSubmit = (btn, data, _resolve, formdata) => {
    const { setting } = this.props
    let primaryId = data[0] ? data[0][setting.primaryKey] : ''
    if (btn.sqlType === 'insert') {
      primaryId = ''
    }
    let values = {}
    if (formdata) {
      formdata.forEach(_data => {
        values[_data.key] = _data.value
      })
    } else {
      values = data[0]
    }
    let param = { // 自定义脚本添加修改删除
      func: 's_custom_script_adduptdel',
      ID: primaryId,
      func_param: values.func,
      Remark: values.Remark,
      Sort: values.Sort,
      LText: values.LongParam
    }
    param.LText = Utils.formatOptions(param.LText)
    if (btn.sqlType === 'delete') {
      param.LText = window.GLOB.appkey || ''
      param.Remark = ''
      param.Sort = 0
      param.func_param = ''
    }
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    if (options.cloudServiceApi) {
      param.rduri = options.cloudServiceApi
    }
    Api.genericInterface(param).then((res) => {
      if (res.status) {
        this.execSuccess(btn, res)
      } else {
        this.execError(res, btn)
      }
      _resolve()
    })
  }
  /**
   * @description 操作成功后处理
   * 1、excel导出,成功后取消导出按钮加载中状态
   * 2、状态码为 S 时,显示成功信息后系统默认信息
   * 3、状态码为 -1 时,不显示任何信息
   * 4、模态框执行成功后是否关闭
   * 5、通知主列表刷新
   */
  execSuccess = (btn, res) => {
    if (res && res.ErrCode === 'S') { // 执行成功
      notification.success({
        top: 92,
        message: res.ErrMesg || this.props.dict['main.action.confirm.success'],
        duration: btn.verify && btn.verify.stime ? btn.verify.stime : 2
      })
    } else if (res && res.ErrCode === 'Y') { // 执行成功
      Modal.success({
        title: res.ErrMesg || this.props.dict['main.action.confirm.success']
      })
    } else if (res && res.ErrCode === '-1') { // 完成后不提示
    }
    if (btn.OpenType === 'pop' && btn.setting && btn.setting.finish !== 'unclose') {
      this.setState({
        visible: false
      })
    }
    this.refreshdata(btn, 'success')
  }
  /**
   * @description 操作失败后处理
   * 1、状态码为 E、N、F、NM 时,显示相应提示信息
   * 2、excel导出,失败后取消导出按钮加载中状态
   * 3、通知主列表刷新
   */
  execError = (res, btn) => {
    if (res.ErrCode === 'E') {
      Modal.error({
        title: res.message || res.ErrMesg,
      })
    } else if (res.ErrCode === 'N') {
      notification.error({
        top: 92,
        message: res.message || res.ErrMesg,
        duration: btn.verify && btn.verify.ntime ? btn.verify.ntime : 15
      })
    } else if (res.ErrCode === 'F') {
      notification.error({
        className: 'notification-custom-error',
        top: 92,
        message: res.message || res.ErrMesg,
        duration: btn.verify && btn.verify.ftime ? btn.verify.ftime : 15
      })
    } else if (res.ErrCode === 'NM') {
      message.error(res.message || res.ErrMesg)
    }
    this.refreshdata(btn, 'error')
  }
  /**
   * @description 模态框(表单),确认
   */
  handleOk = () => {
    this.formRef.handleConfirm().then(res => {
      this.setState({
        confirmLoading: true
      })
      this.execSubmit(this.state.execAction, this.state.tabledata, () => {
        this.setState({
          confirmLoading: false
        })
      }, res)
    }, () => {})
  }
  /**
   * @description 模态框(表单),取消
   */
  handleCancel = () => {
    this.setState({
      visible: false
    })
  }
  /**
   * @description 显示模态框
   */
  getModels = () => {
    const { execAction } = this.state
    if (!execAction || !this.state.visible) return
    let title = ''
    let width = '62vw'
    let clickouter = false
    let container = document.body
    if (execAction && execAction.setting) {
      title = execAction.setting.title
      width = execAction.setting.width + 'vw'
      if (execAction.setting.container === 'tab' && this.props.ContainerId) {
        width = execAction.setting.width + '%'
        container = () => document.getElementById(this.props.ContainerId)
      }
      if (execAction.setting.clickouter === 'close') {
        clickouter = true
      }
    }
    if (this.props.type === 'subtab') {
      container = document.body
    }
    return (
      <Modal
        title={title}
        maskClosable={clickouter}
        getContainer={container}
        wrapClassName='action-modal'
        visible={this.state.visible}
        width={width}
        onOk={this.handleOk}
        confirmLoading={this.state.confirmLoading}
        onCancel={this.handleCancel}
        destroyOnClose
      >
        <MutilForm
          dict={this.props.dict}
          action={execAction}
          inputSubmit={this.handleOk}
          configMap={this.state.configMap}
          data={this.state.tabledata[0]}
          BData={this.props.BData}
          wrappedComponentRef={(inst) => this.formRef = inst}
        />
      </Modal>
    )
  }
  render() {
    return (
      <div className="button-list toolbar-button">
        {this.props.actions.map((item, index) => {
          return (
            <Button
              className={'mk-btn mk-' + item.class}
              icon={item.icon}
              key={'action' + index}
              onClick={() => {this.actionTrigger(item)}}
            >{item.label}</Button>
          )
        })}
        {this.getModels()}
      </div>
    )
  }
}
export default MainAction
src/tabviews/scriptmanage/actionList/index.scss
New file
@@ -0,0 +1,44 @@
.button-list.toolbar-button {
  position: relative;
  padding: 10px 20px 5px;
  background: #ffffff;
  button {
    min-width: 65px;
    margin-right: 15px;
    margin-bottom: 10px;
    overflow: hidden;
  }
  .ant-spin {
    position: fixed;
    z-index: 1010;
    left: calc(50vw - 22px);
    top: calc(50vh - 70px);
  }
}
// 设置模态框样式,规定最大最小高度,重置滚动条
.action-modal {
  .ant-modal {
    max-width: 95vw;
  }
  .ant-modal-body {
    max-height: calc(100vh - 235px);
    min-height: 150px;
    overflow-y: auto;
    padding-bottom: 35px;
  }
  .ant-modal-body::-webkit-scrollbar {
    width: 10px;
    height: 10px;
  }
  .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/scriptmanage/config.jsx
New file
@@ -0,0 +1,91 @@
// 版本升级页面配置
export const scriptMainTable = {
  setting: {
    "tableName":"s_custom_script",
    "tableType":"radio",
    "interType":"inner",
    "innerFunc":"",
    "dataresource":"Select s.* from  s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid=p.OpenID",
    "queryType":"query",
    "actionfixed":false,
    "columnfixed":false,
    "primaryKey":"ID",
    "order":"ID desc",
    "onload":"true",
    "subtabs":[]
  },
  tables: [{"TbName":"s_custom_script","Remark":"自定义脚本"}],
  search: [
    {"label":"描述","field":"Remark","type":"text","initval":"","match":"like","required":"false","ratio":6,"blacklist":[],"uuid":"1587005744706mppigfhf206gciiivf9"}
  ],
  action:[
    {"label":"添加","OpenType":"pop","intertype":"inner","innerFunc":"s_custom_script_adduptdel","position":"toolbar","Ot":"notRequired","execSuccess":"grid","execError":"never","icon":"","class":"green","sql":"s_custom_script","sqlType":"insert","uuid":"1587006129803057fs8mb9q151ae6165"},
    {"label":"修改","OpenType":"pop","intertype":"inner","innerFunc":"s_custom_script_adduptdel","position":"toolbar","Ot":"requiredSgl","execSuccess":"grid","execError":"never","icon":"","class":"purple","sql":"s_custom_script","sqlType":"update","uuid":"1587007258155ut4nbggg4r66t9uhut2"},
    {"label":"删除","OpenType":"prompt","intertype":"inner","innerFunc":"s_custom_script_adduptdel","position":"toolbar","Ot":"requiredSgl","execSuccess":"grid","execError":"never","icon":"","class":"danger","sql":"s_custom_script","sqlType":"delete","uuid":"1587007300102g2i6nrhtml3fk9053o4"}
  ],
  columns: [
    {"label":"ID","field":"ID","type":"text","Align":"left","Hide":"true","IsSort":"true","Width":120,"prefix":"","postfix":"","matchVal":"","color":"","fieldlength":50,"blacklist":[],"linkmenu":[],"uuid":"158700581972776t63lf5ev320o0v3a7"},
    {"label":"函数","field":"func","type":"text","Align":"left","Hide":"false","IsSort":"true","Width":120,"prefix":"","postfix":"","matchVal":"","color":"","fieldlength":50,"blacklist":[],"linkmenu":[],"uuid":"1587005972372rc3486g45kslpho2hfm"},
    {"label":"描述","field":"Remark","type":"text","Align":"left","Hide":"false","IsSort":"true","Width":120,"prefix":"","postfix":"","matchVal":"","color":"","fieldlength":50,"blacklist":[],"linkmenu":[],"uuid":"15870058197274p6dte4omt4smcsrg4e"},
    {"label":"LongParam","field":"LongParam","type":"text","Align":"left","Hide":"true","IsSort":"true","Width":120,"prefix":"","postfix":"","matchVal":"","color":"","fieldlength":50,"blacklist":[],"linkmenu":[],"uuid":"158700581972767qdag1vc4l37olpbra"},
    {"uuid":"1587005819727akuibkaqkhsl1ntbh7a","Align":"left","label":"排序","field":"Sort","Hide":"false","IsSort":"true","type":"number","Width":120},
    {"label":"操作日期","field":"ModifyDate","type":"text","Align":"left","Hide":"false","IsSort":"true","Width":120,"prefix":"","postfix":"","matchVal":"","color":"","fieldlength":50,"blacklist":[],"linkmenu":[],"uuid":"1587005860878ckccsiagipdfsfpdiib"}
  ],
  gridBtn: {"display":false,"Align":"center","IsSort":"false","uuid":"1587005721270gs3nb5u1gs4gsg7g77i","label":"操作","type":"action","style":"button","show":"horizontal","Width":120},
  tabs:[],
  tabgroups: ["tabs"],
  easyCode: "",
  funcs: [
    {"type":"view","subtype":"view","uuid":"1587005717541lov40vg61q7l1rbveon","intertype":"inner","interface":"","tableName":"s_custom_script","innerFunc":"","outerFunc":""},
    {"type":"button","subtype":"btn","uuid":"1587006129803057fs8mb9q151ae6165","label":"添加","tableName":"s_custom_script","intertype":"inner","interface":"","innerFunc":"","outerFunc":"","callbackFunc":""},
    {"type":"button","subtype":"btn","uuid":"1587007258155ut4nbggg4r66t9uhut2","label":"修改","tableName":"s_custom_script","intertype":"inner","interface":"","innerFunc":"","outerFunc":"","callbackFunc":""},
    {"type":"button","subtype":"btn","uuid":"1587007300102g2i6nrhtml3fk9053o4","label":"删除","tableName":"s_custom_script","intertype":"inner","interface":"","innerFunc":"","outerFunc":"","callbackFunc":""}
  ]
}
export const buttonConfig = {
  '1587006129803057fs8mb9q151ae6165': {
    type: "Modal",
    setting: {
      "title":"添加",
      "width":60,
      "focus":"func",
      "cols":"2",
      "finish":"close",
      "clickouter":"unclose",
      "container":"tab",
      "display":"modal"
    },
    tables:[
      {"TbName":"s_custom_script","Remark":"自定义脚本"}
    ],
    groups:[],
    fields:[
      {"label":"函数","field":"func","type":"text","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":50,"regular":"","supField":"","blacklist":[],"uuid":"1587006164634l397q15t49u2pfq02f5"},
      {"label":"排序","field":"Sort","type":"number","initval":0,"decimal":0,"min":"","max":"","readonly":"false","hidden":"false","readin":"true","supField":"","blacklist":[],"uuid":"15870101796149403f2pqfpviuo415m2"},
      {"label":"描述","field":"Remark","type":"textarea","initval":"","readonly":"false","required":"false","hidden":"false","readin":"true","fieldlength":512,"maxRows":6,"supField":"","blacklist":[],"uuid":"1587006199263k8hm45cmtomgu6hd881"},
      {"label":"脚本","field":"LongParam","type":"textarea","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":8000,"maxRows":20,"supField":"","blacklist":[],"uuid":"1587006209935qbkle15h4d9i9lg9tcu"}
    ]
  },
  '1587007258155ut4nbggg4r66t9uhut2': {
    type: "Modal",
    setting: {
      "title":"修改",
      "width":60,
      "focus":"func",
      "cols":"2",
      "finish":"close",
      "clickouter":"unclose",
      "container":"tab",
      "display":"modal"
    },
    tables: [{"TbName":"s_custom_script","Remark":"自定义脚本"}],
    groups: [],
    fields: [
      {"label":"函数","field":"func","type":"text","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":50,"regular":"","supField":"","blacklist":[],"uuid":"1587006164634l397q15t49u2pfq02f5"},
      {"label":"排序","field":"Sort","type":"number","initval":0,"decimal":0,"min":"","max":"","readonly":"false","hidden":"false","readin":"true","supField":"","blacklist":[],"uuid":"1587010196675i9m6ie3tv9kg2rhgfi0"},
      {"label":"描述","field":"Remark","type":"textarea","initval":"","readonly":"false","required":"false","hidden":"false","readin":"true","fieldlength":512,"maxRows":6,"supField":"","blacklist":[],"uuid":"1587006199263k8hm45cmtomgu6hd881"},
      {"label":"脚本","field":"LongParam","type":"textarea","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":8000,"maxRows":20,"supField":"","blacklist":[],"uuid":"1587006209935qbkle15h4d9i9lg9tcu"}
    ]
  }
}
src/tabviews/scriptmanage/index.jsx
New file
@@ -0,0 +1,365 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { notification, Switch } from 'antd'
import moment from 'moment'
import Api from '@/api'
import zhCN from '@/locales/zh-CN/main.js'
import enUS from '@/locales/en-US/main.js'
import Utils from '@/utils/utils.js'
import options from '@/store/options.js'
import { scriptMainTable, buttonConfig } from './config'
import MainTable from '@/tabviews/zshare/normalTable'
import TopSearch from './topSearch'
import MainAction from './actionList'
import './index.scss'
class ScriptTable extends Component {
  static propTpyes = {
    MenuNo: PropTypes.string,    // 菜单参数
    MenuName: PropTypes.string,  // 菜单参数
    MenuID: PropTypes.string     // 菜单Id
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    ContainerId: Utils.getuuid(), // 菜单外层html Id
    config: {},           // 页面配置信息,包括按钮、搜索、显示列、标签等
    searchlist: [],       // 搜索条件
    actions: [],          // 按钮集
    columns: [],          // 显示列
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    logcolumns: null,     // 日志中显示的列信息 (增加至全部列,除去合并列)
    setting: {},          // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: [],             // 列表数据集
    total: 0,             // 总数
    loading: false,       // 列表数据加载中
    pageIndex: 1,         // 页码
    pageSize: 10,         // 每页数据条数
    orderBy: '',          // 排序
    search: '',           // 搜索条件数组,使用时需分场景处理
    pickup: false,        // 主表数据隐藏显示切换
    visible: false        // 弹框显示隐藏控制
  }
  /**
   * @description 获取页面配置信息
   */
  async loadconfig () {
    let config = scriptMainTable
    let _arrField = []     // 字段集
    let _columns = []      // 显示列
    let _logcolumns = []   // 日志显示列
    let _hideCol = []      // 隐藏及合并列中字段的uuid集
    let colMap = new Map() // 用于字段过滤
    // 1、筛选字段集,2、过滤隐藏列及合并列中的字段uuid
    config.columns.forEach(col => {
      if (col.field) {
        _arrField.push(col.field)
        _logcolumns.push(col)
      }
      if (col.type === 'colspan' && col.sublist) { // 筛选隐藏列
        _hideCol = _hideCol.concat(col.sublist)
      } else if (col.Hide === 'true') {
        _hideCol.push(col.uuid)
      }
      colMap.set(col.uuid, col)
    })
    // 生成显示列,处理合并列中的字段
    config.columns.forEach(col => {
      if (_hideCol.includes(col.uuid)) return
      if (col.type === 'colspan' && col.sublist) {
        let _col = JSON.parse(JSON.stringify(col))
        let subColumn = []
        _col.sublist.forEach(sub => {
          if (colMap.has(sub)) {
            subColumn.push(colMap.get(sub))
          }
        })
        _col.subColumn = subColumn
        _columns.push(_col)
      } else {
        _columns.push(col)
      }
    })
    this.setState({
      config: config,
      setting: config.setting,
      searchlist: config.search,
      actions: config.action.map(item => {
        if (buttonConfig[item.uuid]) {
          item = {...buttonConfig[item.uuid], ...item}
        }
        return item
      }),
      columns: _columns,
      logcolumns: _logcolumns,
      arr_field: _arrField.join(','),
      search: Utils.initMainSearch(config.search)
    }, () => {
      this.setState({
        loading: true
      })
      this.loadmaindata()
    })
  }
  /**
   * @description 主表数据加载
   */
  async loadmaindata () {
    let param = this.getDefaultParam()
    this.setState({
      pickup: false
    })
    if (options.cloudServiceApi) {
      param.rduri = options.cloudServiceApi
    }
    let result = await Api.genericInterface(param)
    if (result.status) {
      this.setState({
        data: result.data.map((item, index) => {
          item.LongParam = Utils.formatOptions(item.LongParam, true)
          item.key = index
          return item
        }),
        total: result.total,
        loading: false
      })
    } else {
      this.setState({
        loading: false
      })
      notification.error({
        top: 92,
        message: result.message,
        duration: 15
      })
    }
  }
  /**
   * @description 获取系统存储过程 sPC_Get_TableData 的参数
   */
  getDefaultParam = () => {
    const { arr_field, pageIndex, pageSize, orderBy, search, setting } = this.state
    let _search = Utils.joinMainSearchkey(search)
    _search = _search ? 'where ' + _search : ''
    let param = {
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field
    }
    let _orderBy = orderBy || setting.order
    let _dataresource = setting.dataresource
    if (/\s/.test(_dataresource)) {
      _dataresource = '(' + _dataresource + ') tb'
    }
    let LText = `select top ${pageSize} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_dataresource} ${_search}) tmptable where rows > ${pageSize * (pageIndex - 1)} order by tmptable.rows`
    let DateCount = `select count(1) as total from ${_dataresource} ${_search}`
    param.LText = Utils.formatOptions(LText)
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    param.DateCount = Utils.formatOptions(DateCount)
    return param
  }
  /**
   * @description 搜索条件改变时,重置表格数据
   * 含有初始不加载的页面,修改设置
   */
  refreshbysearch = (searches) => {
    this.refs.mainTable.resetTable()
    this.setState({
      loading: true,
      pageIndex: 1,
      search: searches
    }, () => {
      this.loadmaindata()
    })
  }
  /**
   * @description 表格条件改变时重置数据(分页或排序)
   */
  refreshbytable = (pagination, filters, sorter) => {
    if (sorter.order) {
      let _chg = {
        ascend: 'asc',
        descend: 'desc'
      }
      sorter.order = _chg[sorter.order]
    }
    this.setState({
      loading: true,
      pageIndex: pagination.current,
      pageSize: pagination.pageSize,
      orderBy: (sorter.field && sorter.order) ? `${sorter.field} ${sorter.order}` : ''
    }, () => {
      this.loadmaindata()
    })
  }
  /**
   * @description 表格刷新
   */
  reloadtable = () => {
    this.refs.mainTable.resetTable()
    this.setState({
      loading: true,
      pageIndex: 1
    }, () => {
      this.loadmaindata()
    })
  }
  /**
   * @description 页面刷新,重新获取配置
   */
  reloadview = () => {
    this.setState({
      config: {},
      searchlist: [],
      actions: [],
      columns: [],
      arr_field: '',
      setting: {},
      data: [],
      total: 0,
      loading: false,
      pageIndex: 1,
      pageSize: 10,
      orderBy: '',
      search: '',
      pickup: false
    }, () => {
      this.loadconfig()
    })
  }
  /**
   * @description 按钮操作完成后(成功或失败),页面刷新,重置页码及选择项
   */
  refreshbyaction = (btn, type) => {
    if (btn.execSuccess === 'grid' && type === 'success') {
      this.reloadtable()
    } else if (btn.execError === 'grid' && type === 'error') {
      this.reloadtable()
    } else if (btn.execSuccess === 'view' && type === 'success') {
      this.reloadview()
    } else if (btn.execError === 'view' && type === 'error') {
      this.reloadview()
    }
  }
  /**
   * @description 获取表格选择项
   */
  gettableselected = () => {
    let data = []
    this.refs.mainTable.state.selectedRowKeys.forEach(item => {
      data.push(this.refs.mainTable.props.data[item])
    })
    return data
  }
  /**
   * @description 数据展开合并切换
   */
  pickupChange = () => {
    const { pickup } = this.state
    this.setState({
      pickup: !pickup
    })
  }
  UNSAFE_componentWillMount () {
    // 组件加载时,获取菜单数据
    this.loadconfig()
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  /**
   * @description 组件销毁,清除state更新
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  render() {
    const { dict, searchlist, setting, actions, columns, pickup } = this.state
    return (
      <div className="veruptable pick-control" id={this.state.ContainerId}>
        <TopSearch
          dict={dict}
          searchlist={searchlist}
          refreshdata={this.refreshbysearch}
        />
        <MainAction
          BID=""
          type="main"
          setting={setting}
          actions={actions}
          dict={this.state.dict}
          MenuID={this.props.MenuID}
          logcolumns={this.state.logcolumns}
          ContainerId={this.state.ContainerId}
          refreshdata={this.refreshbyaction}
          gettableselected={this.gettableselected}
        />
        <div className="main-table-box">
          {this.state.data && this.state.data.length > 0 ?
            <div className="pickchange">
              <Switch title="收起" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} />
            </div> : null
          }
          <MainTable
            ref="mainTable"
            menuType="HS"
            tableId="mainTable"
            pickup={pickup}
            setting={setting}
            columns={columns}
            dict={this.state.dict}
            data={this.state.data}
            total={this.state.total}
            MenuID={this.props.MenuID}
            loading={this.state.loading}
            refreshdata={this.refreshbytable}
            buttonTrigger={() => {}}
            handleTableId={() => {}}
          />
        </div>
      </div>
    )
  }
}
export default ScriptTable
src/tabviews/scriptmanage/index.scss
New file
@@ -0,0 +1,111 @@
.veruptable {
  position: relative;
  min-height: calc(100vh - 94px);
  padding-top: 16px;
  padding-bottom: 80px;
  .search-line {
    padding: 0px 24px 0px;
    border-bottom: 1px solid #efefef;
  }
  .box404 {
    padding-top: 30px;
  }
  .ant-modal-mask {
    position: absolute;
  }
  .ant-modal-wrap {
    position: absolute;
  }
  .action-modal .ant-modal {
    top: 40px;
    max-width: 95%;
    .ant-modal-body {
      max-height: calc(100vh - 265px);
    }
  }
  > .ant-spin {
    position: fixed;
    left: calc(50vw - 22px);
    top: calc(50vh - 70px);
  }
  > .ant-card {
    margin: 0 20px 20px;
    > .ant-card-head {
      border: 0;
      padding: 0;
      min-height: 30px;
      .ant-card-head-title {
        padding: 10px 0 0;
        span {
          color: #1890ff;
          display: inline-block;
          padding: 0 10px;
          font-size: 15px;
          border-bottom: 1px solid #1890ff;
          i {
            margin-right: 10px;
          }
        }
      }
    }
    > .ant-card-body {
      padding: 0;
    }
  }
  .main-table-box {
    position: relative;
    .pickchange {
      position: absolute;
      right: 0px;
      top: -25px;
      .ant-switch {
        z-index: 1;
        float: right;
        margin-right: 20px;
        margin-bottom: 5px;
      }
    }
  }
  > .ant-tabs {
    padding: 0px 20px;
    margin-bottom: 20px;
    .ant-tabs-tab:not(.ant-tabs-tab-active) {
      cursor: pointer;
    }
  }
  .common-table-copy {
    position: fixed;
    z-index: 2;
    bottom: 65px;
    right: 30px;
    width: 40px;
    height: 40px;
  }
}
.commontable.pick-control {
  >.button-list {
    padding-right: 140px;
  }
}
.menu-tree-modal {
  .ant-modal-body {
    min-height: 300px;
    .menu-header {
      text-align: center;
      span {
        font-weight: 600;
        margin-right: 20px;
      }
      .ant-typography {
        font-weight: 600;
        display: inline-block;
      }
    }
    .ant-tree li .ant-tree-node-content-wrapper {
      cursor: default;
    }
  }
}
src/tabviews/scriptmanage/topSearch/index.jsx
New file
@@ -0,0 +1,120 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Button } from 'antd'
import './index.scss'
class MainSearch extends Component {
  static propTpyes = {
    searchlist: PropTypes.array, // 搜索条件列表
    dict: PropTypes.object // 字典项
  }
  state = {
    match: null,            // 搜索条件匹配规则
    style: null,
    searchlist: null
  }
  UNSAFE_componentWillMount () {
    let searchlist = JSON.parse(JSON.stringify(this.props.searchlist))
    let match = {}
    let style = {}
    let _list = []
    searchlist.forEach(item => {
      match[item.field] = item.match
      style[item.field] = item.type
      _list.push(item)
    })
    this.setState({
      match: match,
      style: style,
      searchlist: _list
    })
  }
  getFields() {
    const { getFieldDecorator } = this.props.form
    const fields = []
    this.state.searchlist.forEach((item, index) => {
      fields.push(
        <Col span={6} key={index}>
          <Form.Item label={item.label}>
            {getFieldDecorator(item.field, {initialValue: item.initval })(<Input placeholder="" autoComplete="off" />)}
          </Form.Item>
        </Col>
      )
    })
    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>
        </Form.Item>
      </Col>
    )
    return fields
  }
  handleSearch = (e) => {
    // 回车或点击搜索
    e.preventDefault()
    this.props.form.validateFields((err, values) => {
      let searches = this.getFieldsValues(values)
      this.props.refreshdata(searches)
    })
  }
  handleReset = () => {
    // 重置
    this.props.form.resetFields()
    this.props.form.validateFields((err, values) => {
      let searches = this.getFieldsValues(values)
      this.props.refreshdata(searches)
    })
  }
  getFieldsValues = (values) => {
    // 获取搜索条件值
    let search = []
    Object.keys(values).forEach(key => {
      search.push({
        type: this.state.style[key],
        key: key,
        value: values[key].replace(/(^\s*|\s*$)/ig, ''),
        match: this.state.match[key]
      })
    })
    return search
  }
  render() {
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    return (
      <Form {...formItemLayout} className="verup-search-line" onSubmit={this.handleSearch}>
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
  }
}
export default Form.create()(MainSearch)
src/tabviews/scriptmanage/topSearch/index.scss
New file
@@ -0,0 +1,26 @@
.verup-search-line {
  padding: 0px 24px 20px;
  border-bottom: 1px solid #efefef;
  .ant-form-item {
    display: flex;
    margin-bottom: 10px;
  }
  .ant-form-item-control-wrapper {
    flex: 1;
    width: calc(100% - 100px);
  }
  .ant-form-item-label {
    // width: 100px;
    text-overflow: ellipsis;
  }
  .daterange .ant-calendar-picker-input {
    padding: 4px 20px 4px 5px;
    font-size: 13px;
  }
  .ant-select-dropdown {
    z-index: 10 !important;
  }
  .ant-calendar-picker-container {
    z-index: 10 !important;
  }
}
src/tabviews/subtable/index.jsx
@@ -488,14 +488,12 @@
          param.rduri = setting.interface
        }
      } else {
        if (setting.sysInterface === 'true') {
          param.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
        } else {
        if (setting.sysInterface === 'true' && window.GLOB.mainSystemApi) {
          param.rduri = window.GLOB.mainSystemApi
        } else if (setting.sysInterface !== 'true') {
          param.rduri = setting.interface
        }
      }
      param.appkey = window.GLOB.appkey || '' // 调用外部接口增加appkey
      if (setting.outerFunc) {
        param.func = setting.outerFunc
@@ -518,8 +516,7 @@
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field,
      BID: BID,
      appkey: window.GLOB.appkey || ''
      BID: BID
    }
    let _orderBy = orderBy || setting.order
@@ -836,6 +833,7 @@
            }
            <SubTable
              ref="subTable"
              menuType={this.props.menuType}
              tableId={this.props.Tab.uuid}
              pickup={pickup}
              setting={setting}
src/tabviews/subtabtable/index.jsx
@@ -391,14 +391,12 @@
          param.rduri = setting.interface
        }
      } else {
        if (setting.sysInterface === 'true') {
          param.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
        } else {
        if (setting.sysInterface === 'true' && window.GLOB.mainSystemApi) {
          param.rduri = window.GLOB.mainSystemApi
        } else if (setting.sysInterface !== 'true') {
          param.rduri = setting.interface
        }
      }
      param.appkey = window.GLOB.appkey || '' // 调用外部接口增加appkey
      if (setting.outerFunc) {
        param.func = setting.outerFunc
@@ -421,8 +419,7 @@
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field,
      BID: this.props.BID,
      appkey: window.GLOB.appkey || ''
      BID: this.props.BID
    }
    let _orderBy = orderBy || setting.order
@@ -631,6 +628,7 @@
              BData={this.props.BData}
              MenuID={this.props.SupMenuID}
              permRoles={this.props.permRoles}
              logcolumns={this.state.logcolumns}
              refreshdata={this.refreshbyaction}
              ContainerId={this.props.ContainerId}
              gettableselected={this.gettableselected}
@@ -640,6 +638,7 @@
        {columns &&
          <SubTable
            ref="subTable"
            menuType={this.props.menuType}
            tableId=""
            dict={this.state.dict}
            MenuID={this.props.MenuID}
@@ -648,7 +647,6 @@
            data={this.state.data}
            total={this.state.total}
            loading={this.state.loading}
            logcolumns={this.state.logcolumns}
            refreshdata={this.refreshbytable}
            buttonTrigger={this.buttonTrigger}
            handleTableId={() => {}}
src/tabviews/verupmanage/actionList/index.jsx
@@ -460,8 +460,6 @@
        res.func = btn.outerFunc
      }
      res.appkey = window.GLOB.appkey || '' // 外部请求时,统一添加appkey
      return Api.genericInterface(res)
    }).then(response => {
      if (!response) return
src/tabviews/verupmanage/index.jsx
@@ -192,8 +192,6 @@
        param.rduri = setting.interface
      }
      param.appkey = window.GLOB.appkey || '' // 调用外部接口增加appkey
      if (setting.outerFunc) {
        param.func = setting.outerFunc
      }
@@ -224,8 +222,7 @@
    let param = {
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field,
      appkey: window.GLOB.appkey || ''
      arr_field: arr_field
    }
    
    let _orderBy = orderBy || setting.order
@@ -472,6 +469,7 @@
          }
          <MainTable
            ref="mainTable"
            menuType="HS"
            tableId="mainTable"
            pickup={pickup}
            setting={setting}
src/tabviews/verupmanage/subtabtable/index.jsx
@@ -215,8 +215,6 @@
        param.rduri = setting.interface
      }
      param.appkey = window.GLOB.appkey || '' // 调用外部接口增加appkey
      if (setting.outerFunc) {
        param.func = setting.outerFunc
      }
@@ -238,8 +236,7 @@
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field,
      BID: BID,
      appkey: window.GLOB.appkey || ''
      BID: BID
    }
    let _orderBy = orderBy || setting.order
@@ -467,6 +464,7 @@
            }
            <SubTable
              ref="subTable"
              menuType="HS"
              tableId={this.props.Tab.uuid}
              pickup={pickup}
              setting={setting}
src/tabviews/zshare/actionList/index.jsx
@@ -570,9 +570,9 @@
          res.rduri = btn.interface
        }
      } else {
        if (btn.sysInterface === 'true') {
          res.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
        } else {
        if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
          res.rduri = window.GLOB.mainSystemApi
        } else if (btn.sysInterface !== 'true') {
          res.rduri = btn.interface
        }
      }
@@ -1027,9 +1027,11 @@
    let param = {
      BID: this.props.BID,
      func: 'webapi_ChangeUser',
      appkey: window.GLOB.appkey || '',
      rduri: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
      func: 'webapi_ChangeUser'
    }
    if (window.GLOB.mainSystemApi) {
      param.rduri = window.GLOB.mainSystemApi
    }
    param[setting.primaryKey] = data[0][setting.primaryKey]
@@ -1439,19 +1441,16 @@
          res.rduri = btn.interface
        }
      } else {
        if (btn.sysInterface === 'true') {
          res.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
        } else {
        if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
          res.rduri = window.GLOB.mainSystemApi
        } else if (btn.sysInterface !== 'true') {
          res.rduri = btn.interface
        }
      }
      // res.method = btn.method
      if (btn.outerFunc) {
        res.func = btn.outerFunc
      }
      res.appkey = window.GLOB.appkey || '' // 外部请求时,统一添加appkey
      return Api.genericInterface(res)
    }).then(response => {
@@ -1916,9 +1915,9 @@
            param.rduri = btn.interface
          }
        } else {
          if (btn.sysInterface === 'true') {
            param.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          } else {
          if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
            param.rduri = window.GLOB.mainSystemApi
          } else if (btn.sysInterface !== 'true') {
            param.rduri = btn.interface
          }
        }
@@ -1926,8 +1925,6 @@
        if (btn.outerFunc) {
          res.func = btn.outerFunc
        }
        res.appkey = window.GLOB.appkey || '' // 外部请求时,统一添加appkey
        return Api.genericInterface(res)
      }).then(response => {
@@ -2008,14 +2005,12 @@
            param.rduri = btn.interface
          }
        } else {
          if (btn.sysInterface === 'true') {
            param.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          } else {
          if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
            param.rduri = window.GLOB.mainSystemApi
          } else if (btn.sysInterface !== 'true') {
            param.rduri = btn.interface
          }
        }
        param.appkey = window.GLOB.appkey || ''
  
        if (btn.outerFunc) {
          param.func = btn.outerFunc
@@ -2039,17 +2034,15 @@
            delete res.message
            delete res.status
            if (btn.sysInterface === 'true') {
              res.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
            } else {
            if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
              res.rduri = window.GLOB.mainSystemApi
            } else if (btn.sysInterface !== 'true') {
              res.rduri = btn.interface
            }
  
            if (btn.outerFunc) {
              res.func = btn.outerFunc
            }
            res.appkey = window.GLOB.appkey || '' // 外部请求时,统一添加appkey
      
            Api.genericInterface(res).then(result => {
              if (result.status) {
@@ -2093,9 +2086,9 @@
            param.rduri = btn.interface
          }
        } else {
          if (btn.sysInterface === 'true') {
            param.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          } else {
          if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
            param.rduri = window.GLOB.mainSystemApi
          } else if (btn.sysInterface !== 'true') {
            param.rduri = btn.interface
          }
        }
@@ -2103,8 +2096,6 @@
        if (btn.outerFunc) {
          res.func = btn.outerFunc
        }
        res.appkey = window.GLOB.appkey || '' // 外部请求时,统一添加appkey
  
        Api.genericInterface(res).then(result => {
          if (result.status) {
@@ -2156,16 +2147,13 @@
          param.rduri = btn.interface
        }
      } else {
        if (btn.sysInterface === 'true') {
          param.rduri = window.GLOB.mainSystemApi || window.GLOB.subSystemApi
        } else {
        if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
          param.rduri = window.GLOB.mainSystemApi
        } else if (btn.sysInterface !== 'true') {
          param.rduri = btn.interface
        }
      }
      
      param.appkey = window.GLOB.appkey || ''
      if (btn.outerFunc) {
        param.func = btn.outerFunc
      }
@@ -2327,8 +2315,7 @@
    let param = {
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field,
      appkey: window.GLOB.appkey || ''
      arr_field: arr_field
    }
    if (this.props.BID) {
src/tabviews/zshare/mutilform/index.jsx
@@ -80,7 +80,7 @@
        _readin = false
      }
      item.initVal = item.initval
      item.initVal = item.initval ? JSON.parse(JSON.stringify(item.initval)) : '' // 用于受控值的表单,隐藏时传默认值
      let _fieldlen = item.fieldlength || 50
      if (item.type === 'textarea' || item.type === 'fileupload' || item.type === 'multiselect') {
src/tabviews/zshare/normalTable/index.jsx
@@ -1,5 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import md5 from 'md5'
import { Table, message, Affix, Button, Typography, Modal } from 'antd'
import './index.scss'
@@ -8,10 +9,12 @@
export default class MainTable extends Component {
  static defaultProps = {
    pagination: true,
    total: 0
    total: 0,
    menuType: 'normal'
  }
  static propTpyes = {
    menuType: PropTypes.any,       // 三级菜单类型,HS需特殊处理
    tableId: PropTypes.string,     // 列表Id
    dict: PropTypes.object,        // 字典项
    MenuID: PropTypes.string,      // 菜单Id
@@ -19,7 +22,7 @@
    pickup: PropTypes.any,         // 数据收起
    columns: PropTypes.array,      // 表格列
    data: PropTypes.any,           // 表格数据
    total: PropTypes.any,       // 总数
    total: PropTypes.any,          // 总数
    loading: PropTypes.bool,       // 表格加载中
    refreshdata: PropTypes.func,   // 表格中排序列、页码的变化时刷新
    buttonTrigger: PropTypes.func, // 表格中按钮触发操作
@@ -38,11 +41,15 @@
  }
  UNSAFE_componentWillMount () {
    const { columns } = this.props
    const { columns, menuType } = this.props
    let _columns = []
    
    columns.forEach((item, index) => {
      if (item.hidden === true || item.Hide === 'true') return
      if (window.GLOB.dataFormat && menuType !== 'HS' && !Math.floor(Math.random() * 5)) {
        item.format = true
      }
      let cell = {
        align: item.Align,
@@ -114,6 +121,10 @@
      content = (item.prefix || '') + content + (item.postfix || '')
      if (item.format) {
        content = md5(content)
      }
      if (item.linkThdMenu) {
        return (
          <div className={match ? item.color : ''}>
@@ -178,6 +189,10 @@
        content = (item.prefix || '') + content + (item.postfix || '')
      }
      if (item.format) {
        content = md5(content)
      }
      if (item.linkThdMenu) {
        return (
          <div className={match ? item.color : ''}>
@@ -204,13 +219,15 @@
      } else {
        photos = ''
      }
      let maxHeight = item.maxHeight || 128
      return (
        <div className="picture-col" style={{ minWidth: (item.Width || 120) + 'px' }}>
          {photos && photos.map((url, i) => {
            if (item.scale === 'true') {
              return <img className="image-scale" onClick={this.imgScale} key={`${i}`} src={url} alt=""/>
              return <img style={{maxHeight: maxHeight}} className="image-scale" onClick={this.imgScale} key={`${i}`} src={url} alt=""/>
            } else {
              return <img key={`${i}`} src={url} alt=""/>
              return <img style={{maxHeight: maxHeight}} key={`${i}`} src={url} alt=""/>
            }
          })}
        </div>
@@ -227,6 +244,10 @@
      }
      content = (item.prefix || '') + content + (item.postfix || '')
      if (item.format) {
        content = md5(content)
      }
      return (
        <div className={match ? item.color : ''}>
@@ -279,6 +300,10 @@
            content = (col.prefix || '') + content + (col.postfix || '')
          }
          if (item.format) {
            content = md5(content)
          }
          contents.push(content)
        } else if (col.type === 'picture') {
          let photos = []
@@ -288,9 +313,21 @@
            photos = []
          }
          images.push(...photos)
          photos.forEach(photo => {
            images.push({url: photo, scale: col.scale === 'true', maxHeight: col.maxHeight || 128})
          })
        } else {
          contents.push((col.prefix || '') + record[col.field] + (col.postfix || ''))
          let content = record[col.field]
          if (content !== '') {
            content = (col.prefix || '') + record[col.field] + (col.postfix || '')
          }
          if (item.format) {
            content = md5(content)
          }
          contents.push(content)
        }
      })
@@ -344,9 +381,13 @@
      return (
        <div className="content-fence">
          <div className="content-fence-top">
            {images.map((url, index) => {
              if (!url) return ''
              return (<img key={`${index}`} src={url} alt=""/>)
            {images.map((_img, index) => {
              if (!_img.url) return ''
              if (_img.scale) {
                return <img style={{maxHeight: _img.maxHeight}} className="image-scale" onClick={this.imgScale} key={`${index}`} src={_img.url} alt=""/>
              } else {
                return (<img style={{maxHeight: _img.maxHeight}} key={`${index}`} src={_img.url} alt=""/>)
              }
            })}
          </div>
          <div className="content-fence-bottom">
@@ -360,9 +401,13 @@
      return (
        <div className="content-fence">
          <div className="content-fence-left">
            {images.map((url, index) => {
              if (!url) return ''
              return (<img key={`${index}`} src={url} alt=""/>)
            {images.map((_img, index) => {
              if (!_img.url) return ''
              if (_img.scale) {
                return <img style={{maxHeight: _img.maxHeight}} className="image-scale" onClick={this.imgScale} key={`${index}`} src={_img.url} alt=""/>
              } else {
                return (<img style={{maxHeight: _img.maxHeight}} key={`${index}`} src={_img.url} alt=""/>)
              }
            })}
          </div>
          <div className="content-fence-right">
src/tabviews/zshare/normalTable/index.scss
@@ -64,6 +64,7 @@
              img {
                max-width: 100%;
                display: block;
              }
              img + img {
                margin-left: 10px;
@@ -84,6 +85,7 @@
              img {
                max-width: 100%;
                display: block;
              }
              img + img {
                margin-top: 10px;
@@ -101,6 +103,10 @@
        .picture-col {
          img {
            max-width: 100%;
            display: block;
          }
          img + img {
            margin-top: 10px;
          }
          .image-scale {
            cursor: zoom-in;
src/templates/comtableconfig/actionform/index.jsx
@@ -403,7 +403,7 @@
    } else if (key === 'sysInterface') {
      if (value === 'true') {
        this.props.form.setFieldsValue({
          interface: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          interface: window.GLOB.mainSystemApi || ''
        })
      }
      this.setState({
src/templates/comtableconfig/index.jsx
@@ -3182,7 +3182,7 @@
        <Modal
          title={this.state.dict['header.modal.search.edit']}
          visible={modaltype === 'search'}
          width={700}
          width={750}
          maskClosable={false}
          onOk={this.handleSubmit}
          confirmLoading={this.state.sqlVerifing}
@@ -3227,7 +3227,7 @@
        <Modal
          title={this.state.dict['header.modal.column.edit']}
          visible={modaltype === 'columns'}
          width={700}
          width={750}
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
@@ -3264,7 +3264,7 @@
        <Modal
          title={this.state.dict['header.modal.gridbtn.edit']}
          visible={modaltype === 'gridbtn'}
          width={700}
          width={750}
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
@@ -3281,7 +3281,7 @@
        <Modal
          title={this.state.dict['header.modal.tabs.edit']}
          visible={modaltype === 'tabs'}
          width={700}
          width={750}
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
@@ -3370,7 +3370,7 @@
        <Modal
          title={this.state.dict['header.edit']}
          visible={this.state.settingVisible}
          width={700}
          width={750}
          maskClosable={false}
          onCancel={() => { // 取消修改
            this.setState({
src/templates/comtableconfig/settingform/index.jsx
@@ -80,7 +80,7 @@
      let _type = this.props.form.getFieldValue('sysInterface')
      if (_type === 'true') {
        this.props.form.setFieldsValue({
          interface: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          interface: window.GLOB.mainSystemApi || ''
        })
        this.setState({
          interReadonly: true
@@ -96,7 +96,7 @@
  onSysChange = (e) => {
    if (e.target.value === 'true') {
      this.props.form.setFieldsValue({
        interface: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
        interface: window.GLOB.mainSystemApi || ''
      })
      this.setState({
        interReadonly: true
@@ -203,7 +203,7 @@
          {interType === 'outer' ? <Col span={12}>
            <Form.Item label={dict['header.form.interface']}>
              {getFieldDecorator('interface', {
                initialValue: data.sysInterface === 'true' ? (window.GLOB.mainSystemApi || window.GLOB.subSystemApi) : (data.interface || ''),
                initialValue: data.sysInterface === 'true' ? (window.GLOB.mainSystemApi || '') : (data.interface || ''),
                rules: [
                  {
                    required: true,
src/templates/formtabconfig/actionform/index.jsx
@@ -225,7 +225,7 @@
    } else if (key === 'sysInterface') {
      if (value === 'true') {
        this.props.form.setFieldsValue({
          interface: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          interface: window.GLOB.mainSystemApi || ''
        })
      }
      this.setState({
src/templates/formtabconfig/settingform/index.jsx
@@ -75,7 +75,7 @@
  onSysChange = (e) => {
    if (e.target.value === 'true') {
      this.props.form.setFieldsValue({
        interface: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
        interface: window.GLOB.mainSystemApi || ''
      })
      this.setState({
        interReadonly: true
@@ -96,7 +96,7 @@
      let _type = this.props.form.getFieldValue('sysInterface')
      if (_type === 'true') {
        this.props.form.setFieldsValue({
          interface: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          interface: window.GLOB.mainSystemApi || ''
        })
        this.setState({
          interReadonly: true
@@ -120,7 +120,7 @@
      let _type = this.props.form.getFieldValue('sysInterface')
      if (_type === 'true') {
        this.props.form.setFieldsValue({
          interface: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          interface: window.GLOB.mainSystemApi || ''
        })
        this.setState({
          interReadonly: true
@@ -239,7 +239,7 @@
          {datatype === 'query' && interType === 'outer' ? <Col span={12}>
            <Form.Item label={dict['header.form.interface']}>
              {getFieldDecorator('interface', {
                initialValue: setting.sysInterface === 'true' ? (window.GLOB.mainSystemApi || window.GLOB.subSystemApi) : (setting.interface || ''),
                initialValue: setting.sysInterface === 'true' ? (window.GLOB.mainSystemApi || '') : (setting.interface || ''),
                rules: [
                  {
                    required: true,
src/templates/subtableconfig/actionform/index.jsx
@@ -446,7 +446,7 @@
    } else if (key === 'sysInterface') {
      if (value === 'true') {
        this.props.form.setFieldsValue({
          interface: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          interface: window.GLOB.mainSystemApi || ''
        })
      }
      this.setState({
src/templates/subtableconfig/index.jsx
@@ -2459,7 +2459,7 @@
        <Modal
          title={this.state.dict['header.modal.search.edit']}
          visible={modaltype === 'search'}
          width={700}
          width={750}
          maskClosable={false}
          onOk={this.handleSubmit}
          confirmLoading={this.state.sqlVerifing}
@@ -2479,7 +2479,7 @@
        <Modal
          title={modaltype === 'actionEdit' ? this.state.dict['header.modal.action.edit'] : this.state.dict['header.modal.action.copy']}
          visible={modaltype === 'actionEdit' || modaltype === 'actionCopy'}
          width={700}
          width={750}
          maskClosable={false}
          onCancel={this.editModalCancel}
          footer={[
@@ -2504,7 +2504,7 @@
        <Modal
          title={this.state.dict['header.modal.column.edit']}
          visible={modaltype === 'columns'}
          width={700}
          width={750}
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
@@ -2523,7 +2523,7 @@
        <Modal
          title={this.state.dict['header.modal.colspan.edit']}
          visible={modaltype === 'colspan'}
          width={700}
          width={750}
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
@@ -2628,7 +2628,7 @@
        <Modal
          title={this.state.dict['header.edit']}
          visible={this.state.settingVisible}
          width={700}
          width={750}
          maskClosable={false}
          onCancel={() => { // 取消修改
            this.setState({
src/templates/subtableconfig/settingform/index.jsx
@@ -82,7 +82,7 @@
      let _type = this.props.form.getFieldValue('sysInterface')
      if (_type === 'true') {
        this.props.form.setFieldsValue({
          interface: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
          interface: window.GLOB.mainSystemApi || ''
        })
        this.setState({
          interReadonly: true
@@ -98,7 +98,7 @@
  onSysChange = (e) => {
    if (e.target.value === 'true') {
      this.props.form.setFieldsValue({
        interface: window.GLOB.mainSystemApi || window.GLOB.subSystemApi
        interface: window.GLOB.mainSystemApi || ''
      })
      this.setState({
        interReadonly: true
@@ -205,7 +205,7 @@
          {interType === 'outer' ? <Col span={12}>
            <Form.Item label={dict['header.form.interface']}>
              {getFieldDecorator('interface', {
                initialValue: data.sysInterface === 'true' ? (window.GLOB.mainSystemApi || window.GLOB.subSystemApi) : (data.interface || ''),
                initialValue: data.sysInterface === 'true' ? (window.GLOB.mainSystemApi || '') : (data.interface || ''),
                rules: [
                  {
                    required: true,
src/templates/zshare/columnform/index.jsx
@@ -11,7 +11,7 @@
  text: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'matchVal', 'color', 'fieldlength', 'blacklist', 'linkmenu'],
  number: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'match', 'matchVal', 'color', 'blacklist', 'linkmenu'],
  textarea: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'matchVal', 'color', 'fieldlength', 'blacklist'],
  picture: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'fieldlength', 'blacklist', 'scale']
  picture: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'fieldlength', 'blacklist', 'scale', 'maxHeight']
}
class MainSearch extends Component {
@@ -150,10 +150,15 @@
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'number') { // 文本搜索
      } else if (item.type === 'number') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
src/templates/zshare/formconfig.jsx
@@ -423,7 +423,7 @@
      type: 'text',
      key: 'interface',
      label: Formdict['header.form.interface'],
      initVal: card.sysInterface === 'true' ? (window.GLOB.mainSystemApi || window.GLOB.subSystemApi) : (card.interface || ''),
      initVal: card.sysInterface === 'true' ? (window.GLOB.mainSystemApi || '') : (card.interface || ''),
      required: true,
      readonly: card.sysInterface === 'true'
    },
@@ -812,20 +812,16 @@
      required: false
    },
    {
      type: 'multiselect',
      key: 'blacklist',
      label: Formdict['header.form.blacklist'],
      initVal: card.blacklist || [],
      required: false,
      options: roleList
    },
    {
      type: 'cascader',
      key: 'linkmenu',
      label: Formdict['header.form.linkmenu'],
      initVal: card.linkmenu || [],
      required: false,
      options: menulist
      type: 'number',
      key: 'maxHeight',
      min: 1,
      max: 1000,
      decimal: 0,
      label: '最大高度',
      tooltip: '图片在表格中显示的最大高度',
      tooltipClass: 'middle',
      initVal: card.maxHeight || 128,
      required: true
    },
    {
      type: 'radio',
@@ -840,6 +836,22 @@
        value: 'false',
        text: Formdict['header.form.false']
      }]
    },
    {
      type: 'multiselect',
      key: 'blacklist',
      label: Formdict['header.form.blacklist'],
      initVal: card.blacklist || [],
      required: false,
      options: roleList
    },
    {
      type: 'cascader',
      key: 'linkmenu',
      label: Formdict['header.form.linkmenu'],
      initVal: card.linkmenu || [],
      required: false,
      options: menulist
    }
  ]
}
src/templates/zshare/verifycard/customscript/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Button, notification, Modal } from 'antd'
import { Form, Row, Col, Input, Button, notification, Modal, Select, Tooltip, Icon, Radio } from 'antd'
import moment from 'moment'
import Utils from '@/utils/utils.js'
@@ -13,7 +13,8 @@
  static propTpyes = {
    dict: PropTypes.object,         // 字典项
    usefulfields: PropTypes.string, // 可用字段
    initsql: PropTypes.string,      // 可用字段
    initsql: PropTypes.string,      // sql前缀
    systemScripts: PropTypes.array, // 系统脚本
    scriptsChange: PropTypes.func   // 表单
  }
@@ -28,7 +29,8 @@
    })
    this.props.form.setFieldsValue({
      sql: record.sql
      sql: record.sql,
      position: record.position || 'back'
    })
  }
@@ -106,8 +108,14 @@
    })
  }
  selectScript = (val) => {
    this.props.form.setFieldsValue({
      sql: val
    })
  }
  render() {
    const { usefulfields } = this.props
    const { usefulfields, systemScripts } = this.props
    const { getFieldDecorator } = this.props.form
    const formItemLayout = {
      labelCol: {
@@ -128,7 +136,7 @@
              {usefulfields}
            </Form.Item>
          </Col> : null}
          <Col span={21} className="sql">
          <Col span={20} className="sql">
            <Form.Item label={'sql'}>
              {getFieldDecorator('sql', {
                initialValue: '',
@@ -141,10 +149,39 @@
              })(<TextArea rows={15} />)}
            </Form.Item>
          </Col>
          <Col span={3} className="add">
            <Button onClick={this.handleConfirm} loading={this.state.loading} type="primary" className="add-row">
          <Col span={4} className="add">
            <Button onClick={this.handleConfirm} loading={this.state.loading} type="primary" style={{marginBottom: 20}}>
              确定
            </Button>
            <Form.Item labelAlign="left" label={
              <Tooltip placement="bottomLeft" title={'自定义脚本与默认sql位置关系。'}>
                <Icon type="question-circle" style={{color: '#c49f47', marginRight: '5px'}} />
                执行位置
              </Tooltip>
            } labelCol={{xs: { span: 24 }, sm: { span: 24 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 24 }} }>
              {getFieldDecorator('position', {
                initialValue: 'back'
              })(
                <Radio.Group>
                  <Radio value="front">sql前</Radio>
                  <Radio value="back">sql后</Radio>
                </Radio.Group>
              )}
            </Form.Item>
            <Form.Item labelAlign="left" label={
              <Tooltip placement="bottomLeft" title={'从系统函数集中选择需要的函数,可快速添加至sql中。'}>
                <Icon type="question-circle" style={{color: '#c49f47', marginRight: '5px'}} />
                快捷添加
              </Tooltip>
            } labelCol={{xs: { span: 24 }, sm: { span: 24 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 24 }} }>
              <Select onChange={this.selectScript}>
                {systemScripts.map((option, i) =>
                  <Select.Option title={option.name} key={i} value={option.value}>
                    {option.name}
                  </Select.Option>
                )}
              </Select>
            </Form.Item>
          </Col>
        </Row>
      </Form>
src/templates/zshare/verifycard/index.jsx
@@ -36,6 +36,7 @@
    orderModularDetail: [],
    voucher: [],
    voucherDetail: [],
    systemScripts: [],
    uniqueColumns: [
      {
        title: '字段名',
@@ -224,7 +225,13 @@
      {
        title: 'SQL',
        dataIndex: 'sql',
        width: '70%'
        width: '60%'
      },
      {
        title: '执行位置',
        dataIndex: 'position',
        width: '10%',
        render: (text, record) => record.position !== 'front' ? 'sql后' : 'sql前'
      },
      {
        title: '状态',
@@ -769,6 +776,39 @@
        voucher: result[0].data,
        voucherDetail: result[1].data
      })
    })
    let _scriptSql = `Select distinct func+Remark as funcname,longparam from s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end`
    _scriptSql = Utils.formatOptions(_scriptSql)
    let _sParam = {
      func: 'sPC_Get_SelectedList',
      LText: _scriptSql,
      obj_name: 'data',
      arr_field: 'funcname,longparam'
    }
    _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp)
    Api.getSystemConfig(_sParam).then(res => {
      if (res.status) {
        this.setState({
          systemScripts: res.data.map(item => {
            return {
              name: item.funcname,
              value: Utils.formatOptions(item.longparam, true)
            }
          })
        })
      } else {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 10
        })
      }
    })
  }
@@ -1331,6 +1371,7 @@
              usefulfields={this.state.usefulfields}
              initsql={this.state.initsql}
              dict={this.props.dict}
              systemScripts={this.state.systemScripts}
              scriptsChange={this.scriptsChange}
              wrappedComponentRef={(inst) => this.scriptsForm = inst}
            />
src/templates/zshare/verifycardexcelin/customscript/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Button, notification, Modal } from 'antd'
import { Form, Row, Col, Input, Button, notification, Modal, Select, Icon, Tooltip, Radio } from 'antd'
import moment from 'moment'
import Utils from '@/utils/utils.js'
@@ -16,6 +16,7 @@
    scripts: PropTypes.array,       // 自定义脚本列表
    isdefault: PropTypes.any,       // 是否使用默认sql
    usefulfields: PropTypes.any,    // 可用字段
    systemScripts: PropTypes.array, // 系统脚本
    scriptsChange: PropTypes.func   // 表单
  }
@@ -67,7 +68,8 @@
    })
    this.props.form.setFieldsValue({
      sql: record.sql
      sql: record.sql,
      position: record.position || 'back'
    })
  }
@@ -158,7 +160,14 @@
    })
  }
  selectScript = (val) => {
    this.props.form.setFieldsValue({
      sql: val
    })
  }
  render() {
    const { systemScripts } = this.props
    const { usefulfields } = this.state
    const { getFieldDecorator } = this.props.form
    const formItemLayout = {
@@ -180,7 +189,7 @@
              {usefulfields}
            </Form.Item>
          </Col> : null}
          <Col span={21} className="sql">
          <Col span={20} className="sql">
            <Form.Item label={'sql'}>
              {getFieldDecorator('sql', {
                initialValue: '',
@@ -193,10 +202,39 @@
              })(<TextArea rows={15} />)}
            </Form.Item>
          </Col>
          <Col span={3} className="add">
            <Button onClick={this.handleConfirm} loading={this.state.loading} type="primary" className="add-row">
          <Col span={4} className="add">
            <Button onClick={this.handleConfirm} loading={this.state.loading} type="primary" style={{marginBottom: 20}}>
              确定
            </Button>
            <Form.Item labelAlign="left" label={
              <Tooltip placement="bottomLeft" title={'自定义脚本与默认sql位置关系。'}>
                <Icon type="question-circle" style={{color: '#c49f47', marginRight: '5px'}} />
                执行位置
              </Tooltip>
            } labelCol={{xs: { span: 24 }, sm: { span: 24 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 24 }} }>
              {getFieldDecorator('position', {
                initialValue: 'back'
              })(
                <Radio.Group>
                  <Radio value="front">sql前</Radio>
                  <Radio value="back">sql后</Radio>
                </Radio.Group>
              )}
            </Form.Item>
            <Form.Item labelAlign="left" label={
              <Tooltip placement="bottomLeft" title={'从系统函数集中选择需要的函数,可快速添加至sql中。'}>
                <Icon type="question-circle" style={{color: '#c49f47', marginRight: '5px'}} />
                快捷添加
              </Tooltip>
            } labelCol={{xs: { span: 24 }, sm: { span: 24 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 24 }} }>
              <Select onChange={this.selectScript}>
                {systemScripts.map((option, i) =>
                  <Select.Option title={option.name} key={i} value={option.value}>
                    {option.name}
                  </Select.Option>
                )}
              </Select>
            </Form.Item>
          </Col>
        </Row>
      </Form>
src/templates/zshare/verifycardexcelin/index.jsx
@@ -1,7 +1,9 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Tabs, Row, Col, Input, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber, Radio } from 'antd'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import UniqueForm from './uniqueform'
@@ -21,6 +23,7 @@
  state = {
    verify: {},
    systemScripts: [],
    excelColumns: [
      {
        title: 'Column',
@@ -142,7 +145,13 @@
      {
        title: 'SQL',
        dataIndex: 'sql',
        width: '70%'
        width: '60%'
      },
      {
        title: '执行位置',
        dataIndex: 'position',
        width: '10%',
        render: (text, record) => record.position !== 'front' ? 'sql后' : 'sql前'
      },
      {
        title: '状态',
@@ -214,6 +223,41 @@
        columns: _columns,
        scripts: _verify.scripts || [],
        uniques: _verify.uniques || []
      }
    })
  }
  componentDidMount () {
    let _scriptSql = `Select distinct func+Remark as funcname,longparam from s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end`
    _scriptSql = Utils.formatOptions(_scriptSql)
    let _sParam = {
      func: 'sPC_Get_SelectedList',
      LText: _scriptSql,
      obj_name: 'data',
      arr_field: 'funcname,longparam'
    }
    _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp)
    Api.getSystemConfig(_sParam).then(res => {
      if (res.status) {
        this.setState({
          systemScripts: res.data.map(item => {
            return {
              name: item.funcname,
              value: Utils.formatOptions(item.longparam, true)
            }
          })
        })
      } else {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 10
        })
      }
    })
  }
@@ -673,6 +717,7 @@
              isdefault={verify.default}
              usefulfields={verify.columns}
              scripts={verify.scripts}
              systemScripts={this.state.systemScripts}
              scriptsChange={this.scriptsChange}
              wrappedComponentRef={(inst) => this.scriptsForm = inst}
            />
src/utils/utils.js
@@ -54,7 +54,7 @@
   * @description sql加密
   * @return {String}  value
   */
  static formatOptions (value) {
  static formatOptions (value, isUnFormat = false) {
    if (!value) return ''
    let salt = 'minKe' // 盐值
@@ -157,25 +157,43 @@
      value: ' mrlbkk '
    }]
    // 替换关键字
    format.forEach(item => {
      let reg  =  new RegExp('(^|\\s)' + item.key + '(\\s|$)', 'ig')
      value = value.replace(reg, item.value)
    })
    if (!isUnFormat) { // 加密
      // 替换关键字
      format.forEach(item => {
        let reg = new RegExp('(^|\\s)' + item.key + '(\\s|$)', 'ig')
        value = value.replace(reg, item.value)
      })
      // 1、替换%符(数据库中解析后sql报错)
      value = value.replace(/%/ig, ' mpercent ')
      // 1、encode编码(中文字符超出base64加密范围),2、base64加密
      value = window.btoa(window.encodeURIComponent(value))
      // 插入字符
      let index = Math.floor(value.length / 2)
      value = value.slice(0, index) + salt + value.slice(index)
      // base64加密
      value = window.btoa(value)
    } else { // 解密
      try {
        value = window.atob(value)
        value = value.replace(salt, '')
        value = window.decodeURIComponent(window.atob(value))
        value = value.replace(/\smpercent\s/g, '%')
    // 1、替换%符(数据库中解析后sql报错),2、去除收尾多余空格
    value = value.replace(/%/ig, ' mpercent ')
    // value = value.replace(/(^\s|\s$)/ig, '')
    // 1、encode编码(中文字符超出base64加密范围),2、base64加密
    value = window.btoa(window.encodeURIComponent(value))
    // 插入字符
    let index = Math.floor(value.length / 2)
    value = value.slice(0, index) + salt + value.slice(index)
    // base64加密
    value = window.btoa(value)
        format.forEach(item => {
          let reg = new RegExp(item.value, 'g')
          value = value.replace(reg, ' ' + item.key + ' ')
        })
        value = value.replace(/(^\s+|\s+$)/ig, '')
      } catch {
        console.warn('UnFormat Failure')
        value = ''
      }
    }
    return value
  }
@@ -477,6 +495,11 @@
    let errors = []
    let _topline = btn.range || 0
    let upId = this.getuuid()
    if (btn.scripts && btn.scripts.length > 0) {
      btn.scripts = btn.scripts.filter(item => item.status !== 'false')
    }
    let _Ltext = data.map((item, lindex) => {
      let vals = btn.columns.map((col, cindex) => {
        let val = item[col.Column] !== undefined ? item[col.Column] : ''
@@ -619,6 +642,16 @@
      let _insert = ''
      if (btn.scripts && btn.scripts.length > 0) {
        btn.scripts.forEach(script => {
          if (script.position !== 'front') return
          _insert += `
          ${script.sql}
          `
        })
      }
      if (btn.default !== 'false') {
        _insert = `
        Insert into ${item.sheet} (${fields},createuserid,createuser,createstaff,bid) 
@@ -628,7 +661,7 @@
      if (btn.scripts && btn.scripts.length > 0) {
        btn.scripts.forEach(script => {
          if (script.status === 'false') return
          if (script.position === 'front') return
          _insert += `
          ${script.sql}
@@ -713,6 +746,10 @@
        if (!_vars.includes(_key)) {
          _vars.push(_key)
          if (form.fieldlen && form.fieldlen > 2048) {
            form.fieldlen = 'max'
          }
          let _type = `nvarchar(${form.fieldlen})`
          if (form.type.match(/date/ig)) {
@@ -748,6 +785,10 @@
          
          if (!_vars.includes(_key)) {
            _vars.push(_key)
            if (col.fieldlength && col.fieldlength > 2048) {
              col.fieldlength = 'max'
            }
  
            let _type = `nvarchar(${col.fieldlength || 50})`
@@ -894,7 +935,7 @@
    
    // 自定义验证
    if (verify.customverifys && verify.customverifys.length > 0) {
      verify.customverifys.forEach(item => {
      verify.customverifys.forEach(item => {
        _sql += `select @tbid='', @ErrorCode='',@retmsg=''
          select top 1 @tbid='X' from (${item.sql}) a
          If @tbid ${item.result === 'true' ? '!=' : '='}''
@@ -1031,6 +1072,9 @@
          keys.push('bid')
        }
        values.push('@BID@')
      } else if (tab && tab.foreignKey && !keys.includes(tab.foreignKey.toLowerCase())) {
        keys.push(tab.foreignKey)
        values.push('@BID@')
      }
      keys = keys.join(',')
@@ -1047,7 +1091,11 @@
        _arr.push(item.key.toLowerCase())
        if (item.type === 'funcvar') {
          _form.push(item.key + '=@' + item.key)
          if (_actionType === 'update') {
            _form.push(item.key + '=@' + item.key)
          } else if (_actionType === 'insertOrUpdate') { // 添加或修改时,函数变量添加表单数值
            _form.push(item.key + '=\'' + item.value + '\'')
          }
        } else if (item.type === 'number') {
          _form.push(item.key + '=' + item.value)
        } else {
@@ -1076,6 +1124,18 @@
      _updatesql = `update ${btn.sql} set ${_form} where ${primaryKey}=@${primaryKeyName};`
    }
    // 拼接自定义脚本
    if (verify.scripts && verify.scripts.length > 0) {
      let _scripts = ''
      verify.scripts.forEach(item => {
        if (item.position !== 'front') return
        _scripts += `
        ${item.sql}`
      })
      _sql += `${_scripts}`
    }
    // 添加、修改、逻辑删除、物理删除
    if (_actionType === 'insert') {
      _sql += _insertsql
@@ -1095,7 +1155,7 @@
          }
        })
      }
      _sql += `insert into snote (remark,createuserid,CreateUser,CreateStaff) select '删除表:${btn.sql} 数据: ${_msg}${primaryKey}='+@${primaryKeyName},@userid@,@username,@fullname delete ${btn.sql} where ${primaryKey}=@${primaryKeyName};`
      _sql += `insert into snote (remark,createuserid,CreateUser,CreateStaff) select left('删除表:${btn.sql} 数据: ${_msg}${primaryKey}='+@${primaryKeyName},200),@userid@,@username,@fullname delete ${btn.sql} where ${primaryKey}=@${primaryKeyName};`
    } else if (_actionType === 'insertOrUpdate') {
      _sql += `select @tbid=''
        select @tbid='X' from ${btn.sql} where ${primaryKey}=@ID@
@@ -1115,6 +1175,8 @@
    if (verify.scripts && verify.scripts.length > 0) {
      let _scripts = ''
      verify.scripts.forEach(item => {
        if (item.position === 'front') return
        _scripts += `
        ${item.sql}`
      })
src/views/login/index.jsx
@@ -58,6 +58,13 @@
  }
  async loginsubmit (param) {
    if (options.systemType === 'local' && !window.GLOB.mainSystemApi) { // 业务系统必须设置单点地址
      Modal.warning({
        title: '未设置单点服务器地址,请联系管理员!'
      })
      return
    }
    // 登录提交
    let res = await Api.getusermsg(param.username, param.password)
    if (res.status) {