king
2024-05-16 b69b5f6329ca5f87932436b7a6c1ddfc3377e10f
src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -3,7 +3,7 @@
import moment from 'moment'
import qs from 'qs'
import { is, fromJS } from 'immutable'
import { Button, Modal, notification, message, Drawer, Switch, Checkbox, Progress } from 'antd'
import { Button, Modal, notification, message, Popover, Drawer, Switch, Checkbox, Progress } from 'antd'
import md5 from 'md5'
import Api from '@/api'
@@ -28,6 +28,7 @@
    columns: PropTypes.any,           // 字段列
    setting: PropTypes.any,           // 页面通用设置
    disabled: PropTypes.any,          // 行按钮禁用
    name: PropTypes.any
  }
  state = {
@@ -47,6 +48,7 @@
  }
  moduleParams = null
  preCallback = null
  UNSAFE_componentWillMount () {
    const { btn, selectedData, BData, disabled } = this.props
@@ -180,33 +182,17 @@
  }
  actionSubmit = (res) => {
    const { btn, setting, BID } = this.props
    const { btn } = this.props
    const { selines } = this.state
    if (btn.uuid !== res.menuId) return
    let data = selines || []
    if (setting.supModule && !BID) {
      notification.warning({
        top: 92,
        message: '需要上级主键值!',
        duration: 3
      })
      return
    } else if (btn.Ot !== 'notRequired' && data.length === 0) {
      notification.warning({
        top: 92,
        message: '请选择行!',
        duration: 5
      })
      return
    } else if (btn.Ot === 'requiredSgl' && data.length !== 1) {
      notification.warning({
        top: 92,
        message: '请选择单行数据!',
        duration: 5
      })
    let valid = this.checkBtnData(data)
    if (!valid) {
      this.preCallback && this.preCallback()
      return
    }
@@ -214,122 +200,36 @@
    this.execSubmit(data, () => {}, res.form)
  }
  /**
   * @description 按钮状态改变
   */
  updateStatus = () => {
    this.setState({
      loading: false,
      visible: false,
      confirmLoading: false
    })
  }
  
  /**
   * @description 触发按钮操作
   */
  actionTrigger = (triggerId, record, type) => {
    const { BID, btn, selectedData, setting } = this.props
  actionTrigger = (triggerId, record, type, lid, callback) => {
    const { btn, selectedData, LID } = this.props
    const { loading, disabled } = this.state
    if (type === 'preButton') {
      if (btn.uuid !== triggerId) return
      this.preTrigger(callback)
      return
    } else {
      this.preCallback = null
    }
    if (loading || disabled) return
    if (triggerId && btn.uuid !== triggerId) return
    if (setting.supModule && !BID) {
      notification.warning({
        top: 92,
        message: '需要上级主键值!',
        duration: 5
      })
      return
    } else if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(selectedData || []), fromJS(record))) {
      return
    }
    if (type === 'linkbtn' && !btn.$toolbtn && LID !== lid) return
    if (btn.OpenType === 'form' && btn.formType === 'count_line') return
    this.setState({autoMatic: type === 'autoMatic'})
    let _this = this
    let data = record || selectedData || []
    if (btn.Ot !== 'notRequired' && data.length === 0) {
      // 需要选择行时,校验数据
      notification.warning({
        top: 92,
        message: '请选择行!',
        duration: 5
      })
      return
    } else if (btn.Ot === 'requiredSgl' && data.length !== 1) {
      // 需要选择单行时,校验数据
      notification.warning({
        top: 92,
        message: '请选择单行数据!',
        duration: 5
      })
      return
    } else if (btn.intertype === 'system') {
      // 使用内部接口时,操作类型和数据源不可为空
      if (!btn.sql || !btn.sqlType) {
        notification.warning({
          top: 92,
          message: '按钮操作类型错误!',
          duration: 5
        })
        return
      } else if (data.length === 0 && btn.verify && btn.verify.voucher && btn.verify.voucher.enabled) {
        notification.warning({
          top: 92,
          message: '使用创建凭证函数,需要选择行!',
          duration: 5
        })
        return
      }
    } else if (btn.intertype === 'inner') {
      // 使用内部接口时,内部函数不可为空
      if (!btn.innerFunc) {
        notification.warning({
          top: 92,
          message: '按钮内部函数不可为空!',
          duration: 5
        })
        return
      }
    } else if (btn.intertype === 'custom' || btn.intertype === 'outer') {
      if (btn.callbackType === 'script' && (!btn.verify || !btn.verify.cbScripts || !btn.verify.cbScripts.filter(item => item.status !== 'false').length === 0)) {
        notification.warning({
          top: 92,
          message: '使用自定义脚本回调时,回调脚本不可为空!',
          duration: 5
        })
        return
      } else if (btn.procMode === 'system' && data.length === 0 && btn.verify && btn.verify.voucher && btn.verify.voucher.enabled) {
        notification.warning({
          top: 92,
          message: '使用创建凭证函数,需要选择行!',
          duration: 5
        })
        return
      } else if (btn.intertype === 'custom' && window.GLOB.systemType === 'production' && !btn.proInterface) {
        notification.warning({
          top: 92,
          message: '尚未设置正式系统接口地址!',
          duration: 5
        })
        return
      }
    } else if (!['inner', 'outer', 'system', 'custom'].includes(btn.intertype)) {
      if (btn.OpenType === 'form' && btn.formType === 'count_line') {
        return
      }
      // 接口类型错误
      notification.warning({
        top: 92,
        message: '按钮接口类型错误!',
        duration: 5
      })
      return
    }
    let valid = this.checkBtnData(data)
    if (!valid) return
    this.setState({
      selines: data
@@ -339,7 +239,6 @@
      this.setState({}, () => {
        MKEmitter.emit('mkFormSubmit', btn.uuid)
      })
      return
    } else if (btn.OpenType === 'prompt') {
      this.setState({loading: true})
      confirm({
@@ -410,10 +309,158 @@
      let _change = {
        prompt: '提示框',
        exec: '直接执行',
        pop: '弹窗(表单)'
        pop: '弹窗(表单)',
        formSubmit: '表单',
        form: '表单',
      }
      MKEmitter.emit('queryTrigger', {menuId: btn.uuid, name: _change[btn.OpenType]})
    }
  }
  preTrigger = (callback) => {
    const { btn, selectedData } = this.props
    const { loading, disabled } = this.state
    if (loading || disabled) {
      callback()
      return
    } else if (btn.OpenType === 'form') {
      callback()
      return
    }
    let _this = this
    let data = selectedData || []
    let valid = this.checkBtnData(data)
    if (!valid) {
      callback()
      return
    }
    this.preCallback = callback
    this.setState({
      selines: data
    })
    if (btn.OpenType === 'formSubmit') {
      this.setState({}, () => {
        MKEmitter.emit('mkFormSubmit', btn.uuid, callback)
      })
    } else if (btn.OpenType === 'prompt') {
      this.setState({loading: true})
      confirm({
        title: btn.tipTitle || '确定要执行吗?',
        onOk() {
          return new Promise(resolve => {
            _this.execSubmit(data, resolve)
          })
        },
        onCancel() {
          callback()
          _this.setState({loading: false})
        }
      })
    } else if (btn.OpenType === 'exec') {
      this.setState({loading: true})
      this.execSubmit(data, () => { this.setState({loading: false})})
    } else if (btn.OpenType === 'pop') {
      let modal = this.state.btnconfig
      if (!modal && btn.modal) {
        modal = this.handleModelConfig(btn.modal)
      }
      this.setState({
        loading: true,
        btnconfig: modal
      })
      if (modal) {
        if (modal.setting.display === 'prompt' || modal.setting.display === 'exec') {
          this.modelconfirm()
        } else {
          this.setState({
            visible: true
          })
        }
      }
    }
  }
  /**
   * @description 按钮状态改变
   */
  updateStatus = () => {
    this.setState({
      loading: false,
      visible: false,
      confirmLoading: false
    })
  }
  checkBtnData = (data) => {
    const { BID, btn, setting } = this.props
    if (setting.supModule && !BID) {
      notification.warning({
        top: 92,
        message: '需要上级主键值!',
        duration: 5
      })
      return false
    } else if (btn.Ot !== 'notRequired' && data.length === 0) {
      // 需要选择行时,校验数据
      notification.warning({
        top: 92,
        message: '请选择行!',
        duration: 5
      })
      return false
    } else if (btn.Ot === 'requiredSgl' && data.length !== 1) {
      // 需要选择单行时,校验数据
      notification.warning({
        top: 92,
        message: '请选择单行数据!',
        duration: 5
      })
      return false
    } else if (btn.intertype === 'system') {
      if (data.length === 0 && btn.verify && btn.verify.voucher && btn.verify.voucher.enabled) {
        notification.warning({
          top: 92,
          message: '使用创建凭证函数,需要选择行!',
          duration: 5
        })
        return false
      }
    } else if (btn.intertype === 'custom' || btn.intertype === 'outer') {
      if (btn.callbackType === 'script' && (!btn.verify || !btn.verify.cbScripts || !btn.verify.cbScripts.filter(item => item.status !== 'false').length === 0)) {
        notification.warning({
          top: 92,
          message: '使用自定义脚本回调时,回调脚本不可为空!',
          duration: 5
        })
        return false
      } else if (btn.procMode === 'system' && data.length === 0 && btn.verify && btn.verify.voucher && btn.verify.voucher.enabled) {
        notification.warning({
          top: 92,
          message: '使用创建凭证函数,需要选择行!',
          duration: 5
        })
        return false
      } else if (btn.intertype === 'custom' && window.GLOB.systemType === 'production' && !btn.proInterface) {
        notification.warning({
          top: 92,
          message: '尚未设置正式系统接口地址!',
          duration: 5
        })
        return false
      }
    }
    return true
  }
  getSystemParam = (data, formdata, retmsg) => {
@@ -441,17 +488,17 @@
        param.ID = primaryId
        if (retmsg) {
          const { sql, callbacksql } = getSysDefaultSql(btn, setting, '', param, data[0], columns, retmsg, this.moduleParams, Utils.getAllSearchOptions) // 数据源
          const { sql, callbacksql } = getSysDefaultSql(btn, setting, '', param, data[0], columns, retmsg, this.moduleParams) // 数据源
          param.LText = sql
          param.$callbacksql = callbacksql
        } else {
          param.LText = getSysDefaultSql(btn, setting, '', param, data[0], columns, false, this.moduleParams, Utils.getAllSearchOptions) // 数据源
          param.LText = getSysDefaultSql(btn, setting, '', param, data[0], columns, false, this.moduleParams) // 数据源
          if (btn.output) {
            param.key_back_type = 'Y'
          }
        }
        param.exec_type = 'y' // 后台解码
        param.exec_type = window.GLOB.execType || 'y' // 后台解码
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt('', param.timestamp)
@@ -462,7 +509,7 @@
          param.LText = param.LText.replace(/\$check@|@check\$/ig, '')
        }
        param.LText = Utils.formatOptions(param.LText)
        param.LText = Utils.formatOptions(param.LText, param.exec_type)
      } else if (btn.OpenType === 'pop' || btn.OpenType === 'formSubmit' || btn.OpenType === 'form') { // 表单
        if (btn.sqlType === 'insert') { // 系统函数添加时,生成uuid
          primaryId = ''
@@ -477,17 +524,17 @@
          param.ID = primaryId || Utils.getguid()
          if (retmsg) {
            const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, retmsg, this.moduleParams, Utils.getAllSearchOptions) // 数据源
            const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, retmsg, this.moduleParams) // 数据源
            param.LText = sql
            param.$callbacksql = callbacksql
          } else {
            param.LText = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, false, this.moduleParams, Utils.getAllSearchOptions) // 数据源
            param.LText = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, false, this.moduleParams) // 数据源
            if (btn.output) {
              param.key_back_type = 'Y'
            }
          }
          param.exec_type = 'y' // 后台解码
          param.exec_type = window.GLOB.execType || 'y' // 后台解码
          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
          param.secretkey = Utils.encrypt('', param.timestamp)
@@ -498,22 +545,22 @@
            param.LText = param.LText.replace(/\$check@|@check\$/ig, '')
          }
          param.LText = Utils.formatOptions(param.LText)
          param.LText = Utils.formatOptions(param.LText, param.exec_type)
        } else {
          param.ID = primaryId
          if (retmsg) {
            const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, retmsg, this.moduleParams, Utils.getAllSearchOptions) // 数据源
            const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, retmsg, this.moduleParams) // 数据源
            param.LText = sql
            param.$callbacksql = callbacksql
          } else {
            param.LText = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, false, this.moduleParams, Utils.getAllSearchOptions) // 数据源
            param.LText = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, false, this.moduleParams) // 数据源
            if (btn.output) {
              param.key_back_type = 'Y'
            }
          }
          param.exec_type = 'y' // 后台解码
          param.exec_type = window.GLOB.execType || 'y' // 后台解码
          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
          param.secretkey = Utils.encrypt('', param.timestamp)
@@ -524,7 +571,7 @@
            param.LText = param.LText.replace(/\$check@|@check\$/ig, '')
          }
          param.LText = Utils.formatOptions(param.LText)
          param.LText = Utils.formatOptions(param.LText, param.exec_type)
        }
      }
@@ -544,7 +591,7 @@
      if (param.$unCheckParam) {
        param.$unCheckParam.LText = param.$unCheckParam.LText.replace(/\$check@/ig, '/*').replace(/@check\$/ig, '*/')
        param.$unCheckParam.LText = Utils.formatOptions(param.$unCheckParam.LText)
        param.$unCheckParam.LText = Utils.formatOptions(param.$unCheckParam.LText, param.exec_type)
        param.$unCheckParam.menuname = btn.logLabel
        if (window.GLOB.probation) {
@@ -569,17 +616,17 @@
          param.ID = primaryId
          if (retmsg) {
            const { sql, callbacksql } = getSysDefaultSql(btn, setting, '', param, cell, columns, retmsg, this.moduleParams, Utils.getAllSearchOptions) // 数据源
            const { sql, callbacksql } = getSysDefaultSql(btn, setting, '', param, cell, columns, retmsg, this.moduleParams) // 数据源
            param.LText = sql
            param.$callbacksql = callbacksql
          } else {
            param.LText = getSysDefaultSql(btn, setting, '', param, cell, columns, false, this.moduleParams, Utils.getAllSearchOptions) // 数据源
            param.LText = getSysDefaultSql(btn, setting, '', param, cell, columns, false, this.moduleParams) // 数据源
            if (btn.output) {
              param.key_back_type = 'Y'
            }
          }
          param.exec_type = 'y' // 后台解码
          param.exec_type = window.GLOB.execType || 'y' // 后台解码
          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
          param.secretkey = Utils.encrypt('', param.timestamp)
@@ -590,7 +637,7 @@
            param.LText = param.LText.replace(/\$check@|@check\$/ig, '')
          }
          param.LText = Utils.formatOptions(param.LText)
          param.LText = Utils.formatOptions(param.LText, param.exec_type)
        } else if (btn.OpenType === 'pop') { // 表单
          if (index !== 0) {
            let _cell = {}
@@ -609,17 +656,17 @@
            param.ID = Utils.getguid()
            if (retmsg) {
              const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, cell, columns, retmsg, this.moduleParams, Utils.getAllSearchOptions) // 数据源
              const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, cell, columns, retmsg, this.moduleParams) // 数据源
              param.LText = sql
              param.$callbacksql = callbacksql
            } else {
              param.LText = getSysDefaultSql(btn, setting, formdata, param, cell, columns, false, this.moduleParams, Utils.getAllSearchOptions) // 数据源
              param.LText = getSysDefaultSql(btn, setting, formdata, param, cell, columns, false, this.moduleParams) // 数据源
              if (btn.output) {
                param.key_back_type = 'Y'
              }
            }
            param.exec_type = 'y' // 后台解码
            param.exec_type = window.GLOB.execType || 'y' // 后台解码
            param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
            param.secretkey = Utils.encrypt('', param.timestamp)
@@ -630,22 +677,22 @@
              param.LText = param.LText.replace(/\$check@|@check\$/ig, '')
            }
            param.LText = Utils.formatOptions(param.LText)
            param.LText = Utils.formatOptions(param.LText, param.exec_type)
          } else {
            param.ID = primaryId
            if (retmsg) {
              const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, cell, columns, retmsg, this.moduleParams, Utils.getAllSearchOptions) // 数据源
              const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, cell, columns, retmsg, this.moduleParams) // 数据源
              param.LText = sql
              param.$callbacksql = callbacksql
            } else {
              param.LText = getSysDefaultSql(btn, setting, formdata, param, cell, columns, false, this.moduleParams, Utils.getAllSearchOptions) // 数据源
              param.LText = getSysDefaultSql(btn, setting, formdata, param, cell, columns, false, this.moduleParams) // 数据源
              if (btn.output) {
                param.key_back_type = 'Y'
              }
            }
            param.exec_type = 'y' // 后台解码
            param.exec_type = window.GLOB.execType || 'y' // 后台解码
            param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
            param.secretkey = Utils.encrypt('', param.timestamp)
@@ -656,7 +703,7 @@
              param.LText = param.LText.replace(/\$check@|@check\$/ig, '')
            }
            param.LText = Utils.formatOptions(param.LText)
            param.LText = Utils.formatOptions(param.LText, param.exec_type)
          }
        }
@@ -675,7 +722,7 @@
        if (param.$unCheckParam) {
          param.$unCheckParam.LText = param.$unCheckParam.LText.replace(/\$check@/ig, '/*').replace(/@check\$/ig, '*/')
          param.$unCheckParam.LText = Utils.formatOptions(param.$unCheckParam.LText)
          param.$unCheckParam.LText = Utils.formatOptions(param.$unCheckParam.LText, param.exec_type)
          param.$unCheckParam.menuname = btn.logLabel
  
          if (window.GLOB.probation) {
@@ -708,6 +755,9 @@
      if (btn.recordUser === 'true') {
        param.username = sessionStorage.getItem('User_Name') || ''
        param.fullname = sessionStorage.getItem('Full_Name') || ''
      }
      if (btn.dataM === 'true') {
        param.dataM = sessionStorage.getItem('dataM') === 'true' ? 'Y' : ''
      }
      
      let primaryId = ''
@@ -750,6 +800,9 @@
        if (btn.recordUser === 'true') {
          param.username = sessionStorage.getItem('User_Name') || ''
          param.fullname = sessionStorage.getItem('Full_Name') || ''
        }
        if (btn.dataM === 'true') {
          param.dataM = sessionStorage.getItem('dataM') === 'true' ? 'Y' : ''
        }
        let primaryId = setting.primaryKey ? cell[setting.primaryKey] || '' : ''
@@ -971,21 +1024,92 @@
  /**
   * @description 按钮提交执行
   */
  execSubmit = (data, _resolve, formdata) => {
  execSubmit = (data, _resolve, formdata, force) => {
    const { setting, btn } = this.props
    this.moduleParams = null
    if (
      (btn.intertype === 'system' || (btn.intertype === 'custom' && btn.procMode === 'system')) &&
      btn.sqlType !== 'insert' && btn.Ot !== 'notRequired' && btn.verify && btn.verify.invalid === 'true' &&
      setting.dataresource
    ) {
    if (btn.preButton && !force) {
      this.trigger(btn.preButton, data, _resolve, formdata, 0)
    } else if (btn.verify && btn.verify.invalid === 'true' && setting.dataresource) {
      MKEmitter.emit('queryModuleParam', btn.$menuId, (param) => {
        this.moduleParams = param
        let datasource = setting.dataresource
        let customScript = setting.customScript || ''
        let allSearch = Utils.getAllSearchOptions(param.search)
        let regoptions = allSearch.map(item => {
          return {
            reg: new RegExp('@' + item.key + '@', 'ig'),
            value: `'${item.value}'`
          }
        })
        regoptions.push({
          reg: new RegExp('@userName@', 'ig'),
          value: `'${sessionStorage.getItem('User_Name') || ''}'`
        }, {
          reg: new RegExp('@fullName@', 'ig'),
          value: `'${sessionStorage.getItem('Full_Name') || ''}'`
        }, {
          reg: new RegExp('@orderBy@', 'ig'),
          value: setting.order
        }, {
          reg: new RegExp('@pageSize@', 'ig'),
          value: 10
        }, {
          reg: new RegExp('@pageIndex@', 'ig'),
          value: 1
        })
        regoptions.forEach(item => {
          datasource = datasource.replace(item.reg, item.value)
          customScript = customScript.replace(item.reg, item.value)
        })
        this.moduleParams = {
          datasource,
          customScript
        }
        this.execRealSubmit(data, _resolve, formdata)
      })
    } else {
      this.execRealSubmit(data, _resolve, formdata)
    }
  }
  trigger = (btnId, data, resolve, formdata, times) => {
    if (times > 50) {
      notification.warning({
        top: 92,
        message: '前置按钮加载失败!',
        duration: 5
      })
      this.setState({loading: false})
      resolve()
      return
    }
    times++
    let node = document.getElementById('button' + btnId)
    if (node) {
      MKEmitter.emit('triggerBtnId', btnId, null, 'preButton', null, (res) => {
        if (!res) {
          this.setState({loading: false})
          resolve()
          return
        }
        if (res.status) {
          this.execSubmit(data, resolve, formdata, true)
        } else {
          this.execError(res)
        }
      })
    } else {
      setTimeout(() => {
        this.trigger(btnId, data, resolve, formdata, times)
      }, 100)
    }
  }
@@ -1007,6 +1131,12 @@
      if (btn.intertype === 'system') {
        params = this.getSystemParam(data, formdata)
        if (btn.returnValue === 'true') {
          params = params.map(item => {
            item.script_type = 'Y'
            return item
          })
        }
      } else {
        params = this.getInnerParam(data, formdata)
      }
@@ -1178,7 +1308,7 @@
      return
    }
    Api.genericInterface(param).then(res => {
    Api.genericInterface(param, btn.$innerScript, 'inner').then(res => {
      record.mk_api_key = res.mk_api_key || ''
      if (res.status) {
@@ -1418,7 +1548,7 @@
      param.menuname = param.menuname + '(回调)'
    }
    Api.genericInterface(param).then(res => {
    Api.genericInterface(param, btn.$callbackScript, 'callback').then(res => {
      if (res.status) {
        this.triggerNote(res, param.ID) // 消息
@@ -1508,11 +1638,12 @@
      })
      keys = keys.join(',')
      vals = vals.join(',')
      lines.push({
        table: md5(tb + keys),
        insert: `Insert into ${tbName} (${keys},[mk_level],[mk_id],[mk_bid])`,
        select: `Select ${vals.join(',')},'${level}','${id}','${bid}'`
        insert: `Insert into ${tbName} (${keys ? keys + ',' : ''}[mk_level],[mk_id],[mk_bid])`,
        select: `Select ${keys ? vals + ',' : ''}'${level}','${id}','${bid}'`
      })
      subObjs.forEach(item => {
@@ -1598,20 +1729,21 @@
      sql = sql.replace(/@typename@/ig, `'admin'`)
      if (sessionStorage.getItem('dataM') === 'true') { // 数据权限
        sql = sql.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'')
        sql = sql.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, `'Y'`)
      } else {
        sql = sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
        sql = sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
      }
      if (window.GLOB.debugger === true) {
        console.info('%c' + btn.logLabel + '(回调)', 'color: blue')
        console.info(sql.replace(/\n\s{8}/ig, '\n'))
      }
      param.LText = sql
      param.exec_type = 'y' // 后台解码
      param.exec_type = window.GLOB.execType || 'y' // 后台解码
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      param.secretkey = Utils.encrypt('', param.timestamp)
      param.LText = Utils.formatOptions(param.LText)
      param.LText = Utils.formatOptions(param.LText, param.exec_type)
      param.menuname = btn.logLabel
      if (window.GLOB.probation) {
@@ -1774,7 +1906,7 @@
      return
    }
    Api.genericInterface(param).then(res => {
    Api.genericInterface(param, btn.$innerScript, 'inner').then(res => {
      if (res.status) {
        if ((res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) && params.length === 0) {
          this.execSuccess(res)
@@ -1872,7 +2004,7 @@
      }
    }
    Api.genericInterface(result).then(res => {
    Api.genericInterface(result, btn.$outerScript, 'outer').then(res => {
      if (!res) return // LoginError时中断请求
      if (ver_token && res.ErrCode === 'token_error') {
        res.ErrCode = 'E'
@@ -1935,11 +2067,14 @@
        func: btn.callbackFunc
      }
      // special 函数 s_sDataDictb_TBBack 云端验证
      if (window.GLOB.mkHS && param.func === 's_sDataDictb_TBBack' && param.LTextOut) {
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
        param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
      if (window.GLOB.mkHS) {
        if (btn.callbackFunc === 's_sVersion_Local_add' && window.GLOB.forcedUpdate) { // special 传输号添加回调处理
          param.local_userid = sessionStorage.getItem('LocalUserID') || ''
        } else if (btn.callbackFunc === 's_sDataDictb_TBBack' && param.LTextOut) { // special 函数 s_sDataDictb_TBBack 云端验证
          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
          param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
          param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
        }
      }
    } else {
      if (result.status) {
@@ -1961,7 +2096,7 @@
      param.menuname = param.menuname + '(回调)'
    }
    Api.genericInterface(param).then(res => {
    Api.genericInterface(param, btn.$callbackScript, 'callback').then(res => {
      if (res.status) {
        this.triggerNote(res, param.ID) // 消息
@@ -1985,30 +2120,76 @@
    delete result.message
    delete result.status
    result.func = btn.callbackFunc
    let ssoParam = null
    let sinParam = null
    let callParam = {...outParam, ...result}
    if (callParam.LTextOut) {
      callParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      callParam.secretkey = Utils.encrypt(callParam.LTextOut, callParam.timestamp)
      callParam.open_key = Utils.encryptOpenKey(callParam.secretkey, callParam.timestamp)
    }
    callParam.func = btn.callbackFunc
    callParam.userid = sessionStorage.getItem('LocalUserID') || ''
    callParam.LoginUID = sessionStorage.getItem('LocalLoginUID') || ''
    if (callParam.UpType === 'SSO' && window.GLOB.localSystemApi) {
    if (result.LTextOut) {
      callParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      callParam.secretkey = Utils.encrypt(callParam.LTextOut, callParam.timestamp)
      callParam.open_key = Utils.encryptOpenKey(callParam.secretkey, callParam.timestamp)
    } else {
      callParam = {...outParam}
      callParam.func = btn.callbackFunc
      callParam.MenuNO = 'sVersionDetail_LocalM'
      callParam.UpType = 'SSO'
      callParam.LTextOut = 'minke'
      callParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      callParam.secretkey = Utils.encrypt(callParam.LTextOut, callParam.timestamp)
      callParam.open_key = Utils.encryptOpenKey(callParam.secretkey, callParam.timestamp)
      callParam.userid = sessionStorage.getItem('LocalUserID') || ''
      callParam.LoginUID = sessionStorage.getItem('LocalLoginUID') || ''
      delete result.ErrCode
      delete result.ErrMesg
      sinParam = {...result}
      sinParam.func = 'sPC_TrdMenu_AddUpt_sso'
      if (window.GLOB.sysType === 'local') {
        if (!window.GLOB.systemType && window.GLOB.cloudServiceApi) {
          sinParam.rduri = window.GLOB.cloudServiceApi
        } else if (window.GLOB.localSystemApi) {
          sinParam.rduri = window.GLOB.localSystemApi
          sinParam.userid = sessionStorage.getItem('LocalUserID') || ''
          sinParam.LoginUID = sessionStorage.getItem('LocalLoginUID') || ''
        }
      }
    }
    if (result.UpType === 'SSO' && window.GLOB.localSystemApi) {
      ssoParam = fromJS(callParam).toJS()
      ssoParam.rduri = window.GLOB.localSystemApi
      delete ssoParam.UpType
    } else {
      delete callParam.UpType
    }
    if (ssoParam) {
    if (sinParam) {
      Api.genericInterface(sinParam).then(res => {
        if (!res.status) {
          this.execError(res)
          _resolve()
        } else {
          Api.genericInterface(callParam).then(re => {
            if (!re.status) {
              this.execError(re)
              _resolve()
            } else {
              if (params.length === 0) {
                this.execSuccess(res)
                _resolve()
              } else {
                this.outerLoopRequest(params, _resolve)
              }
            }
          })
        }
      })
    } else if (ssoParam) {
      Api.genericInterface(ssoParam).then(res => {
        if (!res.status) {
          this.execError(res)
@@ -2058,7 +2239,30 @@
    const { btn } = this.props
    const { autoMatic } = this.state
    if (autoMatic) {
    if (btn.resetForms) {
      let data = {}
      Object.keys(res).forEach(key => {
        data[key.toLowerCase()] = res[key]
      })
      delete data.errcode
      delete data.errmesg
      delete data.message
      delete data.status
      MKEmitter.emit('resetForms', btn.uuid, data)
      MKEmitter.emit('refreshByButtonResult', btn.$menuId, 'resetData', btn, null, null, data)
    }
    if (this.preCallback) {
      this.setState({
        loading: false,
        visible: false
      })
      this.preCallback(res)
      return
    } else if (autoMatic) {
      this.setState({
        loading: false,
        visible: false
@@ -2148,6 +2352,10 @@
      tabId = btn.refreshTab[btn.refreshTab.length - 1]
    }
    // if (btn.formCache === 'clear') { // 清除表单缓存
    //   window.GLOB.CacheMap = new Map()
    // }
    if (tabId && btn.$MenuID === tabId) { // 刷新当前菜单时,停止其他操作
      MKEmitter.emit('reloadMenuView', tabId, 'table')
      return
@@ -2169,11 +2377,24 @@
      if (btn.syncComponentId === 'multiComponent') {
        btn.syncComponentIds.forEach((id, i) => {
          setTimeout(() => {
            MKEmitter.emit('reloadData', id)
            if (/\$focus/.test(id)) {
              MKEmitter.emit('reloadData', id.split('$')[0], id.split('$')[1])
            } else {
              MKEmitter.emit('reloadData', id)
            }
          }, 20 * i)
        })
      } else if (/\$focus/.test(btn.syncComponentId)) {
        MKEmitter.emit('reloadData', btn.syncComponentId.split('$')[0], btn.syncComponentId.split('$')[1])
      } else {
        MKEmitter.emit('reloadData', btn.syncComponentId)
        if (btn.syncDelay) {
          this.delayTimer && clearTimeout(this.delayTimer)
          this.delayTimer = setTimeout(() => {
            MKEmitter.emit('reloadData', btn.syncComponentId)
          }, btn.syncDelay)
        } else {
          MKEmitter.emit('reloadData', btn.syncComponentId)
        }
      }
    }
@@ -2215,13 +2436,31 @@
    if (btn.execSuccess === 'popclose' && btn.$tabId) { // 标签关闭刷新
      MKEmitter.emit('refreshPopButton', btn.$tabId)
    }
    if (btn.verify && btn.verify.linkEnable === 'true') {
      let url = ''
      if (window.GLOB.systemType === 'production') {
        url = btn.verify.linkProUrl
        if (!url) {
          notification.warning({
            top: 92,
            message: '尚未添加正式系统链接地址!',
            duration: 5
          })
          return
        }
      } else {
        url = btn.verify.linkUrl
      }
      window.open(url)
    }
  }
  triggerNote = (res, ID) => {
    const { btn } = this.props
    if (!btn.verify) return
    if (btn.verify.noteEnable !== 'true' && btn.verify.wxNote !== 'true' && btn.verify.printEnable !== 'true') return
    if (btn.verify.noteEnable !== 'true' && btn.verify.wxNote !== 'true' && btn.verify.printEnable !== 'true' && btn.verify.emailEnable !== 'true') return
    let id = ''
    if (btn.output) {
@@ -2236,6 +2475,9 @@
    if (btn.verify.noteEnable === 'true') {
      this.sendMessage(btn.verify, id)
    }
    if (btn.verify.emailEnable === 'true') {
      this.sendEmail(btn.verify, id)
    }
    if (btn.verify.wxNote === 'true') {
      if (btn.verify.wxTemplateId === 'mk_category_temp') {
@@ -2258,9 +2500,38 @@
    if (!id) return
    setTimeout(() => {
      window.open('#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify({ id: id, tempId: btn.verify.printTempId, pageId: btn.$MenuID || '', dataM: sessionStorage.getItem('dataM') }))))
    }, 500)
    if (btn.verify.preHandle === 'true' && btn.verify.pre_func && /#position-print/.test(btn.verify.pre_func)) {
      MKEmitter.emit('queryModuleParam', btn.$menuId, (res) => {
        let searches = {}
        res.search && res.search.forEach(item => {
          searches[item.key] = item.value
        })
        let _param = { id: id || '', tempId: btn.verify.printTempId, pageId: btn.$MenuID || '', dataM: sessionStorage.getItem('dataM')}
        try {
          // eslint-disable-next-line
          let func = new Function('btn', 'searches', 'param', 'systemType', btn.verify.pre_func)
          _param = func(btn, searches, _param, window.GLOB.systemType)
        } catch (e) {
          console.warn(e)
        }
        if (!_param || _param.error) {
          notification.warning({
            top: 92,
            message: _param ? _param.error : '未获取到打印参数,自定义脚本错误!',
            duration: 5
          })
          return
        }
        window.open('#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify(_param))))
      })
    } else {
      setTimeout(() => {
        window.open('#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify({ id: id, tempId: btn.verify.printTempId, pageId: btn.$MenuID || '', dataM: sessionStorage.getItem('dataM') }))))
      }, 200)
    }
  }
  sendWxMessage = (verify, id) => {
@@ -2278,7 +2549,7 @@
      upid: id
    }
    param.LText = Utils.formatOptions(Utils.getuuid())
    param.LText = Utils.getuuid()
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
@@ -2372,7 +2643,7 @@
                msg_result: msg
              }
              _p.LText = Utils.formatOptions(Utils.getuuid())
              _p.LText = Utils.getuuid()
              _p.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
              _p.secretkey = Utils.encrypt(_p.LText, _p.timestamp)
@@ -2415,12 +2686,12 @@
  sendMessage = (verify, id) => {
    let param = {
      func: 's_get_sms_local',
      TypeCharOne: verify.noteTemp, // N不同内容,Y相同内容
      TypeCharTwo: verify.noteType, // N定时,Y实时
      TypeCharOne: verify.noteTemp || 'Y', // N不同内容,Y相同内容
      TypeCharTwo: verify.noteType || 'N', // N定时,Y实时
      upid: id
    }
    param.LText = Utils.formatOptions(Utils.getuuid())
    param.LText = Utils.getuuid()
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
@@ -2435,9 +2706,9 @@
      }
      let _param = {
        templatecode: verify.noteCode, // 模板编码
        TypeCharOne: verify.noteTemp,  // N不同内容,Y相同内容
        ID: verify.noteId || ''        // 模板Id,暂时未使用
        templatecode: verify.noteCode,        // 模板编码
        TypeCharOne: verify.noteTemp || 'Y',  // N不同内容,Y相同内容
        ID: verify.noteId || ''               // 模板Id,暂时未使用
      }
      _param.submitdate = res.submitdate
@@ -2445,17 +2716,17 @@
      let limit = 5 // 实时最大为5条,定时最大为100条
      let mobMap = new Map()
      if (verify.noteType === 'N') {
      if (verify.noteType === 'Y') {
        _param.func = 's_get_sms_sso_realtime'
      } else {
        _param.func = 's_get_sms_sso_timer'
        limit = 100
      } else if (verify.noteType === 'Y') {
        _param.func = 's_get_sms_sso_realtime'
      }
      let Ltext = []
      let error = false
      if (verify.noteTemp === 'Y') {
      if (verify.noteTemp !== 'N') {
        _param.p1 = res.p1 || ''
        _param.p2 = res.p2 || ''
        _param.p3 = res.p3 || ''
@@ -2464,25 +2735,156 @@
        let _p = _param.p1 + _param.p2 + _param.p3 + _param.p4 + _param.p5
        if (/\/|\.|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信|Q/.test(_p)) {
        if (/\/|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信/.test(_p)) {
          error = true
        }
      }
      res.send_data && res.send_data.forEach(item => {
        if (item.mob && !mobMap.has(item.mob) && Ltext.length < limit) {
          if (verify.noteTemp === 'Y') {
          if (verify.noteTemp !== 'N') {
            Ltext.push(`'${item.mob}'`)
          } else {
            let _p = `'${item.p1 || ''}','${item.p2 || ''}','${item.p3 || ''}','${item.p4 || ''}','${item.p5 || ''}','${item.mob}'`
            if (/\/|\.|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信|Q/.test(_p)) {
            if (/\/|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信/.test(_p)) {
              error = true
            }
            Ltext.push(_p)
          }
          mobMap.set(item.mob, true)
        }
      })
      if (error) {
        notification.warning({
          top: 92,
          message: '消息中含有非法字符',
          duration: 5
        })
        return
      }
      if (Ltext.length === 0) return
      Ltext = Ltext.join(';')
      _param.LText = window.btoa(window.encodeURIComponent(Ltext))
      _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
      _param.rduri = 'https://sso.mk9h.cn/webapi/dostars'
      _param.userid = 'bh0bapabtd45epsgra79segbch6c1ibk'
      _param.LoginUID = 'bh0bapabtd45epsgra79segbch6c1ibk'
      Api.genericInterface(_param).then(result => {
        if (!result.status) {
          notification.warning({
            top: 92,
            message: result.message,
            duration: 5
          })
        }
      }, (error) => {
        if (error && error.ErrCode === 'LoginError') {
          let param = {
            func: 's_visitor_login',
            timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
            SessionUid: 'bh0bapabtd45epsgra79segbch6c1ibk',
            TypeCharOne: 'pc',
            appkey: '202004041613277377A6A2456D34A4948AE84'
          }
          param.LText = md5(window.btoa('bh0bapabtd45epsgra79segbch6c1ibk' + param.timestamp))
          param.secretkey = md5(param.LText + 'mingke' + param.timestamp)
          let params = {
            url: 'https://sso.mk9h.cn/webapi/dologon',
            method: 'post',
            data: JSON.stringify(param)
          }
          Api.directRequest(params)
          return
        }
      })
    })
  }
  sendEmail = (verify, id) => {
    let param = {
      func: 's_get_email_local',
      TypeCharOne: verify.emailTemp || 'Y', // N不同内容,Y相同内容
      TypeCharTwo: verify.emailType || 'N', // N定时,Y实时
      upid: id
    }
    param.LText = Utils.getuuid()
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    Api.genericInterface(param).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
      let _param = {
        msn_email_temp_no: verify.emailCode,   // 模板编码
        TypeCharOne: verify.emailTemp || 'Y',  // N不同内容,Y相同内容
        ID: verify.emailId || ''               // 模板Id,暂时未使用
      }
      _param.submitdate = res.submitdate
      let limit = 5 // 实时最大为5条,定时最大为100条
      let mobMap = new Map()
      if (verify.emailType === 'Y') {
        _param.func = 's_get_email_sso_realtime'
      } else {
        _param.func = 's_get_email_sso_timer'
        limit = 100
      }
      let Ltext = []
      let error = false
      if (verify.emailTemp !== 'N') {
        _param.p1 = res.p1 || ''
        _param.p2 = res.p2 || ''
        _param.p3 = res.p3 || ''
        _param.p4 = res.p4 || ''
        _param.p5 = res.p5 || ''
        let _p = _param.p1 + _param.p2 + _param.p3 + _param.p4 + _param.p5
        if (/\/|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信/.test(_p)) {
          error = true
        }
      }
      res.send_data && res.send_data.forEach(item => {
        if (item.email && !mobMap.has(item.email) && Ltext.length < limit) {
          if (verify.emailTemp !== 'N') {
            Ltext.push(`'${item.email}'`)
          } else {
            let _p = `'${item.p1 || ''}','${item.p2 || ''}','${item.p3 || ''}','${item.p4 || ''}','${item.p5 || ''}','${item.email}'`
            if (/\/|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信/.test(_p)) {
              error = true
            }
            Ltext.push(_p)
          }
          mobMap.set(item.email, true)
        }
      })
@@ -2553,7 +2955,14 @@
    const { btn } = this.props
    const { autoMatic } = this.state
    if (autoMatic) {
    if (this.preCallback) {
      this.setState({
        loading: false,
        visible: false
      })
      this.preCallback(res)
      return
    } else if (autoMatic) {
      notification.error({
        top: 92,
        message: res.message || '执行失败!',
@@ -2623,6 +3032,13 @@
      })
    } else if (res.ErrCode === 'NM') {
      message.error(res.message || '执行失败!')
    } else if (res.ErrCode === '-2') {
      this.setState({
        loadingNumber: '',
        loadingTotal: '',
        loading: false
      })
      return
    }
    this.errorContinue(sign)
@@ -2803,10 +3219,12 @@
      visible: false,
      confirmLoading: false
    })
    this.preCallback && this.preCallback()
  }
  modelconfirm = () => {
    const { btn, BID } = this.props
    const { BID } = this.props
    const { btnconfig, selines } = this.state
    let _this = this
@@ -2881,7 +3299,33 @@
        _item.value = _item.value.replace(/\t+|\v+/g, '')       // 去除制表符
        if (item.interception !== 'false') {                    // 去除首尾空格
          _item.value = _item.value.replace(/(^\s*|\s*$)/g, '')
          if (item.interception === 'func') {
            try {
              // eslint-disable-next-line
              let func = new Function('value', 'data', item.func)
              _item.value = func(_item.value, _data)
              _item.value = _item.value !== undefined ? _item.value : ''
            } catch (e) {
              console.warn(e)
              _item.value = ''
            }
          } else if (item.interception === 'charTure') {
            let str = _item.value.replace(/(^\s*|\s*$)/g, '')
            let result = ''
            for (let i = 0 ; i < str.length; i++) {
              let code = str.charCodeAt(i)
              if (code >= 65281 && code <= 65373) {
                result += String.fromCharCode(str.charCodeAt(i) - 65248)
              } else if (code === 12288) {
                result += String.fromCharCode(str.charCodeAt(i) - 12288 + 32)
              } else {
                result += str.charAt(i)
              }
            }
            _item.value = result
          } else {
            _item.value = _item.value.replace(/(^\s*|\s*$)/g, '')
          }
        }
        if (_item.type === 'text' && /@appkey@|@SessionUid@|@bid@/ig.test(_item.value)) { // 特殊字段替换
          _item.value = _item.value.replace(/^(\s*)@appkey@(\s*)$/ig, window.GLOB.appkey).replace(/^(\s*)@SessionUid@(\s*)$/ig, (localStorage.getItem('SessionUid') || '')).replace(/^(\s*)@bid@(\s*)$/ig, (BID || ''))
@@ -2925,13 +3369,14 @@
      this.execSubmit(selines, () => {}, result)
    } else {
      confirm({
        title: btn.tipTitle || '确定要执行吗?',
        title: btnconfig.setting.tipTitle || '确定要执行吗?',
        onOk() {
          return new Promise(resolve => {
            _this.execSubmit(selines, resolve, result)
          })
        },
        onCancel() {
          _this.preCallback && _this.preCallback()
          _this.setState({ loading: false })
        }
      })
@@ -2993,6 +3438,13 @@
      if (btnconfig.setting.container === 'tab' && btn.ContainerId) {
        width = btnconfig.setting.width > 100 ? btnconfig.setting.width : btnconfig.setting.width + '%'
        container = () => document.getElementById(btn.ContainerId)
      }
      if (btnconfig.setting.icon) {
        title = <>
          <span className={'mk-modal-icon-' + btnconfig.setting.iconType} style={{background: btnconfig.setting.iconColor || 'unset', color: btnconfig.setting.iconColor || 'inherit'}}><MkIcon type={btnconfig.setting.icon}/></span>
          {title}
        </>
      }
      return (
@@ -3097,7 +3549,7 @@
  }
  render() {
    const { btn } = this.props
    const { btn, name } = this.props
    const { loadingNumber, loadingTotal, loading, disabled, hidden, check, count } = this.state
    if (hidden) return null
@@ -3116,45 +3568,36 @@
    }
    let label = ''
    let icon = ''
    let type = 'link'
    let className = ''
    if (btn.show === 'button') {
      label = btn.label
      icon = btn.icon || ''
    } else if (btn.show === 'link') {
      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
      icon = ''
    if (btn.show === 'link') {
      label = <span>{name || btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon} /> : ''}</span>
    } else if (btn.show === 'icon') {
      icon = btn.icon || ''
    } else if (!btn.$toolbtn) {
      icon = btn.icon || ''
      label = btn.label
      className = 'mk-btn mk-' + (btn.class || 'unset')
      label = !loading ? <MkIcon type={btn.icon} /> : null
    } else if (btn.$toolbtn) {
      label = <span>{!loading && btn.icon ? <MkIcon style={{marginRight: '8px'}} type={btn.icon} /> : ''}{loadingNumber && !loadingTotal ? `(${loadingNumber})` : ''}{btn.label}</span>
    } else {
      type = ''
      icon = btn.icon || ''
      label = btn.label
      className = 'mk-btn mk-' + (btn.class || 'unset')
      label = <span>{!loading && btn.icon ? <MkIcon style={{marginRight: '8px'}} type={btn.icon} /> : ''}{name || btn.label}</span>
    }
    if (loadingNumber && btn.progress !== 'progressbar' && btn.$toolbtn && (!btn.show || btn.show === 'button')) {
      label = (loadingNumber ? `(${loadingNumber})` : '') + btn.label
    let BTN = <Button
      type="link"
      id={'button' + btn.uuid}
      title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
      loading={loading}
      disabled={disabled}
      style={btn.style}
      className={btn.hover || ''}
      onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
    >{label}</Button>
    if (btn.hoverTitle) {
      BTN = <Popover mouseLeaveDelay={0.3} mouseEnterDelay={0.3} content={btn.hoverTitle} trigger="hover">
        {BTN}
      </Popover>
    }
    return <>
      <Button
        type={type}
        icon={icon}
        id={'button' + btn.uuid}
        title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
        loading={loading}
        disabled={disabled}
        style={btn.style}
        className={className}
        onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
      >{label}</Button>
      {BTN}
      <span onClick={(e) => {e.stopPropagation()}}>{this.getModels()}</span>
      {loadingTotal ? <Progress className="mk-button-progress" percent={(loadingTotal - loadingNumber) / loadingTotal * 100} size="small" showInfo={false} /> : null}
    </>