king
2024-01-15 45224a77b80aa6bbd905d91f19d7b0d9dd6d6f05
src/menu/components/share/actioncomponent/formconfig.jsx
@@ -1,5 +1,5 @@
import { btnCustomClasses, btnClasses } from '@/utils/option.js'
import React from 'react'
import { btnClasses } from '@/utils/option.js'
/**
 * @description 获取按钮表单配置信息
@@ -7,18 +7,16 @@
 * @param {*} functip        生成存储过程提示
 * @param {*} setting        组件配置
 * @param {*} usefulFields   存储过程可用的开始字段
 * @param {*} type           按钮类型,用于区分可选的打开方式
 */
export function getActionForm (card, functip, config, usefulFields, modules = [], anchors = []) {
export function getActionForm (card, functip, config, usefulFields, modules = [], anchors = [], side) {
  let appType = sessionStorage.getItem('appType')
  let viewType = sessionStorage.getItem('editMenuType') // 弹窗 popview
  let printTemps = sessionStorage.getItem('printTemps')
  printTemps = printTemps ? JSON.parse(printTemps) : []
  let setting = config.setting || {}
  let columns = config.columns || []
  let columns = side === 'sub' && config.subColumns ? config.subColumns : (config.columns || [])
  let appMenus = []
  let menulist = []
  let type = ''
  let alltype = config.type + '_' + config.subtype
  if (card.eleType === 'button') {
    type = 'card'
@@ -84,7 +82,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: '单据打印' },
@@ -97,7 +161,8 @@
    { value: 'print', text: '标签打印' },
    { value: 'refund', text: '退款' },
    { value: 'closetab', text: '标签关闭' },
    { value: 'changeuser', text: '切换用户' },
    { value: 'expPdf', text: '导出PDF' },
    { value: 'shareLink', text: '分享链接' },
    { value: 'megvii', text: '旷视面板机' },
    { value: 'filezip', text: '文件压缩包' },
  ]
@@ -113,6 +178,7 @@
    } else {
      appMenus = []
    }
    appMenus.push({value: 'goback', text: '返回(上一页)'})
  } else {
    menulist = sessionStorage.getItem('fstMenuList')
    if (menulist) {
@@ -139,6 +205,8 @@
      { value: 'reAuth', text: '切换系统(清空缓存-小程序)' },
      { value: 'clearCache', text: '清空本地配置' },
      { value: 'copyurl', text: '复制链接地址' },
      { value: 'expPdf', text: '导出PDF' },
      { value: 'shareLink', text: '分享链接' },
      { value: 'logout', text: '退出' },
      { value: 'goBack', text: '返回' },
    ]
@@ -150,7 +218,6 @@
    opentypes = opentypes.filter(item => item.value !== 'tab')
    funTypes = [
      { value: 'print', text: '标签打印' },
      { value: 'changeuser', text: '切换用户' },
    ]
    pageTemps = [
      { value: 'linkpage', text: '关联菜单' },
@@ -158,6 +225,29 @@
      { value: 'pay', text: '支付' },
      { value: 'custom', text: '链接' }
    ]
  } else {
    if (card.pageTemplate === 'print') { // 原类型支持
      pageTemps.unshift({ value: 'print', text: '标签打印模板' })
    } else if (card.pageTemplate === 'billprintTemp') { // 原类型支持
      pageTemps.unshift({ value: 'billprintTemp', text: '单据打印模板' })
    }
  }
  if (card.$fixed) {
    opentypes = opentypes.filter(item => item.value === card.OpenType)
  }
  if (card.funcType === 'changeuser') { // 原类型支持
    funTypes.unshift({ value: 'changeuser', text: '切换用户' })
  }
  if (config.subtype === 'editable') { // 编辑表的添加、删除
    funTypes.push(
      { value: 'addline', text: '增加行(编辑表)' },
      { value: 'delline', text: '删除行(编辑表)' }
    )
  } else if (card.funcType === 'addline' || card.funcType === 'delline') {
    card.funcType = ''
  }
  
  if (type === 'chart' && appType !== 'mob') {
@@ -170,7 +260,10 @@
  let refresh = []
  if (viewType === 'popview') { // 弹窗标签
    opentypes = opentypes.filter(item => item.value !== 'popview' && item.value !== 'funcbutton')
    opentypes = opentypes.filter(item => item.value !== 'popview')
    funTypes = funTypes.filter(item => item.value !== 'print')
    refresh.push({
      value: 'closepoptab', // 关闭弹窗标签
      text: '关闭弹窗'
@@ -224,7 +317,7 @@
    {
      type: 'select',
      key: 'OpenType',
      label: '打开方式',
      label: '按钮类型',
      initVal: card.OpenType,
      required: true,
      options: opentypes
@@ -234,6 +327,7 @@
      key: 'label',
      label: '按钮名称',
      initVal: card.label,
      tooltip: card.uuid ? '按钮ID:' + card.uuid : '',
      required: true,
    },
    {
@@ -255,7 +349,7 @@
      ]
    },
    {
      type: 'radio',
      type: formTypes.length ? 'select' : 'radio',
      key: 'formType',
      label: '表单类型',
      initVal: card.formType || 'switch',
@@ -269,6 +363,9 @@
      }, {
        value: 'counter',
        text: '计数器'
      }, {
        value: 'count_line',
        text: '计数器(本地)'
      }, 
      ...formTypes]
    },
@@ -316,7 +413,7 @@
      key: 'procMode',
      label: '参数处理',
      initVal: card.procMode || (card.innerFunc ? 'inner' : 'system'),
      tooltip: '当返回值存在 mk_ex_invoke 且值为 false 时,不会调用外部接口。',
      tooltip: '当返回值存在 mk_ex_invoke 且值为 false 时,不会调用外部接口;当返回值存在 mk_ex_data 时,将以此为参数分批请求自定义接口。注:当选“无”时,按钮选行时会传递主键,存在表单时会传递表单字段,存在BID时会传BID字段。',
      required: true,
      options: [{
        value: 'system',
@@ -371,12 +468,24 @@
      options: pageTemps
    },
    {
      type: 'select',
      type: 'printTemps',
      key: 'printTemp',
      label: '打印模板',
      initVal: card.printTemp || '',
      required: true,
      options: printTemps
      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
    },
    {
      type: isApp ? 'select' : 'cascader',
@@ -400,7 +509,16 @@
      key: 'url',
      label: '页面地址',
      initVal: card.url || '',
      tooltip: appType === '' ? '地址格式为:http://******/admin/index.html#/iframe/menuId/loginuid/BID 会打开标签页。注:使用@loginuid@时自动替换为当前系统的loginuid;选择单行且拼接参数时会拼接BID。' : '',
      required: true
    },
    {
      type: 'textarea',
      key: 'proUrl',
      label: '正式地址',
      initVal: card.proUrl || '',
      tooltip: appType === '' ? '地址格式为:http://******/admin/index.html#/iframe/menuId/loginuid/BID 会打开标签页。注:使用@loginuid@时自动替换为当前系统的loginuid;选择单行且拼接参数时会拼接BID。' : '',
      required: false
    },
    {
      type: 'radio',
@@ -460,35 +578,6 @@
    },
    {
      type: 'radio',
      key: 'method',
      label: '请求方式',
      initVal: card.method || 'post',
      required: true,
      options: [{
        value: 'get',
        text: 'GET'
      }, {
        value: 'post',
        text: 'POST'
      }]
    },
    {
      type: 'radio',
      key: 'cross',
      label: '跨域请求',
      initVal: card.cross || 'true',
      tooltip: '如果自定义接口不支持跨域请求,会通过当前系统转发。',
      required: false,
      options: [{
        value: 'true',
        text: '支持'
      }, {
        value: 'false',
        text: '不支持'
      }]
    },
    {
      type: 'radio',
      key: 'callbackType',
      label: '回调方式',
      initVal: card.callbackType || (card.callbackFunc ? 'func' : 'none'),
@@ -523,6 +612,68 @@
      required: true
    },
    {
      type: 'radio',
      key: 'method',
      label: '请求方式',
      initVal: card.method || 'post',
      required: true,
      options: [{
        value: 'get',
        text: 'GET'
      }, {
        value: 'post',
        text: 'POST'
      }]
    },
    {
      type: 'radio',
      key: 'cross',
      label: '接口跨域',
      initVal: card.cross || 'true',
      tooltip: '如果自定义接口不支持跨域请求,会通过当前系统转发。',
      required: false,
      options: [{
        value: 'true',
        text: '支持'
      }, {
        value: 'false',
        text: '不支持'
      }]
    },
    {
      type: 'radio',
      key: 'stringify',
      label: '序列化',
      initVal: card.stringify || 'text',
      required: false,
      options: [{
        value: 'text',
        text: 'Text'
      }, {
        value: 'JSON',
        text: 'JSON'
      }, {
        value: 'qs',
        text: 'qs'
      }]
    },
    {
      type: 'text',
      key: 'ContentType',
      label: 'Content-Type',
      initVal: card.ContentType || '',
      tooltip: '默认值:application/x-www-form-urlencoded;charset=UTF-8',
      required: false
    },
    {
      type: 'text',
      key: 'outerBlacklist',
      label: '字段黑名单',
      initVal: card.outerBlacklist || '',
      tooltip: '不需要回传的字段可设置字段黑名单,多个值请用逗号分隔。',
      required: false
    },
    {
      type: 'select',
      key: 'Ot',
      label: '行设置',
@@ -535,17 +686,22 @@
      key: 'execSuccess',
      label: '成功后',
      initVal: card.execSuccess || 'grid',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。' : '选择刷新行时,如果选择多条数据会刷新表格。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需语音播报请以@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: '刷新上级组件 - 行'
@@ -558,17 +714,22 @@
      key: 'execError',
      label: '失败后',
      initVal: card.execError || 'never',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。' : '选择刷新行时,如果选择多条数据会刷新表格,注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。',
      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: '刷新上级组件 - 行'
@@ -579,7 +740,7 @@
      type: 'select',
      key: 'popClose',
      label: '关闭后',
      initVal: card.popClose || 'never',
      initVal: card.popClose || 'grid',
      required: true,
      options: [{
        value: 'never',
@@ -607,17 +768,69 @@
      }]
    },
    {
      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,
      label: '宽度',
      initVal: card.width || 12,
      tooltip: '栅格布局,每行等分为24列。',
      initVal: card.width || (card.width === 0 ? 0 : 12),
      tooltip: '栅格布局,每行等分为24列。为 0 时宽度自适应。',
      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',
@@ -644,9 +857,6 @@
      required: false,
      forbid: (type !== 'datacard' || appType !== 'mob'),
      options: [{
      //   value: 'false',
      //   text: '否'
      // }, {
        value: 'left',
        text: '左滑'
      }, {
@@ -671,7 +881,7 @@
      tooltip: '此颜色为按钮初始化颜色,可在样式调整中修改。',
      required: false,
      forbid: type === 'datacard' && appType === 'mob', // 移动端,滑动显示的按钮不设置通用颜色
      options: btnCustomClasses
      options: btnClasses
    },
    {
      type: 'radio',
@@ -695,6 +905,9 @@
      }, {
        value: 'light',
        text: '灰'
      }, {
        value: 'system',
        text: '系统'
      }]
    },
    {
@@ -725,7 +938,7 @@
      initVal: card.syncComponent || [],
      tooltip: '执行成功后(或弹窗标签关闭时),需要同步刷新的组件。注:选择当前组件的上级组件无效,刷新上级组件请选择成功后“刷新上级组件 - 行”。',
      required: false,
      options: modules
      options: modules.length ? [...modules, {value: 'multiComponent', label: '多组件'}] : []
    },
    {
      type: 'radio',
@@ -796,8 +1009,18 @@
      extendName: 'MenuNo',
      required: false,
      allowClear: true,
      options: appType === 'mob' || appType === 'pc' ? [...appMenus, {value: 'goback', text: '返回(上一页)'}] : menulist,
      options: appType === 'mob' || appType === 'pc' ? appMenus : menulist,
      forbid: viewType === 'popview'
    },
    {
      type: 'select',
      key: 'preButton',
      label: '前置按钮',
      tooltip: '当前按钮执行前,需要执行的按钮。',
      initVal: card.preButton || '',
      required: false,
      allowClear: true,
      options: linkButtons
    },
    {
      type: 'text',
@@ -827,6 +1050,19 @@
      options: [
        {value: 'blank', text: appType !== 'mob' ? '新窗口' : '新页面'},
        {value: 'self', text: appType !== 'mob' ? '当前窗口' : '当前页面'},
      ]
    },
    {
      type: 'radio',
      key: 'openTab',
      label: '打开方式',
      initVal: card.openTab || 'newtab',
      tooltip: '菜单打开方式。',
      forbid: appType !== '',
      options: [
        {value: 'newtab', text: '标签页'},
        // {value: 'newpage', text: '新页面(标签页)'},
        {value: 'view', text: '新页面(全屏)'}
      ]
    },
    {
@@ -891,6 +1127,22 @@
    },
    {
      type: 'radio',
      key: 'popshow',
      label: '弹窗展示',
      initVal: card.popshow || 'default',
      tooltip: '小窗口展示将隐藏标题及底部按钮。',
      required: false,
      options: [{
        value: 'default',
        text: '默认'
      }, {
        value: 'miniview',
        text: '小窗口'
      }],
      forbid: appType === 'mob'
    },
    {
      type: 'radio',
      key: 'maskStyle',
      label: '蒙层样式',
      initVal: card.maskStyle || 'default',
@@ -951,6 +1203,30 @@
      }]
    },
    {
      type: 'text',
      key: 'preFunc',
      label: '前置函数',
      initVal: card.preFunc || '',
      tooltip: '前置函数执行完成后,结果会传入内部函数中,此时内部函数会异步执行;当前置函数返回中ErrCode等于-1时,将不再执行内部函数。',
      required: false,
      forbid: appType === 'mob'
    },
    {
      type: 'radio',
      key: 'recordUser',
      label: '记录用户',
      initVal: card.recordUser || 'false',
      tooltip: '当选择“是”时,内部函数的传参会增加 username 与 fullname。',
      required: false,
      options: [{
        value: 'false',
        text: '否'
      }, {
        value: 'true',
        text: '是'
      }]
    },
    {
      type: 'radio',
      key: 'control',
      label: '按钮控制',
@@ -996,6 +1272,21 @@
      label: '禁用原因',
      initVal: card.reason || '',
      required: false
    },
    {
      type: 'radio',
      key: 'formCache',
      label: '表单缓存',
      initVal: card.formCache || 'false',
      tooltip: '主要用于数据修改后,更新相关表单的选项,清空缓存后表单再次打开时数据会重新加载。',
      required: false,
      options: [{
        value: 'false',
        text: '不清空'
      }, {
        value: 'clear',
        text: '清空'
      }]
    },
    {
      type: 'radio',
@@ -1135,6 +1426,28 @@
        value: 'progressbar',
        text: '进度条'
      }]
    },
    {
      type: 'table',
      key: 'syncComponents',
      label: '组件列表',
      initVal: card.syncComponents || [],
      required: true,
      actions: ['edit', 'del', 'add', 'move'],
      columns: [
        {
          title: '组件',
          dataIndex: 'syncComId',
          inputType: 'cascader',
          editable: true,
          unique: true,
          required: true,
          extends: [{key: 'label', value: 'label'}],
          width: '70%',
          render: (text, record) => record.label,
          options: modules
        }
      ]
    }
  ]
@@ -1150,8 +1463,6 @@
 */
export function getBaseTableActionForm (card, functip, config, usefulFields, modules) {
  let viewType = sessionStorage.getItem('editMenuType') // 弹窗 popview
  let printTemps = sessionStorage.getItem('printTemps')
  printTemps = printTemps ? JSON.parse(printTemps) : []
  let setting = config.setting || {}
  let columns = config.columns || []
@@ -1194,14 +1505,25 @@
    { value: 'custom', text: '自定义' }
  ]
  if (card.pageTemplate === 'print') { // 原类型支持
    pageTemps.unshift({ value: 'print', text: '标签打印模板' })
  } else if (card.pageTemplate === 'billprintTemp') { // 原类型支持
    pageTemps.unshift({ value: 'billprintTemp', text: '单据打印模板' })
  }
  let funTypes = [
    { value: 'print', text: '标签打印' },
    { value: 'refund', text: '退款' },
    { value: 'closetab', text: '标签关闭' },
    { value: 'changeuser', text: '切换用户' },
    { value: 'expPdf', text: '导出PDF' },
    { value: 'shareLink', text: '分享链接' },
    { value: 'megvii', text: '旷视面板机' },
    { value: 'filezip', text: '文件压缩包' },
  ]
  if (card.funcType === 'changeuser') { // 原类型支持
    funTypes.unshift({ value: 'changeuser', text: '切换用户' })
  }
  let menulist = sessionStorage.getItem('fstMenuList')
  if (menulist) {
@@ -1216,7 +1538,10 @@
  let refresh = []
  if (viewType === 'popview') { // 弹窗标签
    opentypes = opentypes.filter(item => item.value !== 'popview' && item.value !== 'funcbutton')
    opentypes = opentypes.filter(item => item.value !== 'popview')
    funTypes = funTypes.filter(item => item.value !== 'print')
    refresh.push({
      value: 'closepoptab', // 关闭弹窗标签
      text: '关闭弹窗'
@@ -1231,7 +1556,7 @@
    {
      type: 'select',
      key: 'OpenType',
      label: '打开方式',
      label: '按钮类型',
      initVal: card.OpenType,
      required: true,
      options: opentypes
@@ -1241,6 +1566,7 @@
      key: 'label',
      label: '按钮名称',
      initVal: card.label,
      tooltip: card.uuid ? '按钮ID:' + card.uuid : '',
      required: true,
    },
    {
@@ -1305,7 +1631,7 @@
      key: 'procMode',
      label: '参数处理',
      initVal: card.procMode || (card.innerFunc ? 'inner' : 'system'),
      tooltip: '当返回值存在 mk_ex_invoke 且值为 false 时,不会调用外部接口。',
      tooltip: '当返回值存在 mk_ex_invoke 且值为 false 时,不会调用外部接口;当返回值存在 mk_ex_data 时,将以此为参数分批请求自定义接口。注:当选“无”时,按钮选行时会传递主键,存在表单时会传递表单字段,存在BID时会传BID字段。',
      required: true,
      options: [{
        value: 'system',
@@ -1360,12 +1686,24 @@
      options: pageTemps
    },
    {
      type: 'select',
      type: 'printTemps',
      key: 'printTemp',
      label: '打印模板',
      initVal: card.printTemp || '',
      required: true,
      options: printTemps
      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
    },
    {
      type: 'cascader',
@@ -1381,7 +1719,16 @@
      key: 'url',
      label: '页面地址',
      initVal: card.url || '',
      tooltip: '地址格式为:http://******/admin/index.html#/iframe/menuId/loginuid/BID 会打开标签页。注:使用@loginuid@时自动替换为当前系统的loginuid;选择单行且拼接参数时会拼接BID。',
      required: true
    },
    {
      type: 'textarea',
      key: 'proUrl',
      label: '正式地址',
      initVal: card.proUrl || '',
      tooltip: '地址格式为:http://******/admin/index.html#/iframe/menuId/loginuid/BID 会打开标签页。注:使用@loginuid@时自动替换为当前系统的loginuid;选择单行且拼接参数时会拼接BID。',
      required: false
    },
    {
      type: 'radio',
@@ -1441,35 +1788,6 @@
    },
    {
      type: 'radio',
      key: 'method',
      label: '请求方式',
      initVal: card.method || 'post',
      required: true,
      options: [{
        value: 'get',
        text: 'GET'
      }, {
        value: 'post',
        text: 'POST'
      }]
    },
    {
      type: 'radio',
      key: 'cross',
      label: '跨域请求',
      initVal: card.cross || 'true',
      tooltip: '如果自定义接口不支持跨域请求,会通过当前系统转发。',
      required: false,
      options: [{
        value: 'true',
        text: '支持'
      }, {
        value: 'false',
        text: '不支持'
      }]
    },
    {
      type: 'radio',
      key: 'callbackType',
      label: '回调方式',
      initVal: card.callbackType || (card.callbackFunc ? 'func' : 'none'),
@@ -1504,6 +1822,68 @@
      required: true
    },
    {
      type: 'radio',
      key: 'method',
      label: '请求方式',
      initVal: card.method || 'post',
      required: true,
      options: [{
        value: 'get',
        text: 'GET'
      }, {
        value: 'post',
        text: 'POST'
      }]
    },
    {
      type: 'radio',
      key: 'cross',
      label: '接口跨域',
      initVal: card.cross || 'true',
      tooltip: '如果自定义接口不支持跨域请求,会通过当前系统转发。',
      required: false,
      options: [{
        value: 'true',
        text: '支持'
      }, {
        value: 'false',
        text: '不支持'
      }]
    },
    {
      type: 'radio',
      key: 'stringify',
      label: '序列化',
      initVal: card.stringify || 'text',
      required: false,
      options: [{
        value: 'text',
        text: 'Text'
      }, {
        value: 'JSON',
        text: 'JSON'
      }, {
        value: 'qs',
        text: 'qs'
      }]
    },
    {
      type: 'text',
      key: 'ContentType',
      label: 'Content-Type',
      initVal: card.ContentType || '',
      tooltip: '默认值:application/x-www-form-urlencoded;charset=UTF-8',
      required: false
    },
    {
      type: 'text',
      key: 'outerBlacklist',
      label: '字段黑名单',
      initVal: card.outerBlacklist || '',
      tooltip: '不需要回传的字段可设置字段黑名单,多个值请用逗号分隔。',
      required: false
    },
    {
      type: 'select',
      key: 'Ot',
      label: '行设置',
@@ -1516,7 +1896,7 @@
      key: 'execSuccess',
      label: '成功后',
      initVal: card.execSuccess || 'grid',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。' : '选择刷新行时,如果选择多条数据会刷新表格。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。',
      required: true,
      options: [{
        value: 'never',
@@ -1527,6 +1907,9 @@
      }, {
        value: 'grid',
        text: '刷新当前组件'
      }, {
        value: 'line_grid',
        text: '刷新行 / 组件',
      }, {
        value: 'mainline',
        text: '刷新上级组件 - 行'
@@ -1538,7 +1921,7 @@
      key: 'execError',
      label: '失败后',
      initVal: card.execError || 'never',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。' : '选择刷新行时,如果选择多条数据会刷新表格,注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新哪一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。',
      required: true,
      options: [{
        value: 'never',
@@ -1550,6 +1933,9 @@
        value: 'grid',
        text: '刷新当前组件'
      }, {
        value: 'line_grid',
        text: '刷新行 / 组件',
      }, {
        value: 'mainline',
        text: '刷新上级组件 - 行'
      },
@@ -1559,7 +1945,7 @@
      type: 'select',
      key: 'popClose',
      label: '关闭后',
      initVal: card.popClose || 'never',
      initVal: card.popClose || 'grid',
      required: true,
      options: [{
        value: 'never',
@@ -1586,18 +1972,70 @@
        text: '不重置'
      }]
    },
    // {
    //   type: 'radio',
    //   key: 'exportType',
    //   label: '导出方式',
    //   initVal: card.exportType || 'download',
    //   tooltip: '',
    //   required: true,
    //   options: [{
    //     value: 'download',
    //     text: '下载本地'
    //   }, {
    //     value: 'link',
    //     text: '生成链接'
    //   }]
    // },
    {
      type: 'number',
      key: 'width',
      min: 1,
      max: 24,
      precision: 0,
      label: '宽度',
      initVal: card.width || 12,
      tooltip: '栅格布局,每行等分为24列。',
      forbid: card.eleType !== 'button',
      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,
    //   max: 24,
    //   precision: 0,
    //   label: '宽度',
    //   initVal: card.width || 12,
    //   tooltip: '栅格布局,每行等分为24列。',
    //   forbid: card.eleType !== 'button',
    //   required: true
    // },
    {
      type: 'radio',
      key: 'show',
@@ -1659,7 +2097,7 @@
      initVal: card.syncComponent || [],
      tooltip: '执行成功后(或弹窗标签关闭时),需要同步刷新的组件。注:选择当前组件的上级组件无效,刷新上级组件请选择成功后“刷新上级组件 - 行”。',
      required: false,
      options: modules
      options: modules.length ? [...modules, {value: 'multiComponent', label: '多组件'}] : []
    },
    {
      type: 'radio',
@@ -1731,6 +2169,18 @@
    },
    {
      type: 'radio',
      key: 'openTab',
      label: '打开方式',
      initVal: card.openTab || 'newtab',
      tooltip: '菜单打开方式。',
      options: [
        {value: 'newtab', text: '标签页'},
        // {value: 'newpage', text: '新页面(标签页)'},
        {value: 'view', text: '新页面(全屏)'}
      ]
    },
    {
      type: 'radio',
      key: 'display',
      label: '显示方式',
      initVal: card.display || 'modal',
@@ -1790,6 +2240,44 @@
    },
    {
      type: 'radio',
      key: 'popshow',
      label: '弹窗展示',
      initVal: card.popshow || 'default',
      tooltip: '小窗口展示将隐藏标题及底部按钮。',
      required: false,
      options: [{
        value: 'default',
        text: '默认'
      }, {
        value: 'miniview',
        text: '小窗口'
      }]
    },
    {
      type: 'text',
      key: 'preFunc',
      label: '前置函数',
      initVal: card.preFunc || '',
      tooltip: '前置函数执行完成后,结果会传入内部函数中,此时内部函数会异步执行;当前置函数返回中ErrCode等于-1时,将不再执行内部函数。',
      required: false
    },
    {
      type: 'radio',
      key: 'recordUser',
      label: '记录用户',
      initVal: card.recordUser || 'false',
      tooltip: '当选择“是”时,内部函数的传参会增加 username 与 fullname。',
      required: false,
      options: [{
        value: 'false',
        text: '否'
      }, {
        value: 'true',
        text: '是'
      }]
    },
    {
      type: 'radio',
      key: 'control',
      label: '按钮控制',
      initVal: card.control || (card.controlField ? 'disabled' : ''),
@@ -1837,6 +2325,21 @@
    },
    {
      type: 'radio',
      key: 'formCache',
      label: '表单缓存',
      initVal: card.formCache || 'false',
      tooltip: '主要用于数据修改后,更新相关表单的选项,清空缓存后表单再次打开时数据会重新加载。',
      required: false,
      options: [{
        value: 'false',
        text: '不清空'
      }, {
        value: 'clear',
        text: '清空'
      }]
    },
    {
      type: 'radio',
      key: 'hidden',
      label: '隐藏',
      initVal: card.hidden || 'false',
@@ -1878,6 +2381,28 @@
        value: 'progressbar',
        text: '进度条'
      }]
    },
    {
      type: 'table',
      key: 'syncComponents',
      label: '组件列表',
      initVal: card.syncComponents || [],
      required: true,
      actions: ['edit', 'del', 'add', 'move'],
      columns: [
        {
          title: '组件',
          dataIndex: 'syncComId',
          inputType: 'cascader',
          unique: true,
          editable: true,
          required: true,
          extends: [{key: 'label', value: 'label'}],
          width: '70%',
          render: (text, record) => record.label,
          options: modules
        }
      ]
    }
  ]