king
2024-11-15 c5a07dba94694d13f0a78e051dfa26c3522933ee
src/menu/components/share/actioncomponent/formconfig.jsx
@@ -1,5 +1,5 @@
import React from 'react'
import { btnClasses } from '@/utils/option.js'
/**
 * @description 获取按钮表单配置信息
@@ -7,9 +7,8 @@
 * @param {*} functip        生成存储过程提示
 * @param {*} setting        组件配置
 * @param {*} usefulFields   存储过程可用的开始字段
 * @param {*} type           按钮类型,用于区分可选的打开方式
 */
export function getActionForm (card, functip, config, usefulFields, modules = [], anchors = [], side) {
export function getActionForm (card, functip, config, usefulFields, modules = [], anchors = [], side, position) {
  let appType = sessionStorage.getItem('appType')
  let viewType = sessionStorage.getItem('editMenuType') // 弹窗 popview
  let setting = config.setting || {}
@@ -17,6 +16,12 @@
  let appMenus = []
  let menulist = []
  let type = ''
  let alltype = config.type + '_' + config.subtype
  columns = columns.map(item => ({
    value: item.field,
    text: `${item.label}(${item.field})`
  }))
  if (card.eleType === 'button') {
    type = 'card'
@@ -24,6 +29,10 @@
    type = 'datacard'
  } else if (config.type === 'line' || config.type === 'bar' || config.type === 'scatter') {
    type = 'chart'
  }
  if (card.color && (type !== 'datacard' || appType !== 'mob') && !card.class) {
    card.class = 'primary'
  }
  let opentypes = [
@@ -82,7 +91,73 @@
    return _list
  }
  let tabs = getTabs(JSON.parse(JSON.stringify(window.GLOB.customMenu.components)))
  let tabs = getTabs(window.GLOB.customMenu.components)
  let linkButtons = []
  let filterComponent = (components) => {
    components.forEach(item => {
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
          filterComponent(tab.components)
        })
      } else if (item.type === 'group') {
        filterComponent(item.components)
      } else {
        item.action && item.action.forEach(cell => {
          if (cell.hidden === 'true' || cell.uuid === card.uuid) return
          if (!['exec', 'prompt', 'pop'].includes(cell.OpenType)) return
          linkButtons.push({
            value: cell.uuid,
            label: cell.label + '(' + item.name + ')'
          })
        })
        if (item.type === 'card' && item.subcards) {
          item.subcards.forEach(m => {
            if ((item.subtype === 'datacard' || item.subtype === 'dualdatacard') && m.$cardType !== 'extendCard') return
            m.elements.forEach(cell => {
              if (cell.eleType !== 'button' || cell.hidden === 'true' || cell.uuid === card.uuid) return
              if (!['exec', 'prompt', 'pop'].includes(cell.OpenType)) return
              linkButtons.push({
                value: cell.uuid,
                label: cell.label + '(' + item.name + ')'
              })
            })
          })
        } else if (item.type === 'balcony') {
          item.elements.forEach(cell => {
            if (cell.eleType !== 'button' || cell.hidden === 'true' || cell.uuid === card.uuid) return
            if (!['exec', 'prompt', 'pop'].includes(cell.OpenType)) return
            linkButtons.push({
              value: cell.uuid,
              label: cell.label + '(' + item.name + ')'
            })
          })
        } else if (item.type === 'form') {
          item.subcards.forEach(group => {
            if(group.uuid === card.uuid) return
            if (item.subcards.length > 1) {
              linkButtons.push({
                value: group.uuid,
                label: group.subButton.label + '(' + item.name + '-' + group.setting.title + ')'
              })
            } else {
              linkButtons.push({
                value: group.uuid,
                label: group.subButton.label + '(' + item.name + ')'
              })
            }
          })
        }
      }
    })
  }
  filterComponent(window.GLOB.customMenu.components)
  let pageTemps = [
    { value: 'billprint', text: '单据打印' },
@@ -95,6 +170,8 @@
    { value: 'print', text: '标签打印' },
    { value: 'refund', text: '退款' },
    { value: 'closetab', text: '标签关闭' },
    { value: 'expPdf', text: '导出PDF' },
    { value: 'shareLink', text: '分享链接' },
    { value: 'megvii', text: '旷视面板机' },
    { value: 'filezip', text: '文件压缩包' },
  ]
@@ -137,6 +214,9 @@
      { value: 'reAuth', text: '切换系统(清空缓存-小程序)' },
      { value: 'clearCache', text: '清空本地配置' },
      { value: 'copyurl', text: '复制链接地址' },
      { value: 'expPdf', text: '导出PDF' },
      { value: 'shareLink', text: '分享链接' },
      { value: 'openLocation', text: '打开地图'},
      { value: 'logout', text: '退出' },
      { value: 'goBack', text: '返回' },
    ]
@@ -148,6 +228,7 @@
    opentypes = opentypes.filter(item => item.value !== 'tab')
    funTypes = [
      { value: 'print', text: '标签打印' },
      { value: 'refund', text: '退款' },
    ]
    pageTemps = [
      { value: 'linkpage', text: '关联菜单' },
@@ -243,6 +324,41 @@
    card.formType = 'switch'
  }
  let width = card.width || (card.width === 0 ? 0 : 12)
  if (card.width && /x/.test(card.width)) {
    width = +width.replace(/x/, '.5')
  }
  let extraParam = []
  if (card.recordUser === 'true') {
    extraParam.push('recordUser')
  }
  if (card.dataM === 'true') {
    extraParam.push('dataM')
  }
  let apps = []
  let merchs = []
  if (!appType) {
    if (typeof(card.openmenu) === 'string') {
      card.openmenu = []
    }
    if (window.GLOB.WXApps) {
      window.GLOB.WXApps.forEach(item => {
        if (item.appType === 'merchant') {
          merchs.push({value: item.appId, text: item.appName})
        } else {
          apps.push({value: item.appId, text: item.appName})
        }
      })
    }
  } else {
    if (typeof(card.openmenu) !== 'string') {
      card.openmenu = ''
    }
  }
  let forms = [
    {
      type: 'select',
@@ -324,20 +440,20 @@
      required: true,
      options: []
    },
    {
      type: 'checkbox',
      key: 'payType',
      label: '支付方式',
      initVal: card.payType || [],
      required: true,
      options: [{
        value: 'wxpay',
        text: '微信'
      // }, {
      //   value: 'alipay',
      //   text: '支付宝'
      }]
    },
    // {
    //   type: 'checkbox',
    //   key: 'payType',
    //   label: '支付方式',
    //   initVal: card.payType || [],
    //   required: true,
    //   options: [{
    //     value: 'wxpay',
    //     text: '微信'
    //   // }, {
    //   //   value: 'alipay',
    //   //   text: '支付宝'
    //   }]
    // },
    {
      type: 'radio',
      key: 'procMode',
@@ -373,15 +489,6 @@
    },
    {
      type: 'text',
      key: 'innerFunc',
      label: '内部函数',
      initVal: card.innerFunc || '',
      tooltip: functip,
      fields: usefulFields,
      required: false,
    },
    {
      type: 'text',
      key: 'urlkey',
      label: '地址字段',
      initVal: card.urlkey || '',
@@ -398,10 +505,70 @@
      options: pageTemps
    },
    {
      type: 'radio',
      key: 'payMode',
      label: '参数处理',
      initVal: card.payMode || 'none',
      tooltip: '支付(或退款)单号的预处理方式。',
      required: true,
      options: [{
        value: 'system',
        text: '系统函数'
      }, {
        value: 'inner',
        text: '内部函数'
      }, {
        value: 'none',
        text: '无'
      }]
    },
    {
      type: 'select',
      key: 'wxApp',
      label: '关联应用',
      initVal: card.wxApp || '',
      tooltip: '请关联支付的公众号或小程序。',
      required: true,
      forbid: apps.length === 0,
      options: apps
    },
    {
      type: 'select',
      key: 'wxMerch',
      label: '关联商户',
      initVal: card.wxMerch || '',
      tooltip: '请关联支付的商户号。',
      required: true,
      forbid: merchs.length === 0,
      options: merchs
    },
    {
      type: 'text',
      key: 'innerFunc',
      label: '内部函数',
      initVal: card.innerFunc || '',
      tooltip: functip,
      fields: usefulFields,
      required: false,
    },
    {
      type: 'printTemps',
      key: 'printTemp',
      label: '打印模板',
      initVal: card.printTemp || '',
      help: (record) => {
        if (record.printTemp) {
          return <span onClick={() => {
            sessionStorage.setItem('mk-print-temp', record.printTemp)
            window.open('#/hs')
            setTimeout(() => {
              sessionStorage.removeItem('mk-print-temp')
            }, 50)
          }} style={{color: '#1890ff', cursor: 'pointer', fontSize: '13px'}}>#查看模板</span>
        }
        return ''
      },
      required: true
    },
    {
@@ -411,14 +578,14 @@
      initVal: card.linkmenu || (isApp ? '' : []),
      required: true,
      extendName: 'MenuNo',
      options: isApp ? appMenus : menulist
      options: isApp ? appMenus : (menulist.length ? [...menulist, {value: 'multiMenu', label: '多菜单'}] : [])
    },
    {
      type: 'text',
      key: 'prefix',
      label: '前缀',
      initVal: card.prefix || '',
      tooltip: '扫码信息将与前缀拼接后执行。注:跳转菜单需以mkbid开头。',
      tooltip: '扫码信息将与前缀拼接后执行。注:跳转菜单需以mkbid(:或,)开头,mkbid(:或,)跳转后将被去除。例如:mkbid:123456 跳转后页面BID为 123456。',
      required: false
    },
    {
@@ -426,7 +593,8 @@
      key: 'url',
      label: '页面地址',
      initVal: card.url || '',
      tooltip: appType === '' ? '地址格式为:http://******/admin/index.html#/iframe/menuId/loginuid/BID 会打开标签页。注:使用@loginuid@时自动替换为当前系统的loginuid;选择单行且拼接参数时会拼接BID。' : '',
      tooltip: '在链接中以@***@形式拼接的字段(字段来源于字段集中,此外 id、appkey、userid、LoginUID 为系统字段),跳转时将替换为对应值,例如:http://sso.mk9h.cn/doc/index.html?appkey=@appkey@&LoginUID=@LoginUID@,其中appkey与LoginUID将被替换。' + (appType === '' ? '地址格式为:******/admin/index.html#/iframe/menuId/@loginuid@ 会打开标签页。' : ''),
      toolWidth: 350,
      required: true
    },
    {
@@ -434,7 +602,8 @@
      key: 'proUrl',
      label: '正式地址',
      initVal: card.proUrl || '',
      tooltip: appType === '' ? '地址格式为:http://******/admin/index.html#/iframe/menuId/loginuid/BID 会打开标签页。注:使用@loginuid@时自动替换为当前系统的loginuid;选择单行且拼接参数时会拼接BID。' : '',
      tooltip: '在链接中以@***@形式拼接的字段(字段来源于字段集中,此外 id、appkey、userid、LoginUID 为系统字段),跳转时将替换为对应值,例如:http://sso.mk9h.cn/doc/index.html?appkey=@appkey@&LoginUID=@LoginUID@,其中appkey与LoginUID将被替换。' + (appType === '' ? '地址格式为:******/admin/index.html#/iframe/menuId/@loginuid@ 会打开标签页。' : ''),
      toolWidth: 350,
      required: false
    },
    {
@@ -603,20 +772,28 @@
      key: 'execSuccess',
      label: '成功后',
      initVal: card.execSuccess || 'grid',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新表格。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮(弹窗按钮)中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需聚焦表单请以 @focus:聚焦字段@ 格式返回。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需聚焦表单请以 @focus:聚焦字段@ 格式返回。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。',
      required: true,
      options: [{
        value: 'never',
        text: '不刷新'
      }, {
        value: 'line',
        text: '刷新行'
        text: '刷新行',
        $disabled: !['table_normaltable', 'table_editable', 'table_basetable', 'card_datacard', 'card_dualdatacard'].includes(alltype)
      }, {
        value: 'grid',
        text: '刷新当前组件'
      }, {
        value: 'line_grid',
        text: '刷新行 / 组件',
        $disabled: !['table_normaltable', 'table_editable', 'table_basetable', 'card_datacard', 'card_dualdatacard'].includes(alltype)
      }, {
        value: 'mainline',
        text: '刷新上级组件 - 行'
      }, {
        value: 'maingrid',
        text: '刷新上级组件'
      }, 
      ...closetab,
      ...refresh]
@@ -626,20 +803,28 @@
      key: 'execError',
      label: '失败后',
      initVal: card.execError || 'never',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。' : '选择刷新行时,如果选择多条数据会刷新表格,注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮(弹窗按钮)中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@open_target_menu@ 可执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@open_target_menu@ 可执行打开菜单。',
      required: true,
      options: [{
        value: 'never',
        text: '不刷新'
      }, {
        value: 'line',
        text: '刷新行'
        text: '刷新行',
        $disabled: !['table_normaltable', 'table_editable', 'table_basetable', 'card_datacard', 'card_dualdatacard'].includes(alltype)
      }, {
        value: 'grid',
        text: '刷新当前组件'
      }, {
        value: 'line_grid',
        text: '刷新行 / 组件',
        $disabled: !['table_normaltable', 'table_editable', 'table_basetable', 'card_datacard', 'card_dualdatacard'].includes(alltype)
      }, {
        value: 'mainline',
        text: '刷新上级组件 - 行'
      }, {
        value: 'maingrid',
        text: '刷新上级组件'
      },
      ...refresh]
    },
@@ -647,7 +832,7 @@
      type: 'select',
      key: 'popClose',
      label: '关闭后',
      initVal: card.popClose || 'never',
      initVal: card.popClose || 'grid',
      required: true,
      options: [{
        value: 'never',
@@ -658,6 +843,9 @@
      }, {
        value: 'mainline',
        text: '刷新上级组件 - 行'
      }, {
        value: 'maingrid',
        text: '刷新上级组件'
      }]
    },
    {
@@ -675,17 +863,88 @@
      }]
    },
    {
      type: 'select',
      key: 'nameField',
      label: '位置名字段',
      initVal: card.nameField || '',
      tooltip: '打开地图时可展示位置名与详细地址,请绑定数据源字段集,经纬度请使用latitude、longitude且经纬度不可为空。',
      required: false,
      allowClear: true,
      options: columns
    },
    {
      type: 'select',
      key: 'addressField',
      label: '地址字段',
      initVal: card.addressField || '',
      required: false,
      allowClear: true,
      options: columns
    },
    {
      type: 'radio',
      key: 'shortUrl',
      label: '短链接',
      initVal: card.shortUrl || 'false',
      options: [{
        value: 'false',
        text: '禁用'
      }, {
        value: 'true',
        text: '启用'
      }]
    },
    {
      type: 'textarea',
      key: 'shareUrl',
      label: '链接地址',
      initVal: card.shareUrl || '',
      tooltip: '链接中如果存在@BID@或@ID@将自动替换。',
      required: true
    },
    {
      type: 'textarea',
      key: 'shareProUrl',
      label: '正式链接',
      initVal: card.shareProUrl || '',
      tooltip: '链接中如果存在@BID@或@ID@将自动替换。',
      required: false
    },
    {
      type: 'text',
      key: 'shareTip',
      label: '分享提示',
      initVal: card.shareTip || '',
      tooltip: '分享时对用户的提示信息。',
      required: false
    },
    {
      type: 'number',
      key: 'width',
      min: 1,
      min: 0,
      max: 24,
      precision: 0,
      precision: 1,
      label: '宽度',
      initVal: card.width || 12,
      tooltip: '栅格布局,每行等分为24列。',
      initVal: width,
      tooltip: '栅格布局,每行等分为24列。为 0 时宽度自适应。可设置半列即.5。',
      forbid: type !== 'card',
      required: true
    },
    // {
    //   type: 'radio',
    //   key: 'exportType',
    //   label: '导出方式',
    //   initVal: card.exportType || 'download',
    //   tooltip: '',
    //   required: true,
    //   options: [{
    //     value: 'download',
    //     text: '下载本地'
    //   }, {
    //     value: 'link',
    //     text: '生成链接'
    //   }]
    // },
    {
      type: 'radio',
      key: 'show',
@@ -706,15 +965,31 @@
    },
    {
      type: 'radio',
      key: 'hover',
      label: '悬浮效果',
      initVal: card.hover || '',
      tooltip: '鼠标悬浮按钮上方时的颜色变化。',
      required: false,
      forbid: appType === 'mob',
      options: [{
        value: '',
        text: '无'
      }, {
        value: 'mk-btn-hover-bg',
        text: '背景变化'
      }, {
        value: 'mk-btn-hover-border',
        text: '边框变化'
      }]
    },
    {
      type: 'radio',
      key: 'swipe',
      label: "滑动显示",
      initVal: card.swipe === 'false' ? 'left' : (card.swipe || 'left'), // 移动端仅保留滑动显示按钮
      required: false,
      forbid: (type !== 'datacard' || appType !== 'mob'),
      options: [{
      //   value: 'false',
      //   text: '否'
      // }, {
        value: 'left',
        text: '左滑'
      }, {
@@ -769,20 +1044,6 @@
      }]
    },
    {
      type: 'radio',
      key: 'joint',
      label: '拼接参数',
      initVal: card.joint || 'true',
      required: false,
      options: [{
        value: 'true',
        text: '是'
      }, {
        value: 'false',
        text: '否'
      }]
    },
    {
      type: 'text',
      key: 'sheet',
      label: '表名',
@@ -794,9 +1055,50 @@
      key: 'syncComponent',
      label: '刷新组件',
      initVal: card.syncComponent || [],
      tooltip: '执行成功后(或弹窗标签关闭时),需要同步刷新的组件。注:选择当前组件的上级组件无效,刷新上级组件请选择成功后“刷新上级组件 - 行”。',
      tooltip: '执行成功后(执行失败且存在刷新项、弹窗标签关闭),需要同步刷新的组件。注:选择当前组件的上级组件无效,刷新上级组件请选择成功后“刷新上级组件 - 行”。',
      required: false,
      options: modules.length ? [...modules, {value: 'multiComponent', label: '多组件'}] : []
    },
    {
      type: 'cascader',
      key: 'refreshTab',
      label: '刷新菜单',
      initVal: card.refreshTab || [],
      tooltip: '执行成功后(或执行失败且存在刷新项时),需要同步刷新的菜单',
      required: false,
      forbid: isApp || viewType === 'popview',
      options: menulist
    },
    {
      type: !appType ? 'cascader' : 'select',
      key: 'openmenu',
      label: '打开菜单',
      tooltip: '执行成功后(或失败时返回@open_target_menu@)需要打开的菜单。',
      initVal: card.openmenu || (!appType ? [] : ''),
      help: appType === 'mob' || appType === 'pc' ? '可返回上一页。' : null,
      extendName: 'MenuNo',
      required: false,
      allowClear: true,
      options: appType === 'mob' || appType === 'pc' ? appMenus : menulist,
      forbid: viewType === 'popview'
    },
    {
      type: 'cascader',
      key: 'switchTab',
      label: '切换标签',
      initVal: card.switchTab || [],
      tooltip: '执行成功后,需要切换的标签页。' + (appType === 'mob' ? '注:小程序中无效' : ''),
      required: false,
      options: tabs
    },
    {
      type: 'cascader',
      key: 'anchors',
      label: '跳转锚点',
      initVal: card.anchors || [],
      tooltip: '执行成功后,需要跳转的锚点。' + (appType === 'mob' ? '注:小程序中无效' : ''),
      required: false,
      options: anchors
    },
    {
      type: 'radio',
@@ -830,45 +1132,14 @@
      forbid: appType === 'mob'
    },
    {
      type: 'cascader',
      key: 'switchTab',
      label: '切换标签',
      initVal: card.switchTab || [],
      tooltip: '执行成功后,需要切换的标签页。' + (appType === 'mob' ? '注:小程序中无效' : ''),
      required: false,
      options: tabs
    },
    {
      type: 'cascader',
      key: 'anchors',
      label: '跳转锚点',
      initVal: card.anchors || [],
      tooltip: '执行成功后,需要跳转的锚点。' + (appType === 'mob' ? '注:小程序中无效' : ''),
      required: false,
      options: anchors
    },
    {
      type: 'cascader',
      key: 'refreshTab',
      label: '刷新菜单',
      initVal: card.refreshTab || [],
      tooltip: '执行成功后(或功能按钮中标签关闭类型),需要同步刷新的菜单',
      required: false,
      forbid: isApp || viewType === 'popview',
      options: menulist
    },
    {
      type: !appType ? 'cascader' : 'select',
      key: 'openmenu',
      label: '打开菜单',
      tooltip: '执行成功后需要打开的菜单。',
      initVal: card.openmenu || (!appType ? [] : ''),
      help: appType === 'mob' || appType === 'pc' ? '可返回上一页。' : null,
      extendName: 'MenuNo',
      type: 'select',
      key: 'preButton',
      label: '前置按钮',
      tooltip: '当前按钮执行前,需要执行的按钮。',
      initVal: card.preButton || '',
      required: false,
      allowClear: true,
      options: appType === 'mob' || appType === 'pc' ? appMenus : menulist,
      forbid: viewType === 'popview'
      options: linkButtons
    },
    {
      type: 'text',
@@ -877,15 +1148,35 @@
      tooltip: '执行成功后的返回值。系统函数可指定返回的变量(以@符开头,返回id时可使用@id@);自定义函数可指定返回字段(如id)。',
      initVal: card.output || '',
      required: false,
      forbid: viewType === 'popview'
      // forbid: viewType === 'popview'
    },
    {
      type: 'text',
      key: 'tipTitle',
      label: '确认提示',
      initVal: card.tipTitle || '',
      tooltip: '注:弹窗(表单)在显示为是否框时有效。',
      tooltip: '提示框的确认提示信息。',
      required: false
    },
    {
      type: 'text',
      key: 'hoverTitle',
      label: '悬浮提示',
      initVal: card.hoverTitle || '',
      tooltip: '鼠标悬浮在按钮上方时的提示信息。',
      forbid: appType === 'mob',
      required: false
    },
    {
      type: 'select',
      key: 'showName',
      label: '显示内容',
      initVal: card.showName || '',
      tooltip: '行级按钮可通过行信息控制按钮显示内容。',
      required: false,
      allowClear: true,
      forbid: position !== 'line',
      options: columns
    },
    {
      type: 'radio',
@@ -1060,6 +1351,21 @@
      forbid: appType === 'mob'
    },
    {
      type: 'checkbox',
      key: 'extraParam',
      label: '扩展参数',
      initVal: extraParam,
      tooltip: '选择“用户信息”时,内部函数的传参会增加 username 与 fullname。选择“数据管理员”时,内部函数的传参会增加 dataM ,管理员值为“Y”,普通用户为空。',
      required: false,
      options: [{
        value: 'recordUser',
        text: '用户信息'
      }, {
        value: 'dataM',
        text: '数据管理员'
      }]
    },
    {
      type: 'radio',
      key: 'control',
      label: '按钮控制',
@@ -1087,10 +1393,7 @@
      initVal: card.controlField || '',
      required: true,
      allowClear: true,
      options: columns.map(item => ({
        value: item.field,
        text: `${item.label}(${item.field})`
      }))
      options: columns
    },
    {
      type: 'text',
@@ -1120,6 +1423,62 @@
        value: 'true',
        text: '是'
      }]
    },
    {
      type: 'radio',
      key: 'database',
      label: '数据库',
      initVal: card.database || 'local',
      options: [{
        value: 'local',
        text: '本地'
      }, {
        value: 'sso',
        text: '单点'
      }]
    },
    {
      type: 'radio',
      key: 'permission',
      label: '权限验证',
      initVal: card.permission || 'true',
      required: false,
      options: [
        {value: 'true', text: '继承组件'},
        {value: 'false', text: '禁用'},
      ],
      forbid: viewType === 'popview'
    },
    {
      type: 'radio',
      key: 'extBtn',
      label: '扩展按钮',
      initVal: card.extBtn || 'false',
      tooltip: '点击扩展按钮时,变量 mk_submit_type 将被赋值。',
      required: false,
      options: [
        {value: 'true', text: '启用'},
        {value: 'false', text: '禁用'},
      ],
      forbid: appType === 'mob'
    },
    {
      type: 'text',
      key: 'extLabel',
      label: '扩展名称',
      initVal: card.extLabel || '',
      required: true,
      readonly: false,
      forbid: appType === 'mob'
    },
    {
      type: 'text',
      key: 'extValue',
      label: '扩展值',
      initVal: card.extValue || '',
      required: true,
      readonly: false,
      forbid: appType === 'mob'
    },
    {
      type: 'splitLine',
@@ -1251,13 +1610,14 @@
      label: '组件列表',
      initVal: card.syncComponents || [],
      required: true,
      actions: [],
      actions: ['edit', 'del', 'add', 'move'],
      columns: [
        {
          title: '组件',
          dataIndex: 'syncComId',
          inputType: 'cascader',
          editable: true,
          unique: true,
          required: true,
          extends: [{key: 'label', value: 'label'}],
          width: '70%',
@@ -1265,6 +1625,90 @@
          options: modules
        }
      ]
    },
    {
      type: 'radio',
      key: 'sysId',
      label: '自定义ID',
      initVal: card.sysId || '',
      tooltip: '不选行按钮可在前端生成ID值(32位),作为后续菜单的BID,存在标记时,ID值后将拼接标记值。',
      required: false,
      options: [{
        value: '',
        text: '组件BID'
      }, {
        value: 'js',
        text: '前端生成'
      }, {
        value: 'empty',
        text: '空'
      }]
    },
    {
      type: 'text',
      key: 'sign',
      label: '标记',
      initVal: card.sign || '',
      required: false
    },
    {
      type: 'table',
      key: 'multiMenus',
      label: '菜单列表',
      initVal: card.multiMenus || [],
      required: true,
      actions: ['edit', 'del', 'add', 'move'],
      columns: [
        {
          title: '名称',
          dataIndex: 'name',
          inputType: 'text',
          editable: true,
          required: false,
          width: '30%'
        },
        {
          title: '菜单',
          dataIndex: 'menuId',
          inputType: 'cascader',
          editable: true,
          required: true,
          extends: [{key: 'label', value: 'label', mutilLabel: 'name'}],
          width: '30%',
          render: (text, record) => record.label,
          options: menulist
        },
        {
          title: '标记',
          dataIndex: 'sign',
          inputType: 'text',
          editable: true,
          required: false,
          width: '20%'
        }
      ]
    },
    {
      type: 'radio',
      key: 'preHandle',
      label: '自定义脚本',
      initVal: card.preHandle || 'false',
      // tooltip: '隐藏后按钮在页面中不显示,且不参与权限分配。',
      required: false,
      options: [{
        value: 'false',
        text: '禁用'
      }, {
        value: 'true',
        text: '启用'
      }]
    },
    {
      type: 'codemirror',
      key: 'pre_func',
      label: '自定义脚本',
      initVal: card.pre_func || '',
      required: true,
    }
  ]
@@ -1278,7 +1722,7 @@
 * @param {*} setting        组件配置
 * @param {*} usefulFields   存储过程可用的开始字段
 */
export function getBaseTableActionForm (card, functip, config, usefulFields, modules) {
export function getBaseTableActionForm (card, functip, config, usefulFields, modules, position) {
  let viewType = sessionStorage.getItem('editMenuType') // 弹窗 popview
  let setting = config.setting || {}
  let columns = config.columns || []
@@ -1332,6 +1776,8 @@
    { value: 'print', text: '标签打印' },
    { value: 'refund', text: '退款' },
    { value: 'closetab', text: '标签关闭' },
    { value: 'expPdf', text: '导出PDF' },
    { value: 'shareLink', text: '分享链接' },
    { value: 'megvii', text: '旷视面板机' },
    { value: 'filezip', text: '文件压缩包' },
  ]
@@ -1365,6 +1811,32 @@
  if (card.OpenType === 'form') { // 拖拽添加类型转换
    card.OpenType = 'pop'
  }
  let extraParam = []
  if (card.recordUser === 'true') {
    extraParam.push('recordUser')
  }
  if (card.dataM === 'true') {
    extraParam.push('dataM')
  }
  let apps = []
  let merchs = []
  if (window.GLOB.WXApps) {
    window.GLOB.WXApps.forEach(item => {
      if (item.appType === 'merchant') {
        merchs.push({value: item.appId, text: item.appName})
      } else {
        apps.push({value: item.appId, text: item.appName})
      }
    })
  }
  let width = card.width || (card.width === 0 ? 0 : 12)
  if (card.width && /x/.test(card.width)) {
    width = +width.replace(/x/, '.5')
  }
  let forms = [
@@ -1427,20 +1899,20 @@
      required: true,
      options: []
    },
    {
      type: 'checkbox',
      key: 'payType',
      label: '支付方式',
      initVal: card.payType || [],
      required: true,
      options: [{
        value: 'wxpay',
        text: '微信'
      // }, {
      //   value: 'alipay',
      //   text: '支付宝'
      }]
    },
    // {
    //   type: 'checkbox',
    //   key: 'payType',
    //   label: '支付方式',
    //   initVal: card.payType || [],
    //   required: true,
    //   options: [{
    //     value: 'wxpay',
    //     text: '微信'
    //   // }, {
    //   //   value: 'alipay',
    //   //   text: '支付宝'
    //   }]
    // },
    {
      type: 'radio',
      key: 'procMode',
@@ -1476,15 +1948,6 @@
    },
    {
      type: 'text',
      key: 'innerFunc',
      label: '内部函数',
      initVal: card.innerFunc || '',
      tooltip: functip,
      fields: usefulFields,
      required: false,
    },
    {
      type: 'text',
      key: 'urlkey',
      label: '地址字段',
      initVal: card.urlkey || '',
@@ -1501,10 +1964,70 @@
      options: pageTemps
    },
    {
      type: 'radio',
      key: 'payMode',
      label: '参数处理',
      initVal: card.payMode || 'none',
      tooltip: '支付(或退款)单号的预处理方式。',
      required: true,
      options: [{
        value: 'system',
        text: '系统函数'
      }, {
        value: 'inner',
        text: '内部函数'
      }, {
        value: 'none',
        text: '无'
      }]
    },
    {
      type: 'select',
      key: 'wxApp',
      label: '关联应用',
      initVal: card.wxApp || '',
      tooltip: '请关联支付的公众号或小程序。',
      required: true,
      forbid: apps.length === 0,
      options: apps
    },
    {
      type: 'select',
      key: 'wxMerch',
      label: '关联商户',
      initVal: card.wxMerch || '',
      tooltip: '请关联支付的商户号。',
      required: true,
      forbid: merchs.length === 0,
      options: merchs
    },
    {
      type: 'text',
      key: 'innerFunc',
      label: '内部函数',
      initVal: card.innerFunc || '',
      tooltip: functip,
      fields: usefulFields,
      required: false,
    },
    {
      type: 'printTemps',
      key: 'printTemp',
      label: '打印模板',
      initVal: card.printTemp || '',
      help: (record) => {
        if (record.printTemp) {
          return <span onClick={() => {
            sessionStorage.setItem('mk-print-temp', record.printTemp)
            window.open('#/hs')
            setTimeout(() => {
              sessionStorage.removeItem('mk-print-temp')
            }, 50)
          }} style={{color: '#1890ff', cursor: 'pointer', fontSize: '13px'}}>#查看模板</span>
        }
        return ''
      },
      required: true
    },
    {
@@ -1514,14 +2037,15 @@
      initVal: card.linkmenu || [],
      required: true,
      extendName: 'MenuNo',
      options: menulist
      options: menulist.length ? [...menulist, {value: 'multiMenu', label: '多菜单'}] : []
    },
    {
      type: 'textarea',
      key: 'url',
      label: '页面地址',
      initVal: card.url || '',
      tooltip: '地址格式为:http://******/admin/index.html#/iframe/menuId/loginuid/BID 会打开标签页。注:使用@loginuid@时自动替换为当前系统的loginuid;选择单行且拼接参数时会拼接BID。',
      tooltip: '在链接中以@***@形式拼接的字段(字段来源于字段集中,此外 id、appkey、userid、LoginUID 为系统字段),跳转时将替换为对应值,例如:http://sso.mk9h.cn/doc/index.html?appkey=@appkey@&LoginUID=@LoginUID@,其中appkey与LoginUID将被替换。地址格式为:******/admin/index.html#/iframe/menuId/@loginuid@ 会打开标签页。',
      toolWidth: 350,
      required: true
    },
    {
@@ -1529,7 +2053,8 @@
      key: 'proUrl',
      label: '正式地址',
      initVal: card.proUrl || '',
      tooltip: '地址格式为:http://******/admin/index.html#/iframe/menuId/loginuid/BID 会打开标签页。注:使用@loginuid@时自动替换为当前系统的loginuid;选择单行且拼接参数时会拼接BID。',
      tooltip: '在链接中以@***@形式拼接的字段(字段来源于字段集中,此外 id、appkey、userid、LoginUID 为系统字段),跳转时将替换为对应值,例如:http://sso.mk9h.cn/doc/index.html?appkey=@appkey@&LoginUID=@LoginUID@,其中appkey与LoginUID将被替换。地址格式为:******/admin/index.html#/iframe/menuId/@loginuid@ 会打开标签页。',
      toolWidth: 350,
      required: false
    },
    {
@@ -1698,7 +2223,7 @@
      key: 'execSuccess',
      label: '成功后',
      initVal: card.execSuccess || 'grid',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新表格。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮(弹窗按钮)中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需聚焦表单请以 @focus:聚焦字段@ 格式返回。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需聚焦表单请以 @focus:聚焦字段@ 格式返回。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。',
      required: true,
      options: [{
        value: 'never',
@@ -1710,8 +2235,14 @@
        value: 'grid',
        text: '刷新当前组件'
      }, {
        value: 'line_grid',
        text: '刷新行 / 组件',
      }, {
        value: 'mainline',
        text: '刷新上级组件 - 行'
      }, {
        value: 'maingrid',
        text: '刷新上级组件'
      }, 
      ...refresh]
    },
@@ -1720,7 +2251,7 @@
      key: 'execError',
      label: '失败后',
      initVal: card.execError || 'never',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新哪一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。' : '选择刷新行时,如果选择多条数据会刷新表格,注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮(弹窗按钮)中设置关闭后刷新哪一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@open_target_menu@ 可执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@open_target_menu@ 可执行打开菜单。',
      required: true,
      options: [{
        value: 'never',
@@ -1732,8 +2263,14 @@
        value: 'grid',
        text: '刷新当前组件'
      }, {
        value: 'line_grid',
        text: '刷新行 / 组件',
      }, {
        value: 'mainline',
        text: '刷新上级组件 - 行'
      }, {
        value: 'maingrid',
        text: '刷新上级组件'
      },
      ...refresh]
    },
@@ -1741,7 +2278,7 @@
      type: 'select',
      key: 'popClose',
      label: '关闭后',
      initVal: card.popClose || 'never',
      initVal: card.popClose || 'grid',
      required: true,
      options: [{
        value: 'never',
@@ -1752,6 +2289,9 @@
      }, {
        value: 'mainline',
        text: '刷新上级组件 - 行'
      }, {
        value: 'maingrid',
        text: '刷新上级组件'
      }]
    },
    {
@@ -1768,16 +2308,68 @@
        text: '不重置'
      }]
    },
    // {
    //   type: 'radio',
    //   key: 'exportType',
    //   label: '导出方式',
    //   initVal: card.exportType || 'download',
    //   tooltip: '',
    //   required: true,
    //   options: [{
    //     value: 'download',
    //     text: '下载本地'
    //   }, {
    //     value: 'link',
    //     text: '生成链接'
    //   }]
    // },
    {
      type: 'radio',
      key: 'shortUrl',
      label: '短链接',
      initVal: card.shortUrl || 'false',
      options: [{
        value: 'false',
        text: '禁用'
      }, {
        value: 'true',
        text: '启用'
      }]
    },
    {
      type: 'textarea',
      key: 'shareUrl',
      label: '链接地址',
      initVal: card.shareUrl || '',
      tooltip: '链接中如果存在@BID@或@ID@将自动替换。',
      required: true
    },
    {
      type: 'textarea',
      key: 'shareProUrl',
      label: '正式链接',
      initVal: card.shareProUrl || '',
      tooltip: '链接中如果存在@BID@或@ID@将自动替换。',
      required: false
    },
    {
      type: 'text',
      key: 'shareTip',
      label: '分享提示',
      initVal: card.shareTip || '',
      tooltip: '分享时对用户的提示信息。',
      required: false
    },
    {
      type: 'number',
      key: 'width',
      min: 1,
      min: 0,
      max: 24,
      precision: 0,
      precision: 1,
      label: '宽度',
      initVal: card.width || 12,
      tooltip: '栅格布局,每行等分为24列。',
      forbid: card.eleType !== 'button',
      initVal: width,
      tooltip: '栅格布局,每行等分为24列。为 0 时宽度自适应。可设置半列即.5。',
      forbid: position !== 'line',
      required: true
    },
    {
@@ -1798,6 +2390,24 @@
      }]
    },
    {
      type: 'radio',
      key: 'hover',
      label: '悬浮效果',
      initVal: card.hover || '',
      tooltip: '鼠标悬浮按钮上方时的颜色变化。',
      required: false,
      options: [{
        value: '',
        text: '无'
      }, {
        value: 'mk-btn-hover-bg',
        text: '背景变化'
      }, {
        value: 'mk-btn-hover-border',
        text: '边框变化'
      }]
    },
    {
      type: 'icon',
      key: 'icon',
      label: '图标',
@@ -1814,20 +2424,6 @@
      options: btnClasses
    },
    {
      type: 'radio',
      key: 'joint',
      label: '拼接参数',
      initVal: card.joint || 'true',
      required: false,
      options: [{
        value: 'true',
        text: '是'
      }, {
        value: 'false',
        text: '否'
      }]
    },
    {
      type: 'text',
      key: 'sheet',
      label: '表名',
@@ -1839,9 +2435,31 @@
      key: 'syncComponent',
      label: '刷新组件',
      initVal: card.syncComponent || [],
      tooltip: '执行成功后(或弹窗标签关闭时),需要同步刷新的组件。注:选择当前组件的上级组件无效,刷新上级组件请选择成功后“刷新上级组件 - 行”。',
      tooltip: '执行成功后(执行失败且存在刷新项、弹窗标签关闭),需要同步刷新的组件。注:选择当前组件的上级组件无效,刷新上级组件请选择成功后“刷新上级组件 - 行”。',
      required: false,
      options: modules.length ? [...modules, {value: 'multiComponent', label: '多组件'}] : []
    },
    {
      type: 'cascader',
      key: 'refreshTab',
      label: '刷新菜单',
      initVal: card.refreshTab || [],
      tooltip: '执行成功后(或执行失败且存在刷新项时),需要同步刷新的菜单',
      required: false,
      forbid: viewType === 'popview',
      options: menulist
    },
    {
      type: 'cascader',
      key: 'openmenu',
      label: '打开菜单',
      tooltip: '执行成功后(或失败时返回@open_target_menu@)需要打开的菜单。',
      initVal: card.openmenu || [],
      extendName: 'MenuNo',
      required: false,
      allowClear: true,
      options: menulist,
      forbid: viewType === 'popview'
    },
    {
      type: 'radio',
@@ -1873,43 +2491,43 @@
      }]
    },
    {
      type: 'cascader',
      key: 'refreshTab',
      label: '刷新菜单',
      initVal: card.refreshTab || [],
      tooltip: '执行成功后(或功能按钮中标签关闭类型),需要同步刷新的菜单',
      required: false,
      forbid: viewType === 'popview',
      options: menulist
    },
    {
      type: 'cascader',
      key: 'openmenu',
      label: '打开菜单',
      tooltip: '执行成功后需要打开的菜单。',
      initVal: card.openmenu || [],
      extendName: 'MenuNo',
      required: false,
      allowClear: true,
      options: menulist,
      forbid: viewType === 'popview'
    },
    {
      type: 'text',
      key: 'output',
      label: '返回值',
      tooltip: '执行成功后的返回值。系统函数可指定返回的变量(以@符开头,返回id时可使用@id@);自定义函数可指定返回字段(如id)。',
      initVal: card.output || '',
      required: false,
      forbid: viewType === 'popview'
      // forbid: viewType === 'popview'
    },
    {
      type: 'text',
      key: 'tipTitle',
      label: '确认提示',
      initVal: card.tipTitle || '',
      tooltip: '注:弹窗(表单)在显示为是否框时有效。',
      tooltip: '提示框的确认提示信息。',
      required: false
    },
    {
      type: 'text',
      key: 'hoverTitle',
      label: '悬浮提示',
      initVal: card.hoverTitle || '',
      tooltip: '鼠标悬浮在按钮上方时的提示信息。',
      required: false
    },
    {
      type: 'select',
      key: 'showName',
      label: '显示内容',
      initVal: card.showName || '',
      tooltip: '行级按钮可通过行信息控制按钮显示内容。',
      required: false,
      allowClear: true,
      forbid: position !== 'line',
      options: columns.map(item => ({
        value: item.field,
        text: `${item.label}(${item.field})`
      }))
    },
    {
      type: 'radio',
@@ -2006,6 +2624,21 @@
      required: false
    },
    {
      type: 'checkbox',
      key: 'extraParam',
      label: '扩展参数',
      initVal: extraParam,
      tooltip: '选择“用户信息”时,内部函数的传参会增加 username 与 fullname。选择“数据管理员”时,内部函数的传参会增加 dataM ,管理员值为“Y”,普通用户为空。',
      required: false,
      options: [{
        value: 'recordUser',
        text: '用户信息'
      }, {
        value: 'dataM',
        text: '数据管理员'
      }]
    },
    {
      type: 'radio',
      key: 'control',
      label: '按钮控制',
@@ -2069,6 +2702,59 @@
    },
    {
      type: 'radio',
      key: 'database',
      label: '数据库',
      initVal: card.database || 'local',
      options: [{
        value: 'local',
        text: '本地'
      }, {
        value: 'sso',
        text: '单点'
      }]
    },
    {
      type: 'radio',
      key: 'permission',
      label: '权限验证',
      initVal: card.permission || 'true',
      required: false,
      options: [
        {value: 'true', text: '启用'},
        {value: 'false', text: '禁用'},
      ],
      forbid: viewType === 'popview'
    },
    {
      type: 'radio',
      key: 'extBtn',
      label: '扩展按钮',
      initVal: card.extBtn || 'false',
      tooltip: '点击扩展按钮时,变量 mk_submit_type 将被赋值。',
      required: false,
      options: [
        {value: 'true', text: '启用'},
        {value: 'false', text: '禁用'},
      ],
    },
    {
      type: 'text',
      key: 'extLabel',
      label: '扩展名称',
      initVal: card.extLabel || '',
      required: true,
      readonly: false
    },
    {
      type: 'text',
      key: 'extValue',
      label: '扩展值',
      initVal: card.extValue || '',
      required: true,
      readonly: false
    },
    {
      type: 'radio',
      key: 'execType',
      label: '请求方式',
      initVal: card.execType || 'multi',
@@ -2102,12 +2788,13 @@
      label: '组件列表',
      initVal: card.syncComponents || [],
      required: true,
      actions: [],
      actions: ['edit', 'del', 'add', 'move'],
      columns: [
        {
          title: '组件',
          dataIndex: 'syncComId',
          inputType: 'cascader',
          unique: true,
          editable: true,
          required: true,
          extends: [{key: 'label', value: 'label'}],
@@ -2116,6 +2803,90 @@
          options: modules
        }
      ]
    },
    {
      type: 'radio',
      key: 'sysId',
      label: '自定义ID',
      initVal: card.sysId || '',
      tooltip: '不选行按钮可在前端生成ID值(32位),作为后续菜单的BID,存在标记时,ID值后将拼接标记值。',
      required: false,
      options: [{
        value: '',
        text: '组件BID'
      }, {
        value: 'js',
        text: '前端生成'
      }, {
        value: 'empty',
        text: '空'
      }]
    },
    {
      type: 'text',
      key: 'sign',
      label: '标记',
      initVal: card.sign || '',
      required: false
    },
    {
      type: 'table',
      key: 'multiMenus',
      label: '菜单列表',
      initVal: card.multiMenus || [],
      required: true,
      actions: ['edit', 'del', 'add', 'move'],
      columns: [
        {
          title: '名称',
          dataIndex: 'name',
          inputType: 'text',
          editable: true,
          required: false,
          width: '30%'
        },
        {
          title: '菜单',
          dataIndex: 'menuId',
          inputType: 'cascader',
          editable: true,
          required: true,
          extends: [{key: 'label', value: 'label', mutilLabel: 'name'}],
          width: '30%',
          render: (text, record) => record.label,
          options: menulist
        },
        {
          title: '标记',
          dataIndex: 'sign',
          inputType: 'text',
          editable: true,
          required: false,
          width: '20%'
        }
      ]
    },
    {
      type: 'radio',
      key: 'preHandle',
      label: '自定义脚本',
      initVal: card.preHandle || 'false',
      // tooltip: '隐藏后按钮在页面中不显示,且不参与权限分配。',
      required: false,
      options: [{
        value: 'false',
        text: '禁用'
      }, {
        value: 'true',
        text: '启用'
      }]
    },
    {
      type: 'codemirror',
      key: 'pre_func',
      label: '自定义脚本',
      initVal: card.pre_func || '',
      required: true,
    }
  ]