king
2020-04-29 4edbf8871d037354662c6683add27808c471948b
2020-04-29
4 文件已重命名
5个文件已修改
34个文件已删除
8333 ■■■■■ 已修改文件
src/templates/comtableconfig/actionform/index.jsx 657 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/actionform/index.scss 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 1585 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.scss 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/actionform/index.jsx 692 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/actionform/index.scss 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/colspanform/index.jsx 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/colspanform/index.scss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/columnform/index.jsx 376 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/columnform/index.scss 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/dragelement/actioncard.jsx 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/dragelement/card.jsx 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/dragelement/index.jsx 296 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/dragelement/itemtypes.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/dragsource/index.jsx 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/dragsource/index.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/exceleditable/index.jsx 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/exceleditable/index.scss 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/gridbtnform/index.jsx 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/gridbtnform/index.scss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/modaleditable/index.jsx 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/modaleditable/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/searchform/index.jsx 475 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/searchform/index.scss 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelin/columnform/index.jsx 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelin/columnform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelin/customscript/index.jsx 284 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelin/customscript/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelin/index.jsx 826 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelin/index.scss 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelin/uniqueform/index.jsx 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelin/uniqueform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelout/columnform/index.jsx 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelout/columnform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelout/index.jsx 339 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardexcelout/index.scss 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardprint/editable/index.jsx 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardprint/editable/index.scss 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardprint/index.jsx 461 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycardprint/index.scss 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/actionform/index.jsx
File was deleted
src/templates/comtableconfig/actionform/index.scss
File was deleted
src/templates/comtableconfig/index.jsx
@@ -4,41 +4,33 @@
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, message } from 'antd'
import { Button, Card, Modal, Collapse, notification, Spin, Icon, Switch, Tooltip } from 'antd'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import options from '@/store/options.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import { getSearchForm, getActionForm, getColumnForm } from '@/templates/zshare/formconfig'
import { queryTableSql } from '@/utils/option.js'
import ActionForm from './actionform'
import TableComponent from '@/templates/sharecomponent/tablecomponent'
import FieldsComponent from '@/templates/sharecomponent/fieldscomponent'
// import ChartGroupComponent from '@/templates/sharecomponent/chartgroupcomponent'
import SearchComponent from '@/templates/sharecomponent/searchcomponent'
import ActionComponent from '@/templates/sharecomponent/actioncomponent'
import ColumnComponent from '@/templates/sharecomponent/columncomponent'
import SettingForm from './settingform'
import TabForm from '@/templates/zshare/tabform'
import SearchForm from '@/templates/zshare/searchform'
import ColumnForm from '@/templates/zshare/columnform'
import DragElement from '@/templates/zshare/dragelement'
import ColspanForm from '@/templates/zshare/colspanform'
import GridBtnForm from '@/templates/zshare/gridbtnform'
import EditCard from '@/templates/zshare/editcard'
import VerifyCard from '@/templates/zshare/verifycard'
import VerifyCardExcelIn from '@/templates/zshare/verifycardexcelin'
import VerifyCardExcelOut from '@/templates/zshare/verifycardexcelout'
import VerifyCardPrint from '@/templates/zshare/verifycardprint'
import MenuForm from '@/templates/zshare/menuform'
import TabDragElement from '@/templates/zshare/tabdragelement'
import EditComponent from '@/templates/zshare/editcomponent'
import SourceElement from '@/templates/zshare/dragelement/source'
import SourceElement from '@/templates/zshare/dragsource'
import CreateFunc from '@/templates/zshare/createfunc'
import CreateInterface from '@/templates/zshare/createinterface'
import Source from './source'
import './index.scss'
const { Panel } = Collapse
const { Option } = Select
const { confirm } = Modal
const CommonDict = (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS
@@ -53,9 +45,7 @@
  state = {
    dict: CommonDict,        // 字典
    config: null,            // 页面配置
    tableVisible: false,     // 数据表字段模态框
    addType: '',             // 添加类型-搜索条件或显示列
    tableColumns: [],        // 表格显示列
    tableFields: [],         // 表格显示列
    fields: null,            // 搜索条件及显示列,可选字段
    menuformlist: null,      // 基本信息表单字段
    formlist: null,          // 搜索条件、按钮、显示列表单字段
@@ -72,13 +62,12 @@
    originActions: null,     // 原始按钮信息,使用已有用户模板
    delActions: [],          // 删除按钮列表
    copyActions: [],         // 复制按钮组
    showColumnName: false,   // 显示列字段名控制
    tabviews: [],            // 所有标签页
    profileVisible: false,   // 验证信息模态框
    optionLibs: null,        // 自定义下拉选项库
    thawButtons: [],         // 已选择要解冻的按钮
    activeKey: '0',          // 默认展开基本信息
    sqlVerifing: false       // sql验证
    sqlVerifing: false,      // sql验证
    pasteContent: null       // 粘贴配置信息
  }
  /**
@@ -243,98 +232,6 @@
   * 3、获取所有标签页信息
   */
  componentDidMount () {
    let param = {
      func: 'sPC_Get_SelectedList',
      LText: queryTableSql,
      obj_name: 'data',
      arr_field: 'TbName,Remark'
    }
    param.LText = Utils.formatOptions(param.LText)
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    Api.getSystemConfig(param).then(res => {
      if (res.status) {
        this.setState({
          tables: res.data
        })
      } else {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      }
    })
    let deffers = this.state.selectedTables.map(item => {
      return new Promise(resolve => {
        Api.getSystemConfig({func: 'sPC_Get_FieldName', TBName: item.TbName}).then(res => {
          res.TBName = item.TbName
          resolve(res)
        })
      })
    })
    Promise.all(deffers).then(response => {
      let _columns = []
      response.forEach(res => {
        if (res.status) {
          let tabmsg = {
            tableName: res.TBName,
            columns: res.FDName.map(item => {
              let _type = item.FieldType.toLowerCase()
              let _decimal = 0
              if (/^nvarchar/.test(_type)) {
                _type = 'text'
              } else if (/^int/.test(_type)) {
                _type = 'number'
              } else if (/^decimal/.test(_type)) {
                _decimal = _type.split(',')[1]
                _decimal = parseInt(_decimal)
                if (_decimal > 4) {
                  _decimal = 4
                }
                _type = 'number'
              } else if (/^decimal/.test(_type)) {
                _decimal = _type.split(',')[1]
                _decimal = parseInt(_decimal)
                if (_decimal > 4) {
                  _decimal = 4
                }
                _type = 'number'
              } else if (/^datetime/.test(_type)) {
                _type = 'datetime'
              } else if (/^date/.test(_type)) {
                _type = 'date'
              } else {
                _type = 'text'
              }
              return {
                field: item.FieldName,
                label: item.FieldDec,
                type: _type,
                datatype: _type,
                decimal: _decimal
              }
            })
          }
          _columns.push(tabmsg)
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
        }
      })
      this.setState({
        tableColumns: _columns
      })
    })
    Api.getSystemConfig({func: 'sPC_Get_UserTemp', TypeCharTwo: 'tab'}).then(res => {
      if (res.status) {
        this.setState({
@@ -413,144 +310,14 @@
  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.handleTab(card)
      }
      this.setState({config: {...config, [card.groupId]: list}})
    } else {
      if (list.length > config[type].length) {
        list = list.filter(item => !item.origin)
        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 }
      })
    if (list.length > config[card.groupId].length) {
      list = list.filter(item => !item.origin)
      this.handleTab(card)
    }
    this.setState({config: {...config, [card.groupId]: list}})
  }
  /**
   * @description 搜索条件编辑,获取搜索条件表单信息
   */
  handleSearch = (card) => {
    this.setState({
      modaltype: 'search',
      card: card,
      formlist: getSearchForm(card, this.props.sysRoles)
    })
  }
  /**
   * @description 按钮编辑,获取按钮表单信息
   */
  handleAction = (card, type) => {
    let ableField = this.props.permFuncField.join(', ')
    let functip = <div>
      <p style={{marginBottom: '5px'}}>{this.state.dict['model.tooltip.func.innerface'].replace('@ableField', ableField)}</p>
      <p>{this.state.dict['model.tooltip.func.outface']}</p>
    </div>
    this.setState({
      modaltype: type === 'copy' ? 'actionCopy' : 'actionEdit',
      card: card,
      formlist: getActionForm(card, functip, this.state.config, this.props.permFuncField)
    })
  }
  /**
   * @description 显示列与合并列编辑,获取表单信息
   */
  handleColumn = (card) => {
    const { menu } = this.props
    if (card.type !== 'colspan') {
      let menulist = menu.fstMenuList.map(item => {
        return {
          value: item.MenuID,
          label: item.text,
          isLeaf: false
        }
      })
      if ((card.type === 'text' || card.type === 'number') && card.linkmenu && card.linkmenu.length > 0) {
        let _param = {
          func: 'sPC_Get_FunMenu',
          ParentID: card.linkmenu[0],
          systemType: options.systemType,
          debug: 'Y'
        }
        this.setState({
          loading: true
        })
        Api.getSystemConfig(_param).then(result => {
          if (result.status) {
            menulist = menulist.map(item => {
              if (item.value === card.linkmenu[0]) {
                item.children = result.data.map(item => {
                  let submenu = {
                    value: item.ParentID,
                    label: item.MenuNameP,
                    children: item.FunMenu.map(cell => {
                      return {
                        value: cell.MenuID,
                        label: cell.MenuName,
                        MenuID: cell.MenuID,
                        MenuName: cell.MenuName,
                        MenuNo: cell.MenuNo,
                        Ot: cell.Ot,
                        PageParam: cell.PageParam,
                        LinkUrl: cell.LinkUrl,
                        disabled: cell.MenuID === menu.MenuID
                      }
                    })
                  }
                  return submenu
                })
              }
              return item
            })
          } else {
            notification.warning({
              top: 92,
              message: result.message,
              duration: 5
            })
          }
          this.setState({
            loading: false,
            modaltype: 'columns',
            card: card,
            formlist: getColumnForm(card, this.props.sysRoles, menulist)
          })
        })
      } else {
        this.setState({
          modaltype: 'columns',
          card: card,
          formlist: getColumnForm(card, this.props.sysRoles, menulist)
        })
      }
    } else {
      this.setState({
        modaltype: 'colspan',
        card: card
      })
    }
  }
  /**
   * @description 标签编辑,筛选可选的下级标签与已关联的下级标签
   */
@@ -693,383 +460,38 @@
  }
  /**
   * @description 操作列编辑
   */
  handleGridBtn = () => {
    this.setState({
      modaltype: 'gridbtn'
    })
  }
  /**
   * @description 搜索、按钮、显示列修改后提交保存
   * 1、搜索条件保存
   * 2、按钮包括正常编辑和复制,复制时,末尾添加,如按钮为表单(保存至数据库),复制按钮id存于复制列表(点击不保存时删除)
   * 3、如按钮位置设置为表格,则修改操作列显示状态
   * @description 标签修改后提交保存
   */
  handleSubmit = () => {
    const { menu } = this.props
    const { config, card, modaltype, optionLibs } = this.state
    if (modaltype === 'search') {
      this.searchFormRef.handleConfirm().then(res => {
        if ( // 更新下拉字典
          (res.type === 'select' || res.type === 'multiselect' || res.type === 'link') &&
          res.resourceType === '0' &&
          res.options && res.options.length > 0
        ) {
          optionLibs.set(menu.MenuID + res.uuid, {
            uuid: menu.MenuID + res.uuid,
            label: res.label,
            parname: menu.MenuName,
            type: 'search',
            options: res.options
          })
        }
        let fieldrepet = false // 字段重复
        let labelrepet = false // 提示文字重复
        let _search = config.search.map(item => {
          if (item.uuid !== res.uuid && res.field && item.field) {
            if (item.field === res.field) {
              fieldrepet = true
            } else if (item.label === res.label) {
              labelrepet = true
            }
          }
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
        if (fieldrepet) {
          notification.warning({
            top: 92,
            message: '字段已存在!',
            duration: 5
          })
          return
        } else if (labelrepet) {
          notification.warning({
            top: 92,
            message: '名称已存在!',
            duration: 5
          })
          return
        }
        _search = _search.filter(item => !item.origin)
        if ((res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && res.resourceType === '1' && /\s/.test(res.dataSource)) {
          this.setState({
            sqlVerifing: true
          })
          let param = {
            func: 's_debug_sql',
            LText: res.dataSource
          }
          param.LText = Utils.formatOptions(param.LText)
          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
          param.secretkey = Utils.encrypt(param.LText, param.timestamp)
          if (window.GLOB.mainSystemApi && res.database === 'sso') {
            param.rduri = window.GLOB.mainSystemApi
          }
          Api.getLocalConfig(param).then(result => {
            if (result.status) {
              this.setState({
                sqlVerifing: false,
                config: {...config, search: _search},
                optionLibs: optionLibs,
                modaltype: ''
              })
            } else {
              this.setState({sqlVerifing: false})
              Modal.error({
                title: result.message
              })
            }
          })
    const { config } = this.state
    this.tabsFormRef.handleConfirm().then(res => {
      let _tabgroup = config[res.groupId].map(item => {
        if (item.uuid === res.uuid) {
          return res
        } else {
          this.setState({
            config: {...config, search: _search},
            optionLibs: optionLibs,
            modaltype: ''
          })
          return item
        }
      })
    } 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)
      _tabgroup = _tabgroup.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
          }).then(result => {
            if (result.status && result.LongParam) {
              let _LongParam = ''
              // 解析配置,修改模态框标题名称
              if (result.LongParam) {
                try {
                  _LongParam = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
                } catch (e) {
                  console.warn('Parse Failure')
                  _LongParam = ''
                }
              }
              if (_LongParam && _LongParam.type === 'Modal') {
                try {
                  _LongParam.setting.title = res.label
                  _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_LongParam)))
                } catch {
                  console.warn('Stringify Failure')
                  _LongParam = ''
                }
              } else {
                _LongParam = ''
              }
              let param = {
                func: 'sPC_ButtonParam_AddUpt',
                ParentID: menu.MenuID,
                MenuID: res.uuid,
                MenuNo: menu.MenuNo,
                Template: 'Modal',
                MenuName: res.label,
                PageParam: JSON.stringify({Template: 'Modal'}),
                LongParam: _LongParam
              }
              Api.getSystemConfig(param).then(response => {
                if (!response.status) {
                  notification.warning({
                    top: 92,
                    message: response.message,
                    duration: 5
                  })
                } else {
                  this.setState({
                    copyActions: [...this.state.copyActions, res.uuid]
                  })
                }
              })
            }
          })
        } else if (
          (res.OpenType === 'tab' || res.OpenType === 'blank') &&
          card.originCard &&
          (card.originCard.OpenType === 'tab' || card.originCard.OpenType === 'blank')
        ) {
          Api.getSystemConfig({
            func: 'sPC_Get_LongParam',
            MenuID: card.originCard.uuid
          }).then(result => {
            if (result.status && result.LongParam) {
              let _LongParam = ''
              // 解析配置,修改模态框标题名称
              if (result.LongParam) {
                try {
                  _LongParam = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
                } catch (e) {
                  console.warn('Parse Failure')
                  _LongParam = ''
                }
              }
              let _temp = ''
              if (_LongParam && _LongParam.type === 'FormTab') {
                try {
                  _LongParam.action = _LongParam.action.map(_btn => {
                    _btn.uuid = Utils.getuuid()
                    return _btn
                  })
                  _LongParam.tabgroups.forEach(_groupId => {
                    _LongParam[_groupId] = _LongParam[_groupId].map(_tab => {
                      _tab.uuid = Utils.getuuid()
                      return _tab
                    })
                  })
                  _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_LongParam)))
                  _temp = 'FormTab'
                } catch {
                  console.warn('Stringify Failure')
                  _LongParam = ''
                }
              } else {
                _LongParam = ''
              }
              if (!_temp) return
              let param = {
                func: 'sPC_ButtonParam_AddUpt',
                ParentID: menu.MenuID,
                MenuID: res.uuid,
                MenuNo: menu.MenuNo,
                Template: _temp,
                MenuName: res.label,
                PageParam: JSON.stringify({Template: _temp}),
                LongParam: _LongParam
              }
              Api.getSystemConfig(param).then(response => {
                if (!response.status) {
                  notification.warning({
                    top: 92,
                    message: response.message,
                    duration: 5
                  })
                } else {
                  this.setState({
                    copyActions: [...this.state.copyActions, res.uuid]
                  })
                }
              })
            }
          })
        }
        // 判断是否存在操作列
        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, action: _action, gridBtn: _gridBtn},
          modaltype: ''
        })
      this.setState({
        config: {...config, [res.groupId]: _tabgroup},
        modaltype: ''
      })
    } else if (modaltype === 'columns' || modaltype === 'colspan') {
      this.columnFormRef.handleConfirm().then(res => {
        let fieldrepet = false // 字段重复
        let labelrepet = false // 提示文字重复
        let _columns = config.columns.map(item => {
          if (item.uuid !== res.uuid && res.field && item.field) {
            if (item.field === res.field) {
              fieldrepet = true
            } else if (item.label === res.label) {
              labelrepet = true
            }
          }
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
        if (fieldrepet) {
          notification.warning({
            top: 92,
            message: '字段已存在!',
            duration: 5
          })
          return
        } else if (labelrepet) {
          notification.warning({
            top: 92,
            message: '名称已存在!',
            duration: 5
          })
          return
        }
        _columns = _columns.filter(item => !item.origin)
        this.setState({
          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 _tabgroup = config[res.groupId].map(item => {
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
        _tabgroup = _tabgroup.filter(item => !item.origin)
        this.setState({
          config: {...config, [res.groupId]: _tabgroup},
          modaltype: ''
        })
      })
    }
    })
  }
  /**
   * @description 取消保存,如果元素为新添元素,则从序列中删除
   */
  editModalCancel = () => {
    const { config, card, modaltype } = this.state
    const { config, card } = this.state
    if (card && 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 if (modaltype === 'tabs') {
        let _tabgroup = config[card.groupId].filter(item => item.uuid !== card.uuid)
        _config = {...config, [card.groupId]: _tabgroup}
      } else {
        _config = config
      }
      let _tabgroup = config[card.groupId].filter(item => item.uuid !== card.uuid)
      _config = {...config, [card.groupId]: _tabgroup}
      this.setState({
        card: null,
@@ -1082,153 +504,6 @@
        modaltype: ''
      })
    }
  }
  /**
   * @description 按钮-创建存储过程
   */
  creatFunc = () => {
    const { menu } = this.props
    const { config } = this.state
    this.actionFormRef.handleConfirm().then(res => {
      let btn = res         // 按钮信息
      let newLText = ''     // 创建存储过程sql
      let DelText = ''      // 删除存储过程sql
      // 创建存储过程,必须填写内部函数名
      if (!btn.innerFunc) {
        notification.warning({
          top: 92,
          message: '请填写内部函数!',
          duration: 5
        })
        return
      }
      new Promise(resolve => {
        // 弹窗(表单)类按钮,先获取按钮配置信息,如果尚未配置按钮则会报错并终止。
        // 获取信息后生成删除和创建存储过程的语句
        if (btn.OpenType === 'pop') {
          Api.getSystemConfig({
            func: 'sPC_Get_LongParam',
            MenuID: btn.uuid
          }).then(res => {
            let _LongParam = ''
            if (res.status && res.LongParam) {
              try {
                _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
              } catch (e) {
                console.warn('Parse Failure')
                _LongParam = ''
              }
            }
            if (_LongParam) {
              let fields = []
              if (_LongParam.groups.length > 0) {
                _LongParam.groups.forEach(group => {
                  fields = [...fields, ...group.sublist]
                })
              } else {
                fields = _LongParam.fields
              }
              let _param = {
                funcName: btn.innerFunc,
                name: config.setting.tableName || '',
                fields: fields,
                menuNo: menu.MenuNo
              }
              newLText = Utils.formatOptions(Utils.getfunc(_param, btn, menu, config))
              DelText = Utils.formatOptions(Utils.dropfunc(_param.funcName))
              resolve(true)
            } else {
              notification.warning({
                top: 92,
                message: '弹窗(表单)按钮,请先配置表单信息!',
                duration: 5
              })
              resolve(false)
            }
          })
        } else if (btn.OpenType === 'excelIn') {
          if (btn.verify && btn.verify.sheet && btn.verify.columns && btn.verify.columns.length > 0) {
            let _param = {
              funcName: btn.innerFunc,
              menuNo: menu.MenuNo
            }
            newLText = Utils.formatOptions(Utils.getexcelInfunc(_param, btn, menu))
            DelText = Utils.formatOptions(Utils.dropfunc(_param.funcName))
            resolve(true)
          } else {
            notification.warning({
              top: 92,
              message: '请完善导入Excel验证信息!',
              duration: 5
            })
            resolve(false)
          }
        } else if (btn.OpenType === 'excelOut') {
          let _param = {
            innerFunc: btn.innerFunc
          }
          newLText = Utils.formatOptions(Utils.getTableFunc(_param, menu, config ))
          DelText = Utils.formatOptions(Utils.dropfunc(btn.innerFunc))
          resolve(true)
        } else {
          let _param = {
            funcName: btn.innerFunc,
            name: config.setting.tableName || '',
            fields: '',
            menuNo: menu.MenuNo
          }
          newLText = Utils.formatOptions(Utils.getfunc(_param, btn, menu, config))
          DelText = Utils.formatOptions(Utils.dropfunc(_param.funcName))
          resolve(true)
        }
      }).then(res => {
        if (!res) return
        this.refs.btnCreatFunc.exec(btn.innerFunc, newLText, DelText).then(result => {
          if (result !== 'success') return
          let _action = config.action.map(item => {
            if (item.uuid === btn.uuid) {
              return btn
            } else {
              return item
            }
          })
          _action = _action.filter(item => !item.origin)
          // 判断是否存在操作列
          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, action: _action, gridBtn: _gridBtn}
          })
        })
      })
    })
  }
  /**
@@ -1259,27 +534,6 @@
            config: _config
          })
        }
      })
    })
  }
  /**
   * @description 创建按钮接口(写入)
   */
  btnCreatInterface = () => {
    const { menu } = this.props
    const { config } = this.state
    this.menuformRef.handleConfirm().then(res => {
      this.actionFormRef.handleConfirm().then(result => {
        let _menu = {
          type: 'main',
          MenuID: menu.MenuID,
          menuName: res.menuName,
          menuNo: res.menuNo
        }
        this.refs.btnCreatInterface.triggerInInterface(result, config, _menu)
      })
    })
  }
@@ -1335,21 +589,6 @@
            }
          })
          _config = {...config, [element.card.groupId]: _tabgroup}
        } else {
          let list = config[element.type].filter(item => {
            if (item.uuid === element.card.uuid) {
              return false
            } else {
              return true
            }
          })
          _config = {...config, [element.type]: list}
          // 删除按钮时判断是否存在操作列
          if (element.type === 'action' && _config.gridBtn) {
            _config.gridBtn.display = _config.action.filter(act => act.position === 'grid').length > 0
          }
        }
        // 删除按钮元素
@@ -1365,55 +604,6 @@
        })
      },
      onCancel() {}
    })
  }
  /**
   * @description 验证信息配置
   */
  profileAction = (element) => {
    this.setState({
      profileVisible: true,
      card: element
    })
  }
  /**
   * @description 按钮双击触发子配置
   */
  btnDoubleClick = (element) => {
    if (!element.origin && (element.OpenType === 'pop' || element.OpenType === 'popview' || element.OpenType === 'blank' || element.OpenType === 'tab')) {
      this.setSubConfig(element, 'button')
    } else {
      notification.warning({
        top: 92,
        message: '此按钮无子配置项!',
        duration: 5
      })
    }
  }
  /**
   * @description 验证信息保存
   */
  verifySubmit = () => {
    const { card } = this.state
    let config = JSON.parse(JSON.stringify(this.state.config))
    this.verifyRef.handleConfirm().then(res => {
      config.action = config.action.map(item => {
        if (item.uuid === card.uuid) {
          item.verify = res
        }
        return item
      })
      this.setState({
        profileVisible: false,
        config: config,
        card: ''
      })
    })
  }
@@ -1523,7 +713,7 @@
      }
      let _LongParam = ''
      let _config = {...config, tables: this.state.selectedTables, easyCode: res.easyCode}
      let _config = {...config, easyCode: res.easyCode}
      let _pageParam = {...menu.PageParam, OpenType: res.opentype}
      // 未设置数据源或标签不合法时,启用状态为false
@@ -2110,7 +1300,7 @@
      })
    } else {
      this.menuformRef.handleConfirm().then(res => {
        let _config = {...config, tables: this.state.selectedTables, easyCode: res.easyCode}
        let _config = {...config, easyCode: res.easyCode}
        let _pageParam = {...menu.PageParam, OpenType: res.opentype}
        let _originMenu = {
          ...originMenu,
@@ -2135,262 +1325,6 @@
        })
      })
    }
  }
  /**
   * @description 筛选可用字段集
   */
  queryField = (type) => {
    const {selectedTables, tableColumns, config} = this.state
    // 判断是否已选择表名
    if (selectedTables.length === 0) {
      notification.warning({
        top: 92,
        message: '请选择表名!',
        duration: 5
      })
      return
    }
    // 表字段集转为map数据
    let columns = new Map()
    tableColumns.forEach(table => {
      table.columns.forEach(column => {
        columns.set(column.field, column)
      })
    })
    if (type === 'search') {
      // 添加搜索条件,字段集中存在搜索条件字段,使用搜索条件对象替换字段集,设置数据类型
      config.search.forEach(item => {
        if (columns.has(item.field)) {
          let _datatype = columns.get(item.field).datatype
          columns.set(item.field, {...item, selected: true, datatype: _datatype})
        }
      })
    } else if (type === 'columns') {
      // 添加显示列,字段集中存在显示列字段,使用显示列对象替换字段集,设置数据类型
      config.columns.forEach(item => {
        if (columns.has(item.field)) {
          let _datatype = columns.get(item.field).datatype
          columns.set(item.field, {...item, selected: true, datatype: _datatype})
        }
      })
    }
    // 显示字段集弹窗
    this.setState({
      addType: type,
      tableVisible: true,
      fields: [...columns.values()]
    })
  }
  /**
   * @description 添加字段集
   */
  addFieldSubmit = () => {
    const {addType, config} = this.state
    // 字段集为空,关闭弹窗
    if (!this.state.fields || this.state.fields.length === 0) {
      this.setState({
        tableVisible: false,
        addType: ''
      })
    }
    // 获取已选字段集合
    let cards = this.refs.searchcard.state.selectCards
    if (cards.length === 0) {
      notification.warning({
        top: 92,
        message: '请选择添加字段',
        duration: 5
      })
      return
    }
    let columnsMap = new Map()
    cards.forEach(card => {
      columnsMap.set(card.field, card)
    })
    if (addType === 'search') {
      let _search = config.search.filter(item => !item.origin)
      // 重置原有搜素条件
      _search = _search.map(item => {
        if (columnsMap.has(item.field)) {
          let cell = columnsMap.get(item.field)
          if (cell.type !== item.type) { // 数据类型修改
            if (cell.type === 'select') {
              item.match = '='
            } else if (cell.type === 'daterange') {
              item.match = 'between'
            } else {
              cell.type = 'text'
              item.match = 'like'
            }
            item.type = cell.type
            item.initval = ''
          }
          columnsMap.delete(item.field)
        }
        return item
      })
      let _columns = [...columnsMap.values()]
      // 顺序添加新增搜索
      _columns.forEach(item => {
        let _match = ''
        if (item.type === 'select') {
          _match = '='
        } else if (item.type === 'daterange') {
          _match = 'between'
        } else {
          _match = 'like'
        }
        let newcard = {
          uuid: Utils.getuuid(),
          label: item.label,
          field: item.field,
          initval: '',
          type: item.type || 'text',
          resourceType: '0',
          setAll: 'false',
          options: [],
          orderType: 'asc',
          match: _match,
          display: 'dropdown'
        }
        _search.push(newcard)
      })
      this.setState({
        config: {...config, search: _search}
      })
    } else {
      let _columns = config.columns.filter(item => !item.origin)
      // 重置原有显示列类型
      _columns = _columns.map(item => {
        if (columnsMap.has(item.field)) {
          let cell = columnsMap.get(item.field)
          if (cell.type) {
            item.type = cell.type
          }
          columnsMap.delete(item.field)
        }
        return item
      })
      let _cols = [...columnsMap.values()]
      // 添加显示列
      _cols.forEach(item => {
        let newcard = {
          uuid: Utils.getuuid(),
          Align: 'left',
          label: item.label,
          field: item.field,
          Hide: 'false',
          IsSort: item.type === 'picture' ? 'false' : 'true',
          type: item.type,
          Width: 120
        }
        _columns.push(newcard)
      })
      this.setState({
        config: {...config, columns: _columns}
      })
    }
    notification.success({
      top: 92,
      message: '操作成功',
      duration: 2
    })
  }
  /**
   * @description 表名切换时,添加表名,新增时查询表相关字段
   */
  onTableChange = (value) => {
    const {tables, selectedTables, tableColumns} = this.state
    let _table = tables.filter(item => item.TbName === value)[0]
    let isSelected = !!selectedTables.filter(cell => cell.TbName === value)[0]
    if (!isSelected) {
      this.setState({
        selectedTables: [...selectedTables, _table]
      })
      Api.getSystemConfig({func: 'sPC_Get_FieldName', TBName: value}).then(res => {
        if (res.status) {
          let tabmsg = {
            tableName: _table.name,
            columns: res.FDName.map(item => {
              let _type = item.FieldType.toLowerCase()
              let _decimal = 0
              if (/^nvarchar/.test(_type)) {
                _type = 'text'
              } else if (/^int/.test(_type)) {
                _type = 'number'
              } else if (/^decimal/.test(_type)) {
                _decimal = _type.split(',')[1]
                _decimal = parseInt(_decimal)
                _type = 'number'
              } else if (/^datetime/.test(_type)) {
                _type = 'datetime'
              } else if (/^date/.test(_type)) {
                _type = 'date'
              } else {
                _type = 'text'
              }
              return {
                field: item.FieldName,
                label: item.FieldDec,
                type: _type,
                datatype: _type,
                decimal: _decimal
              }
            })
          }
          this.setState({
            tableColumns: [...tableColumns, tabmsg]
          })
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
        }
      })
    }
  }
  /**
   * @description 删除表名以及表相关字段
   */
  deleteTable = (table) => {
    const {selectedTables, tableColumns} = this.state
    this.setState({
      selectedTables: selectedTables.filter(item => item.TbName !== table.TbName),
      tableColumns: tableColumns.filter(item => item.tableName !== table.TbName)
    })
  }
  /**
@@ -2664,40 +1598,6 @@
  }
  /**
   * @description 显示隐藏显示列字段名
   */
  onColumnNameChange = () => {
    const { showColumnName, config } = this.state
    if (!showColumnName) {
      let fields = []
      config.columns.forEach(col => {
        if (col.field) {
          fields.push(col.field)
        }
      })
      fields = fields.join(',')
      let textArea = document.createElement('textarea')
      textArea.value = fields
      document.body.appendChild(textArea)
      textArea.select()
      try {
        document.execCommand('copy')
        document.body.removeChild(textArea)
      } catch (err) {
        document.body.removeChild(textArea)
      }
    }
    this.setState({
      showColumnName: !showColumnName
    })
  }
  /**
   * @description 增加标签页分组
   */
  addTabGroup = () => {
@@ -2766,27 +1666,6 @@
    })
  }
  copycolumn = () => {
    const { config } = this.state
    let oInput = document.createElement('input')
    let val = {
      copyType: 'columns',
      columns: config.columns
    }
    oInput.value = window.btoa(window.encodeURIComponent(JSON.stringify(val)))
    document.body.appendChild(oInput)
    oInput.select()
    document.execCommand('Copy')
    oInput.className = 'oInput'
    oInput.style.display = 'none'
    message.success('复制成功。')
    document.body.removeChild(oInput)
  }
  /**
   * @description 选择不保存时,如有复制按钮,则删除
   */
@@ -2801,6 +1680,9 @@
    this.props.handleView()
  }
  /**
   * @description 编辑功能完成更新,包括解冻按钮、粘贴、替换等
   */
  updateConfig = (res) => {
    if (res.type === 'thaw') {
      this.setState({
@@ -2808,32 +1690,90 @@
        config: res.config
      })
    } else if (res.type === 'paste') {
      if (res.copyType === 'action') {
        this.handleAction(res.content, 'copy')
      } else if (res.copyType === 'columns') {
      this.setState({
        pasteContent: res.content
      }, () => {
        this.setState({
          config: res.config
          pasteContent: null
        })
      }
      })
    }
  }
  /**
   * @description 更新搜索条件配置信息
   */
  updatesearch = (config, options) => {
    const { optionLibs } = this.state
    this.setState({
      config: config,
      optionLibs: options || optionLibs
    })
  }
  /**
   * @description 更新按钮配置信息
   */
  updateaction = (config, copyId, delcard) => {
    const { copyActions, delActions } = this.state
    this.setState({
      config: config,
      copyActions: copyId ? [...copyActions, copyId] : copyActions,
      delActions: delcard ? [...delActions, delcard] : delActions
    })
  }
  /**
   * @description 更新显示列配置信息
   */
  updatecolumn = (config) => {
    this.setState({
      config: config
    })
  }
  /**
   * @description 更新图表组配置信息
   */
  updatechartgroup = (config, _chartview) => {
    this.setState({
      config: config,
      chartview: _chartview
    })
  }
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   */
  updatetable = (config, fields) => {
    const { tableFields } = this.state
    this.setState({
      config: config,
      tableFields: fields ? fields : tableFields
    })
  }
  /**
   * @description 批量添加,更新配置信息
   */
  updatefield = (config) => {
    this.setState({
      config: config
    })
  }
  render () {
    const { modaltype, activeKey, config } = this.state
    const configAction = config.action.filter(_action =>
      !_action.origin && (_action.OpenType === 'pop' || _action.OpenType === 'popview' || _action.OpenType === 'blank' || _action.OpenType === 'tab')
    )
    const confActions = config.action.filter(_action => !_action.origin && ['pop', 'popview', 'blank', 'tab'].includes(_action.OpenType))
    let configTabs = []
    config.tabgroups.forEach(group => {
      configTabs.push(...config[group])
    })
    let hasbtncrtinter = false
    if (modaltype === 'actionEdit' && config.setting.interType === 'inner' && !config.setting.innerFunc && config.setting.dataresource) {
      hasbtncrtinter = true
    }
    return (
      <div className="common-table-board">
@@ -2843,7 +1783,7 @@
          <div className="tools">
            <Collapse accordion defaultActiveKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
              {/* 基本信息 */}
              <Panel forceRender={true} header={this.state.dict['header.menu.basedata']} key="0" id="common-basedata">
              <Panel forceRender={true} header={this.state.dict['header.menu.basedata']} key="0" id="main-basedata">
                {/* 菜单信息 */}
                <MenuForm
                  dict={this.state.dict}
@@ -2851,42 +1791,12 @@
                  wrappedComponentRef={(inst) => this.menuformRef = inst}
                />
                {/* 表名添加 */}
                <div className="ant-col ant-form-item-label">
                  <label>
                    <Tooltip placement="topLeft" title="此处可以添加配置相关的常用表,在添加搜索条件和显示列时,可通过工具栏中的添加按钮,批量添加表格相关字段。">
                      <Icon type="question-circle" />
                      {this.state.dict['header.menu.table.add']}
                    </Tooltip>
                  </label>
                </div>
                <Select
                  showSearch
                  className="tables"
                  style={{ width: '100%' }}
                  optionFilterProp="children"
                  value={this.state.dict['header.menu.table.placeholder']}
                  onChange={this.onTableChange}
                  showArrow={false}
                  getPopupContainer={() => document.getElementById('common-basedata')}
                  filterOption={(input, option) => {
                    return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
                      option.props.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
                  }}
                >
                  {this.state.tables.map((table, index) => (
                    <Option key={index} title={table.TbName} value={table.TbName}>{table.Remark}</Option>
                  ))}
                </Select>
                {this.state.selectedTables.length > 0 && <List
                  size="small"
                  bordered
                  dataSource={this.state.selectedTables}
                  renderItem={(item, index) => <List.Item key={index} title={item.Remark + ' (' + item.TbName + ')'}>
                    {item.Remark + ' (' + item.TbName + ')'}
                    <Icon type="close" onClick={() => this.deleteTable(item)}/>
                    <div className="bottom-mask"></div>
                  </List.Item>}
                />}
                <TableComponent
                  config={config}
                  containerId="main-basedata"
                  selectedTables={config.tables || []}
                  updatetable={this.updatetable}
                />
              </Panel>
              {/* 搜索条件添加 */}
              <Panel header={this.state.dict['header.menu.search']} key="1">
@@ -2895,7 +1805,12 @@
                    return (<SourceElement key={index} content={item}/>)
                  })}
                </div>
                <Button type="primary" block onClick={() => this.queryField('search')}>{this.state.dict['header.menu.search.add']}</Button>
                <FieldsComponent
                  config={config}
                  type="search"
                  tableFields={this.state.tableFields}
                  updatefield={this.updatefield}
                />
              </Panel>
              {/* 按钮添加 */}
              <Panel header={this.state.dict['header.menu.action']} key="2">
@@ -2905,7 +1820,7 @@
                  })}
                </div>
                <div className="config-btn">
                  {configAction.length > 0 ?
                  {confActions.length > 0 ?
                    <p className="config-btn-title">
                      <Tooltip placement="topLeft" title="点击按钮,可完成或查看按钮配置信息。">
                        <Icon type="question-circle" />
@@ -2914,7 +1829,7 @@
                    </p> : null
                  }
                </div>
                {configAction.map((item, index) => {
                {confActions.map((item, index) => {
                  return (
                    <div key={index}>
                      <Button
@@ -2934,7 +1849,12 @@
                    return (<SourceElement key={index} content={item}/>)
                  })}
                </div>
                <Button type="primary" block onClick={() => this.queryField('columns')}>{this.state.dict['header.menu.column.add']}</Button>
                <FieldsComponent
                  config={config}
                  type="columns"
                  tableFields={this.state.tableFields}
                  updatefield={this.updatefield}
                />
              </Panel>
              {/* 添加标签 */}
              <Panel header={this.state.dict['header.menu.tab']} key="4">
@@ -2982,56 +1902,32 @@
              </div>
            } style={{ width: '100%' }}>
              <Icon type="setting" onClick={this.changeSetting} />
              <div className="search-list">
                <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《搜索》中,选择对应搜索框拖至此处添加;或点击按钮《添加搜索条件》批量添加,选择批量添加时,需提前选择使用表。">
                  <Icon type="question-circle" />
                </Tooltip>
                <DragElement
                  type="search"
                  list={config.search}
                  handleList={this.handleList}
                  handleMenu={this.handleSearch}
                  deleteMenu={this.deleteElement}
                  placeholder={this.state.dict['header.form.search.placeholder']}
                />
              </div>
              <div className="action-list" id="action-list">
                <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《按钮》中,选择对应类型的按钮拖至此处添加,如选择按钮类型为表单、新标签页等含有配置页面的按钮,可在左侧工具栏-按钮-可配置按钮处,点击按钮完成相关配置。注:当设置按钮显示位置为表格时,显示列会增加操作列。">
                  <Icon type="question-circle" />
                </Tooltip>
                <DragElement
                  type="action"
                  list={config.action}
                  setting={config.setting}
                  handleList={this.handleList}
                  handleMenu={this.handleAction}
                  copyElement={(val) => this.handleAction(val, 'copy')}
                  deleteMenu={this.deleteElement}
                  profileMenu={this.profileAction}
                  doubleClickCard={this.btnDoubleClick}
                  placeholder={this.state.dict['header.form.action.placeholder']}
                />
              </div>
              <SearchComponent
                menu={{MenuID: this.props.menu.MenuID, MenuName: this.props.menu.MenuName}}
                config={config}
                pasteContent={this.state.pasteContent}
                sysRoles={this.props.sysRoles}
                optionLibs={this.state.optionLibs}
                updatesearch={this.updatesearch}
              />
              <ActionComponent
                type="main"
                menu={{MenuID: this.props.menu.MenuID, MenuName: this.props.menu.MenuName, MenuNo: this.props.menu.MenuNo}}
                config={config}
                tabs={this.state.tabviews}
                pasteContent={this.state.pasteContent}
                usefulFields={this.props.permFuncField}
                setSubConfig={(_btn) => this.setSubConfig(_btn, 'button')}
                updateaction={this.updateaction}
              />
              {/* 显示列 */}
              <div className="column-list">
                <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《显示列》中,选择对应类型的显示列拖至此处添加;或点击《添加显示列》按钮批量添加,选择批量添加时,需提前选择使用表。注:添加合并列时,需设置可选列。">
                  <Icon type="question-circle" />
                </Tooltip>
                {config.columns && config.columns.length > 0 ? <Icon className="column-copy" title="copy" type="copy" onClick={this.copycolumn} /> : null}
                <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showColumnName} onChange={this.onColumnNameChange} />
                <DragElement
                  type="columns"
                  list={config.columns}
                  setting={config.setting}
                  gridBtn={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>
              <ColumnComponent
                config={config}
                menu={this.props.menu}
                sysRoles={this.props.sysRoles}
                pasteContent={this.state.pasteContent}
                updatecolumn={this.updatecolumn}
              />
              {/* 标签组 */}
              {config.tabgroups.map((groupId, index) => {
                return (
@@ -3060,105 +1956,6 @@
            </Card>
          </div>
        </DndProvider>
        {/* 编辑搜索条件 */}
        <Modal
          title={this.state.dict['header.modal.search.edit']}
          visible={modaltype === 'search'}
          width={750}
          maskClosable={false}
          onOk={this.handleSubmit}
          confirmLoading={this.state.sqlVerifing}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <SearchForm
            dict={this.state.dict}
            card={this.state.card}
            inputSubmit={this.handleSubmit}
            optionLibs={this.state.optionLibs}
            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={800}
          maskClosable={false}
          onCancel={this.editModalCancel}
          footer={[
            hasbtncrtinter ? <CreateInterface key="interface" dict={this.state.dict} ref="btnCreatInterface" trigger={this.btnCreatInterface}/> : null,
            modaltype === 'actionEdit' ? <CreateFunc key="create" dict={this.state.dict} ref="btnCreatFunc" trigger={this.creatFunc}/> : null,
            <Button key="cancel" onClick={this.editModalCancel}>{this.state.dict['header.cancel']}</Button>,
            <Button key="confirm" type="primary" onClick={this.handleSubmit}>{this.state.dict['model.confirm']}</Button>
          ]}
          destroyOnClose
        >
          <ActionForm
            dict={this.state.dict}
            card={this.state.card}
            tabs={this.state.tabviews}
            formlist={this.state.formlist}
            inputSubmit={this.handleSubmit}
            setting={config.setting}
            wrappedComponentRef={(inst) => this.actionFormRef = inst}
          />
        </Modal>
        {/* 显示列编辑 */}
        <Modal
          title={this.state.dict['header.modal.column.edit']}
          visible={modaltype === 'columns'}
          width={750}
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <ColumnForm
            dict={this.state.dict}
            card={this.state.card}
            MenuID={this.props.menu.MenuID}
            inputSubmit={this.handleSubmit}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.columnFormRef = inst}
          />
        </Modal>
        {/* 合并列编辑 */}
        <Modal
          title={this.state.dict['header.modal.colspan.edit']}
          visible={modaltype === 'colspan'}
          width={700}
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <ColspanForm
            dict={this.state.dict}
            card={this.state.card}
            inputSubmit={this.handleSubmit}
            columns={config.columns}
            wrappedComponentRef={(inst) => this.columnFormRef = inst}
          />
        </Modal>
        {/* 操作列编辑 */}
        <Modal
          title={this.state.dict['header.modal.gridbtn.edit']}
          visible={modaltype === 'gridbtn'}
          width={750}
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <GridBtnForm
            dict={this.state.dict}
            inputSubmit={this.handleSubmit}
            card={config.gridBtn}
            wrappedComponentRef={(inst) => this.gridBtnFormRef = inst}
          />
        </Modal>
        {/* 标签编辑 */}
        <Modal
          title={this.state.dict['header.modal.tabs.edit']}
@@ -3178,76 +1975,6 @@
            inputSubmit={this.handleSubmit}
            wrappedComponentRef={(inst) => this.tabsFormRef = inst}
          />
        </Modal>
        {/* 根据字段名添加显示列及搜索条件 */}
        <Modal
          wrapClassName="common-table-fields-modal"
          title={this.state.dict['model.edit']}
          visible={this.state.tableVisible}
          width={'65vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          cancelText={this.state.dict['header.close']}
          onOk={this.addFieldSubmit}
          onCancel={() => { // 取消添加
            this.setState({
              tableVisible: false,
              addType: ''
            })
          }}
          destroyOnClose
        >
          {this.state.addType && this.state.fields.length > 0 ?
            <EditCard data={this.state.fields} ref="searchcard" type={this.state.addType} dict={this.state.dict} /> : null
          }
          {(!this.state.fields || this.state.fields.length === 0) &&
            <Empty />
          }
        </Modal>
        {/* 按钮使用系统存储过程时,验证信息模态框 */}
        <Modal
          wrapClassName="common-table-fields-modal"
          title={'验证信息'}
          maskClosable={false}
          visible={this.state.profileVisible}
          width={'75vw'}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={this.state.dict['header.submit']}
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ profileVisible: false }) }}
          destroyOnClose
        >
          {this.state.card && !this.state.card.execMode && this.state.card.OpenType !== 'excelIn' && this.state.card.OpenType !== 'excelOut' ?
            <VerifyCard
              card={this.state.card}
              dict={this.state.dict}
              columns={config.columns}
              wrappedComponentRef={(inst) => this.verifyRef = inst}
            /> : null
          }
          {this.state.card && this.state.card.execMode ?
            <VerifyCardPrint
              card={this.state.card}
              dict={this.state.dict}
              columns={config.columns}
              wrappedComponentRef={(inst) => this.verifyRef = inst}
            /> : null
          }
          {this.state.card && this.state.card.OpenType === 'excelIn' ?
            <VerifyCardExcelIn
              card={this.state.card}
              dict={this.state.dict}
              columns={config.columns}
              wrappedComponentRef={(inst) => this.verifyRef = inst}
            /> : null
          }
          {this.state.card && this.state.card.OpenType === 'excelOut' ?
            <VerifyCardExcelOut
              card={this.state.card}
              dict={this.state.dict}
              wrappedComponentRef={(inst) => this.verifyRef = inst}
            /> : null
          }
        </Modal>
        {/* 设置全局配置及列表数据源 */}
        <Modal
src/templates/comtableconfig/index.scss
@@ -71,11 +71,6 @@
        }
      }
    }
    .tables {
      .ant-select-selection-selected-value {
        opacity: 0.4!important;
      }
    }
    .ant-list {
      margin-top: 20px;
      .ant-list-item {
@@ -144,7 +139,6 @@
    position: relative;
    width: calc(100vw - 235px);
    height: 100%;
    // overflow-y: hidden;
    background: #ffffff;
    .ant-switch.big {
      min-width: 60px;
@@ -176,224 +170,6 @@
      position: relative;
      padding: 0 0 40px;
      .search-list {
        padding: 1px 24px 20px;
        min-height: 87px;
        border-bottom: 1px solid #d9d9d9;
        > .ant-row {
          min-height: 65px;
        }
        .ant-row .ant-col-6 {
          padding: 0 12px!important;
        }
        .ant-row.ant-form-item .ant-col {
          padding: 0;
        }
        .page-card {
          position: relative;
          background: #ffffff;
          border-radius: 2px;
          padding-top: 15px;
          .ant-form-item {
            cursor: move;
            display: flex;
            margin-bottom: 0px;
            .ant-form-item-label {
              // width: 100px;
              height: 40px;
              label {
                width: 100%;
                cursor: move;
                overflow: hidden;
                display: inline-block;
                text-overflow: ellipsis;
                white-space: nowrap;
              }
            }
            .ant-form-item-control-wrapper {
              flex: 1 1;
              .ant-select {
                width: 100%;
                margin-top: 4px;
              }
              .ant-calendar-picker {
                margin-top: 4px;
              }
              .input-mask {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                opacity: 0;
                z-index: 2;
              }
              .data-range .ant-calendar-picker-input {
                padding: 4px 20px 4px 5px;
                font-size: 13px;
              }
            }
          }
          .edit {
            position: absolute;
            left: 0;
            top: 5px;
            color: #1890ff;
            cursor: pointer;
            display: none;
          }
          .edit.close {
            left: 20px;
            color: #ff4d4f;
          }
        }
        .page-card:hover {
          .edit {
            display: inline-block;
          }
        }
        .ant-calendar-picker {
          min-width: 100px!important;
          width: 100%;
        }
      }
      .action-list {
        position: relative;
        padding: 0px 20px 15px;
        min-height: 82px;
        > .ant-row {
          min-height: 80px;
        }
        .page-card {
          display: inline-block;
          margin: 0px 0px 0px 0px;
          padding: 15px 10px 0 0;
          position: relative;
          div {
            cursor: move;
          }
          .edit {
            position: absolute;
            left: 0;
            top: 0px;
            color: #1890ff;
            cursor: pointer;
            display: none;
          }
          .edit.close {
            left: 40px;
            color: #ff4d4f;
          }
          .edit.copy {
            left: 20px;
            color: #26C281;
          }
          .edit.profile {
            left: 60px;
            color: purple;
          }
          button {
            cursor: move;
            min-width: 65px;
            .anticon-table {
              font-size: 10px;
              position: absolute;
              right: 1px;
              bottom: 0px;
            }
          }
        }
        .page-card:hover {
          .edit {
            display: inline-block;
          }
        }
      }
      .column-list {
        position: relative;
        padding: 0px 20px;
        .ant-switch {
          position: absolute;
          right: 20px;
          top: -10px;
        }
        .column-copy {
          position: absolute;
          font-size: 16px;
          right: 75px;
          top: -7px;
          color: #26C281;
        }
        > .ant-row {
          background: #fafafa;
          border-radius: 4px;
          min-height: 47px;
          border: 1px solid #e8e8e8;
          .column-box {
            display: flex;
          }
          .column-box:not(:first-child) {
            border-top: 1px solid #e8e8e8;
          }
          .page-card {
            position: relative;
            padding: 0px;
            min-height: 45px;
            > div {
              padding: 12px 0px 0px;
              cursor: move;
              height: 100%;
              .ant-table-column-sorters {
                padding: 0px 8px 12px;
              }
              .ant-table-column-fields {
                padding: 0px 8px 5px;
              }
            }
            .ant-table-column-sorter {
              position: relative;
              display: inline-block;
              width: 24px;
              font-size: 12px;
              color: #bfbfbf;
              .anticon-caret-up {
                position: relative;
                left: 10px;
                top: -3px;
              }
              .anticon-caret-down {
                position: relative;
                left: -2px;
                top: 3px;
              }
            }
            .edit {
              position: absolute;
              left: 0;
              top: 0px;
              color: #1890ff;
              cursor: pointer;
              display: none;
            }
            .edit.close {
              left: 20px;
              color: #ff4d4f;
            }
            .ant-checkbox-inner {
              margin-top: 14px;
              margin-left: calc(50% - 8px);
            }
          }
          .page-card:hover {
            .edit {
              display: inline-block;
            }
          }
          .page-card:not(:last-child) {
            border-right: 1px solid #e8e8e8;
          }
        }
      }
      .tab-list {
        position: relative;
        padding: 30px 20px 0px;
@@ -533,30 +309,3 @@
  }
}
.common-table-fields-modal {
  .ant-modal {
    top: 50px;
    padding-bottom: 5px;
    .ant-modal-body {
      max-height: calc(100vh - 190px);
      overflow-y: auto;
      .ant-empty {
        margin: 15vh 8px;
      }
    }
    .ant-modal-body::-webkit-scrollbar {
      width: 7px;
    }
    .ant-modal-body::-webkit-scrollbar-thumb {
      border-radius: 5px;
      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
      background: rgba(0, 0, 0, 0.13);
    }
    .ant-modal-body::-webkit-scrollbar-track {
      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
      border-radius: 3px;
      border: 1px solid rgba(0, 0, 0, 0.07);
      background: rgba(0, 0, 0, 0);
    }
  }
}
src/templates/formtabconfig/index.jsx
@@ -25,7 +25,7 @@
import VerifyCard from '@/templates/zshare/verifycard'
import MenuForm from '@/templates/zshare/menuform'
import TabDragElement from '@/templates/zshare/tabdragelement'
import SourceElement from '@/templates/zshare/dragelement/source'
import SourceElement from '@/templates/zshare/dragsource'
import CreateFunc from '@/templates/zshare/createfunc'
import Source from './source'
import './index.scss'
src/templates/subtableconfig/actionform/index.jsx
File was deleted
src/templates/subtableconfig/actionform/index.scss
File was deleted
src/templates/subtableconfig/index.jsx
@@ -22,7 +22,7 @@
import SettingForm from './settingform'
import MenuForm from '@/templates/zshare/menuform'
import EditComponent from '@/templates/zshare/editcomponent'
import SourceElement from '@/templates/zshare/dragelement/source'
import SourceElement from '@/templates/zshare/dragsource'
import CreateFunc from '@/templates/zshare/createfunc'
import CreateInterface from '@/templates/zshare/createinterface'
import ChartComponent from '@/templates/zshare/chartcomponent'
@@ -54,21 +54,16 @@
    fields: null,            // 搜索条件及显示列,可选字段
    menuformlist: null,      // 基本信息表单字段
    formlist: null,          // 搜索条件、按钮、显示列表单字段
    formtemp: '',            // 表单类型,显示列、按钮、搜索条件
    card: null,              // 编辑元素
    menuloading: false,      // 菜单保存中
    menucloseloading: false, // 菜单关闭时,选择保存
    loading: false,          // 加载中,页面spin
    settingVisible: false,   // 全局配置模态框
    closeVisible: false,     // 关闭模态框
    tables: [],              // 可用表名
    selectedTables: [],      // 已选表名
    originConfig: null,      // 原配置
    originActions: null,     // 原始按钮信息,使用已有用户模板
    delActions: [],          // 删除按钮列表
    copyActions: [],         // 复制按钮组
    tabviews: [],            // 所有标签页
    profileVisible: false,   // 验证信息模态框
    optionLibs: null,        // 自定义下拉选项库
    thawButtons: [],         // 已选择要解冻的按钮
    activeKey: '0',          // 默认展开基本信息
@@ -132,7 +127,7 @@
    let _activeKey =  editSubTab ? editSubTab.activeKey : editTab.activeKey
    // 兼容
    // 兼容图表
    if (!_config.charts) {
      _config.expand = false
      _config.charts = [{
@@ -153,7 +148,6 @@
      config: _config,
      activeKey: _activeKey || '0',
      originConfig: _config,
      selectedTables: _config.tables || [],
      menuformlist: [
        {
          type: 'text',
@@ -347,7 +341,7 @@
      }
      let _LongParam = ''
      let _config = {...config, tables: this.state.selectedTables, ...res}
      let _config = {...config, ...res}
      // 未设置数据源或主键时,启用状态为false
      if (_config.setting.interType === 'inner' && !_config.setting.innerFunc && !_config.setting.dataresource) {
@@ -803,7 +797,7 @@
      })
    } else {
      this.menuformRef.handleConfirm().then(res => {
        let _config = {...config, tables: this.state.selectedTables, ...res}
        let _config = {...config, ...res}
        if (!is(fromJS(originConfig), fromJS(_config))) {
          this.setState({
@@ -930,7 +924,7 @@
      })
    } else {
      this.menuformRef.handleConfirm().then(res => {
        let _config = {...config, tables: this.state.selectedTables, ...res}
        let _config = {...config, ...res}
        if (!is(fromJS(originConfig), fromJS(_config))) {
          notification.warning({
@@ -1290,7 +1284,7 @@
              <Icon type="setting" onClick={this.changeSetting} />
              <SearchComponent
                menu={{MenuID: this.state.config.uuid, MenuName: this.state.config.tabName}}
                config={this.state.config}
                config={config}
                pasteContent={this.state.pasteContent}
                sysRoles={this.props.sysRoles}
                optionLibs={this.state.optionLibs}
src/templates/zshare/colspanform/index.jsx
File was deleted
src/templates/zshare/colspanform/index.scss
File was deleted
src/templates/zshare/columnform/index.jsx
File was deleted
src/templates/zshare/columnform/index.scss
File was deleted
src/templates/zshare/dragelement/actioncard.jsx
File was deleted
src/templates/zshare/dragelement/card.jsx
File was deleted
src/templates/zshare/dragelement/index.jsx
File was deleted
src/templates/zshare/dragelement/itemtypes.js
File was deleted
src/templates/zshare/dragsource/index.jsx
src/templates/zshare/dragsource/index.scss
File was renamed from src/templates/zshare/dragelement/index.scss
@@ -6,10 +6,4 @@
  margin: 0px 0px 10px;
  cursor: move;
  border-radius: 4px;
}
.common-drawarea-placeholder {
  width: 100%;
  line-height: 65px;
  text-align: center;
  color: #bcbcbc;
}
src/templates/zshare/exceleditable/index.jsx
File was deleted
src/templates/zshare/exceleditable/index.scss
File was deleted
src/templates/zshare/gridbtnform/index.jsx
File was deleted
src/templates/zshare/gridbtnform/index.scss
File was deleted
src/templates/zshare/modalform/index.jsx
@@ -4,7 +4,7 @@
import { formRule } from '@/utils/option.js'
import { dateOptions } from '@/utils/option.js'
import Utils from '@/utils/utils.js'
import EditTable from '../modaleditable'
import EditTable from './modaleditable'
import './index.scss'
const { TextArea } = Input
src/templates/zshare/modalform/modaleditable/index.jsx
src/templates/zshare/modalform/modaleditable/index.scss
src/templates/zshare/searchform/index.jsx
File was deleted
src/templates/zshare/searchform/index.scss
File was deleted
src/templates/zshare/verifycardexcelin/columnform/index.jsx
File was deleted
src/templates/zshare/verifycardexcelin/columnform/index.scss
src/templates/zshare/verifycardexcelin/customscript/index.jsx
File was deleted
src/templates/zshare/verifycardexcelin/customscript/index.scss
src/templates/zshare/verifycardexcelin/index.jsx
File was deleted
src/templates/zshare/verifycardexcelin/index.scss
File was deleted
src/templates/zshare/verifycardexcelin/uniqueform/index.jsx
File was deleted
src/templates/zshare/verifycardexcelin/uniqueform/index.scss
src/templates/zshare/verifycardexcelout/columnform/index.jsx
File was deleted
src/templates/zshare/verifycardexcelout/columnform/index.scss
src/templates/zshare/verifycardexcelout/index.jsx
File was deleted
src/templates/zshare/verifycardexcelout/index.scss
File was deleted
src/templates/zshare/verifycardprint/editable/index.jsx
File was deleted
src/templates/zshare/verifycardprint/editable/index.scss
File was deleted
src/templates/zshare/verifycardprint/index.jsx
File was deleted
src/templates/zshare/verifycardprint/index.scss
File was deleted