king
2019-12-21 65e310e342effbb7d98bd5f97b3404a44e3c5233
2019-12-21
19个文件已修改
5个文件已添加
659 ■■■■■ 已修改文件
src/assets/css/main.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tabview/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/comtable.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/comtable.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.scss 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/mutilform/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/dragelement/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/dragelement/itemtypes.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.scss 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/source.jsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/tabdragelement/card.jsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/tabdragelement/index.jsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/tabdragelement/index.scss 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/tabform/index.jsx 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/tabform/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/settingform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/source.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/main.scss
@@ -34,7 +34,7 @@
/*背景色*/
html, body {
  width: 100%;
  font-size: 10px;
  font-size: 14px;
}
#root {
  height: 100%;
src/components/header/index.scss
@@ -52,7 +52,7 @@
    line-height: 48px;
    li {
      float: left;
      font-size: 1.8rem;
      font-size: 1.3rem;
      cursor: pointer;
      span {
        padding: 0 10px;
@@ -84,7 +84,7 @@
    }
    span {
      color: #ffffff;
      font-size: 1.3rem;
      font-size: 0.95rem;
      .username {
        display: inline-block;
        height: 30px;
src/components/sidemenu/index.scss
@@ -32,7 +32,7 @@
    background: #06b4f7;
  }
  .ant-menu-inline .ant-menu-item {
    font-size: 1.5rem;
    font-size: 1.1rem;
  }
  .ant-menu-dark.ant-menu-inline .ant-menu-submenu-title {
    margin: 0;
src/components/tabview/index.jsx
@@ -4,7 +4,8 @@
import { is, fromJS } from 'immutable'
import {Tabs, Icon, Button, ConfigProvider, message} from 'antd'
import {modifyTabview, toggleIsiframe} from '@/store/action'
import asyncComponent from '@/utils/asyncComponent'
// import asyncComponent from '@/utils/asyncComponent'
import asyncComponent from '@/utils/asyncLoadComponent'
import NotFount from '@/components/404'
import enUS from 'antd/es/locale/en_US'
import zhCN from 'antd/es/locale/zh_CN'
src/locales/en-US/comtable.js
@@ -39,9 +39,12 @@
  'header.menu.openType.newWindow': 'A new window',
  'header.menu.newpage.service': 'Customer Service',
  'header.menu.func.create': '创建存储过程',
  'header.menu.tab': '标签页',
  'header.menu.tab.subtable': '子表',
  'header.form.search.placeholder': 'Please add search criteria',
  'header.form.modal.placeholder': 'Please add the form',
  'header.form.action.placeholder': 'Please add buttons',
  'header.form.tab.placeholder': '请添加标签页',
  'header.form.column.placeholder': 'Please add columns',
  'header.form.column.source': 'Columns',
  'header.form.column.target': '已添加',
@@ -69,6 +72,7 @@
  'header.form.pageTemplate': '页面模板',
  'header.form.type': 'Type',
  'header.form.text': 'Text',
  'header.form.description': '描述',
  'header.form.textarea': '多行文本',
  'header.form.picture': '图片',
  'header.form.number': '数字',
src/locales/zh-CN/comtable.js
@@ -39,9 +39,12 @@
  'header.menu.openType.newWindow': '新窗口',
  'header.menu.newpage.service': '客服',
  'header.menu.func.create': '创建存储过程',
  'header.menu.tab': '标签页',
  'header.menu.tab.subtable': '子表',
  'header.form.search.placeholder': '请添加搜索条件',
  'header.form.modal.placeholder': '请添加表单',
  'header.form.action.placeholder': '请添加按钮',
  'header.form.tab.placeholder': '请添加标签页',
  'header.form.column.placeholder': '请添加显示列',
  'header.form.column.source': '显示列',
  'header.form.column.target': '已添加',
@@ -69,6 +72,7 @@
  'header.form.pageTemplate': '页面模板',
  'header.form.type': '类型',
  'header.form.text': '文本',
  'header.form.description': '描述',
  'header.form.textarea': '多行文本',
  'header.form.picture': '图片',
  'header.form.number': '数字',
src/router/index.js
@@ -1,10 +1,12 @@
import React, {Component} from 'react'
import {HashRouter, Switch, Route, Redirect} from 'react-router-dom'
import moment from 'moment'
import md5 from 'md5'
import moment from 'moment'
import asyncComponent from '@/utils/asyncComponent'
const main = asyncComponent(() => import('@/views/main'))
const login = asyncComponent(() => import('@/views/login'))
import asyncLoadComponent from '@/utils/asyncLoadComponent'
const main = asyncLoadComponent(() => import('@/views/main'))
const login = asyncLoadComponent(() => import('@/views/login'))
const NotFound = asyncComponent(() => import('@/views/404'))
const routers = [
src/tabviews/commontable/index.jsx
@@ -1,14 +1,13 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { BackTop, notification} from 'antd'
import { BackTop, notification, Spin} from 'antd'
import moment from 'moment'
import Api from '@/api'
import MainSearch from './mainSearch'
import MainAction from './mainAction'
import MainTable from './mainTable'
import NotFount from '@/components/404'
import Loading from '@/components/loading'
import zhCN from '@/locales/zh-CN/main.js'
import enUS from '@/locales/en-US/main.js'
import Utils from '@/utils/utils.js'
@@ -294,7 +293,7 @@
    const { arr_field, pageIndex, pageSize, orderColumn, orderType, search, setting } = this.state
    let _search = Utils.joinMainSearchkey(search)
    _search = _search ? 'where (' + _search + ')' : ''
    _search = _search ? 'where ' + _search : ''
    let param = {
      func: 'sPC_Get_TableData',
@@ -306,7 +305,7 @@
    let LText = `select top ${pageSize} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${orderBy}) as rows from ${setting.dataresource} ${_search}) tmptable where rows > ${pageSize * (pageIndex - 1)} order by tmptable.rows`
    let DateCount = `select count(1) as total from ${setting.dataresource} ${_search}`
    console.log(LText)
    param.LText = Utils.formatOptions(LText)
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
@@ -428,7 +427,7 @@
    let orderBy = orderColumn ? (orderColumn + ' ' + orderType) : setting.order
    let LText = `select ${_arr_label_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${orderBy}) as rows from ${setting.dataresource} ${_search}) tmptable order by tmptable.rows`
    console.log(LText)
    param.LText = Utils.formatOptions(LText)
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
@@ -472,7 +471,7 @@
    return (
      <div className="commontable" id={'commontable' + this.props.MenuID}>
        {loadingview && <Loading />}
        {loadingview && <Spin size="large" />}
        {searchlist && searchlist.length > 0 ?
          <MainSearch
            refreshdata={this.refreshbysearch}
src/tabviews/commontable/index.scss
@@ -15,9 +15,14 @@
    top: 40px;
    max-width: 95%;
    .ant-modal-body {
      max-height: calc(100vh - 250px);
      max-height: calc(100vh - 265px);
    }
  }
  > .ant-spin {
    position: fixed;
    left: calc(50vw - 22px);
    top: calc(50vh - 70px);
  }
}
.ant-back-top {
  bottom: 30px;
src/tabviews/commontable/mutilform/index.jsx
@@ -114,9 +114,16 @@
      formlist: formlist
    }, () => {
      if (action.setting && action.setting.focus) {
        let _item = document.getElementById(action.setting.focus)
        if (_item) {
          _item.select()
        try {
          let _form = document.getElementById('main-form-box')
          let _item = _form.getElementsByTagName('input')
          _item = [..._item]
          _item.forEach(input => {
            if (!input || input.id !== action.setting.focus) return
            input.select()
          })
        } catch {
          console.warn('表单获取失败!')
        }
      }
    })
@@ -202,7 +209,7 @@
          <Col span={24 / cols} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.field, {
                initialValue: item.initval || 'text',
                initialValue: item.initval || '',
                rules: [
                  {
                    required: item.required === 'true',
@@ -426,7 +433,7 @@
      }
    }
    return (
      <Form {...formItemLayout} className="ant-advanced-search-form main-form-field" id="form-box">
      <Form {...formItemLayout} className="ant-advanced-search-form main-form-field" id="main-form-box">
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
src/templates/comtableconfig/dragelement/index.scss
@@ -1,7 +1,7 @@
.common-source-item {
  display: block;
  box-shadow: 0px 0px 2px #bcbcbc;
  padding: 0.5rem 1rem;
  padding: 0.4rem 0.7rem;
  background-color: white;
  margin: 0px 0px 10px;
  cursor: move;
src/templates/comtableconfig/dragelement/itemtypes.js
@@ -3,5 +3,6 @@
  form: 'form',
  search: 'search',
  action: 'action',
  columns: 'columns'
  columns: 'columns',
  tab: 'tab'
}
src/templates/comtableconfig/index.jsx
@@ -7,8 +7,10 @@
import { Button, Card, Modal, Collapse, notification, Spin, Select, List, Icon, Empty, Switch, Tooltip } from 'antd'
import moment from 'moment'
import DragElement from './dragelement'
import TabDragElement from './tabdragelement'
import SourceElement from './dragelement/source'
import Api from '@/api'
import TabForm from './tabform'
import SearchForm from './searchform'
import ActionForm from './actionform'
import ColumnForm from './columnform'
@@ -42,6 +44,7 @@
    dict: CommonDict,        // 字典
    config: null,            // 页面配置
    visible: false,          // 搜索条件、按钮、显示列,模态框显示控制
    modalTitle: '',          // 模态框的标题
    tableVisible: false,     // 数据表字段模态框
    addType: '',             // 添加类型-搜索条件或显示列
    tableColumns: [],        // 表格显示列
@@ -53,6 +56,7 @@
    searchloading: false,    // 搜索条件加载中
    actionloading: false,    // 按钮加载中
    columnsloading: false,   // 显示列加载中
    tabloading: false,       // 标签页加载中
    menuloading: false,      // 菜单保存中
    menucloseloading: false, // 菜单关闭时,选择保存
    loading: false,          // 加载中,页面spin
@@ -107,6 +111,9 @@
        return item
      })
    }
    _config.tabs = _config.tabs || []
    _config.subtabs = _config.subtabs || []
    this.setState({
      originActions: _oriActions,
@@ -280,6 +287,8 @@
          this.handleAction(card)
        } else if (type === 'columns') {
          this.handleColumn(card)
        } else if (type === 'tabs' || type === 'subtabs') {
          this.handleTab(card)
        }
      })
    } else {
@@ -291,6 +300,7 @@
    this.setState({
      visible: true,
      formtemp: 'search',
      modalTitle: '编辑-搜索条件',
      card: card,
      formlist: [
        {
@@ -474,11 +484,12 @@
    })
  }
  handleAction = (card) => {
  handleAction = (card, type) => {
    let ableField = this.props.permFuncField.join(', ')
    this.setState({
      visible: true,
      formtemp: 'action',
      modalTitle: type === 'copy' ? '复制-按钮' : '编辑-按钮',
      card: card,
      formlist: [
        {
@@ -692,6 +703,7 @@
      this.setState({
        visible: true,
        formtemp: 'columns',
        modalTitle: '编辑-显示列',
        card: card,
        formlist: [
          {
@@ -900,10 +912,90 @@
    }
  }
  handleTab = (card) => {
    this.setState({
      visible: true,
      formtemp: 'tabs',
      modalTitle: '编辑-标签页',
      card: card,
      formlist: [
        {
          type: 'text',
          key: 'label',
          label: this.state.dict['header.form.name'],
          initVal: card.label || '',
          required: true
        },
        {
          type: 'select',
          key: 'type',
          label: this.state.dict['header.form.type'],
          initVal: card.type || '',
          required: true,
          options: [{
            value: 'SubTable',
            text: this.state.dict['header.menu.tab.subtable']
          }]
        },
        {
          type: 'select',
          key: 'linkId',
          label: '关联标签',
          initVal: card.linkId || '',
          required: true,
          options: [{
            value: 'table',
            text: 'table'
          }, {
            value: 'bar-chart',
            text: 'bar-chart'
          }, {
            value: 'pie-chart',
            text: 'pie-chart'
          }, {
            value: 'line-chart',
            text: 'line-chart'
          }]
        },
        {
          type: 'select',
          key: 'icon',
          label: this.state.dict['header.menu.icon'],
          initVal: card.icon || '',
          required: false,
          options: [{
            value: '',
            text: this.state.dict['header.form.empty']
          }, {
            value: 'table',
            text: 'table'
          }, {
            value: 'bar-chart',
            text: 'bar-chart'
          }, {
            value: 'pie-chart',
            text: 'pie-chart'
          }, {
            value: 'line-chart',
            text: 'line-chart'
          }]
        },
        {
          type: 'text',
          key: 'description',
          label: this.state.dict['header.form.description'],
          initVal: card.description || '',
          required: false
        }
      ]
    })
  }
  handleGridBtn = () => {
    this.setState({
      visible: true,
      formtemp: 'gridbtn'
      formtemp: 'gridbtn',
      modalTitle: '编辑-操作列',
    })
  }
@@ -1009,12 +1101,14 @@
          searchloading: true,
          actionloading: true,
          columnsloading: true,
          tabloading: true,
          visible: false
        }, () => {
          this.setState({
            searchloading: false,
            actionloading: false,
            columnsloading: false
            columnsloading: false,
            tabloading: false
          })
        })
      })
@@ -1576,13 +1670,20 @@
            return true
          }
        })
        let refreshtype = element.type + 'loading'
        if (/^tab/.test(refreshtype)) {
          refreshtype = 'tabloading'
        }
        _this.setState({
          config: _config,
          delActions: [..._this.state.delActions, element.card.uuid],
          [element.type + 'loading']: true
          [refreshtype]: true
        }, () => {
          _this.setState({
            [element.type + 'loading']: false
            [refreshtype]: false
          })
        })
      },
@@ -1613,6 +1714,12 @@
      }
      if (config.columns[0] && config.columns[0].origin) {
        config.columns = config.columns.filter(item => !item.origin)
      }
      if (config.tabs[0] && config.tabs[0].origin) {
        config.tabs = config.tabs.filter(item => !item.origin)
      }
      if (config.subtabs[0] && config.subtabs[0].origin) {
        config.subtabs = config.subtabs.filter(item => !item.origin)
      }
      let _LongParam = ''
@@ -1869,7 +1976,9 @@
    if (
      (config.search[0] && config.search[0].origin) ||
      (config.action[0] && config.action[0].origin) ||
      (config.columns[0] && config.columns[0].origin)
      (config.columns[0] && config.columns[0].origin) ||
      (config.tabs[0] && config.tabs[0].origin) ||
      (config.subtabs[0] && config.subtabs[0].origin)
    ) {
      isAdd = true
    }
@@ -2229,7 +2338,9 @@
    if (
      (config.search[0] && config.search[0].origin) ||
      (config.action[0] && config.action[0].origin) ||
      (config.columns[0] && config.columns[0].origin)
      (config.columns[0] && config.columns[0].origin) ||
      (config.tabs[0] && config.tabs[0].origin) ||
      (config.subtabs[0] && config.subtabs[0].origin)
    ) {
      isAdd = true
    }
@@ -2421,6 +2532,13 @@
                </div>
                <Button type="primary" block onClick={() => this.queryField('columns')}>{this.state.dict['header.menu.column.add']}</Button>
              </Panel>
              <Panel header={this.state.dict['header.menu.tab']} key="4">
                <div className="search-element">
                  {Source.tabItems.map((item, index) => {
                    return (<SourceElement key={index} content={item}/>)
                  })}
                </div>
              </Panel>
            </Collapse>
          </div>
          <div className="setting">
@@ -2439,12 +2557,12 @@
                </Tooltip>
                {!this.state.searchloading ?
                  <DragElement
                    list={this.state.config.search}
                    type="search"
                    placeholder={this.state.dict['header.form.search.placeholder']}
                    list={this.state.config.search}
                    handleList={this.handleList}
                    handleMenu={this.handleSearch}
                    deleteMenu={this.deleteElement}
                    placeholder={this.state.dict['header.form.search.placeholder']}
                  /> : null
                }
              </div>
@@ -2454,13 +2572,13 @@
                </Tooltip>
                {!this.state.actionloading ?
                  <DragElement
                    list={this.state.config.action}
                    type="action"
                    placeholder={this.state.dict['header.form.action.placeholder']}
                    list={this.state.config.action}
                    handleList={this.handleList}
                    handleMenu={this.handleAction}
                    copyElement={this.handleAction}
                    copyElement={(val) => this.handleAction(val, 'copy')}
                    deleteMenu={this.deleteElement}
                    placeholder={this.state.dict['header.form.action.placeholder']}
                  /> : null
                }
              </div>
@@ -2471,16 +2589,33 @@
                <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}
                    type="columns"
                    placeholder={this.state.dict['header.form.column.placeholder']}
                    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
                }
              </div>
              <div className="tab-list">
                <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《标签页》中,选择对应类型的标签页拖至此处添加。">
                  <Icon type="question-circle" />
                </Tooltip>
                {/* {this.state.config.tabs.length > 0 ? <Icon type="setting" onClick={this.changeSetting} /> : null} */}
                {!this.state.tabloading ?
                  <TabDragElement
                    type="tabs"
                    list={this.state.config.tabs}
                    setting={this.state.config.setting}
                    handleList={this.handleList}
                    handleMenu={this.handleTab}
                    deleteMenu={this.deleteElement}
                    placeholder={this.state.dict['header.form.tab.placeholder']}
                  /> : null
                }
              </div>
@@ -2489,11 +2624,10 @@
        </DndProvider>
        {/* 编辑搜索条件、按钮、显示列 */}
        <Modal
          title={this.state.dict['header.edit']}
          title={this.state.modalTitle}
          visible={this.state.visible}
          width={700}
          onCancel={() => { this.setState({ visible: false }) }}
          // onOk={this.handleSubmit}
          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,
@@ -2541,6 +2675,15 @@
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'tabs' ?
            <TabForm
              type="tabs"
              dict={this.state.dict}
              card={this.state.card}
              formlist={this.state.formlist}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
        </Modal>
        {/* 根据字段名添加显示列及搜索条件 */}
        <Modal
src/templates/comtableconfig/index.scss
@@ -363,10 +363,58 @@
          }
        }
      }
      .tab-list {
        position: relative;
        padding: 30px 20px 0px;
        .ant-switch {
          position: absolute;
          right: 20px;
          top: 20px;
        }
        > .ant-row {
          min-height: 47px;
          .page-card {
            position: relative;
            padding: 0px;
            > div {
              padding: 12px 0px 0px;
              cursor: move;
            }
          }
          .ant-tabs-tab {
            .edit {
              position: absolute;
              left: 0;
              top: 0px;
              color: #1890ff;
              cursor: pointer;
              display: none;
            }
            .edit.close {
              left: 20px;
              color: #ff4d4f;
            }
          }
          .ant-tabs-bar {
            min-height: 55px;
          }
          .ant-tabs-tab:hover {
            .edit {
              display: inline-block;
            }
          }
        }
      > .anticon-setting {
        position: absolute;
        font-size: 16px;
        right: 10px;
          font-size: 18px;
          right: 15px;
          top: 30px;
        }
      }
      > .anticon-setting {
        position: absolute;
        font-size: 18px;
        right: 15px;
        top: 10px;
      }
    }
src/templates/comtableconfig/source.jsx
@@ -198,7 +198,28 @@
      style: 'button',
      show: 'horizontal',
      Width: 120
    },
    tabs: [
      {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'tab1',
        icon: '',
        type: 'SubTable',
        linkId: '',
        description: ''
      },
      {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'tab2',
        icon: '',
        type: 'SubTable',
        linkId: '',
        description: ''
    }
    ],
    subtabs: []
  }
  searchItems = [
@@ -329,6 +350,14 @@
      url: ''
    }
  ]
  tabItems = [
    {
      type: 'tabs',
      label: CommonDict['header.menu.tab.subtable'],
      subType: 'SubTable',
    }
  ]
}
export default new CommonTableBaseData()
src/templates/comtableconfig/tabdragelement/card.jsx
New file
@@ -0,0 +1,41 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Icon } from 'antd'
import './index.scss'
const Card = ({ id, type, card, moveCard, findCard, editCard, delCard, hasDrop }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: type, id, originalIndex },
    collect: monitor => ({
      isDragging: monitor.isDragging(),
    }),
  })
  const [, drop] = useDrop({
    accept: type,
    canDrop: () => true,
    drop: (item) => {
      if (!item.hasOwnProperty('originalIndex')) {
        hasDrop(card)
      }
    },
    hover({ id: draggedId }) {
      if (!draggedId) return
      if (draggedId !== id) {
        const { index: overIndex } = findCard(id)
        moveCard(draggedId, overIndex)
      }
    },
  })
  const opacity = isDragging ? 0 : 1
  return (
    <div className="page-card" style={{ opacity: opacity}}>
      <div ref={node => drag(drop(node))}>
        {card.icon ? <Icon type={card.icon} /> : null}
        {card.label}
      </div>
    </div>
  )
}
export default Card
src/templates/comtableconfig/tabdragelement/index.jsx
New file
@@ -0,0 +1,109 @@
import React, { useState } from 'react'
import { useDrop } from 'react-dnd'
import update from 'immutability-helper'
import { Tabs, Icon } from 'antd'
import Utils from '@/utils/utils.js'
import Card from './card'
import './index.scss'
const { TabPane } = Tabs
const Container = ({list, type, setting, placeholder, handleList, handleMenu, deleteMenu }) => {
  let target = null
  const [cards, setCards] = useState(list)
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    setCards(_cards)
    handleList(type, _cards)
  }
  const findCard = id => {
    const card = cards.filter(c => `${c.uuid}` === id)[0]
    return {
      card,
      index: cards.indexOf(card),
    }
  }
  const hasDrop = (item) => {
    target = item
  }
  const [, drop] = useDrop({
    accept: type,
    drop(item) {
      if (item.hasOwnProperty('originalIndex')) {
        return
      }
      let newcard = {}
      newcard.uuid = Utils.getuuid()
      newcard.label = 'tab'
      newcard.icon = ''
      newcard.type = item.subType
      newcard.linkId = ''
      newcard.description = ''
      let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0
      if (target) {
        targetId = target.uuid
      }
      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
    }
  })
  const edit = (card) => {
    handleMenu(card)
  }
  const del = (card) => {
    deleteMenu({card: card, type: type})
  }
  return (
    <div ref={drop} className="ant-row">
      <Tabs defaultActiveKey="0" tabPosition="top">
        {cards.map((card, index) => (
          <TabPane tab={
            <div key={card.uuid}>
              <Card
                key={card.uuid}
                id={`${card.uuid}`}
                type={type}
                card={card}
                moveCard={moveCard}
                findCard={findCard}
                hasDrop={hasDrop}
              />
              <Icon className="edit" type="edit" onClick={() => edit(card)} />
              <Icon className="edit close" type="close" onClick={() => del(card)} />
            </div>
          } key={`${index}`}>
            {card.description}
          </TabPane>
        ))}
      </Tabs>
      {cards.length === 0 ?
        <div className="commontab-drawarea-placeholder">
          {placeholder}
        </div> : null
      }
    </div>
  )
}
export default Container
src/templates/comtableconfig/tabdragelement/index.scss
New file
@@ -0,0 +1,15 @@
.common-source-item {
  display: block;
  box-shadow: 0px 0px 2px #bcbcbc;
  padding: 0.4rem 0.7rem;
  background-color: white;
  margin: 0px 0px 10px;
  cursor: move;
  border-radius: 4px;
}
.commontab-drawarea-placeholder {
  position: absolute;
  top: 25px;
  left: calc(50% - 50px);
  color: #bcbcbc;
}
src/templates/comtableconfig/tabform/index.jsx
New file
@@ -0,0 +1,149 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Select, Icon } from 'antd'
import './index.scss'
class MainTab extends Component {
  static propTpyes = {
    type: PropTypes.string,  // 类型
    dict: PropTypes.object,  // 字典项
    formlist: PropTypes.any, // 表单
    card: PropTypes.object   // 标签页信息
  }
  state = {
    formlist: null           // 表单
  }
  /**
   * @description 表单预处理
   */
  UNSAFE_componentWillMount () {
    const { formlist } = this.props
    let type = formlist.filter(cell => cell.key === 'type')[0].initVal
    console.log(type)
    this.setState({
      formlist: formlist
    })
  }
  /**
   * @description 标签页类型切换
   */
  openTypeChange = (key, value) => {
    console.log(value)
    // if (key === 'type') {
    //   console.log(value)
    //   this.setState({
    //     formlist: this.state.formlist.map(form => {
    //       return form
    //     })
    //   }, () => {
    //     this.setState({
    //       formlist: this.state.formlist.map(form => {
    //         return form
    //       })
    //     })
    //   })
    // }
  }
  getFields() {
    const { getFieldDecorator } = this.props.form
    const fields = []
    this.state.formlist.forEach((item, index) => {
      if (item.hidden) return
      if (item.type === 'text') { // 文本搜索
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') { // 下拉搜索
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  onChange={(value) => {this.openTypeChange(item.key, value)}}
                >
                  {item.options.map((option, i) =>
                    <Select.Option id={`${i}`} title={option.text} key={`${i}`} value={option.value}>
                      {item.key === 'icon' && i !== 0 ? <Icon type={option.text} /> : option.text}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      }
    })
    return fields
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          values.uuid = this.props.card.uuid
          resolve({
            type: this.props.type,
            values
          })
        } else {
          reject(err)
        }
      })
    })
  }
  render() {
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    return (
      <Form {...formItemLayout} className="ant-advanced-search-form commontable-tab-form">
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
  }
}
export default Form.create()(MainTab)
src/templates/comtableconfig/tabform/index.scss
New file
@@ -0,0 +1,3 @@
.ant-advanced-search-form.commontable-tab-form {
  min-height: 180px;
}
src/templates/modalconfig/dragelement/index.scss
@@ -1,7 +1,7 @@
.modal-source-item {
  display: block;
  box-shadow: 0px 0px 2px #bcbcbc;
  padding: 0.5rem 1rem;
  padding: 0.4rem 0.7rem;
  background-color: white;
  margin: 0px 0px 10px;
  cursor: move;
src/templates/modalconfig/settingform/index.jsx
@@ -145,7 +145,7 @@
          <Col span={12}>
            <Form.Item label="挂载对象">
              {getFieldDecorator('container', {
                initialValue: config.setting.container || 'view'
                initialValue: config.setting.container || 'tab'
              })(
                <Radio.Group>
                  <Radio value="view">页面</Radio>
src/templates/modalconfig/source.jsx
@@ -11,7 +11,7 @@
      title: '',
      width: 60,
      cols: '2',
      container: 'view',
      container: 'tab',
      focus: '',
      finish: 'close',
      clickouter: 'unclose'
src/utils/utils.js
@@ -213,8 +213,16 @@
        item.value = item.value ? [moment().subtract(item.value * 7, 'days').startOf('week').format('YYYY-MM-DD'),
          moment().subtract(item.value * 7, 'days').endOf('week').format('YYYY-MM-DD')] : ''
      } else if (item.type === 'daterange') {
        item.value = item.value ? [moment().subtract(item.value, 'days').format('YYYY-MM-DD'),
          moment().subtract(item.value === 1 ? 1 : 0, 'days').format('YYYY-MM-DD')] : ''
        let _val = item.value
        if (_val) {
          try {
            _val = JSON.parse(_val)
          } catch {
            _val = ''
          }
        }
        item.value = _val ? [moment().subtract(_val[0], 'days').format('YYYY-MM-DD'),
          moment().subtract(_val[1], 'days').format('YYYY-MM-DD')] : ''
      }
      newsearches.push(item)
    })
@@ -479,6 +487,7 @@
    @PageSize nvarchar(50)='',
    @OrderCol nvarchar(50)='',
    @OrderType nvarchar(50)='',
    @exceltype nvarchar(50)='',
    @sEPTMenuNo nvarchar(50)='${menu.MenuNo}',
    @lang nvarchar(50)='',
    @debug nvarchar(50)='',