king
2025-01-16 0a932e56960fc8d39eb9cb04e16cac2249445062
src/templates/zshare/verifycard/index.jsx
@@ -2,14 +2,13 @@
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Form, Tabs, Row, Col, Button, Popconfirm, notification, Modal, message, InputNumber, Typography } from 'antd'
import { CheckCircleOutlined, StopOutlined, EditOutlined, SwapOutlined, DeleteOutlined, ExclamationOutlined } from '@ant-design/icons'
import { CheckCircleOutlined, StopOutlined, EditOutlined, SwapOutlined, DeleteOutlined, ExclamationOutlined, ConsoleSqlOutlined } from '@ant-design/icons'
import Toast from 'antd-mobile/es/components/toast'
import Dialog from 'antd-mobile/es/components/dialog'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import options from '@/store/options.js'
import BaseForm from './baseform'
import UniqueForm from './uniqueform'
import ContrastForm from './contrastform'
@@ -19,7 +18,7 @@
import BillcodeForm from './billcodeform'
import VoucherForm from './voucherform'
import asyncComponent from '@/utils/asyncComponent'
import { updateForm } from '@/utils/utils-update.js'
// import { updateForm } from '@/utils/utils-update.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
@@ -31,23 +30,21 @@
class VerifyCard extends Component {
  static propTpyes = {
    btnTab: PropTypes.any,     // 表单标签页(按钮)参数
    config: PropTypes.any,     // 表单标签页参数
    card: PropTypes.object,    // 按钮信息
    columns: PropTypes.array
  }
  state = {
    initsql: '',            // sql验证时变量声明及赋值
    verifyInter: 'system',  // 接口类型
    activeKey: 'base',
    appType: sessionStorage.getItem('appType'),
    notes: [],              // 短信模板
    setting: null,
    emailCodes: [],         // 邮箱模板
    verify: {},
    fields: [],
    usefulfields: '',
    defaultsql: '',         // 默认Sql
    formfields: '',
    colfields: '',
    orderModular: [],
    orderModularDetail: [],
    voucher: [],
@@ -55,7 +52,6 @@
    systemScripts: [],
    columnsFields: [],
    unionFields: [],
    uniqueFields: [],  // 唯一性验证,表单字段
    uniqueColumns: [
      {
        title: '名称',
@@ -87,7 +83,7 @@
        title: '验证类型',
        dataIndex: 'verifyType',
        width: '14%',
        render: (text, record) => record.verifyType === 'logic' ? '逻辑验证' : '物理验证',
        render: (text) => text === 'logic' ? '逻辑验证' : '物理验证',
        inputType: 'select',
        editable: true,
        options: [
@@ -115,6 +111,34 @@
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
      },
      {
        dataIndex: 'sqlRender',
        render: (record) => {
          let _fieldValue = []
          let _value = []
          let _labels = record.fieldlabel.split(',')
          record.field.split(',').forEach((_field, index) => {
            let _key = _field.toLowerCase()
            _fieldValue.push(`${_key}=${_key === 'bid' ? '@BID@' : `''`}`)
            _value.push(`${_labels[index] || ''}:xxx`)
          })
          let _verifyType = ''
          if (record.verifyType === 'logic') {
            _verifyType = ' and deleted=0'
          }
          let sql = `select @tbid='', @ErrorCode='',@retmsg=''
          select @tbid='X' from ${this.props.card.sql} where ${_fieldValue.join(' and ')}${_verifyType}
          If @tbid!=''
          Begin
            select @ErrorCode='${record.errorCode}',@retmsg='${_value.join(', ')} 已存在'
            goto aaa
          end`
          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
        }
      }
    ],
    onceUniqueColumns: [
@@ -152,6 +176,27 @@
            </div>
          )
      },
      {
        dataIndex: 'sqlRender',
        render: (record) => {
          let primaryKey = 'id'
          if (this.props.config && this.props.config.setting && this.props.config.setting.primaryKey) {
            primaryKey = this.props.config.setting.primaryKey
          }
          let sql = `Set @tbid=''
          Select top 1 @tbid='X' from (select distinct ${record.field},1 as n from (数据源) tb inner join (select ID from  dbo.SplitComma(@ID@)) sp on tb.${primaryKey}=sp.ID ) a having sum(n)>1
          If @tbid!=''
          Begin
            Set @ErrorCode='E' Set @retmsg='${record.fieldlabel} 值不唯一'
            goto aaa
          end`
          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
        }
      }
    ],
    contrastColumns: [
      {
@@ -164,7 +209,7 @@
      {
        title: '运算符',
        dataIndex: 'operator',
        width: '14%',
        width: '13%',
        editable: true,
        inputType: 'select',
        options: [
@@ -188,14 +233,14 @@
      {
        title: '提示信息',
        dataIndex: 'errmsg',
        width: '14%',
        width: '13%',
        inputType: 'input',
        editable: true
      },
      {
        title: '报错编码',
        dataIndex: 'errorCode',
        width: '14%',
        width: '13%',
        editable: true,
        inputType: 'select',
        options: [
@@ -225,6 +270,18 @@
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
      },
      {
        dataIndex: 'sqlRender',
        render: (record) => {
          let sql = `If ${record.frontfield} ${record.operator} ${record.backfield}
          Begin
            select @ErrorCode='${record.errorCode}',@retmsg='${record.errmsg}'
            goto aaa
          end`
          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
        }
      }
    ],
    customColumns: [
@@ -531,59 +588,100 @@
            }>
              <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span>
            </Popconfirm>
            <span className="operation-btn" title="SQL" onClick={() => this.orderSql(record)} style={{color: '#1890ff'}}><ConsoleSqlOutlined /></span>
          </div>)
      }
    ]
  }
  UNSAFE_componentWillMount() {
    const { columns, config, card, btnTab } = this.props
    const { columns, config, card } = this.props
    const { appType } = this.state
    let _verify = fromJS(card.verify || {}).toJS()
    let _invalid = _verify.invalid
    let _invalid = _verify.invalid || 'true'
    if (!_invalid) { // 选择行时,失效验证默认开启
      if (config.setting && config.setting.maxScript && config.setting.maxScript >= 300) {
        _invalid = 'false'
      } else {
        _invalid = card.Ot !== 'notRequired' ? 'true' : 'false'
      }
    _verify.limitInvalid = false
    if (config.wrap && config.wrap.datatype === 'public') {
      _verify.limitInvalid = true
      _verify.limitText = '公共数据源,不可使用失效验证'
      _invalid = 'false'
    } else if (config.wrap && config.wrap.datatype === 'static') {
      _verify.limitInvalid = true
      _verify.limitText = '静态数据源,不可使用失效验证'
      _invalid = 'false'
    } else if (!config.setting || config.setting.interType !== 'system') {
      _verify.limitInvalid = true
      _verify.limitText = '数据源未使用系统接口,不能使用失效验证!'
      _invalid = 'false'
    } else if (config.setting.execute !== 'true' || !config.setting.dataresource) {
      _verify.limitInvalid = true
      _verify.limitText = '尚未添加数据源,不能使用失效验证!'
      _invalid = 'false'
    } else if (config.setting.maxScript && config.setting.maxScript >= 300) {
      _verify.limitInvalid = true
      _verify.limitText = '数据源中自定义脚本过于复杂,不能使用失效验证!'
      _invalid = 'false'
    } else if (card.sqlType === 'insert') {
      _verify.limitInvalid = true
      _verify.limitText = '按钮操作类型为《添加》时,不能使用失效验证!'
      _invalid = 'false'
    } else if (card.Ot === 'notRequired') {
      _verify.limitInvalid = true
      _verify.limitText = '按钮《不选择行》时,不能使用失效验证!'
      _invalid = 'false'
    }
    if (card.sqlType === 'custom') { // 自定义验证时,不使用默认sql
      _verify.default = 'false'
    }
    _verify.default = _verify.default || 'true'
    _verify.wxNote = _verify.wxNote || 'false'         // 公众号消息推送是否开启
    _verify.noteEnable = _verify.noteEnable || 'false' // 短信发送是否开启
    _verify.noteType = _verify.noteType || 'N'         // 短信发送模式:Y(实时)、N(定时)
    _verify.noteTemp = _verify.noteTemp || 'Y'         // 短信发送模板:Y(相同)、N(不同)
    _verify.wxNote = _verify.wxNote || 'false'           // 公众号消息推送是否开启
    _verify.noteEnable = _verify.noteEnable || 'false'   // 短信发送是否开启
    _verify.emailEnable = _verify.emailEnable || 'false' // 邮件发送是否开启
    _verify.printEnable = _verify.printEnable || 'false' // 单据打印是否开启
    _verify.preHandle = _verify.preHandle || 'false'     // 按钮预处理是否开启
    _verify.invalid = _invalid
    _verify.uniques = _verify.uniques || []
    _verify.contrasts = _verify.contrasts || []
    _verify.accountdate = _verify.accountdate || 'false'
    _verify.accountfield = _verify.accountfield || ''
    _verify.voucherdate = _verify.voucherdate || ''
    _verify.customverifys = _verify.customverifys || []
    _verify.billcodes = _verify.billcodes || []
    _verify.voucher = _verify.voucher || {enabled: false}
    _verify.scripts = _verify.scripts || []
    _verify.cbScripts = _verify.cbScripts || []
    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
      window.GLOB.funcs.forEach(m => {
        let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
        _verify.customverifys.forEach(item => {
          item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
        })
        _verify.scripts.forEach(item => {
          item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
        })
        _verify.cbScripts.forEach(item => {
          item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
        })
      })
    if (window.GLOB.process && card.intertype !== 'inner') {
      _verify.workFlow = _verify.workFlow || 'false'
      _verify.flowType = _verify.flowType || (card.sqlType === 'insert' ? 'start' : 'approval')
      _verify.flowSql = _verify.flowSql || 'true'
    } else {
      delete _verify.workFlow
      delete _verify.flowRemark
      delete _verify.flowType
      delete _verify.flowSql
    }
    if (appType === 'mob') {
      _verify.printEnable = 'false'
      _verify.printTempId = ''
    }
    // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
    //   window.GLOB.funcs.forEach(m => {
    //     let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
    //     _verify.customverifys.forEach(item => {
    //       item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
    //     })
    //     _verify.scripts.forEach(item => {
    //       item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
    //     })
    //     _verify.cbScripts.forEach(item => {
    //       item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
    //     })
    //   })
    // }
    _verify.customverifys.forEach((item, i) => {
      item.$index = i + 1
@@ -602,405 +700,165 @@
      activeKey = 'cbScripts'
    }
    let oriVerify = fromJS(_verify).toJS()
    if (_verify.wxAppId) {
      if (!window.GLOB.WXApps || window.GLOB.WXApps.filter(app => app.appType === 'public').length === 0) {
        delete _verify.wxAppId
      }
    }
    this.setState({
      activeKey: activeKey,
      verifyInter: verifyInter,
      setting: config.setting || {},
      verify: _verify,
      oriVerify: fromJS(_verify).toJS()
      oriVerify: oriVerify
    })
    if (config.Template !== 'FormTab' && card.intertype === 'inner') {
      return
    if (card.intertype === 'inner') return
    let _fields = []
    if (card.OpenType === 'form') {
      let item = {
        field: card.field,
        label: card.label,
        type: 'text',
        writein: true,
        fieldlen: 50
      }
      if (card.formType === 'counter') {
        item.type = 'number'
        item.fieldlen = 0
      } else if (card.formType === 'switch' || card.formType === 'radio') {
        if (typeof(card.openVal) === 'number') {
          item.type = 'number'
          item.fieldlen = 0
        }
      }
      _fields.push(item)
    } else if (card.modal && (card.OpenType === 'pop' || !card.OpenType)) {
      _fields = fromJS(card.modal.fields || []).toJS()
      _fields = _fields.filter(_f => {
        if (!_f.field) return false
        _f.writein = _f.writein !== 'false'
        _f.fieldlen = _f.fieldlength || 50
        if (_f.type === 'datemonth') {
          _f.type = 'text'
        } else if (_f.type === 'number' || _f.type === 'rate') {
          _f.fieldlen = _f.decimal || 0
        } else if (_f.type === 'date') {
          _f.type = _f.declareType === 'nvarchar(50)' ? 'text' : 'date'
        } else if (_f.type === 'datetime') {
          _f.type = 'date'
        } else if (_f.declare === 'decimal') {
          _f.type = 'number'
          _f.fieldlen = _f.decimal || 0
        }
        return true
      })
    }
    new Promise(resolve => {
      let _fields = []
      if (card.OpenType === 'form') {
        _fields.push({
          field: card.field,
          label: card.label,
          type: 'text'
        })
        resolve(_fields)
      } else if (config.Template === 'FormTab') {
        config.groups.forEach(group => {
          _fields.push(...group.sublist)
        })
        resolve(_fields)
      } else if (card.modal && (card.OpenType === 'pop' || !card.OpenType)) {
        _fields = card.modal.fields || []
        resolve(_fields)
      } else if (card.OpenType === 'pop') {
        Api.getSystemConfig({
          func: 'sPC_Get_LongParam',
          MenuID: card.uuid
        }).then(res => {
          if (res.status) {
            let _LongParam = ''
            if (res.LongParam) {
              try {
                _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
              } catch (e) {
                console.warn('Parse Failure')
                _LongParam = ''
              }
            }
            if (!_LongParam) {
              message.warning('未获取到表单信息,部分验证将无法设置!')
            } else {
              _LongParam = updateForm(_LongParam)
              _fields = _LongParam.fields || []
            }
          } else {
            notification.warning({
              top: 92,
              message: res.message,
              duration: 5
            })
          }
          resolve(_fields)
        })
      } else {
        resolve(_fields)
      }
    }).then(_fields => {
      let _usefulfields = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'BillCode', 'BVoucher', 'FIBVoucherDate', 'FiYear', 'ModularDetailCode', 'tbid', 'mk_deleted']
      let _declare = ['@UserName nvarchar(50)', '@FullName nvarchar(50)', '@RoleID nvarchar(512)', '@mk_departmentcode nvarchar(512)', '@mk_organization nvarchar(512)', '@mk_user_type nvarchar(20)', '@mk_nation nvarchar(50)', '@mk_province nvarchar(50)', '@mk_city nvarchar(50)', '@mk_district nvarchar(50)', '@mk_address nvarchar(100)', '@ErrorCode nvarchar(50)', '@retmsg nvarchar(4000)', '@BillCode nvarchar(50)', '@BVoucher nvarchar(50)', '@FIBVoucherDate nvarchar(50)', '@FiYear nvarchar(50)', '@ModularDetailCode nvarchar(50)', '@bid nvarchar(50)', '@tbid nvarchar(50)', '@mk_deleted int']
      let _select = ['@UserName=\'\'', '@FullName=\'\'', '@RoleID=\'\'', '@mk_departmentcode=\'\'', '@mk_organization=\'\'', '@mk_user_type=\'\'', '@mk_nation=\'\'', '@mk_province=\'\'', '@mk_city=\'\'', '@mk_district=\'\'', '@mk_address=\'\'', '@ErrorCode=\'\'', '@retmsg=\'\'', '@BillCode=\'\'', '@BVoucher=\'\'', '@FIBVoucherDate=\'\'', '@FiYear=\'\'', '@ModularDetailCode=\'\'', '@bid=\'\'', '@mk_deleted=1']
      let fieldArr = _usefulfields.map(_f => _f.toLowerCase())
      let hasBid = false
    let verIndex = _fields.findIndex(item => item.type === 'vercode')
    if (verIndex > -1) {
      _fields = fromJS(_fields).toJS()
      _fields.splice(verIndex, 0, {
        type: 'text',
        fieldlen: 50,
        writein: false,
        field: 'mk_timestamp'
      }, {
        type: 'text',
        fieldlen: 50,
        writein: false,
        field: 'mk_send_type'
      }, {
        type: 'text',
        fieldlen: 50,
        writein: false,
        field: 'mk_n_id'
      })
    }
      _usefulfields = []
      fieldArr.push('bid')
    let sysfields = ['tbid', 'errorcode', 'retmsg', 'billcode', 'bvoucher', 'fibvoucherdate', 'fiyear', 'username', 'fullname', 'modulardetailcode', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'mk_deleted', 'bid', 'mk_submit_type']
    let hasBid = false
      let verIndex = _fields.findIndex(item => item.type === 'vercode')
      if (verIndex > -1) {
        _fields = fromJS(_fields).toJS()
        _fields.splice(verIndex, 0, {
          type: 'text',
          fieldlength: 50,
          writein: 'false',
          field: 'mk_timestamp'
        }, {
          type: 'text',
          fieldlength: 50,
          writein: 'false',
          field: 'mk_send_type'
        }, {
          type: 'text',
          fieldlength: 50,
          writein: 'false',
          field: 'mk_n_id'
        })
    let formfields = []
    _fields.forEach(_f => {
      let key = _f.field.toLowerCase()
      if (key === 'bid') {
        hasBid = true
      }
      _fields = _fields.filter(_f => _f.field)
      _fields.forEach(_f => {
        if (_f.field.toLowerCase() === 'bid') {
          hasBid = true
      if (sysfields.includes(key)) return
      formfields.push(_f.field)
    })
    if (!hasBid) {
      _fields.unshift({ uuid: 'BID', field: 'BID', label: 'BID', type: 'text', writein: false, fieldlen: 50 })
    }
    let unionFields = fromJS(_fields).toJS()
    let formArr = _fields.map(_f => _f.field.toLowerCase())
    let fieldArr = [...sysfields, ...formArr]
    let colfields = []
    if (card.Ot !== 'notRequired' && columns) {
      columns.forEach(_f => {
        if (!_f.field) return
        let key = _f.field.toLowerCase()
        if (formArr.includes(key)) return
        unionFields.push(_f)
        if (fieldArr.includes(key)) return
        colfields.push(_f.field)
      })
    }
    let _columns = []
    if (columns) {
      _columns = fromJS(columns).toJS()
      let hasbid = false
      _columns = _columns.filter(col => {
        if (col.field && col.field.toLowerCase() === 'bid') {
          hasbid = true
        }
        if (fieldArr.includes(_f.field.toLowerCase())) return
        fieldArr.push(_f.field.toLowerCase())
        _usefulfields.push(_f.field)
        let _fieldlen = _f.fieldlength || 50
        if (_f.type === 'number') {
          _fieldlen = _f.decimal ? _f.decimal : 0
        }
        if (_fieldlen > 2048) {
          _fieldlen = 'max'
        }
        let _type = `nvarchar(${_fieldlen})`
        if (_f.type.match(/date/ig)) {
          _type = 'datetime'
          _select.push(`@${_f.field}='1949-10-01'`)
        } else if (_f.type === 'number') {
          _type = `decimal(18,${_fieldlen})`
          _select.push(`@${_f.field}=0`)
        } else if (_f.type === 'rate') {
          _type = `decimal(18,2)`
          _select.push(`@${_f.field}=0`)
        } else {
          _select.push(`@${_f.field}=''`)
        }
        _declare.push(`@${_f.field} ${_type}`)
        return !!col.field
      })
      let uniqueFields = fromJS(_fields).toJS()
      if (!hasBid) { // 唯一性验证添加BID
        uniqueFields.unshift({ uuid: 'BID', field: 'BID', label: 'BID', type: 'text' })
        _fields.unshift({ uuid: 'BID', field: 'BID', label: 'BID', type: 'text' })
      if (!hasbid) {
        _columns.unshift({ uuid: 'BID', field: 'BID', label: 'BID', type: 'text' })
      }
    }
      let hasColumn = false
      if (columns && columns.length > 0) {
        if (btnTab) { // 表单标签
          hasColumn = btnTab.Ot !== 'notRequired'
        } else if (card.Ot !== 'notRequired') {
          hasColumn = true
    this.setState({
      fields: _fields,
      columnsFields: _columns,
      formfields: formfields.join(', '),
      colfields: colfields.join(', '),
      uniqueColumns: this.state.uniqueColumns.map(col => {
        if (col.dataIndex === 'field') {
          col.options = unionFields
        }
      }
      let unionFields = fromJS(_fields).toJS()
      let formArr = _fields.map(_f => _f.field.toLowerCase())
      if (hasColumn) {
        columns.forEach(_f => {
          if (_f.field && !formArr.includes(_f.field.toLowerCase())) {
            formArr.push(_f.field.toLowerCase())
            unionFields.push(_f)
          }
          if (!_f.field || fieldArr.includes(_f.field.toLowerCase())) return
          fieldArr.push(_f.field.toLowerCase())
          _usefulfields.push(_f.field)
          if (_f.datatype) { // 自定义字段
            if (/decimal/ig.test(_f.datatype)) {
              _select.push(`@${_f.field}=0`)
            } else {
              _select.push(`@${_f.field}=''`)
            }
            _declare.push(`@${_f.field} ${_f.datatype}`)
            return
          }
          let _fieldlen = _f.fieldlength || 50
          if (_fieldlen > 2048) {
            _fieldlen = 'max'
          }
          let _type = `nvarchar(${_fieldlen})`
          if (_f.type === 'number') {
            _type = `decimal(18,${_f.decimal ? _f.decimal : 0})`
          } else if (_f.type === 'picture' || _f.type === 'textarea') {
            _type = `nvarchar(${_fieldlen})`
          }
          if (_f.type === 'number') {
            _select.push(`@${_f.field}=0`)
          } else {
            _select.push(`@${_f.field}=''`)
          }
          _declare.push(`@${_f.field} ${_type}`)
        })
      }
      let _sql = `Declare ${_declare.join(', ')}
        Select ${_select.join(', ')}
      `
      // 默认sql
      let _defaultsql = ''
      let _insertsql = ''
      let _updatesql = ''
      let _primaryKey = config.setting.primaryKey || 'id'
      if (this.props.side === 'sub') {
        _primaryKey = config.setting.subKey || 'id'
      }
      if (card.sqlType === 'insert' || card.sqlType === 'insertOrUpdate') {
        let keys = []
        let values = []
        _fields.forEach(item => {
          if (!item.field || item.writein === 'false') return
          keys.push(item.field.toLowerCase())
          if (item.field.toLowerCase() === 'bid' && item.uuid === 'BID') {
            values.push('@BID@')
          } else {
            values.push('@' + item.field)
          }
        })
        if (!keys.includes(_primaryKey.toLowerCase())) {
          keys.push(_primaryKey.toLowerCase())
          values.push('@ID@')
        return col
      }),
      onceUniqueColumns: this.state.onceUniqueColumns.map(col => {
        if (col.dataIndex === 'field') {
          col.options = _columns
        }
        if (!keys.includes('createuserid')) {
          keys.push('createuserid')
          values.push('@userid@')
        }
        if (!keys.includes('createuser')) {
          keys.push('createuser')
          values.push('@username')
        }
        if (!keys.includes('createstaff')) {
          keys.push('createstaff')
          values.push('@fullname')
        }
        if (!keys.includes('bid')) {
          keys.push('bid')
          values.push('@BID@')
        }
        if (!keys.includes('typename')) {
          keys.push('typename')
          values.push('@typename@')
        }
        keys = keys.join(', ')
        values = values.join(', ')
        _insertsql = `insert into ${card.sql} (${keys}) select ${values};`
      }
      if (card.sqlType === 'update' || card.sqlType === 'audit' || card.sqlType === 'insertOrUpdate') {
        let _form = []
        let _arr = []
        _fields.forEach(item => {
          if (!item.field || item.writein === 'false' || item.uuid === 'BID') return
          _arr.push(item.field.toLowerCase())
          if (item.field.toLowerCase() === 'bid') {
            _form.push(item.field + '=@BID@')
          } else {
            _form.push(item.field + '=@' + item.field)
          }
        })
        if (this.props.card.sqlType === 'audit') {
          if (!_arr.includes('submitdate')) {
            _form.push('submitdate=getdate()')
          }
          if (!_arr.includes('submituser')) {
            _form.push('submituser=@username')
          }
          if (!_arr.includes('submitstaff')) {
            _form.push('submitstaff=@fullname')
          }
          if (!_arr.includes('submituserid')) {
            _form.push('submituserid=@userid@')
          }
          if (!_arr.includes('typename')) {
            _form.push(`typename=@typename@`)
          }
        } else {
          if (!_arr.includes('modifydate')) {
            _form.push('modifydate=getdate()')
          }
          if (!_arr.includes('modifyuser')) {
            _form.push('modifyuser=@username')
          }
          if (!_arr.includes('modifystaff')) {
            _form.push('modifystaff=@fullname')
          }
          if (!_arr.includes('modifyuserid')) {
            _form.push('modifyuserid=@userid@')
          }
          if (!_arr.includes('typename')) {
            _form.push(`typename=@typename@`)
          }
        }
        if (_verify.voucher && _verify.voucher.enabled) {
          if (!_arr.includes('bvoucher')) {
            _form.push('BVoucher=@BVoucher')
          }
          if (!_arr.includes('fibvoucherdate')) {
            _form.push('FIBVoucherDate=@FIBVoucherDate')
          }
          if (!_arr.includes('fiyear')) {
            _form.push('FiYear=@FiYear')
          }
        }
        _form = _form.join(', ')
        _updatesql = `update ${card.sql} set ${_form} where ${_primaryKey}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
      }
      if (card.sqlType === 'insert') {
        _defaultsql = _insertsql
      } else if (card.sqlType === 'update' || card.sqlType === 'audit') {
        _defaultsql = _updatesql
      } else if (card.sqlType === 'insertOrUpdate') {
        _defaultsql += `select @tbid=''
          select @tbid='X' from ${card.sql} where ${_primaryKey}=@ID@
          if @tbid=''
            begin
            ${_insertsql}
            end
          else
            begin
            ${_updatesql}
            end
        `
      } else if (card.sqlType === 'LogicDelete' || card.sqlType === 'custom') {
        let _voucher = ''
        if (_verify.voucher && _verify.voucher.enabled) {
          _voucher = ',BVoucher=@BVoucher,FIBVoucherDate=@FIBVoucherDate,FiYear=@FiYear'
        }
        _defaultsql = `update ${card.sql} set deleted=@mk_deleted,modifydate=getdate(),modifyuser=@username,modifystaff=@fullname,modifyuserid=@userid@${_voucher} where ${_primaryKey}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
      } else if (card.sqlType === 'delete') {
        let _msg = ''
        if (columns && columns.length > 0 && card.Ot !== 'notRequired') {
          let _index = 0
          columns.forEach(col => {
            if (!col.field || col.Hide === 'true' || _index >= 4) return
            _msg += col.label + '=\'\','
            _index++
          })
        }
        _defaultsql += `insert into snote (remark,createuserid,CreateUser,CreateStaff,typename) select left('删除表:${card.sql} 数据: ${_msg}${_primaryKey}='+@ID@,200),@userid@,@username,@fullname,@typename@ delete ${card.sql} where ${_primaryKey}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
      }
      let _columns = []
      if (columns) {
        _columns = fromJS(columns).toJS()
        let hasbid = false
        _columns = _columns.filter(col => {
          if (col.field && col.field.toLowerCase() === 'bid') {
            hasbid = true
          }
          return !!col.field
        })
        if (!hasbid) {
          _columns.unshift({ uuid: 'BID', field: 'BID', label: 'BID', type: 'text' })
        }
      }
      this.setState({
        fields: _fields,
        columnsFields: _columns,
        initsql: _sql,
        defaultsql: _defaultsql,
        usefulfields: _usefulfields.join(', '),
        uniqueColumns: this.state.uniqueColumns.map(col => {
          if (col.dataIndex === 'field') {
            col.options = uniqueFields
          }
          return col
        }),
        onceUniqueColumns: this.state.onceUniqueColumns.map(col => {
          if (col.dataIndex === 'field') {
            col.options = _columns
          }
          return col
        }),
        unionFields,
        uniqueFields
      })
        return col
      }),
      unionFields
    })
  }
@@ -1035,7 +893,12 @@
      {
        obj_name: 'noteCodes',
        arr_field: 'templatecode,describe,id',
        LText: window.btoa(window.encodeURIComponent(`select t.id,templatecode,'['+SignName+']'+describe as describe from (select * from bd_msn_sms_temp where  deleted=0 and TypeDesc='QX' and status=20 ) t inner join (select openid from susers where uid=@userid@) u on t.openid =t.openid`))
        LText: window.btoa(window.encodeURIComponent(`select t.id,templatecode,'['+SignName+']'+describe as describe from (select * from bd_msn_sms_temp where  deleted=0 and TypeDesc='QX' and status=20 ) t inner join (select openid from susers where uid=@userid@) u on t.openid =u.openid`))
      },
      {
        obj_name: 'emailCodes',
        arr_field: 'msn_email_temp_no,remark,id',
        LText: window.btoa(window.encodeURIComponent(`select t.id,t.msn_email_temp_no,t.remark from (select * from bd_msn_email_temp where deleted=0) t inner join (select openid from susers where uid=@userid@) u on t.openid=u.openid`))
      },
      {
        obj_name: 'scripts',
@@ -1051,16 +914,17 @@
      LText: mutilForms.join(' union all '),
      obj_name: '',
      arr_field: '',
      table_type: 'Y'
      table_type: 'Y',
      exec_type: 'x'
    }
    mutilparam.LText = Utils.formatOptions(mutilparam.LText)
    mutilparam.LText = Utils.formatOptions(mutilparam.LText, 'x')
    mutilparam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    mutilparam.secretkey = Utils.encrypt(mutilparam.LText, mutilparam.timestamp)
    mutilparam.secretkey = Utils.encrypt('', mutilparam.timestamp)
    mutilparam.open_key = Utils.encryptOpenKey(mutilparam.secretkey, mutilparam.timestamp)
    if (options.cloudServiceApi) { // 云端请求
      mutilparam.rduri = options.cloudServiceApi
    if (window.GLOB.cloudServiceApi) { // 云端请求
      mutilparam.rduri = window.GLOB.cloudServiceApi
      mutilparam.userid = sessionStorage.getItem('CloudUserID') || ''
      mutilparam.LoginUID = sessionStorage.getItem('CloudLoginUID') || ''
    }
@@ -1079,6 +943,13 @@
              id: item.id
            }
          }),
          emailCodes: res.emailCodes.map(item => {
            return {
              name: item.remark,
              value: item.msn_email_temp_no,
              id: item.id
            }
          }),
          systemScripts: res.scripts.map(item => {
            return {
              name: item.funcname,
@@ -1093,6 +964,1060 @@
          duration: 5
        })
      }
    })
  }
  getSysExecSql = (verify, retmsg) => {
    const { columns, config, card } = this.props
    const { fields } = this.state
    let btn = card
    let primaryId = Utils.getuuid()
    let BID = Utils.getuuid()
    let _actionType = null
    let setting = config.setting || {}
    if (verify.uniques && verify.uniques.length > 0 && btn.Ot === 'requiredOnce') {
      if (config.wrap && (config.wrap.datatype === 'static' || config.wrap.datatype === 'public')) {
        verify.uniques = []
      }
    }
    if (verify.default !== 'false') { // 判断是否使用默认sql
      _actionType = btn.sqlType
    }
    let _initCustomScript = '' // 初始化脚本
    let _prevCustomScript = '' // 默认sql前执行脚本
    let _backCustomScript = '' // 默认sql后执行脚本
    verify.scripts && verify.scripts.forEach(item => {
      if (item.status === 'false') return
      if (item.position === 'init') {
        _initCustomScript += `
        /* 自定义脚本 */
        ${item.sql}
        `
      } else if (item.position === 'front') {
        _prevCustomScript += `
        /* 自定义脚本 */
        ${item.sql}
        `
      } else {
        _backCustomScript += `
        /* 自定义脚本 */
        ${item.sql}
        `
      }
    })
    // 需要声明的变量集
    let _vars = ['tbid', 'errorcode', 'retmsg', 'billcode', 'bvoucher', 'fibvoucherdate', 'fiyear', 'username', 'fullname', 'modulardetailcode', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'mk_deleted', 'bid', 'mk_submit_type']
    // 主键字段
    let primaryKey = setting.primaryKey || 'id'
    if (this.props.side === 'sub') {
      primaryKey = setting.subKey || 'id'
    }
    // sql语句
    let _sql = ''
    let _initvars = [] // 已赋值字段集
    let _initFormfields = []
    let _initColfields = []
    let _declarefields = []
    let formdata = fields.filter(item => item.uuid !== 'BID')
    formdata = formdata.length ? formdata : null
    // 获取字段键值对
    formdata && formdata.forEach(form => {
      let _key = form.field.toLowerCase()
      if (!_initvars.includes(_key)) {
        _initvars.push(_key)
        if (form.type === 'number' || form.type === 'rate') {
          _initFormfields.push(`@${form.field}=1`)
        } else if (form.type === 'date') {
          _initFormfields.push(`@${form.field}='1949-10-01'`)
        } else if (form.type === 'select' || form.type === 'link' || form.type === 'radio') {
          _initFormfields.push(`@${form.field}='1'`)
        } else {
          _initFormfields.push(`@${form.field}='mk'`)
        }
      }
      if (!_vars.includes(_key)) {
        _vars.push(_key)
        if (form.fieldlen && form.fieldlen > 4000) {
          form.fieldlen = 'max'
        }
        let _type = `nvarchar(${form.fieldlen})`
        if (form.type.match(/date/ig)) {
          _type = 'datetime'
        } else if (form.type === 'number') {
          _type = `decimal(18,${form.fieldlen})`
        } else if (form.type === 'rate') {
          _type = `decimal(18,2)`
        }
        if (['appkey'].includes(_key)) return
        _declarefields.push(`@${form.field} ${_type}`)
      }
    })
    // 添加数据中字段,表单值优先(按钮不选行或多行拼接时跳过)
    if (btn.Ot !== 'notRequired' && columns.length > 0) {
      columns.forEach(col => {
        if (!col.field) return
        let _key = col.field.toLowerCase()
        if (!_initvars.includes(_key)) {
          _initvars.push(_key)
          if (col.datatype && /^date/ig.test(col.datatype)) {
            _initColfields.push(`@${col.field}='1949-10-01'`)
          } else if (col.type === 'number') {
            _initColfields.push(`@${col.field}=1`)
          } else {
            _initColfields.push(`@${col.field}='mk'`)
          }
        }
        if (!_vars.includes(_key) && !['appkey'].includes(_key)) {
          _vars.push(_key)
          _declarefields.push(`@${col.field} ${col.datatype || 'nvarchar(50)'}`)
        }
      })
    }
    // 变量声明
    _declarefields = _declarefields.join(',')
    if (_declarefields) {
      _declarefields = ',' + _declarefields
    }
    _sql = `Declare @tbid nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@BillCode nvarchar(50),@BVoucher nvarchar(50),@FIBVoucherDate nvarchar(50), @FiYear nvarchar(50),@ModularDetailCode nvarchar(50), @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@mk_deleted int,@bid nvarchar(50),@mk_submit_type nvarchar(50)${_declarefields}
      `
    let userName = 'User_Name'
    let fullName = 'Full_Name'
    let RoleID = 'role_id'
    let departmentcode = 'departmentcode'
    let organization = 'organization'
    let mk_user_type = 'mk_user_type'
    let nation = 'nation'
    let province = 'province'
    let city = 'city'
    let district = 'district'
    let address = 'address'
    // 初始化凭证及用户信息字段
    _sql += `
        /* 凭证及用户信息初始化赋值 */
        select @BVoucher='',@FIBVoucherDate='',@FiYear='',@ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}', @mk_deleted=1, @bid='${BID}', @mk_submit_type='', @BillCode='', @ModularDetailCode=''
        `
    // 表单变量赋值
    if (_initFormfields.length > 0) {
      _sql += `
        /* 表单变量赋值 */
        select ${_initFormfields.join(',')}
        `
    }
    // 显示列变量赋值
    if (_initColfields.length > 0) {
      _sql += `
        /* 显示列变量赋值 */
        select ${_initColfields.join(',')}
        `
    }
    if (retmsg) {
      return _sql
    }
    // 去除禁用的验证
    if (verify.contrasts) {
      verify.contrasts = verify.contrasts.filter(item => item.status !== 'false')
    }
    if (verify.uniques) {
      verify.uniques = verify.uniques.filter(item => item.status !== 'false')
    }
    if (verify.customverifys) {
      verify.customverifys = verify.customverifys.filter(item => item.status !== 'false')
    }
    if (verify.billcodes) {
      verify.billcodes = verify.billcodes.filter(item => item.status !== 'false')
    }
    if (_initCustomScript) {
      _sql += _initCustomScript
    }
    // 启用账期验证
    if (verify.accountdate === 'true') {
      let orgcode = `''`
      let date = `''`
      if (verify.accountfield && _initvars.includes(verify.accountfield.toLowerCase())) {
        orgcode = '@' + verify.accountfield
      }
      if (verify.voucherdate && _initvars.includes(verify.voucherdate.toLowerCase())) {
        date = '@' + verify.voucherdate
      }
      _sql += `
        /* 账期验证 */
        exec s_FIBVoucherDateCheck @OrgCode=${orgcode},@FIBVoucherDate=${date},@ErrorCode=@ErrorCode OUTPUT,@retmsg=@retmsg OUTPUT
        if @ErrorCode!=''
          GOTO aaa
        `
    }
    // 失效验证,添加数据时不用
    if (verify.invalid === 'true') {
      let datasource = setting.dataresource
      let customScript = ''
      config.scripts && config.scripts.forEach(script => {
        if (script.status === 'false' || script.position === 'back') return
        customScript += `
        ${script.sql}
        `
      })
      if (/\s/.test(datasource)) {
        datasource = '(' + datasource + ') tb'
      }
      let regoptions = [{
        reg: new RegExp('@userName@', 'ig'),
        value: `'${userName}'`
      }, {
        reg: new RegExp('@fullName@', 'ig'),
        value: `'${fullName}'`
      }, {
        reg: new RegExp('@orderBy@', 'ig'),
        value: setting.order || primaryKey
      }, {
        reg: new RegExp('@pageSize@', 'ig'),
        value: 1
      }, {
        reg: new RegExp('@pageIndex@', 'ig'),
        value: 1
      }]
      regoptions.forEach(item => {
        datasource = datasource.replace(item.reg, item.value)
        customScript = customScript.replace(item.reg, item.value)
      })
      if (customScript) {
        _sql += `
        /* 数据源自定义脚本,请注意变量定义是否重复 */
        ${customScript}
        `
      }
      if (btn.Ot === 'requiredOnce') {
        _sql += `
        /* 失效验证 */
        select @tbid='', @ErrorCode='',@retmsg=''
        select @tbid='X' from ${datasource} right join (select ID from  dbo.SplitComma(@ID@)) sp
        on tb.${primaryKey} =sp.id where tb.${primaryKey} is null
        If @tbid!=''
        Begin
          select @ErrorCode='E',@retmsg='数据已失效'
          goto aaa
        end
        `
      } else {
        _sql += `
        /* 失效验证 */
        select @tbid='', @ErrorCode='',@retmsg=''
        select @tbid=${primaryKey} from ${datasource} where ${primaryKey}=@ID@
        If @tbid=''
        Begin
          select @ErrorCode='E',@retmsg='数据已失效'
          goto aaa
        end
        `
      }
    }
    // 比较验证
    if (verify.contrasts && verify.contrasts.length > 0) {
      verify.contrasts.forEach(item => {
        _sql += `
        /* 比较验证 */
        If ${item.frontfield} ${item.operator} ${item.backfield}
        Begin
          select @ErrorCode='${item.errorCode}',@retmsg='${item.errmsg}'
            goto aaa
        end
        `
      })
    }
    // 自定义验证
    verify.customverifys && verify.customverifys.forEach(item => {
      _sql += `
        /* 自定义验证 */
        select @tbid='', @ErrorCode='',@retmsg=''
        select top 1 @tbid='X' from (${item.sql}) a
        If @tbid ${item.result === 'true' ? '!=' : '='}''
        Begin
          select @ErrorCode='${item.errorCode}',@retmsg='${item.errmsg}'
          goto aaa
        end
        `
    })
    // 单号生成,使用上级id(BID)或列表数据,声明变量(检验)
    let _billcodesSql  = ''
    if (formdata && verify.billcodes && verify.billcodes.length > 0) {
      let keys = formdata.map(item => item.field.toLowerCase()) // 表单字段
      verify.billcodes.forEach(item => {
        let _key = item.field.toLowerCase()
        let _linkKey = item.linkField ? item.linkField.toLowerCase() : ''
        if (!keys.includes(_key)) return // 表单中不含单号生成字段
        let _lpline = ''
        if (item.TypeCharOne === 'Lp') {
          if (_linkKey === 'bid' && BID) { // 替换bid
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
          } else {
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
          }
        } else if (item.TypeCharOne === 'BN') {
          if (_linkKey === 'bid' && BID) { // 替换bid
            _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
          } else {
            _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
          }
        } else {
          _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
        }
        _billcodesSql += `
        /* 单号生成 */
        select @BillCode='', @${_key}='', @ModularDetailCode=''
        ${_lpline}
        exec s_get_BillCode
          @ModularDetailCode=@ModularDetailCode,
          @Type=${item.Type},
          @TypeCharOne='${item.TypeCharOne}',
          @TypeCharTwo ='${item.TypeCharTwo}',
          @BillCode =@BillCode output,
          @ErrorCode =@ErrorCode output,
          @retmsg=@retmsg output
        if @ErrorCode!=''
          goto aaa
        set @${_key}=@BillCode
        `
      })
      if (_actionType !== 'insertOrUpdate') {
        _sql += _billcodesSql
      }
    }
    // 唯一性验证,必须存在表单(表单存在时,主键均为单值),必须填写数据源,多行拼接时不可用
    if (formdata && verify.uniques && verify.uniques.length > 0 && btn.Ot !== 'requiredOnce') {
      let dateForms = []
      let numForms = []
      formdata.forEach(form => {
        let _key = form.field.toLowerCase()
        if (form.type === 'date') {
          dateForms.push(_key)
        } else if (form.type === 'number' || form.type === 'rate') {
          numForms.push(_key)
        }
      })
      verify.uniques.forEach(item => {
        let _fieldValue = []                     // 表单键值对field=value
        let _value = []                          // 表单值,用于错误提示
        let _labels = item.fieldlabel.split(',') // 表单提示文字
        let arr = [] // 验证主键
        item.field.split(',').forEach((_field, index) => {
          let _key = _field.toLowerCase()
          let _val = ''
          let _val2 = ''
          arr.push(_key)
          if (_key === 'bid') {
            _val = `'${BID}'`
          } else {
            _val = `@${_field}`
          }
          if (_key === 'bid') {
            _val2 = BID
          } else {
            _val2 = `' + @${_field} + '`
          }
          _fieldValue.push(`${_key}=${_val}`)
          _value.push(`${_labels[index] || ''}:${_val2}`)
        })
        if (!arr.includes(primaryKey.toLowerCase()) && btn.Ot !== 'notRequired') {
          _fieldValue.push(`${primaryKey} !='${primaryId}'`)
        }
        _sql += `
        /* 唯一性验证 */
        select @tbid='', @ErrorCode='',@retmsg=''
        select @tbid='X' from ${btn.sql} where ${_fieldValue.join(' and ')}${item.verifyType === 'logic' ? ' and deleted=0' : ''}
        If @tbid!=''
        Begin
          select @ErrorCode='${item.errorCode}',@retmsg='${_value.join(', ')} 已存在'
          goto aaa
        end
        `
      })
    } else if (verify.uniques && verify.uniques.length > 0 && btn.Ot === 'requiredOnce' && setting.dataresource) {
      let datasource = setting.dataresource
      if (/\s/.test(datasource)) { // 拼接别名
        if (!/tb$/.test(datasource)) {
          datasource = '(' + datasource + ') tb'
        }
      } else {
        datasource = datasource + ' tb'
      }
      if (setting.customScript) {
        _sql += `
        /* 数据源自定义脚本,请注意变量定义是否重复 */
        ${setting.customScript}
        `
      }
      verify.uniques.forEach(item => {
        _sql += `
        /* 同类数据验证 */
        Set @tbid=''
        Select top 1 @tbid='X' from (select distinct ${item.field},1 as n from ${datasource} inner join (select ID from  dbo.SplitComma(@ID@)) sp on tb.${primaryKey}=sp.ID ) a having sum(n)>1
        If @tbid!=''
        Begin
          Set @ErrorCode='E' Set @retmsg='${item.fieldlabel} 值不唯一'
          goto aaa
        end
        `
      })
    }
    let hasvoucher = false
    // 凭证-显示列中选取,必须选行
    if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'notRequired') {
      let _voucher = verify.voucher
      hasvoucher = true
      _sql += `
        /* 创建凭证 */
        exec s_BVoucher_Create
          @Bill = @${_voucher.linkField},
          @BVoucherType ='${_voucher.BVoucherType}',
          @VoucherTypeOne ='${_voucher.VoucherTypeOne}',
          @VoucherTypeTwo ='${_voucher.VoucherTypeTwo}',
          @Type =${_voucher.Type},
          @UserID=@UserID@,
          @Username=@Username,
          @FullName=@FullName,
          @BVoucher =@BVoucher OUTPUT ,
          @FIBVoucherDate =@FIBVoucherDate OUTPUT ,
          @FiYear =@FiYear OUTPUT ,
          @ErrorCode =@ErrorCode OUTPUT,
          @retmsg=@retmsg OUTPUT
        if @ErrorCode!=''
          GOTO aaa
        `
    }
    let _insertsql = ''
    if (_actionType === 'insert' || _actionType === 'insertOrUpdate') { // 添加语句
      let keys = []
      let values = []
      formdata.forEach(item => {
        if (item.writein === false) return
        let _key = item.field.toLowerCase()
        keys.push(_key)
        values.push('@' + _key)
      })
      if (!keys.includes(primaryKey.toLowerCase())) {
        keys.push(primaryKey.toLowerCase())
        values.push('\'' + primaryId + '\'')
      }
      if (!keys.includes('createuserid')) {
        keys.push('createuserid')
        values.push('@userid@')
      }
      if (!keys.includes('createuser')) {
        keys.push('createuser')
        values.push('@username')
      }
      if (!keys.includes('createstaff')) {
        keys.push('createstaff')
        values.push('@fullname')
      }
      if (!keys.includes('bid')) {
        keys.push('bid')
        values.push('@BID@')
      }
      if (!keys.includes('typename')) {
        keys.push('typename')
        values.push('@typename@')
      }
      keys = keys.join(',')
      values = values.join(',')
      _insertsql = `insert into ${btn.sql} (${keys}) select ${values};`
    }
    let _updatesql = ''
    if (_actionType === 'update' || _actionType === 'audit' || _actionType === 'insertOrUpdate') { // 修改语句
      let _form = []
      let _arr = []
      formdata.forEach(item => {
        if (item.writein === false) return
        let _key = item.field.toLowerCase()
        _arr.push(_key)
        _form.push(_key + '=@' + _key)
      })
      if (_actionType === 'audit') {
        if (!_arr.includes('submitdate')) {
          _form.push('submitdate=getdate()')
        }
        if (!_arr.includes('submituser')) {
          _form.push('submituser=@username')
        }
        if (!_arr.includes('submitstaff')) {
          _form.push('submitstaff=@fullname')
        }
        if (!_arr.includes('submituserid')) {
          _form.push('submituserid=@userid@')
        }
      } else {
        if (!_arr.includes('modifydate')) {
          _form.push('modifydate=getdate()')
        }
        if (!_arr.includes('modifyuser')) {
          _form.push('modifyuser=@username')
        }
        if (!_arr.includes('modifystaff')) {
          _form.push('modifystaff=@fullname')
        }
        if (!_arr.includes('modifyuserid')) {
          _form.push('modifyuserid=@userid@')
        }
      }
      if (hasvoucher) {
        if (!_arr.includes('bvoucher')) {
          _form.push('BVoucher=@BVoucher')
        }
        if (!_arr.includes('fibvoucherdate')) {
          _form.push('FIBVoucherDate=@FIBVoucherDate')
        }
        if (!_arr.includes('fiyear')) {
          _form.push('FiYear=@FiYear')
        }
      }
      if (!_arr.includes('typename')) {
        _form.push('typename=@typename@')
      }
      _form = _form.join(',')
      let _ID = '=@ID@'
      if (btn.Ot === 'requiredOnce') {
        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
      }
      _updatesql = `update ${btn.sql} set ${_form} where ${primaryKey}${_ID};`
    }
    if (_prevCustomScript) {
      _sql += _prevCustomScript
    }
    // 添加、修改、逻辑删除、物理删除
    if (_actionType === 'insert') {
      _sql += `
        /* 默认sql */
        ${_insertsql}`
    } else if (_actionType === 'update' || _actionType === 'audit') {
      _sql += `
        /* 默认sql */
        ${_updatesql}`
    } else if (_actionType === 'LogicDelete') { // 逻辑删除
      let _ID = '=@ID@'
      if (btn.Ot === 'requiredOnce') {
        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
      }
      _sql += `
        /* 默认sql */
        update ${btn.sql} set deleted=@mk_deleted,modifydate=getdate(),modifyuser=@username,modifystaff=@fullname,modifyuserid=@userid@ where ${primaryKey}${_ID};`
    } else if (_actionType === 'delete') {      // 物理删除
      let _msg = ''
      if (columns && columns.length > 0 && btn.Ot !== 'notRequired') {
        let _index = 0
        columns.forEach(col => {
          if (!col.field || col.Hide === 'true' || _index >= 4 || col.field === primaryKey) return
          _msg += col.label + '=0,'
          _index++
        })
      }
      let _ID = '=@ID@'
      if (btn.Ot === 'requiredOnce') {
        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
      }
      _sql += `
        /* 默认sql */
        insert into snote (remark,createuserid,CreateUser,CreateStaff,typename) select left('删除表:${btn.sql} 数据: ${_msg}${primaryKey}='+@ID@,200),@userid@,@username,@fullname,@typename@
        delete ${btn.sql} where ${primaryKey}${_ID};`
    } else if (_actionType === 'insertOrUpdate') {
      _sql += `
        /* 默认sql */
        select @tbid=''
        select @tbid='X' from ${btn.sql} where ${primaryKey}=@ID@
        if @tbid=''
          begin
          ${_billcodesSql}
          ${_insertsql}
          end
        else
          begin
          ${_updatesql}
          end
      `
    }
    if (verify.workFlow === 'true' && window.GLOB.process) {
      let status = 888
      let statusName = '结束'
      let detailId = '0'
      if (verify.flowSql === 'true') {
        if (verify.flowType === 'start') {
          _sql += `
            /* 工作流默认sql */
            insert into s_my_works_flow (works_flow_id,works_flow_code,works_flow_name,works_flow_param,status,statusname,work_group,works_flow_detail_id,work_grade,bid,createuserid,CreateUser,CreateStaff,upid)
            select @ID@,@works_flow_code@,@works_flow_name@,@works_flow_param@,@status@,@statusname@,@work_group@,@works_flow_detail_id@,@work_grade@,@bid@,@UserID@,@UserName,@FullName,@time_id@
            insert into s_my_works_flow_log (works_flow_id,works_flow_code,works_flow_name,works_flow_param,status,statusname,works_flow_detail_id,work_group,work_grade,bid,createuserid,CreateUser,CreateStaff,upid)
            select @ID@,@works_flow_code@,@works_flow_name@ ,@works_flow_param@,@status@,@statusname@,@works_flow_detail_id@,@work_group@,@work_grade@,@bid@,@UserID@,@UserName,@FullName,@time_id@
            insert into s_my_works_flow_notice (works_flow_id,works_flow_code,works_flow_detail_id,userid,notice_type,createuserid,CreateUser,CreateStaff,upid)
            select @ID@,@works_flow_code@,@works_flow_detail_id@,@userid@,@start_type@,@userid@,@UserName,@FullName,@time_id@
            insert into s_my_works_flow_role (works_flow_id,works_flow_code,userid,works_flow_detail_id,createuserid,CreateUser,CreateStaff,upid,typecharone)
            select @ID@,@works_flow_code@,@userid@,@works_flow_detail_id@,@userid@,@UserName,@FullName,@time_id@,'begin'
          `
        } else {
          _sql += `
            /* 工作流默认sql */
            update s_my_works_flow set status=@status@,statusname=@statusname@,works_flow_param=@works_flow_param@,works_flow_detail_id=@works_flow_detail_id@,modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname${verify.flowRemark ? ',remark=@' + verify.flowRemark : ''}
            where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0
            insert into s_my_works_flow_log (works_flow_id,works_flow_code,works_flow_name,works_flow_param,status,statusname,works_flow_detail_id,work_group,work_grade,bid,createuserid,CreateUser,CreateStaff,upid${verify.flowRemark ? ',remark' : ''})
            select @ID@,@works_flow_code@,@works_flow_name@ ,@works_flow_param@,@status@,@statusname@,@works_flow_detail_id@,@work_group@,@work_grade@,@bid@,@UserID@,@UserName,@FullName,@time_id@${verify.flowRemark ? ',@' + verify.flowRemark : ''}
            update s_my_works_flow_role set deleted=10,modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname
            where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0
            if @check_userids@ != ''
            begin
                  insert into s_my_works_flow_role (works_flow_id,works_flow_code,userid,works_flow_detail_id,createuserid,CreateUser,CreateStaff,upid)
                  select @ID@,@works_flow_code@,ID,@works_flow_detail_id@,@userid@,@UserName,@FullName,@time_id@ from dbo.SplitComma(@check_userids@)
                  insert into s_my_works_flow_notice (works_flow_id,works_flow_code,works_flow_detail_id,userid,notice_type,createuserid,CreateUser,CreateStaff,upid)
                  select @ID@,@works_flow_code@,@works_flow_detail_id@,ID,@check_type@,@userid@,@UserName,@FullName,@time_id@ from dbo.SplitComma(@check_userids@)
            end
            if @notice_userids@ != ''
            begin
                  update n
                  set deleted=10,modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname
                  from (select * from s_my_works_flow_notice where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0) n
                  inner join (select ID from dbo.SplitComma(@notice_userids@)) s
                  on n.userid = s.id
                  insert into s_my_works_flow_notice (works_flow_id,works_flow_code,works_flow_detail_id,userid,notice_type,createuserid,CreateUser,CreateStaff,upid)
                  select @ID@,@works_flow_code@,@works_flow_detail_id@,ID,@notice_type@,@userid@,@UserName,@FullName,@time_id@ from dbo.SplitComma(@notice_userids@)
            end
          `
        }
      }
      if (_backCustomScript) {
        _sql += _backCustomScript
      }
      _sql = _sql.replace(/@works_flow_code@/ig, `'mk'`)
      _sql = _sql.replace(/@works_flow_name@/ig, `'mk'`)
      _sql = _sql.replace(/@works_flow_param@/ig, `''`)
      _sql = _sql.replace(/@works_flow_detail_id@/ig, `'${detailId}'`)
      _sql = _sql.replace(/@status@/ig, `'${status}'`)
      _sql = _sql.replace(/@statusname@/ig, `'${statusName}'`)
      _sql = _sql.replace(/@work_group@/ig, `'mk'`)
      _sql = _sql.replace(/@work_grade@/ig, `'0'`)
      if (verify.flowType === 'start') {
        _sql = _sql.replace(/@start_type@/ig, `'开始'`)
      } else {
        _sql = _sql.replace(/@check_type@/ig, `'审核'`)
        _sql = _sql.replace(/@notice_type@/ig, `'抄送'`)
        _sql = _sql.replace(/@check_userids@/ig, `''`)
        _sql = _sql.replace(/@notice_userids@/ig, `''`)
        _sql = _sql.replace(/@works_flow_sign@/ig, `''`)
      }
    } else if (_backCustomScript) {
      _sql += _backCustomScript
    }
    if (btn.procMode === 'system') {
      _sql += `
        aaa: if @ErrorCode!=''
        insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@`
    } else if (btn.output) {
      _sql += `
        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${btn.output} as mk_b_id`
    } else {
      _sql += `
        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
    }
    _sql = _sql.replace(/@ID@/ig, `'${primaryId || ''}'`)
    _sql = _sql.replace(/@BID@/ig, `'${BID}'`)
    _sql = _sql.replace(/@typename@/ig, `'typename'`)
    _sql = _sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
    return _sql
  }
  getSysBackSql = (scripts, cbTable) => {
    let _prev = ''
    let _back = ''
    scripts.forEach(script => {
      if (script.status === 'false') return
      if (script.position === 'front') {
        _prev += `
      /* 自定义脚本 */
      ${script.sql}
      `
      } else {
        _back += `
      /* 自定义脚本 */
      ${script.sql}
      `
      }
    })
    if (!_prev) return _back
    let tbs = []
    _prev.replace(/\/\*[^/*]+\*\//g, '').replace(/\n|\r/g, ' ').split(/\sdeclare\s+|\screate\s+table\s+/ig).forEach(line => {
      if (/^\s*(@|#)[a-zA-Z0-9_]+\s+table\s+\(/ig.test(line)) {
        line = line.replace(/\s+table\s+\(/, '(')
      }
      if (!/^\s*(@|#)[a-zA-Z0-9_]+\s*\(/ig.test(line)) return
      let tb = line.match(/(@|#)[a-zA-Z0-9_]+\s*\(.+(\)|date|datetime)\s*\)/ig)
      if (tb && tb.length === 1) {
        tbs.push(tb[0])
      }
    })
    tbs.forEach(tb => {
      let tbName = tb.match(/(@|#)[a-zA-Z0-9_]+/ig)[0]
      if (!tbName) return
      let content = tb.replace(/(@|#)[a-zA-Z0-9_]+\s*\(\s*/, '').replace(/\s*\)$/, '')
      content = content.replace(/decimal\(\s*\d+\s*,\s*\d+\s*\)/ig, 'decimal')
      let keys = []
      let vals = []
      let error = false
      let istop = new RegExp(cbTable + '$', 'ig').test(tbName)
      let id = tbName.replace(/@|#/, '')
      content.split(/\s*,\s*/).forEach(m => {
        let ms = m.split(/\s+/)
        if (ms.length > 1) {
          keys.push(ms[0])
          if (/^mk_level$/i.test(ms[0])) {
            vals.push(istop ? `'1'` : `'2'`)
          } else if (/^mk_id$/i.test(ms[0])) {
            vals.push(istop ? `'${cbTable}'` : `'${id}'`)
          } else if (/^mk_bid$/i.test(ms[0])) {
            vals.push(istop ? `''` : `'${cbTable}'`)
          } else if (/nvarchar/i.test(ms[1])) {
            vals.push(`'mk'`)
          } else if (/date/i.test(ms[1])) {
            vals.push(`'1949-10-01'`)
          } else if (/int|decimal/i.test(ms[1])) {
            vals.push('0')
          } else {
            error = true
          }
        } else {
          error = true
        }
      })
      if (error || vals.length === 0) return
      _prev += `
      Insert into ${tbName} (${keys.join(',')})
      Select ${vals.join(',')}
      `
    })
    return _prev + _back
  }
  getSysDefSql = () => {
    const { columns, config, card } = this.props
    const { fields, verify } = this.state
    let btn = card
    let _actionType = btn.sqlType
    let setting = config.setting || {}
    // 主键字段
    let primaryKey = setting.primaryKey || 'id'
    if (this.props.side === 'sub') {
      primaryKey = setting.subKey || 'id'
    }
    let _sql = ''
    let _insertsql = ''
    if (_actionType === 'insert' || _actionType === 'insertOrUpdate') { // 添加语句
      let keys = []
      let values = []
      fields.forEach(item => {
        if (item.writein === false) return
        let _key = item.field.toLowerCase()
        keys.push(_key)
        values.push('@' + _key)
      })
      if (!keys.includes(primaryKey.toLowerCase())) {
        keys.push(primaryKey.toLowerCase())
        values.push('@ID@')
      }
      if (!keys.includes('createuserid')) {
        keys.push('createuserid')
        values.push('@userid@')
      }
      if (!keys.includes('createuser')) {
        keys.push('createuser')
        values.push('@username')
      }
      if (!keys.includes('createstaff')) {
        keys.push('createstaff')
        values.push('@fullname')
      }
      if (!keys.includes('bid')) {
        keys.push('bid')
        values.push('@BID@')
      }
      if (!keys.includes('typename')) {
        keys.push('typename')
        values.push('@typename@')
      }
      keys = keys.join(', ')
      values = values.join(', ')
      _insertsql = `insert into ${btn.sql} (${keys}) select ${values};`
    }
    let _updatesql = ''
    if (_actionType === 'update' || _actionType === 'audit' || _actionType === 'insertOrUpdate') { // 修改语句
      let _form = []
      let _arr = []
      fields.forEach(item => {
        if (item.writein === false) return
        let _key = item.field.toLowerCase()
        _arr.push(_key)
        _form.push(_key + '=@' + _key)
      })
      if (_actionType === 'audit') {
        if (!_arr.includes('submitdate')) {
          _form.push('submitdate=getdate()')
        }
        if (!_arr.includes('submituser')) {
          _form.push('submituser=@username')
        }
        if (!_arr.includes('submitstaff')) {
          _form.push('submitstaff=@fullname')
        }
        if (!_arr.includes('submituserid')) {
          _form.push('submituserid=@userid@')
        }
      } else {
        if (!_arr.includes('modifydate')) {
          _form.push('modifydate=getdate()')
        }
        if (!_arr.includes('modifyuser')) {
          _form.push('modifyuser=@username')
        }
        if (!_arr.includes('modifystaff')) {
          _form.push('modifystaff=@fullname')
        }
        if (!_arr.includes('modifyuserid')) {
          _form.push('modifyuserid=@userid@')
        }
      }
      let hasvoucher = false
      // 凭证-显示列中选取,必须选行
      if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'notRequired') {
        hasvoucher = true
      }
      if (hasvoucher) {
        if (!_arr.includes('bvoucher')) {
          _form.push('BVoucher=@BVoucher')
        }
        if (!_arr.includes('fibvoucherdate')) {
          _form.push('FIBVoucherDate=@FIBVoucherDate')
        }
        if (!_arr.includes('fiyear')) {
          _form.push('FiYear=@FiYear')
        }
      }
      if (!_arr.includes('typename')) {
        _form.push('typename=@typename@')
      }
      _form = _form.join(', ')
      let _ID = '=@ID@'
      if (btn.Ot === 'requiredOnce') {
        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
      }
      _updatesql = `update ${btn.sql} set ${_form} where ${primaryKey}${_ID};`
    }
    // 添加、修改、逻辑删除、物理删除
    if (_actionType === 'insert') {
      _sql = _insertsql
    } else if (_actionType === 'update' || _actionType === 'audit') {
      _sql = _updatesql
    } else if (_actionType === 'LogicDelete' || _actionType === 'custom') { // 逻辑删除
      let _ID = '=@ID@'
      if (btn.Ot === 'requiredOnce') {
        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
      }
      _sql = `update ${btn.sql} set deleted=@mk_deleted,modifydate=getdate(),modifyuser=@username,modifystaff=@fullname,modifyuserid=@userid@ where ${primaryKey}${_ID};`
    } else if (_actionType === 'delete') {      // 物理删除
      let _msg = ''
      if (columns && columns.length > 0 && btn.Ot !== 'notRequired') {
        let _index = 0
        columns.forEach(col => {
          if (!col.field || col.Hide === 'true' || _index >= 4 || col.field === primaryKey) return
          _msg += col.label + '=0,'
          _index++
        })
      }
      let _ID = '=@ID@'
      if (btn.Ot === 'requiredOnce') {
        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
      }
      _sql = `insert into snote (remark,createuserid,CreateUser,CreateStaff,typename) select left('删除表:${btn.sql} 数据: ${_msg}${primaryKey}='+@ID@,200),@userid@,@username,@fullname,@typename@
        delete ${btn.sql} where ${primaryKey}${_ID};`
    } else if (_actionType === 'insertOrUpdate') {
      _sql = `
        /* 默认sql */
        select @tbid=''
        select @tbid='X' from ${btn.sql} where ${primaryKey}=@ID@
        if @tbid=''
          begin
          ${_insertsql}
          end
        else
          begin
          ${_updatesql}
          end
      `
    }
    return _sql
  }
  orderSql = (record) => {
    let _lpline = ''
    if (record.TypeCharOne === 'Lp') {
      if (record.linkField.toLowerCase() === 'bid') {
        _lpline = `set @ModularDetailCode= 'Lp'+ right('${record.mark || this.props.card.uuid}'+@BID@,48)`
      } else {
        _lpline = `set @ModularDetailCode= 'Lp'+ right('${record.mark || this.props.card.uuid}'+@${record.linkField.toLowerCase()},48)`
      }
    } else if (record.TypeCharOne === 'BN') {
      if (record.linkField.toLowerCase() === 'bid') {
        _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
      } else {
        _lpline = `set @ModularDetailCode= 'BN'+ right(@${record.linkField.toLowerCase()},48)`
      }
    } else {
      _lpline = `set @ModularDetailCode= right('${record.ModularDetailCode}',50)`
    }
    let sql = `select @BillCode='', @${record.field}='', @ModularDetailCode=''
    ${_lpline}
    exec s_get_BillCode
      @ModularDetailCode=@ModularDetailCode,
      @Type=${record.Type},
      @TypeCharOne='${record.TypeCharOne}',
      @TypeCharTwo ='${record.TypeCharTwo}',
      @BillCode =@BillCode output,
      @ErrorCode =@ErrorCode output,
      @retmsg=@retmsg output
    if @ErrorCode!=''
      goto aaa
    set @${record.field}=@BillCode`
    Modal.info({
      title: '',
      width: 500,
      className: 'sql-example',
      icon: null,
      content: sql.split(/\n\s{4}/ig).map((n, index) => <div key={index} dangerouslySetInnerHTML={{ __html: n.replace(/\s/ig, '&nbsp;') }} style={{whiteSpace: 'nowrap'}}></div>)
    })
  }
@@ -1125,7 +2050,7 @@
    this.setState({ verify })
  }
  customChange = (values) => {
  customChange = (values, resolve, reject) => {
    let verify = fromJS(this.state.verify).toJS()
    if (values.uuid) {
@@ -1141,10 +2066,34 @@
      verify.customverifys.push(values)
    }
    this.setState({ verify })
    if (resolve) {
      let sql = this.getSysExecSql(verify, false)
      Api.sDebug(sql).then(res => {
        if (res.status || res.ErrCode === '-2') {
          resolve()
          this.setState({ verify })
        } else {
          reject()
          Modal.error({
            title: res.message
          })
        }
      })
    } else {
      let sql = this.getSysExecSql(verify, false)
      Api.sDebug(sql, true)
      this.setState({ verify })
    }
  }
  scriptsChange = (values) => {
  scriptsChange = (values, resolve, reject) => {
    const { columns, card } = this.props
    let verify = fromJS(this.state.verify).toJS()
    if (values.uuid) {
@@ -1160,12 +2109,65 @@
      verify.scripts.push(values)
    }
    MKEmitter.emit('editLineId', values.uuid)
    if (/@bvoucher(\s|\))/ig.test(values.sql) && !/s_BVoucher_Create/ig.test(values.sql)) {
      if (verify.voucher && verify.voucher.enabled) {
    this.setState({ verify })
      } else if (card.Ot !== 'notRequired' && columns) {
        let hasvoucher = false
        columns.forEach(_f => {
          if (!_f.field) return
          if (_f.field.toLowerCase() === 'bvoucher') {
            hasvoucher = true
          }
        })
        if (!hasvoucher) {
          notification.warning({
            top: 92,
            message: '未启用创建凭证,且字段集中不存在凭证字段(bvoucher)。',
            duration: 5
          })
        }
      } else {
        notification.warning({
          top: 92,
          message: '未启用创建凭证,且字段集中不存在凭证字段(bvoucher)。',
          duration: 5
        })
      }
    }
    if (resolve) {
      let sql = this.getSysExecSql(verify, false)
      Api.sDebug(sql).then(res => {
        if (res.status || res.ErrCode === '-2') {
          resolve()
          values && MKEmitter.emit('editLineId', values.uuid)
          this.setState({ verify })
        } else {
          reject()
          Modal.error({
            title: res.message
          })
        }
      })
    } else {
      let sql = this.getSysExecSql(verify, false)
      Api.sDebug(sql, true)
      MKEmitter.emit('editLineId', values.uuid)
      this.setState({ verify })
    }
  }
  cbScriptsChange = (values) => {
  cbScriptsChange = (values, resolve, reject) => {
    const { card } = this.props
    let verify = fromJS(this.state.verify).toJS()
    if (values.uuid) {
@@ -1181,9 +2183,75 @@
      verify.cbScripts.push(values)
    }
    MKEmitter.emit('editLineId', values.uuid)
    if (resolve) {
      let sql = this.getSysBackSql(verify.cbScripts, card.cbTable)
      if (sql) {
        let defSql = this.getSysExecSql(verify, true)
    this.setState({ verify })
        sql = `${defSql}
          ${sql}
        `
        if (card.output) {
          sql += `
            aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${card.output} as mk_b_id`
        } else {
          sql += `
            aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
        }
        sql = sql.replace(/@typename@/ig, `'typename'`)
        sql = sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
        Api.sDebug(sql).then(res => {
          if (res.status || res.ErrCode === '-2') {
            resolve()
            MKEmitter.emit('editLineId', values.uuid)
            this.setState({ verify })
          } else {
            reject()
            Modal.error({
              title: res.message
            })
          }
        })
      } else {
        MKEmitter.emit('editLineId', values.uuid)
        this.setState({ verify })
      }
    } else {
      let sql = this.getSysBackSql(verify.cbScripts, card.cbTable)
      if (sql) {
        let defSql = this.getSysExecSql(verify, true)
        sql = `${defSql}
          ${sql}
        `
        if (card.output) {
          sql += `
            aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${card.output} as mk_b_id`
        } else {
          sql += `
            aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
        }
        sql = sql.replace(/@typename@/ig, `'typename'`)
        sql = sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
        Api.sDebug(sql, true)
      }
      MKEmitter.emit('editLineId', values.uuid)
      this.setState({ verify })
    }
  }
  orderChange = (values) => {
@@ -1379,12 +2447,12 @@
  changeUniques = (uniques) => {
    const { card } = this.props
    const { verify, fields, columnsFields } = this.state
    const { verify, unionFields, columnsFields } = this.state
    let _fields = []
    let change = {}
    if (card.Ot !== 'requiredOnce') {
      _fields = fields
      _fields = unionFields
    } else {
      _fields = columnsFields
    }
@@ -1413,7 +2481,7 @@
  handleConfirm = () => {
    const { card } = this.props
    const { setting, activeKey } = this.state
    const { activeKey } = this.state
    let verify = fromJS(this.state.verify).toJS()
    if (activeKey === 'base') {
@@ -1431,17 +2499,10 @@
    
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      if ((card.sqlType === 'custom' || verify.default === 'false') && verify.scripts.length === 0) {
      if ((card.sqlType === 'custom' || verify.default === 'false') && !(verify.workFlow === 'true' && verify.flowSql === 'true') && verify.scripts.length === 0) {
        notification.warning({
          top: 92,
          message: '不执行默认sql时,必须设置自定义脚本!',
          duration: 5
        })
        return
      } else if (verify.invalid === 'true' && setting.maxScript && setting.maxScript >= 300) {
        notification.warning({
          top: 92,
          message: '数据源中自定义脚本过于复杂,不能使用失效验证!',
          duration: 5
        })
        return
@@ -1460,20 +2521,23 @@
        msg = '自定义脚本'
      }
      if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
        window.GLOB.funcs.forEach(m => {
          let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig')
          verify.customverifys.forEach(item => {
            item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
          })
          verify.scripts.forEach(item => {
            item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
          })
          verify.cbScripts.forEach(item => {
            item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
          })
        })
      }
      // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
      //   window.GLOB.funcs.forEach(m => {
      //     let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig')
      //     verify.customverifys.forEach(item => {
      //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
      //     })
      //     verify.scripts.forEach(item => {
      //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
      //     })
      //     verify.cbScripts.forEach(item => {
      //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
      //     })
      //   })
      // }
      delete verify.limitInvalid
      delete verify.limitText
      if (msg) {
        confirm({
@@ -1537,8 +2601,8 @@
  }
  render() {
    const { card } = this.props
    const { activeKey, verifyInter, setting, verify, fields, uniqueFields, uniqueColumns, unionFields, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, cbScriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail, notes, appType } = this.state
    const { card, columns } = this.props
    const { activeKey, verifyInter, verify, fields, uniqueColumns, unionFields, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, cbScriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail, notes, emailCodes, appType, formfields, colfields } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -1560,7 +2624,7 @@
              {verify.default === 'false' ? <span className="count-tip"><ExclamationOutlined style={{color: 'orange'}}/></span> : null}
            </span>
          } key="base">
            <BaseForm card={card} unionFields={unionFields} setting={setting} verify={verify} notes={notes} onChange={(verify) => this.setState({verify})} wrappedComponentRef={(inst) => this.baseForm = inst}/>
            <BaseForm card={card} appType={appType} fields={fields} columns={columns} unionFields={unionFields} verify={verify} notes={notes} emailCodes={emailCodes} onChange={(verify) => this.setState({verify})} wrappedComponentRef={(inst) => this.baseForm = inst}/>
          </TabPane> : null}
          {verifyInter === 'system' ? <TabPane tab={
            <span>
@@ -1569,7 +2633,7 @@
            </span>
          } key="contrasts">
            <ContrastForm contrastChange={this.contrastChange}/>
            <EditTable actions={['edit', 'move', 'copy', 'del', 'status']} type="contrastverify" data={verify.contrasts} columns={contrastColumns} onChange={(contrasts) => this.setState({verify: {...verify, contrasts}})}/>
            <EditTable actions={['edit', 'move', 'copy', 'del', 'status', 'sql']} type="contrastverify" data={verify.contrasts} columns={contrastColumns} onChange={(contrasts) => this.setState({verify: {...verify, contrasts}})}/>
          </TabPane> : null}
          {verifyInter === 'system' ? <TabPane tab={
            <span>
@@ -1579,14 +2643,14 @@
          } key="customverifys" id="mk-custom-script">
            <CustomForm
              btn={this.props.card}
              initsql={this.state.initsql}
              usefulfields={this.state.usefulfields}
              formfields={formfields}
              colfields={colfields}
              customChange={this.customChange}
              wrappedComponentRef={(inst) => this.customForm = inst}
            />
            <EditTable actions={['move']} data={verify.customverifys} columns={customColumns} onChange={(customverifys) => {this.setState({verify: {...verify, customverifys}})}}/>
          </TabPane> : null}
          {verifyInter === 'system' ? <TabPane tab={
          {verifyInter === 'system' && (['form', 'pop'].includes(card.OpenType) || !card.OpenType) ? <TabPane tab={
            <span>
              单号生成
              {verify.billcodes.length ? <span className="count-tip">{verify.billcodes.length}</span> : null}
@@ -1596,7 +2660,7 @@
              fields={fields}
              btn={this.props.card}
              billcodes={verify.billcodes}
              columns={this.props.columns}
              columns={columns}
              modular={orderModular}
              modularDetail={orderModularDetail}
              orderChange={this.orderChange}
@@ -1604,7 +2668,7 @@
            />
            <EditTable actions={['move']} data={verify.billcodes} columns={orderColumns} onChange={(billcodes) => {this.setState({verify: {...verify, billcodes}})}}/>
          </TabPane> : null}
          {verifyInter === 'system' ? <TabPane tab={
          {verifyInter === 'system' && (card.Ot === 'requiredOnce' || (['form', 'pop'].includes(card.OpenType) || !card.OpenType)) ? <TabPane tab={
            <span>
              {card.Ot !== 'requiredOnce' ? '唯一性验证' : '同类数据验证'}
              {verify.uniques.length ? <span className="count-tip">{verify.uniques.length}</span> : null}
@@ -1612,20 +2676,20 @@
          } key="uniques">
            <UniqueForm
              btn={card}
              fields={card.Ot !== 'requiredOnce' ? uniqueFields : columnsFields}
              fields={card.Ot !== 'requiredOnce' ? unionFields : columnsFields}
              uniqueChange={this.uniqueChange}
            />
            <EditTable actions={['edit', 'move', 'del', 'status']} data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
            <EditTable actions={['edit', 'move', 'del', 'status', 'sql']} data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
          </TabPane> : null}
          {verifyInter === 'system' ? <TabPane tab={
            <span>
            <span title={card.Ot === 'notRequired' ? '不选行时创建凭证不可用' : ''}>
              创建凭证
              {verify.voucher && verify.voucher.enabled ? <span className="count-tip">1</span> : null}
            </span>
          } key="voucher">
          } key="voucher" disabled={card.Ot === 'notRequired'}>
            <VoucherForm
              voucher={voucher}
              columns={this.props.columns}
              columns={columns}
              voucherobj={verify.voucher}
              voucherDetail={voucherDetail}
              voucherChange={this.voucherChange}
@@ -1639,7 +2703,7 @@
            </span>
          } key="scripts" id="mk-normal-script">
            <FullScripts
              verify={verify}
              scripts={verify.scripts}
              getScriptsFullForm={() => this.scriptsFullForm}
              getScriptsForm={() => this.scriptsForm}
              handleStatus={this.handleStatus}
@@ -1648,10 +2712,12 @@
              <CustomScript
                type="fullscreen"
                btn={this.props.card}
                initsql={this.state.initsql}
                customScripts={verify.scripts}
                defaultsql={this.state.defaultsql}
                usefulfields={this.state.usefulfields}
                workFlow={verify.workFlow}
                flowRemark={verify.flowRemark}
                flowType={verify.flowType}
                flowSql={verify.flowSql}
                formfields={formfields}
                colfields={colfields}
                systemScripts={this.state.systemScripts}
                scriptsChange={this.scriptsChange}
                wrappedComponentRef={(inst) => this.scriptsFullForm = inst}
@@ -1659,10 +2725,13 @@
            </FullScripts>
            <CustomScript
              btn={this.props.card}
              initsql={this.state.initsql}
              customScripts={verify.scripts}
              defaultsql={this.state.defaultsql}
              usefulfields={this.state.usefulfields}
              workFlow={verify.workFlow}
              flowRemark={verify.flowRemark}
              flowType={verify.flowType}
              flowSql={verify.flowSql}
              getSysDefSql={this.getSysDefSql}
              formfields={formfields}
              colfields={colfields}
              systemScripts={this.state.systemScripts}
              scriptsChange={this.scriptsChange}
              wrappedComponentRef={(inst) => this.scriptsForm = inst}
@@ -1675,13 +2744,29 @@
              {verify.cbScripts.length ? <span className="count-tip">{verify.cbScripts.length}</span> : null}
            </span>
          } key="cbScripts" id="mk-callback-script">
            <FullScripts
              scripts={verify.cbScripts}
              getScriptsFullForm={() => this.cbscriptsFullForm}
              getScriptsForm={() => this.cbscriptsForm}
              handleStatus={(item) => this.handleStatus(item, 'cbscripts')}
              handleDelete={(item) => this.handleDelete(item, 'cbscripts')}
            >
              <CallBackCustomScript
                type="fullscreen"
                btn={this.props.card}
                formfields={formfields}
                colfields={colfields}
                systemScripts={this.state.systemScripts}
                cbScriptsChange={this.cbScriptsChange}
                wrappedComponentRef={(inst) => this.cbscriptsFullForm = inst}
              />
            </FullScripts>
            <CallBackCustomScript
              btn={this.props.card}
              initsql={this.state.initsql}
              customScripts={verify.cbScripts}
              usefulfields={this.state.usefulfields}
              formfields={formfields}
              colfields={colfields}
              systemScripts={this.state.systemScripts}
              scriptsChange={this.cbScriptsChange}
              cbScriptsChange={this.cbScriptsChange}
              wrappedComponentRef={(inst) => this.cbscriptsForm = inst}
            />
            <EditTable actions={['move']} data={verify.cbScripts} columns={cbScriptsColumns} onChange={(cbScripts) => {this.setState({verify: {...verify, cbScripts}})}}/>
@@ -1690,7 +2775,7 @@
            <Form {...formItemLayout}>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> S </span>
                    <Button onClick={() => {this.showError('S')}} type="primary" size="small">
                      查看
@@ -1698,14 +2783,14 @@
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={'停留时间'}>
                  <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={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> Y </span>
                    <Button onClick={() => {this.showError('Y')}} type="primary" size="small">
                      查看
@@ -1715,7 +2800,15 @@
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                  <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">
                      查看
@@ -1723,14 +2816,14 @@
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={'停留时间'}>
                  <Form.Item label="停留时间">
                    <InputNumber defaultValue={verify.ntime || (appType === 'mob' ? 3 : 10)} 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={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> F </span>
                    <Button onClick={() => {this.showError('F')}} type="primary" size="small">
                      查看
@@ -1738,14 +2831,14 @@
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={'停留时间'}>
                  <Form.Item label="停留时间">
                    <InputNumber defaultValue={verify.ftime || (appType === 'mob' ? 3 : 10)} 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={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> E </span>
                    <Button onClick={() => {this.showError('E')}} type="primary" size="small">
                      查看
@@ -1755,7 +2848,7 @@
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> NM </span>
                    <Button onClick={() => {this.showError('NM')}} type="primary" size="small">
                      查看
@@ -1765,9 +2858,9 @@
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                    <span className="errorval"> -1 </span>
                    不提示
                  <Form.Item label="提示编码">
                    <span className="errorval"> -2 </span>
                    执行失败无提示
                  </Form.Item>
                </Col>
              </Row>