king
2020-01-15 12c4dd8bb0bb4c523dcf2fbb81191a7f3556a430
2020-01-15
12个文件已修改
1个文件已添加
2127 ■■■■ 已修改文件
src/assets/css/action.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/viewstyle.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/comtable.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/tableshare/actionList/index.jsx 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/actionform/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 1268 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/tabdragelement/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/settingform/index.jsx 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/dragelement/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/formconfig.js 669 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/tableshare/searchform/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/action.scss
@@ -31,8 +31,8 @@
  }
  .mk-default:hover, .mk-dashed:hover {
    color: #096dd9;
    border-color: #096dd9;
    color: #1890ff;
    border-color: #1890ff;
  }
  // 红色
src/assets/css/viewstyle.scss
@@ -16,8 +16,8 @@
    
          &:hover {
            span {
              color: #06B4F7;
              border-bottom: 4px solid #06B4F7;
              color: #1890ff;
              border-bottom: 4px solid #1890ff;
            }
          }
          &.active {
src/components/header/index.scss
@@ -69,7 +69,7 @@
      &.active {
        color: #ffffff;
        span {
          border-bottom: 4px solid #06b4f7;
          border-bottom: 4px solid #1890ff;
        }
      }
    }
src/locales/zh-CN/comtable.js
@@ -172,6 +172,15 @@
  'header.form.request.method': '请求方式',
  'header.form.readonly': '是否只读',
  'header.form.field.required': '是否必填',
  'header.modal.search.edit': '搜索条件-编辑',
  'header.modal.action.edit': '按钮-编辑',
  'header.modal.action.copy': '按钮-复制',
  'header.modal.column.edit': '显示列-编辑',
  'header.modal.colspan.edit': '合并列-编辑',
  'header.modal.gridbtn.edit': '操作列-编辑',
  'header.modal.tabs.edit': '标签-编辑',
  'header.modal.func.innerface': '内部接口: 可自定义数据处理函数,函数名称需以@ableField等字符开始;未设置时会调用系统函数,使用系统函数需完善数据源及操作类型;',
  'header.modal.func.outface': '外部接口: 可自定义数据处理函数,提交数据经过内部函数处理后,传入外部接口,未设置时,数据会直接传入外部接口。',
  'form.required.input': '请输入',
  'form.required.select': '请选择'
}
src/tabviews/tableshare/actionList/index.jsx
@@ -109,7 +109,14 @@
        duration: 10
      })
    } else if (item.OpenType === 'outerpage') {
      console.log(item)
      let url = item.url
      if (item.Ot === 'requiredSgl' && setting.primaryKey) {
        url = url + '?ID=' + data[0][setting.primaryKey]
      } else if (item.Ot !== 'notRequired' && !setting.primaryKey) {
        let ids = data.map(_data => _data[setting.primaryKey]).join(',')
        url = url + '?ID=' + ids
      }
      window.open(url)
    } else {
      notification.warning({
        top: 92,
src/templates/comtableconfig/actionform/index.jsx
@@ -488,7 +488,6 @@
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          values.id = this.props.card.id
          values.uuid = this.props.card.uuid
          values.verify = this.props.card.verify || null
@@ -512,10 +511,7 @@
              duration: 10
            })
          } else {
            resolve({
              type: 'action',
              values
            })
            resolve(values)
          }
        } else {
          reject(err)
src/templates/comtableconfig/index.jsx
@@ -1,16 +1,22 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import { connect } from 'react-redux'
import { is, fromJS } from 'immutable'
import { DndProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import { Button, Card, Modal, Collapse, notification, Spin, Select, List, Icon, Empty, Switch, Tooltip } from 'antd'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/comtable.js'
import enUS from '@/locales/en-US/comtable.js'
import { getSearchForm, getActionForm, getColumnForm } from '@/templates/tableshare/formconfig'
import ActionForm from './actionform'
import SettingForm from './settingform'
import TabForm from './tabform'
import TabDragElement from './tabdragelement'
import Api from '@/api'
import SearchForm from '@/templates/tableshare/searchform'
import ColumnForm from '@/templates/tableshare/columnform'
import DragElement from '@/templates/tableshare/dragelement'
@@ -20,9 +26,6 @@
import VerifyCard from '@/templates/tableshare/verifycard'
import MenuForm from '@/templates/tableshare/menuform'
import SourceElement from '@/templates/tableshare/dragelement/source'
import zhCN from '@/locales/zh-CN/comtable.js'
import enUS from '@/locales/en-US/comtable.js'
import Utils from '@/utils/utils.js'
import Source from './source'
import './index.scss'
@@ -52,12 +55,8 @@
    fields: null,            // 搜索条件及显示列,可选字段
    menuformlist: null,      // 基本信息表单字段
    formlist: null,          // 搜索条件、按钮、显示列表单字段
    formtemp: '',            // 表单类型,显示列、按钮、搜索条件
    modaltype: '',           // 模态框类型,控制模态框显示
    card: null,              // 编辑元素
    searchloading: false,    // 搜索条件加载中
    actionloading: false,    // 按钮加载中
    columnsloading: false,   // 显示列加载中
    tabloading: false,       // 标签页加载中
    menuloading: false,      // 菜单保存中
    menucloseloading: false, // 菜单关闭时,选择保存
    loading: false,          // 加载中,页面spin
@@ -68,6 +67,7 @@
    originMenu: null,        // 原始菜单
    originActions: null,     // 原始按钮信息,使用已有用户模板
    delActions: [],          // 删除按钮列表
    copyActions: [],         // 删除按钮列表
    funcLoading: false,      // 存储过程创建中
    showColumnName: false,   // 显示列字段名控制
    tabviews: [],            // 所有标签页
@@ -294,732 +294,75 @@
    }
  }
  /**
   * @description 元素添加或拖动时顺序变化
   */
  handleList = (type, list, card) => {
    const { config } = this.state
    if (type === 'tabs') { // 标签页调整顺序或添加元素
      if (list.length > config[card.groupId].length) {
        list = list.filter(item => !item.origin)
        this.setState({
          tabloading: true,
          config: {...config, [card.groupId]: list }
        }, () => {
          // 刷新对应的配置信息
          this.setState({
            tabloading: false
          })
          this.handleTab(card)
        })
      } else {
        this.setState({config: {...config, [card.groupId]: list}})
        this.handleTab(card)
      }
      this.setState({config: {...config, [card.groupId]: list}})
    } else {
      if (list.length > config[type].length) {
        list = list.filter(item => !item.origin)
        this.setState({
          [type + 'loading']: true,
          config: {...config, [type]: list }
        }, () => {
          // 刷新对应的配置信息
          this.setState({
            [type + 'loading']: false
          })
          if (type === 'search') {
            this.handleSearch(card)
          } else if (type === 'action') {
            this.handleAction(card)
          } else if (type === 'columns') {
            this.handleColumn(card)
          } else if (type === 'tabs') {
            this.handleTab(card)
          }
        })
      } else {
        this.setState({config: {...config, [type]: list}})
        if (type === 'search') {
          this.handleSearch(card)
        } else if (type === 'action') {
          this.handleAction(card)
        } else if (type === 'columns') {
          this.handleColumn(card)
        }
      }
      this.setState({
        config: {...config, [type]: list }
      })
    }
  }
  /**
   * @description 搜索条件编辑,获取搜索条件表单信息
   */
  handleSearch = (card) => {
    this.setState({
      visible: true,
      formtemp: 'search',
      modalTitle: '编辑-搜索条件',
      modaltype: 'search',
      card: card,
      formlist: [
        {
          type: 'text',
          key: 'label',
          label: this.state.dict['header.form.name'],
          initVal: card.label || '',
          required: true,
          readonly: false
        },
        {
          type: 'text',
          key: 'field',
          label: this.state.dict['header.form.field'],
          initVal: card.field || '',
          tooltip: '字段名可以使用逗号分隔,进行多字段综合搜索,注:综合搜索仅在文本类型时有效',
          tooltipClass: 'middle',
          required: true,
          readonly: false
        },
        {
          type: 'select',
          key: 'type',
          label: this.state.dict['header.form.type'],
          initVal: card.type,
          required: true,
          options: [{
            value: 'text',
            text: this.state.dict['header.form.text']
          }, {
            value: 'select',
            text: this.state.dict['header.form.select']
          }, {
            value: 'multiselect',
            text: this.state.dict['header.form.multiselect']
          }, {
            value: 'link',
            text: this.state.dict['header.form.link']
          }, {
            value: 'date',
            text: this.state.dict['header.form.dateday']
          }, {
            value: 'dateweek',
            text: this.state.dict['header.form.dateweek']
          }, {
            value: 'datemonth',
            text: this.state.dict['header.form.datemonth']
          }, {
            value: 'daterange',
            text: this.state.dict['header.form.daterange']
          }]
        },
        {
          type: 'text',
          key: 'initval',
          label: this.state.dict['header.form.initval'],
          initVal: card.initval,
          required: false
        },
        {
          type: 'radio',
          key: 'resourceType',
          label: this.state.dict['header.form.resourceType'],
          initVal: card.resourceType || '0',
          required: true,
          options: [{
            value: '0',
            text: this.state.dict['header.form.custom']
          }, {
            value: '1',
            text: this.state.dict['header.form.datasource']
          }]
        },
        {
          type: 'radio',
          key: 'setAll',
          label: this.state.dict['header.form.setAll'],
          initVal: card.setAll || 'false',
          options: [{
            value: 'true',
            text: this.state.dict['header.form.true']
          }, {
            value: 'false',
            text: this.state.dict['header.form.false']
          }]
        },
        {
          type: 'textarea',
          key: 'dataSource',
          label: this.state.dict['header.form.datasource'],
          initVal: card.dataSource || '',
          required: true,
          readonly: false
        },
        {
          type: 'options',
          key: 'options',
          label: '',
          initVal: card.options || [],
          required: true,
          readonly: false
        },
        {
          type: 'text',
          key: 'linkField',
          label: this.state.dict['header.form.linkField'],
          initVal: card.linkField || '',
          required: true,
          readonly: false
        },
        {
          type: 'text',
          key: 'valueField',
          label: this.state.dict['header.form.valueField'],
          initVal: card.valueField || '',
          required: true,
          readonly: false
        },
        {
          type: 'text',
          key: 'valueText',
          label: this.state.dict['header.form.valueText'],
          initVal: card.valueText || '',
          required: true,
          readonly: false
        },
        {
          type: 'text',
          key: 'orderBy',
          label: this.state.dict['header.form.orderBy'],
          initVal: card.orderBy || '',
          required: false,
          readonly: false
        },
        {
          type: 'select',
          key: 'orderType',
          label: this.state.dict['header.form.orderType'],
          initVal: card.orderType || 'asc',
          options: [{
            value: 'asc',
            text: this.state.dict['header.form.asc']
          }, {
            value: 'desc',
            text: this.state.dict['header.form.desc']
          }]
        },
        {
          type: 'select',
          key: 'match',
          label: this.state.dict['header.form.match'],
          initVal: card.match || 'like',
          required: true,
          options: [{
            value: 'like',
            text: 'like'
          }, {
            value: 'equal',
            text: 'equal'
          }, {
            value: 'greater',
            text: '>'
          }, {
            value: 'less',
            text: '<'
          }, {
            value: 'greaterequal',
            text: '>='
          }]
        },
        {
          type: 'select',
          key: 'display',
          label: this.state.dict['header.form.display'],
          initVal: card.display || 'dropdown',
          required: true,
          options: [{
            value: 'dropdown',
            text: this.state.dict['header.form.dropdown']
          }, {
            value: 'button',
            text: this.state.dict['header.form.button']
          }]
        }
      ]
      formlist: getSearchForm(card)
    })
  }
  /**
   * @description 按钮编辑,获取按钮表单信息
   */
  handleAction = (card, type) => {
    let ableField = this.props.permFuncField.join(', ')
    let functip = <div>
      <p style={{marginBottom: '5px'}}>{this.state.dict['header.modal.func.innerface'].replace('@ableField', ableField)}</p>
      <p>{this.state.dict['header.modal.func.outface']}</p>
    </div>
    this.setState({
      visible: true,
      formtemp: 'action',
      modalTitle: type === 'copy' ? '复制-按钮' : '编辑-按钮',
      modaltype: type === 'copy' ? 'actionCopy' : 'actionEdit',
      card: card,
      formlist: [
        {
          type: 'text',
          key: 'label',
          label: this.state.dict['header.form.name'],
          initVal: card.label,
          required: true,
          readonly: false
        },
        {
          type: 'select',
          key: 'OpenType',
          label: this.state.dict['header.form.openType'],
          initVal: card.OpenType,
          required: true,
          options: [{
            value: 'pop',
            text: this.state.dict['header.form.popform']
          }, {
            value: 'prompt',
            text: this.state.dict['header.form.prompt']
          }, {
            value: 'exec',
            text: this.state.dict['header.form.exec']
          }, {
            value: 'excelIn',
            text: this.state.dict['header.form.excelIn']
          }, {
            value: 'excelOut',
            text: this.state.dict['header.form.excelOut']
          }, {
            value: 'popview',
            text: this.state.dict['header.form.popview']
          }, {
            value: 'tab',
            text: this.state.dict['header.form.tab']
          }, {
            value: 'blank',
            text: this.state.dict['header.form.blank']
          }, {
            value: 'innerpage',
            text: this.state.dict['header.form.newpage.inner']
          }, {
            value: 'outerpage',
            text: this.state.dict['header.form.newpage.outer']
          }]
        }, {
          type: 'select',
          key: 'tabType',
          label: this.state.dict['header.form.tabType'],
          initVal: card.tabType || 'SubTable',
          required: true,
          options: [{
            value: 'SubTable',
            text: this.state.dict['header.menu.tab.subtable']
          }]
        },
        {
          type: 'select',
          key: 'linkTab',
          label: '关联标签',
          initVal: card.linkTab || '',
          required: false,
          options: []
        },
        {
          type: 'select',
          key: 'pageTemplate',
          label: this.state.dict['header.form.pageTemplate'],
          initVal: card.pageTemplate || '',
          required: true,
          options: []
        },
        {
          type: 'text',
          key: 'url',
          label: this.state.dict['header.form.newpage.url'],
          initVal: card.url || '',
          required: true
        },
        {
          type: 'radio',
          key: 'intertype',
          label: this.state.dict['header.form.intertype'],
          initVal: card.intertype || 'inner',
          required: true,
          options: [{
            value: 'inner',
            text: this.state.dict['header.form.interface.inner']
          }, {
            value: 'outer',
            text: this.state.dict['header.form.interface.outer']
          }]
        },
        {
          type: 'text',
          key: 'innerFunc',
          label: this.state.dict['header.form.innerFunc'],
          initVal: card.innerFunc || '',
          tooltip: <div>
            <p>内部接口: 可自定义数据处理函数,函数名称需以{ableField}等字符开始;未设置时会调用系统函数,使用系统函数需完善数据源及操作类型;</p>
            <p>外部接口: 可自定义数据处理函数,提交数据经过内部函数处理后,传入外部接口,未设置时,数据会直接传入外部接口。</p>
          </div>,
          fields: this.props.permFuncField,
          tooltipClass: 'middle',
          required: false,
          readonly: false
        },
        {
          type: 'radio',
          key: 'sysInterface',
          label: this.state.dict['header.form.sysInterface'],
          initVal: card.sysInterface || 'false',
          required: true,
          options: [{
            value: 'true',
            text: this.state.dict['header.form.true']
          }, {
            value: 'false',
            text: this.state.dict['header.form.false']
          }]
        },
        {
          type: 'text',
          key: 'outerFunc',
          label: this.state.dict['header.form.outerFunc'],
          initVal: card.outerFunc || '',
          required: false,
          readonly: false
        },
        {
          type: 'text',
          key: 'interface',
          label: this.state.dict['header.form.interface'],
          initVal: card.sysInterface === 'true' ? (window.GLOB.mainSystemApi || window.GLOB.subSystemApi) : (card.interface || ''),
          required: true,
          readonly: card.sysInterface === 'true'
        },
        {
          type: 'text',
          key: 'callbackFunc',
          label: this.state.dict['header.form.callbackFunc'],
          initVal: card.callbackFunc || '',
          required: false,
          readonly: false
        },
        {
          type: 'select',
          key: 'position',
          label: this.state.dict['header.form.position'],
          initVal: card.position || 'toolbar',
          required: true,
          options: [{
            value: 'toolbar',
            text: this.state.dict['header.form.toolbar']
          }, {
            value: 'grid',
            text: this.state.dict['header.form.grid']
          }]
        },
        {
          type: 'select',
          key: 'Ot',
          label: this.state.dict['header.form.isRequired'],
          initVal: card.Ot || 'requiredSgl',
          required: true,
          options: []
        },
        {
          type: 'select',
          key: 'tabTemplate',
          label: '标签模板',
          initVal: card.tabTemplate || 'formTab',
          required: true,
          options: [{
            value: 'formTab',
            text: '带标签表单'
          }]
        },
        {
          type: 'select',
          key: 'execSuccess',
          label: this.state.dict['header.form.execSuccess'],
          initVal: card.execSuccess || 'never',
          required: true,
          options: [{
            value: 'never',
            text: this.state.dict['header.form.refresh.never']
          }, {
            value: 'grid',
            text: this.state.dict['header.form.refresh.grid']
          }, {
            value: 'view',
            text: this.state.dict['header.form.refresh.view']
          }]
        },
        {
          type: 'select',
          key: 'execError',
          label: this.state.dict['header.form.execError'],
          initVal: card.execError || 'never',
          required: true,
          options: [{
            value: 'never',
            text: this.state.dict['header.form.refresh.never']
          }, {
            value: 'grid',
            text: this.state.dict['header.form.refresh.grid']
          }, {
            value: 'view',
            text: this.state.dict['header.form.refresh.view']
          }]
        },
        {
          type: 'select',
          key: 'popClose',
          label: this.state.dict['header.form.popClose'],
          initVal: card.popClose || 'never',
          required: true,
          options: [{
            value: 'never',
            text: this.state.dict['header.form.refresh.never']
          }, {
            value: 'grid',
            text: this.state.dict['header.form.refresh.grid']
          }, {
            value: 'view',
            text: this.state.dict['header.form.refresh.view']
          }]
        },
        {
          type: 'select',
          key: 'icon',
          label: this.state.dict['header.form.icon'],
          initVal: card.icon,
          required: false,
          options: []
        },
        {
          type: 'select',
          key: 'class',
          label: this.state.dict['header.form.class'],
          initVal: card.class,
          required: false,
          options: []
        },
        {
          type: 'text',
          key: 'sql',
          label: this.state.dict['header.form.datasource'],
          initVal: card.sql || this.state.config.setting.tableName || '',
          tooltip: this.state.dict['header.form.actionhelp.datasource'],
          required: false
        },
        {
          type: 'select',
          key: 'sqlType',
          label: this.state.dict['header.form.action.type'],
          initVal: card.sqlType || '',
          tooltip: this.state.dict['header.form.actionhelp.sqlType'],
          required: false,
          options: []
        }
      ]
      formlist: getActionForm(card, functip, this.state.config, this.props.permFuncField)
    })
  }
  handleColumn = (card) => {
    if (card.type !== 'colspan') {
      this.setState({
        visible: true,
        formtemp: 'columns',
        modalTitle: '编辑-显示列',
        modaltype: 'columns',
        card: card,
        formlist: [
          {
            type: 'text',
            key: 'label',
            label: this.state.dict['header.form.name'],
            initVal: card.label,
            required: true
          },
          {
            type: 'text',
            key: 'field',
            label: this.state.dict['header.form.field'],
            initVal: card.field,
            required: true,
            readonly: false
          },
          {
            type: 'select',
            key: 'type',
            label: this.state.dict['header.form.type'],
            initVal: card.type,
            required: true,
            options: [{
              value: 'text',
              text: this.state.dict['header.form.text']
            }, {
              value: 'number',
              text: this.state.dict['header.form.number']
            }, {
              value: 'picture',
              text: this.state.dict['header.form.picture']
            }, {
              value: 'textarea',
              text: this.state.dict['header.form.textarea']
            }]
          },
          {
            type: 'select',
            key: 'Align',
            label: this.state.dict['header.form.align'],
            initVal: card.Align,
            required: true,
            options: [{
              value: 'left',
              text: this.state.dict['header.form.alignLeft']
            }, {
              value: 'right',
              text: this.state.dict['header.form.alignRight']
            }, {
              value: 'center',
              text: this.state.dict['header.form.alignCenter']
            }]
          },
          {
            type: 'radio',
            key: 'Hide',
            label: this.state.dict['header.form.Hide'],
            initVal: card.Hide,
            required: true,
            options: [{
              value: 'true',
              text: this.state.dict['header.form.true']
            }, {
              value: 'false',
              text: this.state.dict['header.form.false']
            }]
          },
          {
            type: 'radio',
            key: 'IsSort',
            label: this.state.dict['header.form.IsSort'],
            initVal: card.IsSort,
            required: true,
            options: [{
              value: 'true',
              text: this.state.dict['header.form.true']
            }, {
              value: 'false',
              text: this.state.dict['header.form.false']
            }]
          },
          {
            type: 'number',
            key: 'Width',
            min: 1,
            max: 1000,
            decimal: 0,
            label: this.state.dict['header.form.columnWidth'],
            initVal: card.Width,
            required: true
          },
          {
            type: 'number',
            key: 'decimal',
            min: 0,
            max: 18,
            decimal: 0,
            label: this.state.dict['header.form.decimal'],
            initVal: card.decimal,
            required: false
          },
          {
            type: 'select',
            key: 'format',
            label: this.state.dict['header.form.format'],
            initVal: card.format || '',
            options: [{
              value: '',
              text: this.state.dict['header.form.empty']
            }, {
              value: 'thdSeparator',
              text: this.state.dict['header.form.thdSeparator']
            }],
            required: false
          },
          {
            type: 'text',
            key: 'prefix',
            label: this.state.dict['header.form.prefix'],
            initVal: card.prefix || '',
            required: false,
            readonly: false
          },
          {
            type: 'text',
            key: 'postfix',
            label: this.state.dict['header.form.postfix'],
            initVal: card.postfix || '',
            // tooltip: '后缀值设置为"\\n",表示换行',
            tooltipClass: 'middle',
            required: false,
            readonly: false
          },
          {
            type: 'select',
            key: 'match',
            label: this.state.dict['header.form.match'],
            initVal: card.match || '',
            options: [{
              value: '',
              text: this.state.dict['header.form.empty']
            }, {
              value: '>',
              text: '>'
            }, {
              value: '<',
              text: '<'
            }, {
              value: '>=',
              text: '>='
            }, {
              value: '<=',
              text: '<='
            }],
            required: false
          },
          {
            type: 'text',
            key: 'matchVal',
            min: -Infinity,
            max: Infinity,
            decimal: 0,
            label: this.state.dict['header.form.matchVal'],
            initVal: card.matchVal || '',
            required: false,
            readonly: false
          },
          {
            type: 'select',
            key: 'color',
            label: this.state.dict['header.form.color'],
            initVal: card.color || '',
            options: [{
              value: '',
              text: this.state.dict['header.form.empty']
            }, {
              value: 'red',
              text: '红色(内容)'
            }, {
              value: 'redbg',
              text: '红色(背景)'
            }, {
              value: 'orange',
              text: '橙色(内容)'
            }, {
              value: 'orangebg',
              text: '橙色(背景)'
            }, {
              value: 'green',
              text: '绿色(内容)'
            }, {
              value: 'greenbg',
              text: '绿色(背景)'
            }],
            required: false
          }
        ]
        formlist: getColumnForm(card)
      })
    } else {
      this.setState({
        visible: true,
        formtemp: 'columns',
        modalTitle: '编辑-合并列',
        modaltype: 'colspan',
        card: card
      })
    }
@@ -1067,9 +410,7 @@
    }
    this.setState({
      visible: true,
      formtemp: 'tabs',
      modalTitle: '编辑-标签页',
      modaltype: 'tabs',
      card: card,
      formlist: [
        {
@@ -1135,28 +476,53 @@
  handleGridBtn = () => {
    this.setState({
      visible: true,
      formtemp: 'gridbtn',
      modalTitle: '编辑-操作列',
      modaltype: 'gridbtn'
    })
  }
  /**
   * @description 搜索、按钮、显示列修改后提交保存
   * 1、搜索条件保存,当类型为下拉框且存在数据源时,将查询条件拼接为sql,并用base64转码
   * 2、按钮包括正常编辑和复制,复制时,按钮列末尾添加
   * 1、搜索条件保存
   * 2、按钮包括正常编辑和复制,复制时,末尾添加,如按钮为表单(保存至数据库),复制按钮id存于复制列表(点击不保存时删除)
   * 3、添加或编辑列,保存时,如按钮位置设置为表格,则修改操作列显示状态
   */
  handleSubmit = () => {
    const { menu } = this.props
    const { card } = this.state
    let _config = JSON.parse(JSON.stringify(this.state.config))
    const { config, card, modaltype } = this.state
    if (this.state.formtemp !== 'gridbtn') {
      this.formRef.handleConfirm().then(res => {
        let isupdate = false
    if (modaltype === 'search') {
      this.searchFormRef.handleConfirm().then(res => {
        let _search = config.search.map(item => {
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
        _search = _search.filter(item => !item.origin)
        if (res.type === 'action' && card.originCard && res.values.OpenType === 'pop') {
        this.setState({
          config: {...config, search: _search},
          modaltype: ''
        })
      })
    } else if (modaltype === 'actionEdit' || modaltype === 'actionCopy') {
      this.actionFormRef.handleConfirm().then(res => {
        let _action = config.action.map(item => {
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
        _action = _action.filter(item => !item.origin)
        if (modaltype === 'actionCopy') {
          _action.push(res)
        }
        // 复制按钮前后皆为表单时,复制表单配置信息,id存于复制列表
        if (res.OpenType === 'pop' && card.originCard && card.originCard.OpenType === 'pop') {
          Api.getSystemConfig({
            func: 'sPC_Get_LongParam',
            MenuID: card.originCard.uuid
@@ -1165,10 +531,10 @@
              let param = {
                func: 'sPC_ButtonParam_AddUpt',
                ParentID: menu.MenuID,
                MenuID: res.values.uuid,
                MenuID: res.uuid,
                MenuNo: menu.MenuNo,
                Template: 'Modal',
                MenuName: res.values.label,
                MenuName: res.label,
                PageParam: JSON.stringify({Template: 'Modal'}),
                LongParam: result.LongParam
              }
@@ -1179,105 +545,129 @@
                    message: response.message,
                    duration: 10
                  })
                } else {
                  this.setState({
                    copyActions: [...this.state.copyActions, res.uuid]
                  })
                }
              })
            }
          })
        }
        if (res.type !== 'tabs') {
          _config[res.type] = _config[res.type].map(item => {
            if (item.uuid === res.values.uuid) {
              isupdate = true
              return res.values
            } else {
              return item
            }
          })
          _config[res.type] = _config[res.type].filter(item => !item.origin)
          if (!isupdate) { // 操作不是修改,添加元素至列表
            _config[res.type].push(res.values)
          }
        } else { // 标签页的添加与修改
          _config[res.values.groupId] = _config[res.values.groupId].map(item => {
            if (item.uuid === res.values.uuid) {
              isupdate = true
              return res.values
            } else {
              return item
            }
          })
          _config[res.values.groupId] = _config[res.values.groupId].filter(item => !item.origin)
          if (!isupdate) { // 操作不是修改,添加元素至列表
            _config[res.values.groupId].push(res.values)
          }
        }
        if (res.type === 'action') {
          let gridbtn = _config.action.filter(act => act.position === 'grid')
          let _display = false
          if (gridbtn.length > 0) {
            _display = true
          }
          if (_config.gridBtn) {
            _config.gridBtn.display = _display
          } else {
            _config.gridBtn = {
              display: _display,
              Align: 'center',
              IsSort: 'false',
              uuid: Utils.getuuid(),
              label: this.state.dict['header.form.column.action'],
              type: 'action',
              style: 'button',
              show: 'horizontal',
              Width: 120
            }
        // 判断是否存在操作列
        let _hasGridbtn = _action.filter(act => act.position === 'grid').length > 0
        let _gridBtn = {...config.gridBtn}
        if (_gridBtn) {
          _gridBtn.display = _hasGridbtn
        } else {
          _gridBtn = {
            display: _hasGridbtn,
            Align: 'center',
            IsSort: 'false',
            uuid: Utils.getuuid(),
            label: this.state.dict['header.form.column.action'],
            type: 'action',
            style: 'button',
            show: 'horizontal',
            Width: 120
          }
        }
        this.setState({
          config: _config,
          searchloading: true,
          actionloading: true,
          columnsloading: true,
          tabloading: true,
          visible: false
        }, () => {
          this.setState({
            searchloading: false,
            actionloading: false,
            columnsloading: false,
            tabloading: false
          })
          config: {...config, action: _action, gridBtn: _gridBtn},
          modaltype: ''
        })
      })
    } else {
      this.formRef.handleConfirm().then(res => {
        _config.gridBtn = res
    } else if (modaltype === 'columns' || modaltype === 'colspan') {
      this.columnFormRef.handleConfirm().then(res => {
        let _columns = config.columns.map(item => {
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
        _columns = _columns.filter(item => !item.origin)
        this.setState({
          config: _config,
          visible: false
          config: {...config, columns: _columns},
          modaltype: ''
        })
      })
    } else if (modaltype === 'gridbtn') {
      this.gridBtnFormRef.handleConfirm().then(res => {
        this.setState({
          config: {...config, gridBtn: res},
          modaltype: ''
        })
      })
    } else if (modaltype === 'tabs') {
      this.tabsFormRef.handleConfirm().then(res => {
        let isupdate = false
        let _tabgroup = config[res.values.groupId].map(item => {
          if (item.uuid === res.values.uuid) {
            isupdate = true
            return res.values
          } else {
            return item
          }
        })
        _tabgroup = _tabgroup.filter(item => !item.origin)
        if (!isupdate) { // 操作不是修改,添加元素至列表
          _tabgroup.push(res.values)
        }
        this.setState({
          config: {...config, [res.values.groupId]: _tabgroup},
          modaltype: ''
        })
      })
    }
  }
  editModalCancel = () => {
    const { config, card, modaltype } = this.state
    if (card.focus) {
      let _config = null
      if (modaltype === 'search') {
        let _search = config.search.filter(item => item.uuid !== card.uuid)
        _config = {...config, search: _search}
      } else if (modaltype === 'actionEdit') {
        let _action = config.action.filter(item => item.uuid !== card.uuid)
        _config = {...config, action: _action}
      } else if (modaltype === 'columns' || modaltype === 'colspan') {
        let _columns = config.columns.filter(item => item.uuid !== card.uuid)
        _config = {...config, columns: _columns}
      } else {
        _config = config
      }
      this.setState({
        card: null,
        config: _config,
        modaltype: ''
      })
    } else {
      this.setState({
        card: null,
        modaltype: ''
      })
    }
  }
  /**
   * @description 创建按钮存储过程
   * @description 按钮-创建存储过程
   */
  creatFunc = () => {
    const { menu } = this.props
    let _config = JSON.parse(JSON.stringify(this.state.config))
    this.formRef.handleConfirm().then(res => {
      let btn = res.values  // 按钮信息
    this.actionFormRef.handleConfirm().then(res => {
      let btn = res         // 按钮信息
      let newLText = ''     // 创建存储过程sql
      let DelText = ''      // 删除存储过程sql
      let isExit = false    // 存储过程是否存在
@@ -1359,6 +749,7 @@
      }).then(res => {
        // 获取云端及本地,是否已存在该存储过程的信息
        if (res === false) return res
        if (res !== false) return false
        let sysDefer = new Promise(resolve => {
          Api.getSystemConfig({
@@ -1568,12 +959,7 @@
        this.setState({
          config: _config,
          actionloading: true,
          funcLoading: false
        }, () => {
          this.setState({
            actionloading: false
          })
        })
      })
    })
@@ -1827,20 +1213,9 @@
          })
        }
        let refreshtype = element.type + 'loading'
        if (/^tab/.test(refreshtype)) {
          refreshtype = 'tabloading'
        }
        _this.setState({
          config: _config,
          delActions: [..._this.state.delActions, element.card.uuid],
          [refreshtype]: true
        }, () => {
          _this.setState({
            [refreshtype]: false
          })
          delActions: [..._this.state.delActions, element.card.uuid]
        })
      },
      onCancel() {}
@@ -1877,11 +1252,6 @@
      profileVisible: false,
      config: config,
      card: '',
      actionloading: true
    }, () => {
      this.setState({
        actionloading: false
      })
    })
  }
@@ -2008,16 +1378,7 @@
              MenuName: res.menuName,
              MenuNo: res.menuNo,
              ParentID: res.parentId
            },
            searchloading: true,
            actionloading: true,
            columnsloading: true
          }, () => {
            this.setState({
              searchloading: false,
              actionloading: false,
              columnsloading: false
            })
            }
          })
          this.props.reloadmenu()
@@ -2111,6 +1472,9 @@
      if (response === false || response === 'copy') return response
      if (response.status) {
        this.setState({
          copyActions: []
        })
        return 'copy'
      } else {
        notification.warning({
@@ -2545,13 +1909,6 @@
      this.setState({
        config: {...config, setting: res},
        settingVisible: false,
        columnsloading: true,
        tabloading: true
      }, () => {
        this.setState({
          columnsloading: false,
          tabloading: false
        })
      })
    })
  }
@@ -2721,12 +2078,7 @@
        _config[newgroup] = []
        _this.setState({
          config: _config,
          tabloading: true
        }, () => {
          _this.setState({
            tabloading: false
          })
          config: _config
        })
      },
      onCancel() {}
@@ -2747,19 +2099,26 @@
        delete _config[groupId]
        _this.setState({
          config: _config,
          tabloading: true
        }, () => {
          _this.setState({
            tabloading: false
          })
          config: _config
        })
      },
      onCancel() {}
    })
  }
  notsave = () => {
    this.state.copyActions.forEach(item => {
      let _param = {
        func: 'sPC_MainMenu_Del',
        MenuID: item
      }
      Api.getSystemConfig(_param)
    })
    this.props.handleConfig('')
  }
  render () {
    const { modaltype } = this.state
    const configAction = this.state.config.action.filter(_action =>
      !_action.origin && (_action.OpenType === 'pop' || _action.OpenType === 'popview' || _action.OpenType === 'blank' || _action.OpenType === 'tab')
    )
@@ -2911,33 +2270,29 @@
                <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《搜索》中,选择对应搜索框拖至此处添加;或点击按钮《添加搜索条件》批量添加,选择批量添加时,需提前选择使用表。">
                  <Icon type="question-circle" />
                </Tooltip>
                {!this.state.searchloading ?
                  <DragElement
                    type="search"
                    list={this.state.config.search}
                    handleList={this.handleList}
                    handleMenu={this.handleSearch}
                    deleteMenu={this.deleteElement}
                    placeholder={this.state.dict['header.form.search.placeholder']}
                  /> : null
                }
                <DragElement
                  type="search"
                  list={this.state.config.search}
                  handleList={this.handleList}
                  handleMenu={this.handleSearch}
                  deleteMenu={this.deleteElement}
                  placeholder={this.state.dict['header.form.search.placeholder']}
                />
              </div>
              <div className="action-list">
                <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《按钮》中,选择对应类型的按钮拖至此处添加,如选择按钮类型为表单、新标签页等含有配置页面的按钮,可在左侧工具栏-按钮-可配置按钮处,点击按钮完成相关配置。注:当设置按钮显示位置为表格时,显示列会增加操作列。">
                  <Icon type="question-circle" />
                </Tooltip>
                {!this.state.actionloading ?
                  <DragElement
                    type="action"
                    list={this.state.config.action}
                    handleList={this.handleList}
                    handleMenu={this.handleAction}
                    copyElement={(val) => this.handleAction(val, 'copy')}
                    deleteMenu={this.deleteElement}
                    profileMenu={this.profileAction}
                    placeholder={this.state.dict['header.form.action.placeholder']}
                  /> : null
                }
                <DragElement
                  type="action"
                  list={this.state.config.action}
                  handleList={this.handleList}
                  handleMenu={this.handleAction}
                  copyElement={(val) => this.handleAction(val, 'copy')}
                  deleteMenu={this.deleteElement}
                  profileMenu={this.profileAction}
                  placeholder={this.state.dict['header.form.action.placeholder']}
                />
              </div>
              {/* 显示列 */}
              <div className="column-list">
@@ -2945,23 +2300,21 @@
                  <Icon type="question-circle" />
                </Tooltip>
                <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showColumnName} onChange={this.onColumnNameChange} />
                {!this.state.columnsloading ?
                  <DragElement
                    type="columns"
                    list={this.state.config.columns}
                    setting={this.state.config.setting}
                    gridBtn={this.state.config.gridBtn}
                    handleList={this.handleList}
                    handleMenu={this.handleColumn}
                    deleteMenu={this.deleteElement}
                    handleGridBtn={this.handleGridBtn}
                    showfield={this.state.showColumnName}
                    placeholder={this.state.dict['header.form.column.placeholder']}
                  /> : null
                }
                <DragElement
                  type="columns"
                  list={this.state.config.columns}
                  setting={this.state.config.setting}
                  gridBtn={this.state.config.gridBtn}
                  handleList={this.handleList}
                  handleMenu={this.handleColumn}
                  deleteMenu={this.deleteElement}
                  handleGridBtn={this.handleGridBtn}
                  showfield={this.state.showColumnName}
                  placeholder={this.state.dict['header.form.column.placeholder']}
                />
              </div>
              {/* 标签组 */}
              {!this.state.tabloading && this.state.config.tabgroups.map((groupId, index) => {
              {this.state.config.tabgroups.map((groupId, index) => {
                return (
                  <div key={index} className="tab-list">
                    {index === 0 ? <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《标签页》中,选择对应类型的标签页拖至此处添加。">
@@ -2983,70 +2336,107 @@
            </Card>
          </div>
        </DndProvider>
        {/* 编辑搜索条件、按钮、显示列 */}
        {/* 编辑搜索条件 */}
        <Modal
          title={this.state.modalTitle}
          visible={this.state.visible}
          title={this.state.dict['header.modal.search.edit']}
          visible={modaltype === 'search'}
          width={700}
          onCancel={() => { this.setState({ visible: false }) }}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <SearchForm
            dict={this.state.dict}
            card={this.state.card}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.searchFormRef = inst}
          />
        </Modal>
        {/* 编辑按钮:复制、编辑 */}
        <Modal
          title={modaltype === 'actionEdit' ? this.state.dict['header.modal.action.edit'] : this.state.dict['header.modal.action.copy']}
          visible={modaltype === 'actionEdit' || modaltype === 'actionCopy'}
          width={700}
          onCancel={this.editModalCancel}
          footer={[
            this.state.formtemp === 'action' ?
            <Button key="delete" className="mk-btn mk-purple" onClick={this.creatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button> : null,
            <Button key="cancel" onClick={() => { this.setState({ visible: false }) }}>{this.state.dict['header.cancel']}</Button>,
            modaltype === 'actionEdit' ? <Button key="delete" className="mk-btn mk-purple" onClick={this.creatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button> : null,
            <Button key="cancel" onClick={this.editModalCancel}>{this.state.dict['header.cancel']}</Button>,
            <Button key="confirm" type="primary" onClick={this.handleSubmit}>{this.state.dict['header.confirm']}</Button>
          ]}
          destroyOnClose
        >
          {this.state.formtemp === 'search' ?
            <SearchForm
              dict={this.state.dict}
              formlist={this.state.formlist}
              card={this.state.card}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'action' ?
            <ActionForm
              dict={this.state.dict}
              card={this.state.card}
              tabs={this.state.tabviews}
              formlist={this.state.formlist}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'columns' && this.state.card.type !== 'colspan' ?
            <ColumnForm
              dict={this.state.dict}
              card={this.state.card}
              formlist={this.state.formlist}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'columns' && this.state.card.type === 'colspan' ?
            <ColspanForm
              dict={this.state.dict}
              card={this.state.card}
              columns={this.state.config.columns}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'gridbtn' ?
            <GridBtnForm
              dict={this.state.dict}
              card={this.state.config.gridBtn}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'tabs' ?
            <TabForm
              type="tabs"
              tabs={this.state.tabviews}
              dict={this.state.dict}
              card={this.state.card}
              formlist={this.state.formlist}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          <ActionForm
            dict={this.state.dict}
            card={this.state.card}
            tabs={this.state.tabviews}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.actionFormRef = inst}
          />
        </Modal>
        {/* 显示列编辑 */}
        <Modal
          title={this.state.dict['header.modal.column.edit']}
          visible={modaltype === 'columns'}
          width={700}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <ColumnForm
            dict={this.state.dict}
            card={this.state.card}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.columnFormRef = inst}
          />
        </Modal>
        {/* 合并列编辑 */}
        <Modal
          title={this.state.dict['header.modal.colspan.edit']}
          visible={modaltype === 'colspan'}
          width={700}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <ColspanForm
            dict={this.state.dict}
            card={this.state.card}
            columns={this.state.config.columns}
            wrappedComponentRef={(inst) => this.columnFormRef = inst}
          />
        </Modal>
        {/* 合并列编辑 */}
        <Modal
          title={this.state.dict['header.modal.gridbtn.edit']}
          visible={modaltype === 'gridbtn'}
          width={700}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <GridBtnForm
            dict={this.state.dict}
            card={this.state.config.gridBtn}
            wrappedComponentRef={(inst) => this.gridBtnFormRef = inst}
          />
        </Modal>
        {/* 标签编辑 */}
        <Modal
          title={this.state.dict['header.modal.tabs.edit']}
          visible={modaltype === 'tabs'}
          width={700}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <TabForm
            type="tabs"
            tabs={this.state.tabviews}
            dict={this.state.dict}
            card={this.state.card}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.tabsFormRef = inst}
          />
        </Modal>
        {/* 根据字段名添加显示列及搜索条件 */}
        <Modal
@@ -3120,7 +2510,7 @@
          onCancel={() => { this.setState({closeVisible: false}) }}
          footer={[
            <Button key="save" className="mk-btn mk-green" loading={this.state.menucloseloading} onClick={this.submitConfig}>{this.state.dict['header.save']}</Button>,
            <Button key="confirm" className="mk-btn mk-yellow" onClick={() => {this.props.handleConfig('')}}>{this.state.dict['header.notsave']}</Button>,
            <Button key="notsave" className="mk-btn mk-yellow" onClick={this.notsave}>{this.state.dict['header.notsave']}</Button>,
            <Button key="cancel" onClick={() => { this.setState({closeVisible: false}) }}>{this.state.dict['header.cancel']}</Button>
          ]}
          destroyOnClose
src/templates/comtableconfig/tabdragelement/index.jsx
@@ -1,6 +1,7 @@
import React, { useState } from 'react'
import { useDrop } from 'react-dnd'
import update from 'immutability-helper'
import { is, fromJS } from 'immutable'
import { Tabs, Icon } from 'antd'
import Utils from '@/utils/utils.js'
import Card from './card'
@@ -13,12 +14,13 @@
  const [cards, setCards] = useState(list)
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
    if (!card) return
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    setCards(_cards)
    handleList(type, _cards)
  }
  if (!is(fromJS(cards), fromJS(list))) {
    setCards(list)
  }
  const findCard = id => {
@@ -58,15 +60,10 @@
      const { index: overIndex } = findCard(`${targetId}`)
      let targetIndex = overIndex
      // if (!target) {
      targetIndex++
      // }
      // if (targetIndex < 0) {
      //   targetIndex = 0
      // }
      const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
      setCards(_cards)
      handleList(type, _cards, newcard)
      target = null
    }
src/templates/formtabconfig/index.jsx
@@ -2624,7 +2624,6 @@
            dict={this.state.dict}
            menu={this.props.menu}
            config={this.state.config}
            columns={this.state.config.columns}
            usefulFields={this.props.permFuncField}
            wrappedComponentRef={(inst) => this.settingRef = inst}
          />
src/templates/formtabconfig/settingform/index.jsx
@@ -10,24 +10,44 @@
  static propTpyes = {
    dict: PropTypes.object, // 字典项
    menu: PropTypes.object,
    data: PropTypes.object,
    config: PropTypes.object,
    columns: PropTypes.array,
    usefulFields: PropTypes.array
  }
  state = {
    interType: this.props.data.interType || 'inner',
    columns: this.props.columns.filter(item => item.field && item.type !== 'colspan'),
    interType: null,
    columns: null,
    currentTabs: null,
    selectTabs: []
  }
  UNSAFE_componentWillMount() {
    const { config, data } = this.props
    const { config, menu } = this.props
    console.log(menu)
    console.log(config)
    let _tabs = []
    let _select = []
    let _tabMap = new Map()
    let _columns = []
    let _interType = 'inner'
    let _setting = config.setting
    try {
      _columns = menu.LongParam.columns.filter(item => item.field && item.type !== 'colspan')
      // config.groups.forEach(group => {
      //   if (group.isDefault) {
      //     _columns.push()
      //   }
      //   group.sublist
      // })
      _interType = menu.LongParam.setting.interType
    } catch {
      notification.warning({
        top: 92,
        message: '菜单信息错误!',
        duration: 10
      })
    }
    config.tabgroups.forEach(groupname => {
      config[groupname].forEach(tab => {
@@ -38,7 +58,7 @@
      })
    })
    data.subtabs && data.subtabs.forEach(tabId => {
    _setting.subtabs && _setting.subtabs.forEach(tabId => {
      if (_tabMap.has(tabId)) {
        _select.push(tabId)
      }
@@ -46,7 +66,10 @@
    this.setState({
      currentTabs: _tabs,
      selectTabs: _select
      selectTabs: _select,
      columns: _columns,
      interType: _interType,
      setting: _setting
    })
  }
@@ -81,16 +104,15 @@
  }
  selectChange = (val) => {
    // let _order = this.props.form.getFieldValue('order')
    this.props.form.setFieldsValue({
      order: `${val} desc`
    })
  }
  render() {
    const { data, dict, menu, usefulFields } = this.props
    const { dict, menu, usefulFields } = this.props
    const { getFieldDecorator } = this.props.form
    const { interType, columns, selectTabs } = this.state
    const { interType, columns, selectTabs, setting } = this.state
    const formItemLayout = {
      labelCol: {
@@ -103,7 +125,7 @@
      }
    }
    let primaryKey = data.primaryKey
    let primaryKey = setting.primaryKey
    if (primaryKey) {
      let field = columns.filter(column => column.field === primaryKey)
      if (field.length !== 1) {
@@ -123,7 +145,7 @@
          <Col span={12}>
            <Form.Item label="表名">
              {getFieldDecorator('tableName', {
                initialValue: data.tableName,
                initialValue: setting.tableName,
                rules: [
                  {
                    required: true,
@@ -138,24 +160,9 @@
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="表格属性">
              {getFieldDecorator('tableType', {
                initialValue: data.tableType
              })(
                <Select
                  getPopupContainer={() => document.getElementById('commontable-setting-form')}
                >
                  <Select.Option value="">不可选</Select.Option>
                  <Select.Option value="radio">单选</Select.Option>
                  <Select.Option value="checkbox">多选</Select.Option>
                </Select>
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label={dict['header.form.intertype']}>
              {getFieldDecorator('interType', {
                initialValue: data.interType || 'inner'
                initialValue: setting.interType || 'inner'
              })(
                <Radio.Group onChange={this.onChange}>
                  <Radio value="inner">{dict['header.form.interface.inner']}</Radio>
@@ -167,7 +174,7 @@
          {interType === 'outer' ? <Col span={12}>
            <Form.Item label={dict['header.form.interface']}>
              {getFieldDecorator('interface', {
                initialValue: data.interface || '',
                initialValue: setting.interface || '',
                rules: [
                  {
                    required: true,
@@ -189,7 +196,7 @@
              </Tooltip>
            }>
              {getFieldDecorator('innerFunc', {
                initialValue: data.innerFunc || '',
                initialValue: setting.innerFunc || '',
                rules: [
                  {
                    pattern: _patten,
@@ -210,26 +217,14 @@
              </Tooltip>
            } className="textarea">
              {getFieldDecorator('dataresource', {
                initialValue: data.dataresource
                initialValue: setting.dataresource
              })(<TextArea rows={4} />)}
            </Form.Item>
          </Col> : null}
          <Col span={12}>
            <Form.Item label="固定按钮">
              {getFieldDecorator('actionfixed', {
                initialValue: data.actionfixed ? 'true' : 'false'
              })(
                <Select>
                  <Select.Option value="true">是</Select.Option>
                  <Select.Option value="false">否</Select.Option>
                </Select>
              )}
            </Form.Item>
          </Col>
          {interType === 'outer' ? <Col span={12}>
            <Form.Item label={dict['header.form.outerFunc']}>
              {getFieldDecorator('outerFunc', {
                initialValue: data.outerFunc || '',
                initialValue: setting.outerFunc || '',
                rules: [
                  {
                    pattern: formRule.func.pattern,
@@ -242,18 +237,7 @@
              })(<Input placeholder="" autoComplete="off" />)}
            </Form.Item>
          </Col> : null}
          <Col span={12}>
            <Form.Item label="固定列">
              {getFieldDecorator('columnfixed', {
                initialValue: data.columnfixed ? 'true' : 'false'
              })(
                <Select>
                  <Select.Option value="true">是</Select.Option>
                  <Select.Option value="false">否</Select.Option>
                </Select>
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="主键">
              {getFieldDecorator('primaryKey', {
@@ -270,35 +254,6 @@
                  {columns.map((option, index) =>
                    <Select.Option id={option.uuid} title={option.label} key={index} value={option.field}>{option.label}</Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="默认排序">
              {getFieldDecorator('order', {
                initialValue: data.order || (primaryKey ? primaryKey + ' desc' : ''),
                rules: [
                  {
                    required: true,
                    message: dict['form.required.input'] + '默认排序字段!'
                  },
                  {
                    max: formRule.input.max,
                    message: formRule.input.message
                  }
                ]
              })(<Input placeholder="ID asc, UID desc" autoComplete="off" />)}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="初始化">
              {getFieldDecorator('onload', {
                initialValue: data.onload || 'true'
              })(
                <Select>
                  <Select.Option value="true">加载数据</Select.Option>
                  <Select.Option value="false">不加载数据</Select.Option>
                </Select>
              )}
            </Form.Item>
src/templates/tableshare/dragelement/index.jsx
@@ -1,5 +1,6 @@
import React, { useState } from 'react'
import { useDrop } from 'react-dnd'
import { is, fromJS } from 'immutable'
import update from 'immutability-helper'
import { Col, Icon } from 'antd'
import Utils from '@/utils/utils.js'
@@ -14,10 +15,12 @@
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    setCards(_cards)
    handleList(type, _cards)
  }
  if (!is(fromJS(cards), fromJS(list))) {
    setCards(list)
  }
  const findCard = id => {
    const card = cards.filter(c => `${c.uuid}` === id)[0]
    return {
@@ -47,6 +50,7 @@
    copycard.uuid = Utils.getuuid()
    copycard.origin = false
    copycard.label = copycard.label + '(copy)'
    copycard.focus = true
    copycard.originCard = card
@@ -135,7 +139,7 @@
      targetIndex++
      const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
      setCards(_cards)
      handleList(type, _cards, newcard)
      target = null
    }
src/templates/tableshare/formconfig.js
New file
@@ -0,0 +1,669 @@
import zhCN from '@/locales/zh-CN/comtable.js'
import enUS from '@/locales/en-US/comtable.js'
const Formdict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
/**
 * @description 获取搜索条件表单配置信息
 * @param {*} card
 */
export function getSearchForm (card) {
  return [
    {
      type: 'text',
      key: 'label',
      label: Formdict['header.form.name'],
      initVal: card.label || '',
      required: true,
      readonly: false
    },
    {
      type: 'text',
      key: 'field',
      label: Formdict['header.form.field'],
      initVal: card.field || '',
      tooltip: '字段名可以使用逗号分隔,进行多字段综合搜索,注:综合搜索仅在文本类型时有效',
      tooltipClass: 'middle',
      required: true,
      readonly: false
    },
    {
      type: 'select',
      key: 'type',
      label: Formdict['header.form.type'],
      initVal: card.type,
      required: true,
      options: [{
        value: 'text',
        text: Formdict['header.form.text']
      }, {
        value: 'select',
        text: Formdict['header.form.select']
      }, {
        value: 'multiselect',
        text: Formdict['header.form.multiselect']
      }, {
        value: 'link',
        text: Formdict['header.form.link']
      }, {
        value: 'date',
        text: Formdict['header.form.dateday']
      }, {
        value: 'dateweek',
        text: Formdict['header.form.dateweek']
      }, {
        value: 'datemonth',
        text: Formdict['header.form.datemonth']
      }, {
        value: 'daterange',
        text: Formdict['header.form.daterange']
      }]
    },
    {
      type: 'text',
      key: 'initval',
      label: Formdict['header.form.initval'],
      initVal: card.initval,
      required: false
    },
    {
      type: 'radio',
      key: 'resourceType',
      label: Formdict['header.form.resourceType'],
      initVal: card.resourceType || '0',
      required: true,
      options: [{
        value: '0',
        text: Formdict['header.form.custom']
      }, {
        value: '1',
        text: Formdict['header.form.datasource']
      }]
    },
    {
      type: 'radio',
      key: 'setAll',
      label: Formdict['header.form.setAll'],
      initVal: card.setAll || 'false',
      options: [{
        value: 'true',
        text: Formdict['header.form.true']
      }, {
        value: 'false',
        text: Formdict['header.form.false']
      }]
    },
    {
      type: 'textarea',
      key: 'dataSource',
      label: Formdict['header.form.datasource'],
      initVal: card.dataSource || '',
      required: true,
      readonly: false
    },
    {
      type: 'options',
      key: 'options',
      label: '',
      initVal: card.options || [],
      required: true,
      readonly: false
    },
    {
      type: 'text',
      key: 'linkField',
      label: Formdict['header.form.linkField'],
      initVal: card.linkField || '',
      required: true,
      readonly: false
    },
    {
      type: 'text',
      key: 'valueField',
      label: Formdict['header.form.valueField'],
      initVal: card.valueField || '',
      required: true,
      readonly: false
    },
    {
      type: 'text',
      key: 'valueText',
      label: Formdict['header.form.valueText'],
      initVal: card.valueText || '',
      required: true,
      readonly: false
    },
    {
      type: 'text',
      key: 'orderBy',
      label: Formdict['header.form.orderBy'],
      initVal: card.orderBy || '',
      required: false,
      readonly: false
    },
    {
      type: 'select',
      key: 'orderType',
      label: Formdict['header.form.orderType'],
      initVal: card.orderType || 'asc',
      options: [{
        value: 'asc',
        text: Formdict['header.form.asc']
      }, {
        value: 'desc',
        text: Formdict['header.form.desc']
      }]
    },
    {
      type: 'select',
      key: 'match',
      label: Formdict['header.form.match'],
      initVal: card.match || 'like',
      required: true,
      options: [{
        value: 'like',
        text: 'like'
      }, {
        value: 'equal',
        text: 'equal'
      }, {
        value: 'greater',
        text: '>'
      }, {
        value: 'less',
        text: '<'
      }, {
        value: 'greaterequal',
        text: '>='
      }]
    },
    {
      type: 'select',
      key: 'display',
      label: Formdict['header.form.display'],
      initVal: card.display || 'dropdown',
      required: true,
      options: [{
        value: 'dropdown',
        text: Formdict['header.form.dropdown']
      }, {
        value: 'button',
        text: Formdict['header.form.button']
      }]
    }
  ]
}
/**
 * @description 获取按钮表单配置信息
 * @param {*} card           编辑按钮
 * @param {*} functip        生成存储过程提示
 * @param {*} config         页面配置
 * @param {*} permFuncField  存储过程可用的开始字段
 */
export function getActionForm (card, functip, config, permFuncField) {
  return [
    {
      type: 'text',
      key: 'label',
      label: Formdict['header.form.name'],
      initVal: card.label,
      required: true,
      readonly: false
    },
    {
      type: 'select',
      key: 'OpenType',
      label: Formdict['header.form.openType'],
      initVal: card.OpenType,
      required: true,
      options: [{
        value: 'pop',
        text: Formdict['header.form.popform']
      }, {
        value: 'prompt',
        text: Formdict['header.form.prompt']
      }, {
        value: 'exec',
        text: Formdict['header.form.exec']
      }, {
        value: 'excelIn',
        text: Formdict['header.form.excelIn']
      }, {
        value: 'excelOut',
        text: Formdict['header.form.excelOut']
      }, {
        value: 'popview',
        text: Formdict['header.form.popview']
      }, {
        value: 'tab',
        text: Formdict['header.form.tab']
      }, {
        value: 'blank',
        text: Formdict['header.form.blank']
      }, {
        value: 'innerpage',
        text: Formdict['header.form.newpage.inner']
      }, {
        value: 'outerpage',
        text: Formdict['header.form.newpage.outer']
      }]
    }, {
      type: 'select',
      key: 'tabType',
      label: Formdict['header.form.tabType'],
      initVal: card.tabType || 'SubTable',
      required: true,
      options: [{
        value: 'SubTable',
        text: Formdict['header.menu.tab.subtable']
      }]
    },
    {
      type: 'select',
      key: 'linkTab',
      label: '关联标签',
      initVal: card.linkTab || '',
      required: false,
      options: []
    },
    {
      type: 'select',
      key: 'pageTemplate',
      label: Formdict['header.form.pageTemplate'],
      initVal: card.pageTemplate || '',
      required: true,
      options: []
    },
    {
      type: 'text',
      key: 'url',
      label: Formdict['header.form.newpage.url'],
      initVal: card.url || '',
      required: true
    },
    {
      type: 'radio',
      key: 'intertype',
      label: Formdict['header.form.intertype'],
      initVal: card.intertype || 'inner',
      required: true,
      options: [{
        value: 'inner',
        text: Formdict['header.form.interface.inner']
      }, {
        value: 'outer',
        text: Formdict['header.form.interface.outer']
      }]
    },
    {
      type: 'text',
      key: 'innerFunc',
      label: Formdict['header.form.innerFunc'],
      initVal: card.innerFunc || '',
      tooltip: functip,
      fields: permFuncField,
      tooltipClass: 'middle',
      required: false,
      readonly: false
    },
    {
      type: 'radio',
      key: 'sysInterface',
      label: Formdict['header.form.sysInterface'],
      initVal: card.sysInterface || 'false',
      required: true,
      options: [{
        value: 'true',
        text: Formdict['header.form.true']
      }, {
        value: 'false',
        text: Formdict['header.form.false']
      }]
    },
    {
      type: 'text',
      key: 'outerFunc',
      label: Formdict['header.form.outerFunc'],
      initVal: card.outerFunc || '',
      required: false,
      readonly: false
    },
    {
      type: 'text',
      key: 'interface',
      label: Formdict['header.form.interface'],
      initVal: card.sysInterface === 'true' ? (window.GLOB.mainSystemApi || window.GLOB.subSystemApi) : (card.interface || ''),
      required: true,
      readonly: card.sysInterface === 'true'
    },
    {
      type: 'text',
      key: 'callbackFunc',
      label: Formdict['header.form.callbackFunc'],
      initVal: card.callbackFunc || '',
      required: false,
      readonly: false
    },
    {
      type: 'select',
      key: 'position',
      label: Formdict['header.form.position'],
      initVal: card.position || 'toolbar',
      required: true,
      options: [{
        value: 'toolbar',
        text: Formdict['header.form.toolbar']
      }, {
        value: 'grid',
        text: Formdict['header.form.grid']
      }]
    },
    {
      type: 'select',
      key: 'Ot',
      label: Formdict['header.form.isRequired'],
      initVal: card.Ot || 'requiredSgl',
      required: true,
      options: []
    },
    {
      type: 'select',
      key: 'tabTemplate',
      label: '标签模板',
      initVal: card.tabTemplate || 'formTab',
      required: true,
      options: [{
        value: 'formTab',
        text: '带标签表单'
      }]
    },
    {
      type: 'select',
      key: 'execSuccess',
      label: Formdict['header.form.execSuccess'],
      initVal: card.execSuccess || 'never',
      required: true,
      options: [{
        value: 'never',
        text: Formdict['header.form.refresh.never']
      }, {
        value: 'grid',
        text: Formdict['header.form.refresh.grid']
      }, {
        value: 'view',
        text: Formdict['header.form.refresh.view']
      }]
    },
    {
      type: 'select',
      key: 'execError',
      label: Formdict['header.form.execError'],
      initVal: card.execError || 'never',
      required: true,
      options: [{
        value: 'never',
        text: Formdict['header.form.refresh.never']
      }, {
        value: 'grid',
        text: Formdict['header.form.refresh.grid']
      }, {
        value: 'view',
        text: Formdict['header.form.refresh.view']
      }]
    },
    {
      type: 'select',
      key: 'popClose',
      label: Formdict['header.form.popClose'],
      initVal: card.popClose || 'never',
      required: true,
      options: [{
        value: 'never',
        text: Formdict['header.form.refresh.never']
      }, {
        value: 'grid',
        text: Formdict['header.form.refresh.grid']
      }, {
        value: 'view',
        text: Formdict['header.form.refresh.view']
      }]
    },
    {
      type: 'select',
      key: 'icon',
      label: Formdict['header.form.icon'],
      initVal: card.icon,
      required: false,
      options: []
    },
    {
      type: 'select',
      key: 'class',
      label: Formdict['header.form.class'],
      initVal: card.class,
      required: false,
      options: []
    },
    {
      type: 'text',
      key: 'sql',
      label: Formdict['header.form.datasource'],
      initVal: card.sql || config.setting.tableName || '',
      tooltip: Formdict['header.form.actionhelp.datasource'],
      required: false
    },
    {
      type: 'select',
      key: 'sqlType',
      label: Formdict['header.form.action.type'],
      initVal: card.sqlType || '',
      tooltip: Formdict['header.form.actionhelp.sqlType'],
      required: false,
      options: []
    }
  ]
}
/**
 * @description 获取显示列表单配置信息
 * @param {*} card
 */
export function getColumnForm (card) {
  return [
    {
      type: 'text',
      key: 'label',
      label: Formdict['header.form.name'],
      initVal: card.label,
      required: true
    },
    {
      type: 'text',
      key: 'field',
      label: Formdict['header.form.field'],
      initVal: card.field,
      required: true,
      readonly: false
    },
    {
      type: 'select',
      key: 'type',
      label: Formdict['header.form.type'],
      initVal: card.type,
      required: true,
      options: [{
        value: 'text',
        text: Formdict['header.form.text']
      }, {
        value: 'number',
        text: Formdict['header.form.number']
      }, {
        value: 'picture',
        text: Formdict['header.form.picture']
      }, {
        value: 'textarea',
        text: Formdict['header.form.textarea']
      }]
    },
    {
      type: 'select',
      key: 'Align',
      label: Formdict['header.form.align'],
      initVal: card.Align,
      required: true,
      options: [{
        value: 'left',
        text: Formdict['header.form.alignLeft']
      }, {
        value: 'right',
        text: Formdict['header.form.alignRight']
      }, {
        value: 'center',
        text: Formdict['header.form.alignCenter']
      }]
    },
    {
      type: 'radio',
      key: 'Hide',
      label: Formdict['header.form.Hide'],
      initVal: card.Hide,
      required: true,
      options: [{
        value: 'true',
        text: Formdict['header.form.true']
      }, {
        value: 'false',
        text: Formdict['header.form.false']
      }]
    },
    {
      type: 'radio',
      key: 'IsSort',
      label: Formdict['header.form.IsSort'],
      initVal: card.IsSort,
      required: true,
      options: [{
        value: 'true',
        text: Formdict['header.form.true']
      }, {
        value: 'false',
        text: Formdict['header.form.false']
      }]
    },
    {
      type: 'number',
      key: 'Width',
      min: 1,
      max: 1000,
      decimal: 0,
      label: Formdict['header.form.columnWidth'],
      initVal: card.Width,
      required: true
    },
    {
      type: 'number',
      key: 'decimal',
      min: 0,
      max: 18,
      decimal: 0,
      label: Formdict['header.form.decimal'],
      initVal: card.decimal,
      required: false
    },
    {
      type: 'select',
      key: 'format',
      label: Formdict['header.form.format'],
      initVal: card.format || '',
      options: [{
        value: '',
        text: Formdict['header.form.empty']
      }, {
        value: 'thdSeparator',
        text: Formdict['header.form.thdSeparator']
      }],
      required: false
    },
    {
      type: 'text',
      key: 'prefix',
      label: Formdict['header.form.prefix'],
      initVal: card.prefix || '',
      required: false,
      readonly: false
    },
    {
      type: 'text',
      key: 'postfix',
      label: Formdict['header.form.postfix'],
      initVal: card.postfix || '',
      tooltipClass: 'middle',
      required: false,
      readonly: false
    },
    {
      type: 'select',
      key: 'match',
      label: Formdict['header.form.match'],
      initVal: card.match || '',
      options: [{
        value: '',
        text: Formdict['header.form.empty']
      }, {
        value: '>',
        text: '>'
      }, {
        value: '<',
        text: '<'
      }, {
        value: '>=',
        text: '>='
      }, {
        value: '<=',
        text: '<='
      }],
      required: false
    },
    {
      type: 'text',
      key: 'matchVal',
      min: -Infinity,
      max: Infinity,
      decimal: 0,
      label: Formdict['header.form.matchVal'],
      initVal: card.matchVal || '',
      required: false,
      readonly: false
    },
    {
      type: 'select',
      key: 'color',
      label: Formdict['header.form.color'],
      initVal: card.color || '',
      options: [{
        value: '',
        text: Formdict['header.form.empty']
      }, {
        value: 'red',
        text: '红色(内容)'
      }, {
        value: 'redbg',
        text: '红色(背景)'
      }, {
        value: 'orange',
        text: '橙色(内容)'
      }, {
        value: 'orangebg',
        text: '橙色(背景)'
      }, {
        value: 'green',
        text: '绿色(内容)'
      }, {
        value: 'greenbg',
        text: '绿色(背景)'
      }],
      required: false
    }
  ]
}
src/templates/tableshare/searchform/index.jsx
@@ -293,7 +293,6 @@
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'textarea') {
        fields.push(
          <Col span={20} offset={4} key={index}>
@@ -328,7 +327,6 @@
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          let isvalid = true
          values.id = this.props.card.id
          values.uuid = this.props.card.uuid
          // 下拉菜单或关联菜单
          if ((values.type === 'multiselect' || values.type === 'select' || values.type === 'link') && values.resourceType === '0') {
@@ -348,10 +346,7 @@
          }
          if (isvalid) {
            resolve({
              type: 'search',
              values
            })
            resolve(values)
          } else {
            notification.warning({
              top: 92,