From cd42d41344f0f780e0c0ac0a3625aeb78160f9dd Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期五, 19 六月 2020 19:58:52 +0800
Subject: [PATCH] 2020-06-19

---
 src/mob/datasource/verifycard/settingform/index.scss  |   45 ++
 package-lock.json                                     |   31 +
 src/mob/datasource/verifycard/index.jsx               |   54 --
 src/components/header/index.jsx                       |    4 
 src/mob/datasource/verifycard/settingform/index.jsx   |  376 ++++++++++++++++++++
 src/mob/datasource/verifycard/customscript/index.jsx  |  142 ++++---
 src/mob/mobshell/index.jsx                            |   97 ++--
 src/mob/datasource/verifycard/settingform/utils.jsx   |   84 ++++
 /dev/null                                             |    9 
 src/mob/datasource/verifycard/customscript/index.scss |   32 +
 src/mob/modelsource/dragsource/index.jsx              |    4 
 src/mob/mobcard/mutilform/index.jsx                   |   35 +
 src/mob/modelsource/option.jsx                        |   10 
 src/views/mobdesign/index.scss                        |    2 
 package.json                                          |    1 
 src/mob/login/index.scss                              |    2 
 src/tabviews/zshare/actionList/normalbutton/index.jsx |   42 ++
 src/views/mobdesign/index.jsx                         |   67 +++
 src/mob/mobshell/card.jsx                             |   16 
 src/mob/mobcard/index.jsx                             |    2 
 src/utils/utils.js                                    |   22 
 21 files changed, 870 insertions(+), 207 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index e4d96e2..660b4b4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1269,6 +1269,11 @@
         "@hapi/hoek": "8.2.2"
       }
     },
+    "@icons/material": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
+      "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw=="
+    },
     "@jest/console": {
       "version": "24.9.0",
       "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz",
@@ -10771,6 +10776,11 @@
         "object-visit": "1.0.1"
       }
     },
+    "material-colors": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
+      "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
+    },
     "math-random": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz",
@@ -13949,6 +13959,19 @@
       "resolved": "https://registry.npmjs.org/react-codemirror2/-/react-codemirror2-7.1.0.tgz",
       "integrity": "sha512-Rel0QbPnCTjHxgZYt6TkGw4icSZXNyONHb72a+1wWA+PlYJIvzFAv4pZlDPG0rpKpKmy4kSUlkoWgneH7w3A0g=="
     },
+    "react-color": {
+      "version": "2.18.1",
+      "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.18.1.tgz",
+      "integrity": "sha512-X5XpyJS6ncplZs74ak0JJoqPi+33Nzpv5RYWWxn17bslih+X7OlgmfpmGC1fNvdkK7/SGWYf1JJdn7D2n5gSuQ==",
+      "requires": {
+        "@icons/material": "0.2.4",
+        "lodash": "4.17.15",
+        "material-colors": "1.2.6",
+        "prop-types": "15.7.2",
+        "reactcss": "1.2.3",
+        "tinycolor2": "1.4.1"
+      }
+    },
     "react-dev-utils": {
       "version": "9.0.3",
       "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-9.0.3.tgz",
@@ -14234,6 +14257,14 @@
         "tween-functions": "1.2.0"
       }
     },
+    "reactcss": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
+      "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==",
+      "requires": {
+        "lodash": "4.17.15"
+      }
+    },
     "read-pkg": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
diff --git a/package.json b/package.json
index 8353143..79a9c9d 100644
--- a/package.json
+++ b/package.json
@@ -64,6 +64,7 @@
     "react": "^16.9.0",
     "react-app-polyfill": "^1.0.2",
     "react-codemirror2": "^7.1.0",
+    "react-color": "^2.18.1",
     "react-dev-utils": "^9.0.3",
     "react-dnd": "^9.4.0",
     "react-dnd-html5-backend": "^9.4.0",
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 7774abf..1fb87ed 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -678,9 +678,9 @@
         {this.props.editLevel === 'HS' ? <Button className="level4-close" type="primary" onClick={this.exitManage}>閫�鍑�</Button> : null}
         {/* 杩涘叆缂栬緫鎸夐挳 */}
         {this.props.editState && !this.props.editLevel ? <Icon onClick={this.enterEdit} className="edit-check" type="edit" /> : null}
-        {this.props.editState && !this.props.editLevel && options.systemType === 'local' && window.GLOB.systemType !== 'official' ?
+        {/* {this.props.editState && !this.props.editLevel && options.systemType === 'local' && window.GLOB.systemType !== 'official' ?
           <a href="#/mobmanage" target="_blank" className="mobile" type="edit"> 搴旂敤绠$悊 <Icon type="arrow-right" /></a> : null
-        }
+        } */}
         {/* 缂栬緫鑿滃崟 */}
         {this.props.editLevel === 'level1' ? <EditMenu menulist={this.state.menulist} reload={this.reload} exitEdit={this.exitEdit}/> : null}
         {/* 澶村儚銆佺敤鎴峰悕 */}
diff --git a/src/mob/datasource/verifycard/customscript/index.jsx b/src/mob/datasource/verifycard/customscript/index.jsx
index 7191459..6c9d489 100644
--- a/src/mob/datasource/verifycard/customscript/index.jsx
+++ b/src/mob/datasource/verifycard/customscript/index.jsx
@@ -1,9 +1,10 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Button, notification, Modal, Tooltip, Icon, Radio, Select } from 'antd'
+import { Form, Row, Col, Input, Button, notification, Modal, Select } from 'antd'
 import moment from 'moment'
 
 import Utils from '@/utils/utils.js'
+import SettingUtils from '../utils.jsx'
 import Api from '@/api'
 import './index.scss'
 
@@ -11,18 +12,47 @@
 
 class CustomForm extends Component {
   static propTpyes = {
+    type: PropTypes.string,         // 鑿滃崟绫诲瀷
     dict: PropTypes.object,         // 瀛楀吀椤�
-    btn: PropTypes.object,          // 鎸夐挳淇℃伅
-    usefulfields: PropTypes.string, // 鍙敤瀛楁
-    initsql: PropTypes.string,      // sql鍓嶇紑
+    setting: PropTypes.object,      // 璁剧疆
+    searches: PropTypes.array,      // 鎼滅储鏉′欢
+    swhere: PropTypes.string,       // where鏉′欢
+    arr_field: PropTypes.string,    // 鍒楀瓧娈�
+    regoptions: PropTypes.array,    // 姝e垯鏇挎崲
     systemScripts: PropTypes.array, // 绯荤粺鑴氭湰
-    customScripts: PropTypes.array, // 鑷畾涔夎剼鏈�
     scriptsChange: PropTypes.func   // 琛ㄥ崟
   }
 
   state = {
     editItem: null,
-    loading: false
+    loading: false,
+    usefulFields: ''
+  }
+
+  UNSAFE_componentWillMount() {
+    const { searches } = this.props
+
+    let _usefulFields = []
+    searches.forEach(item => {
+      if (item.type === 'group') {
+        if (item.transfer === 'true') {
+          _usefulFields.push(item.field)
+        }
+        _usefulFields.push(item.datefield)
+        _usefulFields.push(item.datefield + '1')
+      } else if (['dateweek', 'datemonth', 'daterange'].includes(item.type)) {
+        _usefulFields.push(item.field)
+        _usefulFields.push(item.field + '1')
+      } else if (_usefulFields.includes(item.field)) {
+        _usefulFields.push(item.field + '1')
+      } else {
+        _usefulFields.push(item.field)
+      }
+    })
+
+    this.setState({
+      usefulFields: _usefulFields.join(', ')
+    })
   }
 
   edit = (record) => {
@@ -31,12 +61,22 @@
     })
 
     this.props.form.setFieldsValue({
-      sql: record.sql,
-      position: record.position || 'back'
+      sql: record.sql
+    })
+  }
+
+  handleCancel = () => {
+    this.setState({
+      editItem: null
+    })
+    this.props.form.setFieldsValue({
+      sql: ''
     })
   }
 
   handleConfirm = () => {
+    const { setting, arr_field, regoptions, swhere } = this.props
+    
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     this.props.form.validateFieldsAndScroll((err, values) => {
       if (!err) {
@@ -84,27 +124,37 @@
           return
         }
 
-        let tail = `
-          aaa:
-        `
-
-        let _initsql = ''
-        this.props.customScripts.forEach(script => {
-          if (this.state.editItem && this.state.editItem.uuid === script.uuid) return
-          if (script.status === 'false' || script.position !== 'init') return
-
-          _initsql += `
+        let _customScript = ''
+        setting.scripts && setting.scripts.forEach(script => {
+          if (this.state.editItem && this.state.editItem.uuid === script.uuid) {
+            _customScript += `
+            ${values.sql}
+            `
+          } else if (script.status !== 'false') {
+            _customScript += `
             ${script.sql}
             `
+          }
         })
+
+        if (!this.state.editItem) {
+          _customScript += `
+            ${values.sql}
+            `
+        }
+
+        if (_customScript) {
+          _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
+            ${_customScript}
+          `
+        }
+
+        let _setting = {...setting, customScript: _customScript}
 
         let param = {
           func: 's_debug_sql',
-          LText: this.props.initsql + _initsql + values.sql + tail
+          LText: SettingUtils.getDebugSql(_setting, arr_field, regoptions, swhere)
         }
-
-        // 鏁版嵁鏉冮檺
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
 
         param.LText = Utils.formatOptions(param.LText)
         param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
@@ -134,16 +184,6 @@
     })
   }
 
-  handleCancel = () => {
-    this.setState({
-      editItem: null
-    })
-
-    this.props.form.setFieldsValue({
-      sql: ''
-    })
-  }
-
   selectScript = (value, option) => {
     let _sql = this.props.form.getFieldValue('sql')
     if (_sql) {
@@ -164,8 +204,9 @@
   }
 
   render() {
-    const { usefulfields, systemScripts, btn } = this.props
+    const { systemScripts, setting, type } = this.props
     const { getFieldDecorator } = this.props.form
+    const { usefulFields } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -178,11 +219,11 @@
     }
 
     return (
-      <Form {...formItemLayout} className="verify-form" id="verify-custom-scripts">
+      <Form {...formItemLayout} className="modal-menu-setting-script">
         <Row gutter={24}>
-          {btn.sql ? <Col span={8}>
+          {setting.tableName ? <Col span={8}>
             <Form.Item label={'琛ㄥ悕'} style={{whiteSpace: 'nowrap', margin: 0}}>
-              {btn.sql}
+              {setting.tableName}
             </Form.Item>
           </Col> : null}
           <Col span={16}>
@@ -190,27 +231,9 @@
               ErrorCode, retmsg
             </Form.Item>
           </Col>
-          {usefulfields ? <Col span={24} className="sqlfield">
+          <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
-              {usefulfields}
-            </Form.Item>
-          </Col> : null}
-          <Col span={8} style={{whiteSpace: 'nowrap'}}>
-            <Form.Item style={{marginBottom: 0}} label={
-              <Tooltip placement="bottomLeft" title={'鑷畾涔夎剼鏈笌榛樿sql浣嶇疆鍏崇郴銆�'}>
-                <Icon type="question-circle" style={{color: '#c49f47', marginRight: '5px'}} />
-                鎵ц浣嶇疆
-              </Tooltip>
-            }>
-              {getFieldDecorator('position', {
-                initialValue: 'front'
-              })(
-                <Radio.Group>
-                  <Radio value="init">鍒濆鍖�</Radio>
-                  <Radio value="front">sql鍓�</Radio>
-                  <Radio value="back">sql鍚�</Radio>
-                </Radio.Group>
-              )}
+              id, bid, loginuid, sessionuid, userid, appkey, {type === 'main' ? 'out_id, ' : '' }time_id, orderBy{setting.laypage !== 'false' ? ', pageSize, pageIndex': ''}{usefulFields ? ', ' + usefulFields : ''}
             </Form.Item>
           </Col>
           <Col span={10}>
@@ -219,19 +242,18 @@
                 showSearch
                 filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                 onChange={this.selectScript}
-                getPopupContainer={() => document.getElementById('verify-custom-scripts')}
               >
                 {systemScripts.map((option, i) =>
-                  <Select.Option key={i} value={option.value}>{option.name}</Select.Option>
+                  <Select.Option style={{whiteSpace: 'normal'}} key={i} value={option.value}>{option.name}</Select.Option>
                 )}
               </Select>
             </Form.Item>
           </Col>
           <Col span={6} className="add">
-            <Button onClick={this.handleConfirm} loading={this.state.loading} className="mk-green" style={{marginBottom: 15, marginLeft: 40}}>
+            <Button onClick={this.handleConfirm} loading={this.state.loading} className="mk-green" style={{marginTop: 5, marginBottom: 15, marginLeft: 30}}>
               淇濆瓨
             </Button>
-            <Button onClick={this.handleCancel} style={{marginBottom: 15, marginLeft: 10}}>
+            <Button onClick={this.handleCancel} style={{marginTop: 5, marginBottom: 15, marginLeft: 10}}>
               鍙栨秷
             </Button>
           </Col>
diff --git a/src/mob/datasource/verifycard/customscript/index.scss b/src/mob/datasource/verifycard/customscript/index.scss
index 89791c7..80c8d19 100644
--- a/src/mob/datasource/verifycard/customscript/index.scss
+++ b/src/mob/datasource/verifycard/customscript/index.scss
@@ -1,5 +1,31 @@
-#verify-custom-scripts {
-  .ant-select-dropdown-menu-item {
-    white-space: normal;
+.modal-menu-setting-script {
+  .sqlfield {
+    .ant-form-item {
+      margin-bottom: 5px;
+    }
+    .ant-form-item-control {
+      line-height: 24px;
+    }
+    .ant-form-item-label {
+      line-height: 25px;
+    }
+    .ant-form-item-children {
+      line-height: 22px;
+    }
+    .ant-col-sm-8 {
+      width: 10.5%;
+    }
+    .ant-col-sm-16 {
+      width: 89.5%;
+    }
+  }
+  .sql {
+    .ant-col-sm-8 {
+      width: 10.5%;
+    }
+    .ant-col-sm-16 {
+      width: 89.5%;
+      padding-top: 4px;
+    }
   }
 }
\ No newline at end of file
diff --git a/src/mob/datasource/verifycard/index.jsx b/src/mob/datasource/verifycard/index.jsx
index ddff706..1731c3c 100644
--- a/src/mob/datasource/verifycard/index.jsx
+++ b/src/mob/datasource/verifycard/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 // import { fromJS } from 'immutable'
-import { Form, Tabs, Row, Col, Radio, Table, Popconfirm, Icon, notification, Modal, message, Tooltip, Typography } from 'antd'
+import { Form, Tabs, Table, Popconfirm, Icon, notification, Modal, message, Typography } from 'antd'
 import moment from 'moment'
 
 import Api from '@/api'
@@ -10,7 +10,7 @@
 import UniqueForm from './uniqueform'
 import ContrastForm from './contrastform'
 import CustomForm from './customform'
-import CustomScript from './customscript'
+import SettingForm from './settingform'
 import BillcodeForm from './billcodeform'
 import VoucherForm from './voucherform'
 import './index.scss'
@@ -924,54 +924,12 @@
   render() {
     const { card } = this.props
     const { verify, fields, uniqueColumns, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail } = this.state
-    const formItemLayout = {
-      labelCol: {
-        xs: { span: 24 },
-        sm: { span: 8 }
-      },
-      wrapperCol: {
-        xs: { span: 24 },
-        sm: { span: 16 }
-      }
-    }
 
     return (
       <div id="verify-card-box-tab">
         <Tabs defaultActiveKey="1" className="verify-card-box">
-          <TabPane tab="鍩虹楠岃瘉" key="1">
-            <Form {...formItemLayout}>
-              <Row gutter={24}>
-                {this.props.card.sqlType !== 'custom' ? <Col span={8}>
-                  <Form.Item label={
-                    <Tooltip placement="bottomLeft" title={'榛樿sql鎵ц椤哄簭涓鸿嚜瀹氫箟鑴氭湰涔嬪墠'}>
-                      <Icon type="question-circle" style={{color: '#c49f47', marginRight: '5px'}} />
-                      榛樿sql
-                    </Tooltip>
-                  }>
-                    <Radio.Group value={verify.default} onChange={(e) => {this.onOptionChange(e, 'default')}}>
-                      <Radio value="true">鎵ц</Radio>
-                      <Radio value="false">涓嶆墽琛�</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Col> : null}
-                <Col span={8}>
-                  <Form.Item label={'璐︽湡楠岃瘉'}>
-                    <Radio.Group value={verify.accountdate} onChange={(e) => {this.onOptionChange(e, 'accountdate')}}>
-                      <Radio value="true">寮�鍚�</Radio>
-                      <Radio value="false">涓嶅紑鍚�</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Col>
-                <Col span={8}>
-                  <Form.Item label={'澶辨晥楠岃瘉'}>
-                    <Radio.Group value={verify.invalid} onChange={(e) => {this.onOptionChange(e, 'invalid')}}>
-                      <Radio value="true">寮�鍚�</Radio>
-                      <Radio value="false">涓嶅紑鍚�</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Col>
-              </Row>
-            </Form>
+          <TabPane tab="鏁版嵁婧�" key="1">
+            <SettingForm dict={this.props.dict} />
           </TabPane>
           <TabPane tab="姣旇緝楠岃瘉" key="2x">
             <ContrastForm
@@ -1056,7 +1014,7 @@
             />
           </TabPane>
           <TabPane tab="鑷畾涔夎剼鏈�" key="6">
-            <CustomScript
+            {/* <CustomScript
               usefulfields={this.state.usefulfields}
               initsql={this.state.initsql}
               dict={this.props.dict}
@@ -1065,7 +1023,7 @@
               systemScripts={this.state.systemScripts}
               scriptsChange={this.scriptsChange}
               wrappedComponentRef={(inst) => this.scriptsForm = inst}
-            />
+            /> */}
             <Table
               bordered
               rowKey="uuid"
diff --git a/src/mob/datasource/verifycard/settingform/index.jsx b/src/mob/datasource/verifycard/settingform/index.jsx
new file mode 100644
index 0000000..9720ab4
--- /dev/null
+++ b/src/mob/datasource/verifycard/settingform/index.jsx
@@ -0,0 +1,376 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { fromJS } from 'immutable'
+import { Form, Row, Col, Input, Radio, Select, Tooltip, Icon, notification, InputNumber } from 'antd'
+import moment from 'moment'
+
+import Api from '@/api'
+import Utils from '@/utils/utils.js'
+// import SettingUtils from './utils.jsx'
+import './index.scss'
+
+const { TextArea } = Input
+
+class SettingForm extends Component {
+  static propTpyes = {
+    type: PropTypes.string,      // 鑿滃崟绫诲瀷
+    dict: PropTypes.object,      // 瀛楀吀椤�
+    menu: PropTypes.object,      // 鑿滃崟淇℃伅
+    config: PropTypes.object,    // 椤甸潰閰嶇疆淇℃伅
+    formlist: PropTypes.array,   // 琛ㄥ崟淇℃伅
+  }
+
+  state = {
+    
+  }
+
+  handleConfirm = (otype) => {
+    const { menu } = this.props
+    const { setting } = this.state
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      this.props.form.validateFieldsAndScroll((err, values) => {
+        if (!err) {
+          values = {...setting, ...values}
+
+          // 鏁版嵁婧愬墠绔獙璇�
+          if (values.interType === 'inner' && !values.innerFunc && values.default !== 'false' && !values.dataresource) {
+            notification.warning({
+              top: 92,
+              message: '璇峰~鍐欏唴閮ㄥ嚱鏁版垨鏁版嵁婧愶紒',
+              duration: 5
+            })
+            reject()
+            return
+          } else if (values.interType === 'inner' && !values.innerFunc && values.default !== 'false' && values.dataresource) {
+            let _quot = values.dataresource.match(/'{1}/g)
+            let _lparen = values.dataresource.match(/\({1}/g)
+            let _rparen = values.dataresource.match(/\){1}/g)
+
+            _quot = _quot ? _quot.length : 0
+            _lparen = _lparen ? _lparen.length : 0
+            _rparen = _rparen ? _rparen.length : 0
+
+            if (_quot % 2 !== 0) {
+              notification.warning({
+                top: 92,
+                message: '鏁版嵁婧愪腑\'蹇呴』鎴愬鍑虹幇',
+                duration: 5
+              })
+              return
+            } else if (_lparen !== _rparen) {
+              notification.warning({
+                top: 92,
+                message: '鏁版嵁婧愪腑()蹇呴』鎴愬鍑虹幇',
+                duration: 5
+              })
+              return
+            } else if (/--/ig.test(values.dataresource)) {
+              notification.warning({
+                top: 92,
+                message: '鏁版嵁婧愪腑锛屼笉鍙嚭鐜板瓧绗� -- 锛屾敞閲婅鐢� /*鍐呭*/',
+                duration: 5
+              })
+              return
+            }
+
+            let error = Utils.verifySql(values.dataresource)
+
+            if (error) {
+              notification.warning({
+                top: 92,
+                message: '鏁版嵁婧愪腑涓嶅彲浣跨敤' + error,
+                duration: 5
+              })
+              reject()
+              return
+            }
+          }
+
+          // 鏁版嵁婧愪繚瀛�
+          if (
+            values.interType === 'inner' && !values.innerFunc &&
+            values.default !== 'false' &&
+            /[^\s]+\s+[^\s]+/ig.test(values.dataresource) &&
+            this.props.config.setting.dataresource !== values.dataresource
+          ) {
+            let param = {
+              func: 's_DataSrc_Save',
+              LText: values.dataresource,
+              MenuID: menu.MenuID
+            }
+    
+            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.getLocalConfig(param)
+          }
+
+          if (otype === 'change') {
+            this.setState({
+              setting: values,
+            }, () => {
+              resolve()
+            })
+          } else {
+            values.customScript = this.getCustomScript(values)
+
+            this.sqlverify(values, resolve, reject)
+          }
+        } else {
+          reject(err)
+        }
+      })
+    })
+  }
+
+  onRadioChange = (e, key) => {
+    let value = e.target.value
+    let _formlist = fromJS(this.state.formlist).toJS()
+
+    if (key === 'interType') {
+      this.setState({
+        formlist: _formlist.map(item => {
+          item.hidden = false
+
+          if (value === 'inner' && ['sysInterface', 'interface', 'outerFunc'].includes(item.key)) {
+            item.initVal = this.props.form.getFieldValue(item.key)
+            item.hidden = true
+          } else if (value === 'outer' && ['innerFunc', 'dataresource', 'queryType'].includes(item.key)) {
+            item.initVal = this.props.form.getFieldValue(item.key)
+            item.hidden = true
+          }
+          
+          return item
+        })
+      })
+    } else if (key === 'sysInterface') {
+      if (value === 'true') {
+        this.props.form.setFieldsValue({
+          interface: window.GLOB.mainSystemApi || ''
+        })
+      }
+      this.setState({
+        formlist: _formlist.map(item => {
+          if (item.key === 'interface') {
+            item.readonly = value === 'true'
+          }
+          
+          return item
+        })
+      })
+    }
+  }
+
+  getFields(formlist) {
+    const { getFieldDecorator } = this.props.form
+    const fields = []
+
+    formlist.forEach((item, index) => {
+      if (item.hidden || item.forbid) return
+
+      if (item.type === 'text') { // 鏂囨湰鎼滅储
+        let rules = item.rules || []
+        
+        fields.push(
+          <Col span={8} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal || '',
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  },
+                  ...rules
+                ]
+              })(<Input placeholder={item.placeholder || ''} autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'number') {
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal || 6,
+                rules: [
+                  {
+                    required: item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  }
+                ]
+              })(<InputNumber min={item.min} max={item.max} precision={0} />)}
+            </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) => {
+                    return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
+                      option.props.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                  }}
+                  onChange={(value) => {this.selectChange(item.key, value)}}
+                  getPopupContainer={() => document.getElementById('model-table-setting-form')}
+                >
+                  {item.options.map((option, i) =>
+                    <Select.Option id={i} key={i} value={option.value}>
+                      {option.text}
+                    </Select.Option>
+                  )}
+                </Select>
+              )}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'radio') {
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal,
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.select'] + item.label + '!'
+                  }
+                ]
+              })(
+                <Radio.Group onChange={(e) => {this.onRadioChange(e, item.key)}}>
+                  {
+                    item.options.map((option, i) => {
+                      return (
+                        <Radio key={i} value={option.value}>{option.text}</Radio>
+                      )
+                    })
+                  }
+                </Radio.Group>,
+              )}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'datasource') {
+        fields.push(
+          <Col span={24} key={index} style={{paddingLeft: '7px'}}>
+            <Form.Item labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } help={item.help} label={
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip>
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal
+              })(<TextArea rows={4} />)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'textarea') {
+        fields.push(
+          <Col span={20} offset={4} key={index}>
+            <Form.Item className="text-area">
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal,
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  }
+                ]
+              })(<TextArea rows={4} />)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'multiselect') { // 澶氶��
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.label}>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal || []
+              })(
+                <Select
+                  showSearch
+                  mode="multiple"
+                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+                >
+                  {item.options.map((option, i) =>
+                    <Select.Option id={i} key={i} value={option.value}>{option.text}</Select.Option>
+                  )}
+                </Select>
+              )}
+            </Form.Item>
+          </Col>
+        )
+      }
+    })
+
+    return fields
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form
+    // const { formlist } = this.state
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <div className="model-table-setting-form-box">
+        <Form {...formItemLayout} className="model-table-setting-form">
+          <Row gutter={24}>
+            <Col span={8}>
+              <Form.Item label="鍚嶇О">
+                {getFieldDecorator('label', {
+                  initialValue: '',
+                  rules: [
+                    {
+                      required: true,
+                      message: this.props.dict['form.required.input'] + '鍚嶇О!'
+                    },
+                  ]
+                })(<Input placeholder={''} autoComplete="off" />)}
+              </Form.Item>
+            </Col>
+          </Row>
+        </Form>
+      </div>
+    )
+  }
+}
+
+export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/mob/datasource/verifycard/settingform/index.scss b/src/mob/datasource/verifycard/settingform/index.scss
new file mode 100644
index 0000000..d79c9f6
--- /dev/null
+++ b/src/mob/datasource/verifycard/settingform/index.scss
@@ -0,0 +1,45 @@
+.model-table-setting-form-box {
+  position: relative;
+  .model-table-setting-form {
+    .textarea {
+      .ant-form-item-label {
+        width: 16.3%;
+      }
+      .ant-form-item-control-wrapper {
+        width: 83.33333333%;
+      }
+    }
+    .anticon-question-circle {
+      color: #c49f47;
+      margin-right: 3px;
+    }
+  }
+  .operation-btn {
+    display: inline-block;
+    font-size: 16px;
+    padding: 0 5px;
+    cursor: pointer;
+  }
+  td {
+    word-break: break-all;
+  }
+  .setting-custom-back {
+    position: absolute;
+    top: -20px;
+    left: -10px;
+    font-size: 16px;
+    z-index: 1;
+    cursor: pointer;
+    padding: 10px;
+    color: rgb(24, 144, 255);
+  }
+  .to-custom-script {
+    float: right;
+    color: #1890ff;
+    margin-right: 12px;
+    margin-top: 15px;
+    cursor: pointer;
+    border: 0;
+    box-shadow: unset;
+  }
+}
\ No newline at end of file
diff --git a/src/mob/datasource/verifycard/settingform/utils.jsx b/src/mob/datasource/verifycard/settingform/utils.jsx
new file mode 100644
index 0000000..ebd508d
--- /dev/null
+++ b/src/mob/datasource/verifycard/settingform/utils.jsx
@@ -0,0 +1,84 @@
+
+export default class SettingUtils {
+  /**
+   * @description 鐢熸垚椤甸潰鏌ヨ璇彞
+   * @return {String}  arr_field     鏄剧ず鍒楀瓧娈�
+   * @return {String}  search        鎼滅储鏉′欢
+   * @return {Object}  setting       椤甸潰璁剧疆
+   * @return {Array}   regoptions    鎼滅储鏉′欢姝e垯鏇挎崲
+   */
+  static getDebugSql (setting, arr_field, regoptions, search) {
+    let sql = ''
+    let _dataresource = setting.dataresource
+    let _customScript = setting.customScript
+
+    if (setting.interType === 'inner' && !setting.innerFunc && setting.default === 'false') {
+      _dataresource = ''
+    }
+    
+    if (_dataresource) {
+      _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
+    }
+    if (_customScript) {
+      _customScript = _customScript.replace(/@\$|\$@/ig, '')
+    }
+    
+    // 姝e垯鏇挎崲
+    let _regoptions = regoptions.map(item => {
+      return {
+        reg: new RegExp('@' + item.key + '@', 'ig'),
+        value: `'${item.value}'`
+      }
+    })
+    let _search = search
+
+    if (setting.queryType === 'statistics' && _dataresource) {
+      _regoptions.forEach(item => {
+        _dataresource = _dataresource.replace(item.reg, item.value)
+      })
+
+      _search = ''
+    }
+
+    if (_customScript) {
+      _regoptions.push({
+        reg: new RegExp('@orderBy@', 'ig'),
+        value: setting.order
+      })
+      if (setting.laypage !== 'false') {
+        _regoptions.push({
+          reg: new RegExp('@pageSize@', 'ig'),
+          value: 10
+        }, {
+          reg: new RegExp('@pageIndex@', 'ig'),
+          value: 1
+        })
+      }
+      _regoptions.forEach(item => {
+        _customScript = _customScript.replace(item.reg, item.value)
+      })
+    }
+
+    // 鏁版嵁婧愬鐞�, 瀛樺湪鏄剧ず鍒楁椂 
+    if (arr_field && _dataresource) {
+      if (/\s/.test(_dataresource)) {
+        _dataresource = '(' + _dataresource + ') tb'
+      }
+
+      _dataresource = `select ${setting.laypage !== 'false' ?  'top 10' : ''} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${setting.order}) as rows from ${_dataresource} ${_search}) tmptable ${setting.laypage !== 'false' ?  'where rows > 0' : ''} order by tmptable.rows`
+    }
+
+    if (_customScript) {
+      sql = `${_customScript}
+        ${_dataresource}
+        aaa:
+        if @ErrorCode!=''
+          insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@
+      `
+    } else {
+      sql = _dataresource
+    }
+    
+    return sql
+  }
+}
\ No newline at end of file
diff --git a/src/mob/dragsource/index.jsx b/src/mob/dragsource/index.jsx
deleted file mode 100644
index ab22158..0000000
--- a/src/mob/dragsource/index.jsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import React from 'react'
-import { useDrag } from 'react-dnd'
-import './index.scss'
-
-const SourceElement = ({content}) => {
-  const [, drag] = useDrag({ item: content })
-  return (
-    <div ref={drag} className="common-source-item">
-      {content.label}
-    </div>
-  )
-}
-export default SourceElement
\ No newline at end of file
diff --git a/src/mob/dragsource/index.scss b/src/mob/dragsource/index.scss
deleted file mode 100644
index a2e19e6..0000000
--- a/src/mob/dragsource/index.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-.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;
-}
\ No newline at end of file
diff --git a/src/mob/login/index.scss b/src/mob/login/index.scss
index 6ff2843..40d5fe8 100644
--- a/src/mob/login/index.scss
+++ b/src/mob/login/index.scss
@@ -3,7 +3,7 @@
   width: 100%;
   height: 100%;
   overflow: hidden;
-  background: linear-gradient(#378DBE, #46C29E, #48A9D6);
+  background: linear-gradient(#378DBE, #46C29E, #48A9D6, yellow);
 
   .logo {
     max-width: 280px;
diff --git a/src/mob/mobcard/index.jsx b/src/mob/mobcard/index.jsx
index 2186629..6daee4f 100644
--- a/src/mob/mobcard/index.jsx
+++ b/src/mob/mobcard/index.jsx
@@ -127,7 +127,7 @@
         ID: card ? card.uuid : Utils.getuuid(),
         TypeName: res.type,
         remark: res.name,
-        kei_no: res.type
+        kei_no: res.keiNo
       }
 
       Api.getCloudConfig(param).then(result => {
diff --git a/src/mob/mobcard/mutilform/index.jsx b/src/mob/mobcard/mutilform/index.jsx
index bbc2592..0ba42e2 100644
--- a/src/mob/mobcard/mutilform/index.jsx
+++ b/src/mob/mobcard/mutilform/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Select } from 'antd'
+import { Form, Row, Col, Input, Select, Radio } from 'antd'
 import './index.scss'
 
 class MainSearch extends Component {
@@ -81,6 +81,39 @@
               )}
             </Form.Item>
           </Col>
+          <Col span={24}>
+            <Form.Item label="搴旂敤缂栫爜">
+              {getFieldDecorator('keiNo', {
+                initialValue: card ? card.keiNo : '',
+                rules: [{
+                  required: true,
+                  message: this.props.dict['mob.required.input'] + '搴旂敤缂栫爜!'
+                }, {
+                  pattern: /^[a-zA-Z_]*$/ig,
+                  message: '搴旂敤缂栫爜鍙厑璁稿寘鍚ぇ灏忓啓瀛楁瘝鍙奯!'
+                }, {
+                  max: 20,
+                  message: '搴旂敤缂栫爜涓嶅彲瓒呰繃20涓瓧绗�!'
+                }]
+              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col>
+          <Col span={24}>
+            <Form.Item label="鏉冮檺绠$悊">
+              {getFieldDecorator('role_manage', {
+                initialValue: card ? card.role_manage || 'false' : 'false',
+                rules: [{
+                  required: true,
+                  message: this.props.dict['mob.required.select'] + '鏄惁鍚敤鏉冮檺绠$悊!'
+                }]
+              })(
+                <Radio.Group>
+                  <Radio value="true">鍚敤</Radio>
+                  <Radio value="false">涓嶅惎鐢�</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
         </Row>
       </Form>
     )
diff --git a/src/mob/mobshell/card.jsx b/src/mob/mobshell/card.jsx
index 10c2fff..34e36fc 100644
--- a/src/mob/mobshell/card.jsx
+++ b/src/mob/mobshell/card.jsx
@@ -10,16 +10,15 @@
 const Login = asyncComponent(() => import('@/mob/login'))
 
 const Card = ({ id, card, moveCard, findCard, editCard, delCard, hasDrop, doubleClickCard }) => {
-  const originalIndex = null
-  // const originalIndex = findCard(id).index
+  const originalIndex = findCard(id).index
   const [{ isDragging }, drag] = useDrag({
-    item: { type: 'action', id, originalIndex },
+    item: { type: 'mob', id, originalIndex },
     collect: monitor => ({
       isDragging: monitor.isDragging(),
     }),
   })
   const [, drop] = useDrop({
-    accept: 'action',
+    accept: 'mob',
     canDrop: () => true,
     drop: (item) => {
       if (!item.hasOwnProperty('originalIndex')) {
@@ -34,10 +33,15 @@
       }
     },
   })
-  const opacity = isDragging ? 0.3 : 1
+
+  console.log(card)
+  const style = isDragging ? { opacity: 0.3} : { opacity: 1}
+  if (card.type === 'login') {
+    style.height = '100%'
+  }
 
   return (
-    <div ref={node => drag(drop(node))} style={{ opacity: opacity, height: '100%'}}>
+    <div ref={node => drag(drop(node))} style={style}>
       <Login />
       {/* <div className="page-card">
         <Button
diff --git a/src/mob/mobshell/index.jsx b/src/mob/mobshell/index.jsx
index 1d64cca..7c4ec11 100644
--- a/src/mob/mobshell/index.jsx
+++ b/src/mob/mobshell/index.jsx
@@ -1,33 +1,35 @@
-import React from 'react'
-// import React, { useState } from 'react'
+import React, { useState } from 'react'
 import { useDrop } from 'react-dnd'
-// import { is, fromJS } from 'immutable'
-// import update from 'immutability-helper'
-// import Utils from '@/utils/utils.js'
+import { is, fromJS } from 'immutable'
+import update from 'immutability-helper'
+import { message } from 'antd'
+
+import Utils from '@/utils/utils.js'
 import Card from './card'
 import './index.scss'
 
-const Container = ({list, placeholder, handleList, handleMenu, deleteMenu, doubleClickCard }) => {
-  // let target = null
+const Container = ({config, handleList, handleMenu, deleteMenu, doubleClickCard }) => {
+  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]] })
-  //   handleList(_cards)
-  // }
+  const [cards, setCards] = useState(config.components)
+  const moveCard = (id, atIndex) => {
+    const { card, index } = findCard(id)
+    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
+    handleList({...config, components: _cards})
+    console.log(_cards)
+  }
 
-  // if (!is(fromJS(cards), fromJS(list))) {
-  //   setCards(list)
-  // }
+  if (!is(fromJS(cards), fromJS(config.components))) {
+    setCards(config.components)
+  }
   
-  // const findCard = id => {
-  //   const card = cards.filter(c => `${c.uuid}` === id)[0]
-  //   return {
-  //     card,
-  //     index: cards.indexOf(card),
-  //   }
-  // }
+  const findCard = id => {
+    const card = cards.filter(c => `${c.uuid}` === id)[0]
+    return {
+      card,
+      index: cards.indexOf(card),
+    }
+  }
 
   // const doubleClickBtn = id => {
   //   const { card } = findCard(id)
@@ -44,54 +46,57 @@
   //   deleteMenu(card)
   // }
 
-  // const hasDrop = (item) => {
-  //   target = item
-  // }
+  const hasDrop = (item) => {
+    target = item
+  }
 
   const [, drop] = useDrop({
-    accept: 'action',
+    accept: 'mob',
     drop(item) {
       if (item.hasOwnProperty('originalIndex')) {
         return
       }
 
-      // let newcard = {}
-      // newcard.uuid = Utils.getuuid()
+      if (cards.length > 0 && cards[0].type === 'login') {
+        message.warning('鐧诲綍椤典笉鍙坊鍔犲叾浠栧厓绱狅紒')
+        return
+      }
+
+      let newcard = fromJS(item.param).toJS()
+      newcard.uuid = Utils.getuuid()
       
-      // let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0
-      // if (target) {
-      //   targetId = target.uuid
-      // }
+      let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0
+      if (target) {
+        targetId = target.uuid
+      }
 
-      // const { index: overIndex } = findCard(`${targetId}`)
-      // let targetIndex = overIndex
+      const { index: overIndex } = findCard(`${targetId}`)
+      let targetIndex = overIndex
 
-      // targetIndex++
+      targetIndex++
 
-      // const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
+      const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
 
-      // handleList(_cards, newcard)
-      // target = null
+      handleList({...config, components: _cards})
+      target = null
     }
   })
 
   return (
     <div ref={drop} className="mob-shell-inner">
-      {/* {cards.map(card => (
+      {cards.map(card => (
         <Card
           id={card.uuid}
           key={card.uuid}
           card={card}
           moveCard={moveCard}
-          editCard={editCard}
-          delCard={delCard}
+          // editCard={editCard}
+          // delCard={delCard}
           findCard={findCard}
           hasDrop={hasDrop}
-          doubleClickCard={doubleClickBtn}
+          // doubleClickCard={doubleClickBtn}
         />
-      ))} */}
-      <Card />
-      
+      ))}
       {/* {cards.length === 0 ?
         <div className="common-drawarea-placeholder">
           {placeholder}
diff --git a/src/mob/modelsource/dragsource/index.jsx b/src/mob/modelsource/dragsource/index.jsx
index 1a00725..6ae90a6 100644
--- a/src/mob/modelsource/dragsource/index.jsx
+++ b/src/mob/modelsource/dragsource/index.jsx
@@ -3,7 +3,7 @@
 import { Tooltip } from 'antd'
 import './index.scss'
 
-const SourceElement = ({content}) => {
+const MobSourceElement = ({content}) => {
   const [, drag] = useDrag({ item: content })
   return (
     <div ref={drag} className="mob-source-item" style={{backgroundImage: 'url(' + content.url + ')', ...content.style}}>
@@ -15,4 +15,4 @@
     </div>
   )
 }
-export default SourceElement
\ No newline at end of file
+export default MobSourceElement
\ No newline at end of file
diff --git a/src/mob/modelsource/option.jsx b/src/mob/modelsource/option.jsx
index 7855e27..f11dc5a 100644
--- a/src/mob/modelsource/option.jsx
+++ b/src/mob/modelsource/option.jsx
@@ -4,11 +4,15 @@
 
 const _dict =  sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
 
-// 琛ㄥ崟鏍¢獙瑙勫垯
+// 缁勪欢閰嶇疆淇℃伅
 export const mobOptions = [{
   title: _dict['mob.login'],
-  type: 'login',
+  sourceType: 'login',
   options: [
-    {type: 'mob-login-1', sourceType: 'mob', url: mobLogin1,  style: {}},
+    {sourceType: 'mob-login-1', type: 'mob', url: mobLogin1,  style: {}, param: {
+      type: 'login', subtype: 'mob-login-1', components: [
+        {}
+      ]
+    }},
   ]
 }]
diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx
index 19cdef0..8b22246 100644
--- a/src/tabviews/zshare/actionList/normalbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -279,7 +279,11 @@
           }
         }
 
-        if (this.props.menuType === 'HS' && param.timestamp) { // 浜戠楠岃瘉
+        if (this.props.menuType === 'HS' && param.timestamp) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+          param.open_key = Utils.encrypt(param.secretkey, param.timestamp, true)
+        } else if (this.props.menuType === 'HS' && param.func === 's_sDataDictb_TBBack' && param.LTextOut) { // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
+          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+          param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
           param.open_key = Utils.encrypt(param.secretkey, param.timestamp, true)
         }
 
@@ -387,7 +391,11 @@
             }
           }
 
-          if (this.props.menuType === 'HS' && param.timestamp) { // 浜戠楠岃瘉
+          if (this.props.menuType === 'HS' && param.timestamp) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+            param.open_key = Utils.encrypt(param.secretkey, param.timestamp, true)
+          } else if (this.props.menuType === 'HS' && param.func === 's_sDataDictb_TBBack' && param.LTextOut) { // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
+            param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+            param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
             param.open_key = Utils.encrypt(param.secretkey, param.timestamp, true)
           }
 
@@ -539,6 +547,14 @@
       // 鍐呴儴璇锋眰
       if (btn.innerFunc) {
         param.func = btn.innerFunc
+
+        // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
+        if (this.props.menuType === 'HS' && param.func === 's_sDataDictb_TBBack' && param.LTextOut) {
+          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+          param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
+          param.open_key = Utils.encrypt(param.secretkey, param.timestamp, true)
+        }
+
         // 瀛樺湪鍐呴儴鍑芥暟鏃讹紝鏁版嵁棰勫鐞�
         Api.genericInterface(param).then(res => {
           if (res.status) {
@@ -571,11 +587,21 @@
       // 澶栭儴璇锋眰
       _outParam = JSON.parse(JSON.stringify(res))
 
+      if (btn.outerFunc) {
+        res.func = btn.outerFunc
+      }
       if (this.props.menuType === 'HS') {
         if (btn.sysInterface === 'true' && options.cloudServiceApi) {
           res.rduri = options.cloudServiceApi
         } else if (btn.sysInterface !== 'true') {
           res.rduri = btn.interface
+        }
+
+        // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
+        if (res.func === 's_sDataDictb_TBBack' && res.LTextOut) {
+          res.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+          res.secretkey = Utils.encrypt(res.LTextOut, res.timestamp)
+          res.open_key = Utils.encrypt(res.secretkey, res.timestamp, true)
         }
       } else {
         if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
@@ -583,10 +609,6 @@
         } else if (btn.sysInterface !== 'true') {
           res.rduri = btn.interface
         }
-      }
-
-      if (btn.outerFunc) {
-        res.func = btn.outerFunc
       }
 
       return Api.genericInterface(res)
@@ -601,6 +623,14 @@
         response.func = btn.callbackFunc
 
         let _callbackparam = {..._outParam, ...response}
+
+        // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
+        if (this.props.menuType === 'HS' && _callbackparam.func === 's_sDataDictb_TBBack' && _callbackparam.LTextOut) {
+          _callbackparam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+          _callbackparam.secretkey = Utils.encrypt(_callbackparam.LTextOut, _callbackparam.timestamp)
+          _callbackparam.open_key = Utils.encrypt(_callbackparam.secretkey, _callbackparam.timestamp, true)
+        }
+
         return Api.genericInterface(_callbackparam)
       } else {
         if (response.status) {
diff --git a/src/utils/utils.js b/src/utils/utils.js
index de70650..dcd0f4f 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -1066,21 +1066,31 @@
         datasource = '(' + datasource + ') tb'
       }
 
-      let _ID = '=@ID@'
       if (btn.Ot === 'requiredOnce') {
-        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
-      }
-
-      _sql += `
+        _sql += `
         /* 澶辨晥楠岃瘉 */
         select @tbid='', @ErrorCode='',@retmsg=''
-        select @tbid=${primaryKey} from ${datasource} where ${primaryKey} ${_ID}
+        select @tbid='X' from ${datasource} right join (select ID from  dbo.SplitComma(@ID@)) sp
+        on tb.id =sp.id where tb.id is null
+
+        If @tbid!=''
+        Begin
+          select @ErrorCode='E',@retmsg='鏁版嵁宸插け鏁�'
+          goto aaa
+        end
+        `
+      } else {
+        _sql += `
+        /* 澶辨晥楠岃瘉 */
+        select @tbid='', @ErrorCode='',@retmsg=''
+        select @tbid=${primaryKey} from ${datasource} where ${primaryKey}=@ID@
         If @tbid=''
         Begin
           select @ErrorCode='E',@retmsg='鏁版嵁宸插け鏁�'
           goto aaa
         end
         `
+      }
     }
 
     // 姣旇緝楠岃瘉
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index f22c849..b98baf9 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -1,8 +1,10 @@
 import React, { Component } from 'react'
 import { connect } from 'react-redux'
 import { DndProvider } from 'react-dnd'
+import { fromJS } from 'immutable'
 import HTML5Backend from 'react-dnd-html5-backend'
-import { Icon, Tabs } from 'antd'
+import { SketchPicker } from 'react-color'
+import { Icon, Tabs, notification } from 'antd'
 
 import Api from '@/api'
 import zhCN from '@/locales/zh-CN/mob.js'
@@ -23,12 +25,14 @@
     dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     appId: this.props.match.params.appId,
     appType: this.props.match.params.appType,
+    appConfig: null,
     saveIng: false,
-    config: null
+    config: null,
+    pageIndex: 0
   }
 
   UNSAFE_componentWillMount() {
-    this.getPageParam(this.props.match.params.appId)
+    this.getAppParam(this.props.match.params.appId)
   }
 
   /**
@@ -51,17 +55,54 @@
     })
   }
 
-  getPageParam = (id) => {
+  getAppParam = (id) => {
     Api.getSystemConfig({
       func: 'sPC_Get_LongParam',
       MenuID: id
     }).then(result => {
+      if (result.status) {
+        let appConfig = null
 
+        if (result.LongParam) {
+          try {
+            appConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
+          } catch (e) {
+            console.warn('Parse Failure')
+            appConfig = null
+          }
+        }
+
+        if (!appConfig) {
+          appConfig = {
+            version: 1.0,
+            label: '',
+            uuid: this.props.match.params.appId,
+            pageIndex: 0,
+            sourcelist: [],
+            components: []
+          }
+        }
+
+        this.setState({
+          appConfig: appConfig,
+          config: fromJS(appConfig).toJS()
+        })
+      } else {
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+      }
     })
   }
 
-  updateConfig = () => {
-    
+  
+
+  updateConfig = (config) => {
+    this.setState({
+      config: config
+    })
   }
 
   render () {
@@ -83,18 +124,20 @@
               </div>
               <div className="mob-tool-other"></div>
             </div>
-            <div className="mob-shell">
-              <MobShell />
-            </div>
+            {appType === 'mob' && config ?
+              <div className="mob-shell">
+                <MobShell config={config} handleList={this.updateConfig} />
+              </div> : null
+            }
             <div className="mob-setting">
-              <Tabs defaultActiveKey="2" animated={false} size="small">
+              {config ? <Tabs defaultActiveKey="2" animated={false} size="small">
                 <TabPane tab="閰嶇疆" key="1">
-                  Content of Tab Pane 1
+                  <SketchPicker />
                 </TabPane>
                 <TabPane tab="鏁版嵁婧�" key="2">
                   <DataSource config={config} updateConfig={this.updateConfig} />
                 </TabPane>
-              </Tabs>
+              </Tabs> : null}
             </div>
           </div>
         </DndProvider>
diff --git a/src/views/mobdesign/index.scss b/src/views/mobdesign/index.scss
index 085ccf3..322a91f 100644
--- a/src/views/mobdesign/index.scss
+++ b/src/views/mobdesign/index.scss
@@ -86,7 +86,7 @@
         height: 100%;
         overflow-y: auto;
         overflow-x: hidden;
-        background-color: #f5f5f9;
+        box-shadow: 0px 0px 3px #d1d1d5;
       }
       .mob-shell-inner::-webkit-scrollbar {
         width: 4px;

--
Gitblit v1.8.0