From 65e310e342effbb7d98bd5f97b3404a44e3c5233 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期六, 21 十二月 2019 00:29:36 +0800
Subject: [PATCH] 2019-12-21

---
 src/components/tabview/index.jsx                       |    3 
 src/components/header/index.scss                       |    4 
 src/components/sidemenu/index.scss                     |    2 
 src/templates/modalconfig/settingform/index.jsx        |    2 
 src/templates/comtableconfig/source.jsx                |   31 ++
 src/templates/comtableconfig/dragelement/itemtypes.js  |    3 
 src/templates/comtableconfig/index.jsx                 |  175 +++++++++++++-
 src/router/index.js                                    |    8 
 src/templates/comtableconfig/tabform/index.scss        |    3 
 src/templates/comtableconfig/dragelement/index.scss    |    2 
 src/templates/modalconfig/dragelement/index.scss       |    2 
 src/tabviews/commontable/mutilform/index.jsx           |   17 +
 src/tabviews/commontable/index.scss                    |    7 
 src/templates/comtableconfig/index.scss                |   52 ++++
 src/templates/comtableconfig/tabdragelement/index.scss |   15 +
 src/templates/modalconfig/source.jsx                   |    2 
 src/templates/comtableconfig/tabdragelement/index.jsx  |  109 +++++++++
 src/locales/zh-CN/comtable.js                          |    4 
 src/tabviews/commontable/index.jsx                     |   11 
 src/templates/comtableconfig/tabdragelement/card.jsx   |   41 +++
 src/locales/en-US/comtable.js                          |    4 
 src/templates/comtableconfig/tabform/index.jsx         |  149 ++++++++++++
 src/utils/utils.js                                     |   21 +
 src/assets/css/main.scss                               |    2 
 24 files changed, 619 insertions(+), 50 deletions(-)

diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss
index 2776c11..fd9f0eb 100644
--- a/src/assets/css/main.scss
+++ b/src/assets/css/main.scss
@@ -34,7 +34,7 @@
 /*鑳屾櫙鑹�*/
 html, body {
   width: 100%;
-  font-size: 10px;
+  font-size: 14px;
 }
 #root {
   height: 100%;
diff --git a/src/components/header/index.scss b/src/components/header/index.scss
index ac20a39..ddaf1df 100644
--- a/src/components/header/index.scss
+++ b/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;
diff --git a/src/components/sidemenu/index.scss b/src/components/sidemenu/index.scss
index 49ebdb2..89a2f0a 100644
--- a/src/components/sidemenu/index.scss
+++ b/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;
diff --git a/src/components/tabview/index.jsx b/src/components/tabview/index.jsx
index a4d322f..415ba69 100644
--- a/src/components/tabview/index.jsx
+++ b/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'
diff --git a/src/locales/en-US/comtable.js b/src/locales/en-US/comtable.js
index 19a812b..80b53b1 100644
--- a/src/locales/en-US/comtable.js
+++ b/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': '鏁板瓧',
diff --git a/src/locales/zh-CN/comtable.js b/src/locales/zh-CN/comtable.js
index 4af26b3..d78fa70 100644
--- a/src/locales/zh-CN/comtable.js
+++ b/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': '鏁板瓧',
diff --git a/src/router/index.js b/src/router/index.js
index 1833c7e..bf812ca 100644
--- a/src/router/index.js
+++ b/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 = [
diff --git a/src/tabviews/commontable/index.jsx b/src/tabviews/commontable/index.jsx
index 7bdf4db..d17c945 100644
--- a/src/tabviews/commontable/index.jsx
+++ b/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}
diff --git a/src/tabviews/commontable/index.scss b/src/tabviews/commontable/index.scss
index 92fae90..65aee8b 100644
--- a/src/tabviews/commontable/index.scss
+++ b/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;
diff --git a/src/tabviews/commontable/mutilform/index.jsx b/src/tabviews/commontable/mutilform/index.jsx
index 4ceb1e2..a2aacd7 100644
--- a/src/tabviews/commontable/mutilform/index.jsx
+++ b/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>
     )
diff --git a/src/templates/comtableconfig/dragelement/index.scss b/src/templates/comtableconfig/dragelement/index.scss
index 8c9d54b..38776f9 100644
--- a/src/templates/comtableconfig/dragelement/index.scss
+++ b/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;
diff --git a/src/templates/comtableconfig/dragelement/itemtypes.js b/src/templates/comtableconfig/dragelement/itemtypes.js
index 0e7cd9a..9ea1f2c 100644
--- a/src/templates/comtableconfig/dragelement/itemtypes.js
+++ b/src/templates/comtableconfig/dragelement/itemtypes.js
@@ -3,5 +3,6 @@
   form: 'form',
   search: 'search',
   action: 'action',
-  columns: 'columns'
+  columns: 'columns',
+  tab: 'tab'
 }
diff --git a/src/templates/comtableconfig/index.jsx b/src/templates/comtableconfig/index.jsx
index 3db24cb..f1a2f66 100644
--- a/src/templates/comtableconfig/index.jsx
+++ b/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
diff --git a/src/templates/comtableconfig/index.scss b/src/templates/comtableconfig/index.scss
index e76a155..840a370 100644
--- a/src/templates/comtableconfig/index.scss
+++ b/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: 18px;
+          right: 15px;
+          top: 30px;
+        }
+      }
       > .anticon-setting {
         position: absolute;
-        font-size: 16px;
-        right: 10px;
+        font-size: 18px;
+        right: 15px;
         top: 10px;
       }
     }
diff --git a/src/templates/comtableconfig/source.jsx b/src/templates/comtableconfig/source.jsx
index 6119305..c95b5f3 100644
--- a/src/templates/comtableconfig/source.jsx
+++ b/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()
diff --git a/src/templates/comtableconfig/tabdragelement/card.jsx b/src/templates/comtableconfig/tabdragelement/card.jsx
new file mode 100644
index 0000000..2437661
--- /dev/null
+++ b/src/templates/comtableconfig/tabdragelement/card.jsx
@@ -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
diff --git a/src/templates/comtableconfig/tabdragelement/index.jsx b/src/templates/comtableconfig/tabdragelement/index.jsx
new file mode 100644
index 0000000..ba2c0c0
--- /dev/null
+++ b/src/templates/comtableconfig/tabdragelement/index.jsx
@@ -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
diff --git a/src/templates/comtableconfig/tabdragelement/index.scss b/src/templates/comtableconfig/tabdragelement/index.scss
new file mode 100644
index 0000000..dc8ed55
--- /dev/null
+++ b/src/templates/comtableconfig/tabdragelement/index.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/src/templates/comtableconfig/tabform/index.jsx b/src/templates/comtableconfig/tabform/index.jsx
new file mode 100644
index 0000000..eda77ec
--- /dev/null
+++ b/src/templates/comtableconfig/tabform/index.jsx
@@ -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)
\ No newline at end of file
diff --git a/src/templates/comtableconfig/tabform/index.scss b/src/templates/comtableconfig/tabform/index.scss
new file mode 100644
index 0000000..d92e41a
--- /dev/null
+++ b/src/templates/comtableconfig/tabform/index.scss
@@ -0,0 +1,3 @@
+.ant-advanced-search-form.commontable-tab-form {
+  min-height: 180px;
+}
\ No newline at end of file
diff --git a/src/templates/modalconfig/dragelement/index.scss b/src/templates/modalconfig/dragelement/index.scss
index d084f32..ac78306 100644
--- a/src/templates/modalconfig/dragelement/index.scss
+++ b/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;
diff --git a/src/templates/modalconfig/settingform/index.jsx b/src/templates/modalconfig/settingform/index.jsx
index 7959637..4a77626 100644
--- a/src/templates/modalconfig/settingform/index.jsx
+++ b/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>
diff --git a/src/templates/modalconfig/source.jsx b/src/templates/modalconfig/source.jsx
index 38fda2d..5bdcd00 100644
--- a/src/templates/modalconfig/source.jsx
+++ b/src/templates/modalconfig/source.jsx
@@ -11,7 +11,7 @@
       title: '',
       width: 60,
       cols: '2',
-      container: 'view',
+      container: 'tab',
       focus: '',
       finish: 'close',
       clickouter: 'unclose'
diff --git a/src/utils/utils.js b/src/utils/utils.js
index 8b0a88f..46e4704 100644
--- a/src/utils/utils.js
+++ b/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)='',
@@ -499,7 +508,7 @@
       BEGIN TRAN
         /*鍏蜂綋涓氬姟鎿嶄綔*/
         
-         /* 
+        /* 
         select top 10 * from sProcExcep order by id desc
         
         declare @UserName  nvarchar(50),@FullName nvarchar(50)
@@ -538,7 +547,7 @@
       RAISERROR(@ErrorMessage, /*-- Message text.*/
         @ErrorSeverity, /*-- Severity.*/
         @ErrorState  /*-- State.*/
-        );
+      );
     END CATCH
     
     GOTO_RETURN:
@@ -642,7 +651,7 @@
       BEGIN TRAN
         /*鍏蜂綋涓氬姟鎿嶄綔*/
         
-         /* 
+        /* 
         select top 10 * from sProcExcep order by id desc
         
         declare @UserName  nvarchar(50),@FullName nvarchar(50)
@@ -681,7 +690,7 @@
       RAISERROR(@ErrorMessage, /*-- Message text.*/
         @ErrorSeverity, /*-- Severity.*/
         @ErrorState  /*-- State.*/
-        );
+      );
     END CATCH
     
     GOTO_RETURN:

--
Gitblit v1.8.0