From ee50d5424a093209d1c5c549f4578107893b22f8 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 05 十一月 2020 18:40:54 +0800
Subject: [PATCH] 2020-11-05

---
 src/menu/components/card/table-card/index.scss                         |   75 +++
 src/menu/datasource/verifycard/utils.jsx                               |  105 +++-
 src/tabviews/custom/components/card/prop-card/index.jsx                |   60 ++
 src/tabviews/custom/components/chart/antv-bar-line/index.jsx           |   17 
 src/tabviews/custom/components/share/tabtransfer/index.jsx             |   23 
 src/menu/components/card/table-card/index.jsx                          |  220 +++++++++++
 src/menu/components/card/table-card/wrapsetting/settingform/index.jsx  |  140 +++++++
 src/menu/datasource/verifycard/settingform/index.jsx                   |   67 ++-
 src/menu/datasource/verifycard/customscript/index.jsx                  |   42 +
 src/menu/components/card/table-card/wrapsetting/index.scss             |    7 
 src/menu/components/card/table-card/wrapsetting/settingform/index.scss |   11 
 src/menu/components/chart/antv-pie/index.scss                          |    1 
 src/tabviews/custom/components/chart/antv-pie/index.jsx                |   17 
 src/menu/datasource/index.jsx                                          |   40 +
 src/menu/components/chart/antv-bar/index.scss                          |    1 
 src/menu/components/card/table-card/wrapsetting/index.jsx              |   82 ++++
 src/tabviews/custom/index.jsx                                          |   57 +-
 src/views/menudesign/index.jsx                                         |    1 
 src/menu/datasource/verifycard/index.jsx                               |  138 +++++-
 src/tabviews/custom/components/card/data-card/index.jsx                |   48 ++
 20 files changed, 1,032 insertions(+), 120 deletions(-)

diff --git a/src/menu/components/card/table-card/index.jsx b/src/menu/components/card/table-card/index.jsx
new file mode 100644
index 0000000..1b161aa
--- /dev/null
+++ b/src/menu/components/card/table-card/index.jsx
@@ -0,0 +1,220 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import {connect} from 'react-redux'
+import { is, fromJS } from 'immutable'
+import { Icon, Popover, Modal } from 'antd'
+
+import asyncComponent from '@/utils/asyncComponent'
+import asyncIconComponent from '@/utils/asyncIconComponent'
+
+import MKEmitter from '@/utils/events.js'
+import Utils from '@/utils/utils.js'
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+import './index.scss'
+
+const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
+const WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
+const CardComponent = asyncComponent(() => import('../cardcomponent'))
+
+const { confirm } = Modal
+
+class antvBarLineChart extends Component {
+  static propTpyes = {
+    card: PropTypes.object,
+    deletecomponent: PropTypes.func,
+    updateConfig: PropTypes.func,
+  }
+
+  state = {
+    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    card: null,
+    back: false
+  }
+
+  UNSAFE_componentWillMount () {
+    const { card } = this.props
+
+    if (card.isNew) {
+      let subcards = null
+
+      if (card.config) {
+        subcards = JSON.parse(card.config)
+        subcards = subcards.map(scard => {
+          scard.uuid = Utils.getuuid()
+          scard.elements = scard.elements.map(elem => {
+            elem.uuid = Utils.getuuid()
+            return elem
+          })
+          scard.backElements = scard.backElements.map(elem => {
+            elem.uuid = Utils.getuuid()
+            return elem
+          })
+          return scard
+        })
+      } else {
+        subcards = [{
+          uuid: Utils.getuuid(),
+          setting: { width: 6, type: 'simple'},
+          style: {
+            borderWidth: '1px', borderColor: '#e8e8e8',
+            paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px',
+            marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px'
+          },
+          backStyle: {},
+          elements: [],
+          backElements: []
+        }]
+      }
+
+      let _card = {
+        uuid: card.uuid,
+        type: card.type,
+        floor: card.floor,
+        tabId: card.tabId || '',
+        parentId: card.parentId || '',
+        format: 'array',   // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡
+        pageable: true,    // 缁勪欢灞炴�� - 鏄惁鍙垎椤�
+        switchable: true,  // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹�
+        dataName: card.dataName || '',
+        width: 24,
+        name: card.name,
+        subtype: card.subtype,
+        setting: { interType: 'system' },
+        wrap: { name: card.name, width: 24, addable: 'false', switch: 'false' },
+        style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' },
+        columns: [],
+        scripts: [],
+        subcards: subcards
+      }
+      this.setState({
+        card: _card
+      })
+      this.props.updateConfig(_card)
+    } else {
+      this.setState({
+        card: fromJS(card).toJS()
+      })
+    }
+  }
+
+  componentDidMount () {
+    MKEmitter.addListener('submitStyle', this.getStyle)
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+    MKEmitter.removeListener('submitStyle', this.getStyle)
+  }
+
+  /**
+   * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
+   */
+  updateComponent = (component) => {
+    this.setState({
+      card: component
+    })
+
+    component.width = component.wrap.width
+    component.name = component.wrap.name
+
+    this.props.updateConfig(component)
+  }
+
+  /**
+   * @description 鍗曚釜鍗$墖淇℃伅鏇存柊
+   */
+  updateCard = (cell) => {
+    let card = fromJS(this.state.card).toJS()
+
+    card.subcards = card.subcards.map(item => {
+      if (item.uuid === cell.uuid) return cell
+      return item
+    })
+
+    this.setState({card})
+
+    this.props.updateConfig(card)
+  }
+
+  /**
+   * @description 鍗曚釜鍗$墖淇℃伅鏇存柊
+   */
+  deleteCard = (cell) => {
+    let card = fromJS(this.state.card).toJS()
+    let _this = this
+
+    confirm({
+      content: '纭畾鍒犻櫎鍗$墖鍚楋紵',
+      onOk() {
+        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
+    
+        _this.setState({card})
+        _this.props.updateConfig(card)
+      },
+      onCancel() {}
+    })
+  }
+
+  changeStyle = () => {
+    const { card } = this.state
+
+    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin'], card.style)
+  }
+
+  getStyle = (comIds, style) => {
+    const { card } = this.state
+
+    if (comIds.length !== 1 || comIds[0] !== card.uuid) return
+
+    let _card = {...card, style}
+
+    this.setState({
+      card: _card
+    })
+    
+    this.props.updateConfig(_card)
+  }
+
+  render() {
+    const { card } = this.state
+
+    return (
+      <div className="menu-data-card-edit-box" style={card.style}>
+        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+          <div className="mk-popover-control">
+            <WrapComponent config={card} updateConfig={this.updateComponent} />
+            <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
+            <Icon className="close" title="鍒犻櫎缁勪欢" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
+            <SettingComponent config={card} updateConfig={this.updateComponent} />
+          </div>
+        } trigger="hover">
+          <Icon type="tool" />
+        </Popover>
+        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
+        {card.wrap.addable === 'true' ? <div className="card-add-button"><Icon type="plus" /></div> : null}
+      </div>
+    )
+  }
+}
+
+const mapStateToProps = (state) => {
+  return {
+    menu: state.customMenu
+  }
+}
+
+const mapDispatchToProps = () => {
+  return {}
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(antvBarLineChart)
\ No newline at end of file
diff --git a/src/menu/components/card/table-card/index.scss b/src/menu/components/card/table-card/index.scss
new file mode 100644
index 0000000..d6ce6a3
--- /dev/null
+++ b/src/menu/components/card/table-card/index.scss
@@ -0,0 +1,75 @@
+.menu-data-card-edit-box {
+  position: relative;
+  box-sizing: border-box;
+  background: #ffffff;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: cover;
+  min-height: 20px;
+  
+  .card-control {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    .anticon-tool {
+      right: auto;
+      left: 1px;
+      padding: 1px;
+    }
+  }
+  .anticon-tool {
+    position: absolute;
+    z-index: 1;
+    font-size: 16px;
+    right: 1px;
+    top: 1px;
+    cursor: pointer;
+    padding: 5px;
+    background: rgba(255, 255, 255, 0.55);
+  }
+
+  .card-item {
+    overflow-y: hidden;
+    position: relative;
+    background-position: center center;
+    background-repeat: no-repeat;
+    background-size: cover;
+    min-height: 20px;
+  }
+  
+  .card-item:hover {
+    box-shadow: 0px 0px 2px #e8e8e8;
+  }
+
+  .model-menu-card-cell-list .card-detail-row > .anticon-plus {
+    position: absolute;
+    right: -30px;
+    font-size: 16px;
+  }
+  .model-menu-action-list {
+    line-height: 40px;
+    .ant-row > .anticon-plus {
+      position: absolute;
+      right: -30px;
+      font-size: 16px;
+    }
+  }
+  .card-add-button {
+    text-align: right;
+    clear: left;
+    .anticon-plus {
+      font-size: 20px;
+      color: #26C281;
+      padding: 5px;
+      margin-right: 10px;
+    }
+  }
+}
+.menu-data-card-edit-box::after {
+  display: block;
+  content: ' ';
+  clear: both;
+}
+.menu-data-card-edit-box:hover {
+  box-shadow: 0px 0px 2px #e8e8e8;
+}
diff --git a/src/menu/components/card/table-card/wrapsetting/index.jsx b/src/menu/components/card/table-card/wrapsetting/index.jsx
new file mode 100644
index 0000000..81632e9
--- /dev/null
+++ b/src/menu/components/card/table-card/wrapsetting/index.jsx
@@ -0,0 +1,82 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Icon, Modal } from 'antd'
+
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+import SettingForm from './settingform'
+import './index.scss'
+
+class DataSource extends Component {
+  static propTpyes = {
+    config: PropTypes.any,
+    updateConfig: PropTypes.func
+  }
+
+  state = {
+    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    visible: false,
+    wrap: null
+  }
+
+  UNSAFE_componentWillMount () {
+    const { config } = this.props
+
+    this.setState({wrap: fromJS(config.wrap).toJS()})
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  editDataSource = () => {
+    this.setState({
+      visible: true
+    })
+  }
+
+  verifySubmit = () => {
+    const { config } = this.props
+
+    this.verifyRef.handleConfirm().then(res => {
+
+      this.setState({
+        wrap: res,
+        visible: false
+      })
+      this.props.updateConfig({...config, wrap: res})
+    })
+  }
+
+  render () {
+    const { config } = this.props
+    const { visible, dict, wrap } = this.state
+
+    return (
+      <div className="model-menu-setting-wrap">
+        <Icon type="edit" onClick={() => this.editDataSource()} />
+        <Modal
+          wrapClassName="popview-modal"
+          title={'鍗$墖璁剧疆'}
+          visible={visible}
+          width={700}
+          maskClosable={false}
+          okText={dict['model.submit']}
+          onOk={this.verifySubmit}
+          onCancel={() => { this.setState({ visible: false }) }}
+          destroyOnClose
+        >
+          <SettingForm
+            dict={dict}
+            wrap={wrap}
+            config={config}
+            wrappedComponentRef={(inst) => this.verifyRef = inst}
+          />
+        </Modal>
+      </div>
+    )
+  }
+}
+
+export default DataSource
\ No newline at end of file
diff --git a/src/menu/components/card/table-card/wrapsetting/index.scss b/src/menu/components/card/table-card/wrapsetting/index.scss
new file mode 100644
index 0000000..04372e6
--- /dev/null
+++ b/src/menu/components/card/table-card/wrapsetting/index.scss
@@ -0,0 +1,7 @@
+.model-menu-setting-wrap {
+  display: inline-block;
+
+  >.anticon-edit {
+    color: #1890ff;
+  }
+}
\ No newline at end of file
diff --git a/src/menu/components/card/table-card/wrapsetting/settingform/index.jsx b/src/menu/components/card/table-card/wrapsetting/settingform/index.jsx
new file mode 100644
index 0000000..863b152
--- /dev/null
+++ b/src/menu/components/card/table-card/wrapsetting/settingform/index.jsx
@@ -0,0 +1,140 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Input, Radio, Tooltip, Icon, InputNumber } from 'antd'
+
+import './index.scss'
+
+class SettingForm extends Component {
+  static propTpyes = {
+    dict: PropTypes.object,      // 瀛楀吀椤�
+    config: PropTypes.object,    // 鍗$墖琛屼俊鎭�
+    wrap: PropTypes.object,      // 鏁版嵁婧愰厤缃�
+  }
+
+  handleConfirm = () => {
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      this.props.form.validateFieldsAndScroll((err, values) => {
+        if (!err) {
+          resolve(values)
+        } else {
+          reject(err)
+        }
+      })
+    })
+  }
+
+  render() {
+    const { wrap, config } = this.props
+    const { getFieldDecorator } = this.props.form
+
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <div className="model-menu-setting-form">
+        <Form {...formItemLayout}>
+          <Row gutter={24}>
+            <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�">
+                  <Icon type="question-circle" />
+                  缁勪欢鍚嶇О
+                </Tooltip>
+              }>
+                {getFieldDecorator('name', {
+                  initialValue: wrap.name,
+                  rules: [
+                    {
+                      required: true,
+                      message: this.props.dict['form.required.input'] + '缁勪欢鍚嶇О!'
+                    }
+                  ]
+                })(<Input placeholder={''} autoComplete="off" />)}
+              </Form.Item>
+            </Col>
+            <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��">
+                  <Icon type="question-circle" />
+                  瀹藉害
+                </Tooltip>
+              }>
+                {getFieldDecorator('width', {
+                  initialValue: wrap.width || 24,
+                  rules: [
+                    {
+                      required: true,
+                      message: this.props.dict['form.required.input'] + '瀹藉害!'
+                    }
+                  ]
+                })(<InputNumber min={1} max={24} precision={0} />)}
+              </Form.Item>
+            </Col>
+            {config.subtype === 'propcard' ? <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="閫夋嫨闈欐�佸�硷紝鏃犻渶閰嶇疆鏁版嵁婧愩��">
+                  <Icon type="question-circle" />
+                  鏁版嵁鏉ユ簮
+                </Tooltip>
+              }>
+                {getFieldDecorator('datatype', {
+                  initialValue: wrap.datatype || 'dynamic'
+                })(
+                  <Radio.Group>
+                    <Radio value="dynamic">鍔ㄦ��</Radio>
+                    <Radio value="static">闈欐��</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col> : null}
+            {config.subtype === 'datacard' ? <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="閫夋嫨鍚湁娣诲姞鎸夐挳鏃讹紝璇峰畬鍠勬寜閽厤缃俊鎭��">
+                  <Icon type="question-circle" />
+                  娣诲姞鎸夐挳
+                </Tooltip>
+              }>
+                {getFieldDecorator('addable', {
+                  initialValue: wrap.addable || 'false'
+                })(
+                  <Radio.Group>
+                    <Radio value="true">鏈�</Radio>
+                    <Radio value="false">鏃�</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col> : null}
+            <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="閫夋嫨鍗$墖鍒囨崲鏃讹紝鍙悜鍏朵粬缁勪欢浼犻�掍富閿�笺��">
+                  <Icon type="question-circle" />
+                  鏄惁鍒囨崲
+                </Tooltip>
+              }>
+                {getFieldDecorator('switch', {
+                  initialValue: wrap.switch || 'false'
+                })(
+                  <Radio.Group>
+                    <Radio value="true">鏄�</Radio>
+                    <Radio value="false">鍚�</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
+          </Row>
+        </Form>
+      </div>
+    )
+  }
+}
+
+export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/menu/components/card/table-card/wrapsetting/settingform/index.scss b/src/menu/components/card/table-card/wrapsetting/settingform/index.scss
new file mode 100644
index 0000000..159130b
--- /dev/null
+++ b/src/menu/components/card/table-card/wrapsetting/settingform/index.scss
@@ -0,0 +1,11 @@
+.model-menu-setting-form {
+  position: relative;
+
+  .anticon-question-circle {
+    color: #c49f47;
+    margin-right: 3px;
+  }
+  .ant-input-number {
+    width: 100%;
+  }
+}
\ No newline at end of file
diff --git a/src/menu/components/chart/antv-bar/index.scss b/src/menu/components/chart/antv-bar/index.scss
index c37fad1..161b992 100644
--- a/src/menu/components/chart/antv-bar/index.scss
+++ b/src/menu/components/chart/antv-bar/index.scss
@@ -24,6 +24,7 @@
       position: absolute;
       right: 1px;
       top: 1px;
+      z-index: 1;
       font-size: 16px;
       padding: 5px;
       cursor: pointer;
diff --git a/src/menu/components/chart/antv-pie/index.scss b/src/menu/components/chart/antv-pie/index.scss
index 87c7aa0..bb1752c 100644
--- a/src/menu/components/chart/antv-pie/index.scss
+++ b/src/menu/components/chart/antv-pie/index.scss
@@ -23,6 +23,7 @@
       position: absolute;
       right: 1px;
       top: 1px;
+      z-index: 1;
       font-size: 16px;
       padding: 5px;
       cursor: pointer;
diff --git a/src/menu/datasource/index.jsx b/src/menu/datasource/index.jsx
index 07031e4..9244b6b 100644
--- a/src/menu/datasource/index.jsx
+++ b/src/menu/datasource/index.jsx
@@ -35,9 +35,47 @@
   }
 
   editDataSource = () => {
+    const { config, menu } = this.props
+
+    let search = []
+    let parents = []
+    let _conf = config
+    let getParents = (box) => {
+      box.components.forEach(item => {
+        if (item.type !== 'tabs') return
+
+        item.subtabs.forEach(tab => {
+          if (_conf.parentId === tab.parentId && _conf.tabId === tab.uuid) {
+            parents.unshift(tab)
+            _conf = item
+
+            if (_conf.parentId && _conf.tabId) {
+              getParents(menu)
+            }
+          } else {
+            getParents(tab)
+          }
+        })
+      })
+    }
+
+    if (config.parentId && config.tabId) {
+      getParents(menu)
+    }
+
+    parents.unshift(menu)
+
+    parents.forEach(parent => {
+      parent.components.forEach(item => {
+        if (item.type === 'search') {
+          search = item.search
+        }
+      })
+    })
+
     this.setState({
       visible: true,
-      mainSearch: []
+      mainSearch: search
     })
   }
 
diff --git a/src/menu/datasource/verifycard/customscript/index.jsx b/src/menu/datasource/verifycard/customscript/index.jsx
index 996e2ff..39999b7 100644
--- a/src/menu/datasource/verifycard/customscript/index.jsx
+++ b/src/menu/datasource/verifycard/customscript/index.jsx
@@ -1,5 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
 import { Form, Row, Col, Button, notification, Select } from 'antd'
 
 import Utils from '@/utils/utils.js'
@@ -42,7 +43,7 @@
       } else if (['dateweek', 'datemonth', 'daterange'].includes(item.type)) {
         _usefulFields.push(item.field)
         _usefulFields.push(item.field + '1')
-      } else if (_usefulFields.includes(item.field)) {
+      } else if (item.type === 'date' && _usefulFields.includes(item.field)) {
         _usefulFields.push(item.field + '1')
       } else {
         _usefulFields.push(item.field)
@@ -52,6 +53,35 @@
     this.setState({
       usefulFields: _usefulFields.join(', ')
     })
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    if (!is(fromJS(this.props.searches), fromJS(nextProps.searches))) {
+      
+      let _usefulFields = []
+      nextProps.searches.forEach(item => {
+        if (!item.field) return
+
+        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 (item.type === 'date' && _usefulFields.includes(item.field)) {
+          _usefulFields.push(item.field + '1')
+        } else {
+          _usefulFields.push(item.field)
+        }
+      })
+
+      this.setState({
+        usefulFields: _usefulFields.join(', ')
+      })
+    }
   }
 
   edit = (record) => {
@@ -69,7 +99,7 @@
       editItem: null
     })
     this.props.form.setFieldsValue({
-      sql: ''
+      sql: ' '
     })
   }
 
@@ -128,9 +158,13 @@
             loading: false
           })
           this.props.form.setFieldsValue({
-            sql: ''
+            sql: ' '
           })
           this.props.scriptSubmit(values)
+        }, () => {
+          this.setState({
+            loading: false
+          })
         })
       }
     })
@@ -185,7 +219,7 @@
           </Col>
           <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
-              id, bid, loginuid, sessionuid, userid, appkey, time_id, calendarDate, calendarDate1{usefulFields ? ', ' + usefulFields : ''}
+              id, bid, loginuid, sessionuid, userid, appkey, time_id{usefulFields ? ', ' + usefulFields : ''}
             </Form.Item>
           </Col>
           <Col span={10}>
diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx
index e1b3e56..8332eac 100644
--- a/src/menu/datasource/verifycard/index.jsx
+++ b/src/menu/datasource/verifycard/index.jsx
@@ -122,19 +122,77 @@
   }
 
   UNSAFE_componentWillMount() {
-    const { config, mainSearch } = this.props
+    const { config, mainSearch, menu } = this.props
 
     let search = config.search || []
-    search = [...search, ...mainSearch]
+
+    if (config.setting.useMSearch === 'true') { // 浣跨敤涓绘悳绱㈡潯浠�
+      search = [...search, ...mainSearch]
+    }
+
+    let Marks = []
+    let getcomponentmarks = (box, conf) => {
+      if (!conf.parentId && box.Template === 'CustomPage') {
+        box.components.forEach(item => {
+          if (item.uuid !== conf.uuid && item.setting && item.setting.varMark) {
+            Marks.push(item.setting.varMark)
+          }
+        })
+      } else if (conf.parentId === box.parentId && conf.tabId === box.uuid) {
+        box.components.forEach(item => {
+          if (item.uuid !== conf.uuid && item.setting && item.setting.varMark) {
+            Marks.push(item.setting.varMark)
+          }
+        })
+      } else {
+        box.components.forEach(item => {
+          if (item.type !== 'tabs') return
+  
+          item.subtabs.forEach(tab => {
+            getcomponentmarks(tab, conf)
+          })
+        })
+      }
+    }
+
+    getcomponentmarks(menu, config)
+
+    let _setting = fromJS(config.setting).toJS()
+
+    if (!_setting.varMark) {
+      _setting.varMark = this.getMark(Marks)
+    }
 
     this.setState({
       columns: fromJS(config.columns).toJS(),
-      setting: fromJS(config.setting).toJS(),
+      setting: _setting,
       scripts: fromJS(config.scripts).toJS(),
-      searches: search
+      searches: search,
+      varMarks: Marks
     })
 
     this.getsysScript()
+  }
+
+  getMark = (varMarks) => {
+    let m = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
+    let i = 0
+    let n = 25
+
+    let name = ''
+    while (!name) {
+      name = `${m[n]}${m[i]}_`
+      if (varMarks.includes(name) && n > 0) {
+        i++
+        if (i >= 26) {
+          n--
+          i = 0
+        }
+        name = ''
+      }
+    }
+
+    return name
   }
 
   getsysScript = () => {
@@ -309,12 +367,32 @@
   }
 
   changeTab = (val) => {
-    const { activeKey } = this.state
+    const { config, mainSearch } = this.props
+    const { activeKey, varMarks } = this.state
 
     this.setState({loading: true})
     if (activeKey === 'setting') {
       this.settingForm.handleConfirm().then(res => {
+        let search = config.search || []
+
+        if (res.useMSearch === 'true') { // 浣跨敤涓绘悳绱㈡潯浠�
+          search = [...search, ...mainSearch]
+        }
+
+        if (res.varMark && varMarks.includes(res.varMark)) {
+          notification.warning({
+            top: 92,
+            message: '鍙橀噺鏍囪瘑涓嶅彲閲嶅锛�',
+            duration: 5
+          })
+          this.setState({
+            loading: false
+          })
+          return
+        }
+
         this.setState({
+          searches: search,
           setting: res
         }, () => {
           this.sqlverify(() => { // 楠岃瘉鎴愬姛
@@ -324,6 +402,7 @@
             })
           }, () => {             // 楠岃瘉澶辫触
             this.setState({
+              activeKey: val,
               loading: false
             })
           }, true)
@@ -340,7 +419,7 @@
       let _loading = false
       if (this.scriptsForm && this.scriptsForm.state.editItem) {
         _loading = true
-      } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) {
+      } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && this.scriptsForm.props.form.getFieldValue('sql') !== ' ') {
         _loading = true
       }
 
@@ -360,27 +439,34 @@
         activeKey: val,
         loading: false
       })
-
-      // this.sqlverify(() => { // 楠岃瘉鎴愬姛
-      //   this.setState({
-      //     activeKey: val,
-      //     loading: false
-      //   })
-      // }, () => {             // 楠岃瘉澶辫触
-      //   this.setState({
-      //     loading: false
-      //   })
-      // }, true)
     }
   }
 
   submitDataSource = () => {
-    const { activeKey, setting, columns, scripts } = this.state
+    const { config, mainSearch } = this.props
+    const { activeKey, setting, columns, scripts, varMarks } = this.state
 
     return new Promise((resolve, reject) => {
       if (activeKey === 'setting') {
         this.settingForm.handleConfirm().then(res => {
+          let search = config.search || []
+
+          if (res.useMSearch === 'true') { // 浣跨敤涓绘悳绱㈡潯浠�
+            search = [...search, ...mainSearch]
+          }
+
+          if (res.varMark && varMarks.includes(res.varMark)) {
+            notification.warning({
+              top: 92,
+              message: '鍙橀噺鏍囪瘑涓嶅彲閲嶅锛�',
+              duration: 5
+            })
+            reject()
+            return
+          }
+
           this.setState({
+            searches: search,
             setting: res
           }, () => {
             this.sqlverify(() => { resolve({setting: res, columns, scripts }) }, reject, false)
@@ -394,7 +480,7 @@
         let _loading = false
         if (this.scriptsForm && this.scriptsForm.state.editItem) {
           _loading = true
-        } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) {
+        } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && this.scriptsForm.props.form.getFieldValue('sql') !== ' ') {
           _loading = true
         }
 
@@ -432,9 +518,21 @@
     }
 
     if ((setting.interType === 'system' && setting.execute !== 'false') || _scripts.length > 0) {
+      let result = SettingUtils.getDebugSql(setting, _scripts, columns, searches)
+
+      if (result.error) {
+        notification.warning({
+          top: 92,
+          message: result.error,
+          duration: 5
+        })
+        reject()
+        return
+      }
+
       let param = {
         func: 's_debug_sql',
-        LText: SettingUtils.getDebugSql(setting, _scripts, columns, searches)
+        LText: result.sql
       }
       param.LText = Utils.formatOptions(param.LText)
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
diff --git a/src/menu/datasource/verifycard/settingform/index.jsx b/src/menu/datasource/verifycard/settingform/index.jsx
index de9225c..09621e4 100644
--- a/src/menu/datasource/verifycard/settingform/index.jsx
+++ b/src/menu/datasource/verifycard/settingform/index.jsx
@@ -20,6 +20,7 @@
 
   state = {
     interType: this.props.setting.interType || 'system',
+    laypage: this.props.setting.laypage || 'true',
     modules: [],
     useMSearch: this.props.setting.useMSearch || 'false'
   }
@@ -174,7 +175,7 @@
   render() {
     const { setting, menu, columns, config } = this.props
     const { getFieldDecorator } = this.props.form
-    const { interType, modules, useMSearch } = this.state
+    const { interType, modules, useMSearch, laypage } = this.state
 
     const formItemLayout = {
       labelCol: {
@@ -237,6 +238,32 @@
                 </Radio.Group>)}
               </Form.Item>
             </Col>
+            {interType === 'system' ? <Col span={8}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title={'鑷畾涔夎剼鏈腑鐨勫彉閲忥紙闄ゆ姤閿欏強鍙敤瀛楁澶栵級锛岄渶浠ユ鏍囪瘑寮�澶淬��'}>
+                  <Icon type="question-circle" />
+                  鍙橀噺鏍囪瘑
+                </Tooltip>
+              }>
+                {getFieldDecorator('varMark', {
+                  initialValue: setting.varMark || '',
+                  rules: [
+                    {
+                      required: true,
+                      message: this.props.dict['form.required.input'] + '鍙橀噺鏍囪瘑!'
+                    },
+                    {
+                      pattern: /^[a-zA-Z_]*$/ig,
+                      message: '璇蜂娇鐢ㄥ瓧姣嶆垨_'
+                    },
+                    {
+                      max: 3,
+                      message: '鏈�澶氫笁涓瓧绗︺��'
+                    }
+                  ]
+                })(<Input placeholder={''} autoComplete="off" />)}
+              </Form.Item>
+            </Col> : null}
             {interType === 'inner' ? <Col span={8}>
               <Form.Item label={tooltip ?
                 <Tooltip placement="topLeft" title={tooltip}>
@@ -367,29 +394,12 @@
                 )}
               </Form.Item>
             </Col>
-            {!config.pageable ? <Col span={8}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title={'鍒濆鍖栧姞杞芥椂锛屾槸鍚︿笌鍏朵粬缁勪欢涓�鍚屽姞杞芥暟鎹紝娉細浠呭湪浣跨敤绯荤粺鍑芥暟锛屼笖鍒濆鍖栧姞杞芥暟鎹椂鏈夋晥锛屽垎椤佃姹傛椂鏃犳晥銆�'}>
-                  <Icon type="question-circle" />
-                  鍚屾鏌ヨ
-                </Tooltip>
-              }>
-                {getFieldDecorator('sync', {
-                  initialValue: setting.sync || 'true'
-                })(
-                  <Radio.Group>
-                    <Radio value="true">鏄�</Radio>
-                    <Radio value="false">鍚�</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
             {config.pageable ? <Col span={8}>
               <Form.Item label="鍒嗛〉">
                 {getFieldDecorator('laypage', {
-                  initialValue: setting.laypage || 'false'
+                  initialValue: setting.laypage || 'true'
                 })(
-                  <Radio.Group>
+                  <Radio.Group onChange={(e) => this.setState({laypage: e.target.value})}>
                     <Radio value="true">鏄�</Radio>
                     <Radio value="false">鍚�</Radio>
                   </Radio.Group>
@@ -414,6 +424,23 @@
                 })(<InputNumber min={1} max={500} precision={0} />)}
               </Form.Item>
             </Col> : null}
+            {!config.pageable || (config.pageable && laypage === 'false') ? <Col span={8}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title={'鍒濆鍖栧姞杞芥椂锛屾槸鍚︿笌鍏朵粬缁勪欢涓�鍚屽姞杞芥暟鎹紝娉細浠呭湪浣跨敤绯荤粺鍑芥暟锛屼笖鍒濆鍖栧姞杞芥暟鎹椂鏈夋晥锛屽垎椤佃姹傛椂鏃犳晥銆�'}>
+                  <Icon type="question-circle" />
+                  鍚屾鏌ヨ
+                </Tooltip>
+              }>
+                {getFieldDecorator('sync', {
+                  initialValue: setting.sync || 'true'
+                })(
+                  <Radio.Group>
+                    <Radio value="true">鏄�</Radio>
+                    <Radio value="false">鍚�</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col> : null}
             <Col span={8}>
               <Form.Item label={
                 <Tooltip placement="topLeft" title={'浼樺厛浣跨敤鍚岀骇鐨勬悳绱㈡潯浠剁粍浠讹紝鍚岀骇鎼滅储涓嶅瓨鍦ㄦ椂锛屼緷娆″悜涓婇�夊彇锛屼笌褰撳墠缁勪欢鐨勬悳绱㈡潯浠朵竴鍚岀敤浣滄暟鎹繃婊わ紙褰撳墠缁勪欢鐨勬悳绱㈡潯浠朵紭鍏堬級銆�'}>
diff --git a/src/menu/datasource/verifycard/utils.jsx b/src/menu/datasource/verifycard/utils.jsx
index 12cda4e..bb94a8f 100644
--- a/src/menu/datasource/verifycard/utils.jsx
+++ b/src/menu/datasource/verifycard/utils.jsx
@@ -9,6 +9,7 @@
    */
   static getDebugSql (setting, scripts, columns, searches = []) {
     let sql = ''
+    let error = ''
     let _dataresource = ''
     let _customScript = ''
     let arr_field = columns.map(item => item.field).join(',')
@@ -21,12 +22,6 @@
       })
     }
 
-    if (_customScript) {
-      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
-        ${_customScript}
-      `
-    }
-
     if (setting.interType === 'system' && setting.execute !== 'false') {
       _dataresource = setting.dataresource
     }
@@ -37,53 +32,107 @@
     if (_customScript) {
       _customScript = _customScript.replace(/@\$|\$@/ig, '')
     }
+
+    if (_customScript) {
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
+        ${_customScript}
+      `
+    }
     
     // 姝e垯鏇挎崲
-    let _regoptions = searches.map(item => {
-      return {
-        reg: new RegExp('@' + item.key + '@', 'ig'),
-        value: `'${item.value}'`
+    let _regoptions = []
+    let _fields = []
+
+    searches.forEach(item => {
+      if (item.datefield) {
+        _regoptions.push({
+          var: new RegExp('@' + item.datefield, 'ig'),
+          reg: new RegExp('@' + item.datefield + '@', 'ig')
+        })
+        _regoptions.push({
+          var: new RegExp('@' + item.datefield + '1', 'ig'),
+          reg: new RegExp('@' + item.datefield + '1@', 'ig')
+        })
+      }
+      if (['dateweek', 'datemonth', 'daterange'].includes(item.type)) {
+        _regoptions.push({
+          var: new RegExp('@' + item.field, 'ig'),
+          reg: new RegExp('@' + item.field + '@', 'ig')
+        })
+        _regoptions.push({
+          var: new RegExp('@' + item.field + '1', 'ig'),
+          reg: new RegExp('@' + item.field + '1@', 'ig')
+        })
+      } else if (item.type === 'date') {
+        if (_fields.includes(item.field)) {
+          _regoptions.push({
+            var: new RegExp('@' + item.field + '1', 'ig'),
+            reg: new RegExp('@' + item.field + '1@', 'ig')
+          })
+        } else {
+          _fields.push(item.field)
+          _regoptions.push({
+            var: new RegExp('@' + item.field, 'ig'),
+            reg: new RegExp('@' + item.field + '@', 'ig')
+          })
+        }
+      } else {
+        _regoptions.push({
+          var: new RegExp('@' + item.field, 'ig'),
+          reg: new RegExp('@' + item.field + '@', 'ig')
+        })
       }
     })
-    let _search = ''
 
-    // 鏃ュ巻涓殑骞翠唤鏇挎崲
-    if (setting.queryType === 'statistics' || _customScript) {
-      _regoptions.push({
-        reg: new RegExp('@calendarDate@', 'ig'),
-        value: `1970-01-01 00:00:00.000`
-      })
-      _regoptions.push({
-        reg: new RegExp('@calendarDate1@', 'ig'),
-        value: `2030-12-31 23:59:59.999`
-      })
-    }
+    let _search = ''
 
     if (setting.queryType === 'statistics' && _dataresource) {
       _regoptions.forEach(item => {
-        _dataresource = _dataresource.replace(item.reg, item.value)
+        _dataresource = _dataresource.replace(item.reg, '0')
       })
 
       _search = ''
     }
 
+    let originscript = _customScript
+
     if (_customScript) {
       _regoptions.push({
+        var: new RegExp('@orderBy', 'ig'),
         reg: new RegExp('@orderBy@', 'ig'),
-        value: setting.order
       })
       if (setting.laypage !== 'false') {
         _regoptions.push({
+          var: new RegExp('@pageSize', 'ig'),
           reg: new RegExp('@pageSize@', 'ig'),
-          value: 10
         }, {
+          var: new RegExp('@pageIndex', 'ig'),
           reg: new RegExp('@pageIndex@', 'ig'),
-          value: 1
         })
       }
       _regoptions.forEach(item => {
-        _customScript = _customScript.replace(item.reg, item.value)
+        _customScript = _customScript.replace(item.reg, '0')
+        originscript = originscript.replace(item.reg, '0')
+        originscript = originscript.replace(item.var, '0')
       })
+
+      if (setting.varMark) {
+        originscript = originscript.replace(/@ErrorCode/ig, '')
+        originscript = originscript.replace(/@retmsg/ig, '')
+        originscript = originscript.replace(/@id@/ig, '').replace(/@id/ig, '')
+        originscript = originscript.replace(/@bid@/ig, '').replace(/@bid/ig, '')
+        originscript = originscript.replace(/@loginuid@/ig, '').replace(/@loginuid/ig, '')
+        originscript = originscript.replace(/@sessionuid@/ig, '').replace(/@sessionuid/ig, '')
+        originscript = originscript.replace(/@userid@/ig, '').replace(/@userid/ig, '')
+        originscript = originscript.replace(/@appkey@/ig, '').replace(/@appkey/ig, '')
+        originscript = originscript.replace(/@time_id@/ig, '').replace(/@time_id/ig, '')
+  
+        originscript = originscript.replace(new RegExp('@' + setting.varMark, 'ig'), '')
+
+        if (/@/ig.test(originscript)) {
+          error = '浣跨敤浜嗗彉閲忔爣璇嗗鐨勫瓧娈碉紒'
+        }
+      }
     }
 
     // 鏁版嵁婧愬鐞�, 瀛樺湪鏄剧ず鍒楁椂 
@@ -106,6 +155,6 @@
       sql = _dataresource
     }
     
-    return sql
+    return { error, sql }
   }
 }
\ No newline at end of file
diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx
index 0efdbeb..92ad980 100644
--- a/src/tabviews/custom/components/card/data-card/index.jsx
+++ b/src/tabviews/custom/components/card/data-card/index.jsx
@@ -28,15 +28,25 @@
     pageIndex: 1,
     activeKey: '',             // 閫変腑鍗�
     loading: false,            // 鏁版嵁鍔犺浇鐘舵��
+    sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
     card: null,                // 鍗$墖璁剧疆
     data: null,                // 鏁版嵁
     total: null
   }
 
   UNSAFE_componentWillMount () {
+    const { data } = this.props
     let _config = fromJS(this.props.config).toJS()
     let _card = _config.subcards[0]
     let _cols = new Map()
+
+    let _data = null
+    let _sync = _config.setting.sync === 'true'
+
+    if (_config.setting.sync === 'true' && data) {
+      _data = data[_config.dataName] || []
+      _sync = false
+    }
 
     _config.columns.forEach(item => {
       _cols.set(item.field, item)
@@ -56,11 +66,19 @@
     })
 
     this.setState({
+      sync: _sync,
+      data: _data,
       config: _config,
       card: _card,
       arr_field: _config.columns.map(col => col.field).join(','),
     }, () => {
-      this.loadData()
+      if (_config.setting.sync !== 'true' && _config.setting.onload === 'true') {
+        this.loadData()
+      } else if (_sync && !_data) {
+        this.setState({
+          loading: true
+        })
+      }
     })
   }
 
@@ -70,6 +88,25 @@
 
   shouldComponentUpdate (nextProps, nextState) {
     return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    const { sync, config } = this.state
+
+    if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
+      let _data = []
+      if (nextProps.data && nextProps.data[config.dataName]) {
+        _data = nextProps.data[config.dataName] || []
+      }
+
+      this.setState({sync: false, loading: false, data: _data})
+    } else if (!is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
+      if (config.setting.syncRefresh === 'true') {
+        this.setState({}, () => {
+          this.loadData()
+        })
+      }
+    }
   }
 
   componentWillUnmount () {
@@ -94,10 +131,15 @@
   async loadData () {
     const { mainSearch, BID, menuType, dataManager } = this.props
     const { config, arr_field, pageIndex } = this.state
-    
+
     let searches = []
     if (mainSearch && mainSearch.length > 0) { // 涓昏〃鎼滅储鏉′欢
-      searches = [...mainSearch, ...searches]
+      let keys = searches.map(item => item.key)
+      mainSearch.forEach(item => {
+        if (!keys.includes(item.key)) {
+          searches.push(item)
+        }
+      })
     }
 
     this.setState({
diff --git a/src/tabviews/custom/components/card/prop-card/index.jsx b/src/tabviews/custom/components/card/prop-card/index.jsx
index b3ff9a4..d43b9d6 100644
--- a/src/tabviews/custom/components/card/prop-card/index.jsx
+++ b/src/tabviews/custom/components/card/prop-card/index.jsx
@@ -23,14 +23,29 @@
 
   state = {
     config: null,              // 鍥捐〃閰嶇疆淇℃伅
-    loading: true,             // 鏁版嵁鍔犺浇鐘舵��
+    loading: false,            // 鏁版嵁鍔犺浇鐘舵��
     activeKey: '',             // 閫変腑鏁版嵁
+    sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
     data: null,                // 鏁版嵁
   }
 
   UNSAFE_componentWillMount () {
+    const { data } = this.props
     let _config = fromJS(this.props.config).toJS()
     let _cols = new Map()
+
+    let _data = null
+    let _sync = false
+    if (_config.setting && _config.wrap.datatype !== 'static') {
+      _sync = _config.setting.sync === 'true'
+
+      if (_config.setting.sync === 'true' && data) {
+        _data = data[_config.dataName] || []
+        _sync = false
+      }
+    } else {
+      _data = []
+    }
 
     _config.columns.forEach(item => {
       _cols.set(item.field, item)
@@ -52,10 +67,18 @@
     })
 
     this.setState({
+      sync: _sync,
+      data: _data,
       config: _config,
       arr_field: _config.columns.map(col => col.field).join(','),
     }, () => {
-      this.loadData()
+      if (_config.wrap.datatype !== 'static' && _config.setting && _config.setting.sync !== 'true' && _config.setting.onload === 'true') {
+        this.loadData()
+      } else if (_sync && !_data) {
+        this.setState({
+          loading: true
+        })
+      }
     })
   }
 
@@ -74,6 +97,30 @@
     MKEmitter.removeListener('syncRefreshComponentId', this.reload)
   }
 
+  /**
+   * @description 鍥捐〃鏁版嵁鏇存柊锛屽埛鏂板唴瀹�
+   */
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    const { sync, config } = this.state
+
+    if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
+      let _data = []
+      if (nextProps.data && nextProps.data[config.dataName]) {
+        _data = nextProps.data[config.dataName] || []
+      }
+
+      this.setState({sync: false, loading: false, data: _data}, () => {
+        this.handleData()
+      })
+    } else if (!is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
+      if (config.wrap.datatype !== 'static' && config.setting.syncRefresh === 'true') {
+        this.setState({}, () => {
+          this.loadData()
+        })
+      }
+    }
+  }
+
   reload = (syncId) => {
     const { config } = this.state
 
@@ -85,10 +132,15 @@
   async loadData () {
     const { mainSearch, BID, menuType, dataManager } = this.props
     const { config, arr_field } = this.state
-    
+
     let searches = []
     if (mainSearch && mainSearch.length > 0) { // 涓昏〃鎼滅储鏉′欢
-      searches = [...mainSearch, ...searches]
+      let keys = searches.map(item => item.key)
+      mainSearch.forEach(item => {
+        if (!keys.includes(item.key)) {
+          searches.push(item)
+        }
+      })
     }
 
     if (config.wrap.datatype === 'static') {
diff --git a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
index 3ddb731..d16b55b 100644
--- a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -125,7 +125,7 @@
       search: Utils.initMainSearch(config.search),
       showHeader
     }, () => {
-      if (config.setting.sync !== 'true') {
+      if (config.setting.sync !== 'true' && config.setting.onload === 'true') {
         this.loadData()
       } else if (config.setting.sync === 'true') {
         if (!_data) {
@@ -161,6 +161,12 @@
       this.setState({sync: false, loading: false, data: _data}, () => {
         this.handleData()
       })
+    } else if (!is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
+      if (config.setting.syncRefresh === 'true') {
+        this.setState({}, () => {
+          this.loadData()
+        })
+      }
     }
   }
 
@@ -197,10 +203,15 @@
   async loadData () {
     const { mainSearch, BID, menuType, dataManager } = this.props
     const { config, arr_field, search } = this.state
-    
+
     let searches = fromJS(search).toJS()
     if (mainSearch && mainSearch.length > 0) { // 涓昏〃鎼滅储鏉′欢
-      searches = [...mainSearch, ...searches]
+      let keys = searches.map(item => item.key)
+      mainSearch.forEach(item => {
+        if (!keys.includes(item.key)) {
+          searches.push(item)
+        }
+      })
     }
 
     this.setState({
diff --git a/src/tabviews/custom/components/chart/antv-pie/index.jsx b/src/tabviews/custom/components/chart/antv-pie/index.jsx
index 873f630..ec05d38 100644
--- a/src/tabviews/custom/components/chart/antv-pie/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-pie/index.jsx
@@ -70,7 +70,7 @@
       search: Utils.initMainSearch(config.search),
       showHeader
     }, () => {
-      if (config.setting.sync !== 'true') {
+      if (config.setting.sync !== 'true' && config.setting.onload === 'true') {
         this.loadData()
       } else if (config.setting.sync === 'true') {
         if (!_data) {
@@ -106,6 +106,12 @@
       this.setState({sync: false, loading: false, data: _data}, () => {
         this.handleData()
       })
+    } else if (!is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
+      if (config.setting.syncRefresh === 'true') {
+        this.setState({}, () => {
+          this.loadData()
+        })
+      }
     }
   }
 
@@ -124,10 +130,15 @@
   async loadData () {
     const { mainSearch, BID, menuType, dataManager } = this.props
     const { config, arr_field, search } = this.state
-    
+
     let searches = fromJS(search).toJS()
     if (mainSearch && mainSearch.length > 0) { // 涓昏〃鎼滅储鏉′欢
-      searches = [...mainSearch, ...searches]
+      let keys = searches.map(item => item.key)
+      mainSearch.forEach(item => {
+        if (!keys.includes(item.key)) {
+          searches.push(item)
+        }
+      })
     }
 
     this.setState({
diff --git a/src/tabviews/custom/components/share/tabtransfer/index.jsx b/src/tabviews/custom/components/share/tabtransfer/index.jsx
index f2bb801..ffa91e7 100644
--- a/src/tabviews/custom/components/share/tabtransfer/index.jsx
+++ b/src/tabviews/custom/components/share/tabtransfer/index.jsx
@@ -68,16 +68,17 @@
     }
 
     let params = []
-    config.components.forEach(component => {
-      if (component.type === 'tabs') return
+    config.components.forEach(item => {
+      if (item.type === 'tabs') return
 
-      if (!component.format || (component.subtype === 'propcard' && component.wrap.datatype === 'static')) return
+      if (!item.setting || item.setting.interType !== 'system') return
+      if (!item.format || (item.subtype === 'propcard' && item.wrap.datatype === 'static')) return
 
-      if (component.dataName && !component.pageable && component.setting.interType === 'system' && component.setting.onload === 'true' && component.setting.sync === 'true') {
-        let param = this.getDefaultParam(component, _mainSearch)
+      if (item.dataName && (!item.pageable || (item.pageable && !item.setting.laypage)) && item.setting.onload === 'true' && item.setting.sync === 'true') {
+        let param = this.getDefaultParam(item, _mainSearch)
         params.push(param)
       } else {
-        component.setting.sync = 'false'
+        item.setting.sync = 'false'
       }
     })
 
@@ -103,8 +104,14 @@
     if (search && search.length > 0) {
       searchlist = Utils.initMainSearch(search)
     }
+
     if (setting.useMSearch === 'true') {
-      searchlist = [...mainSearch, ...searchlist]
+      let keys = searchlist.map(item => item.key)
+      mainSearch.forEach(item => {
+        if (!keys.includes(item.key)) {
+          searchlist.push(item)
+        }
+      })
     }
 
     let arr_field = columns.map(col => col.field)
@@ -255,7 +262,7 @@
         if (item.subtype === 'datacard') {
           return (
             <Col span={item.width} key={item.uuid}>
-              <DataCard config={item} BID={BID} mainSearch={mainSearch} menuType={menuType} dataManager={dataManager} />
+              <DataCard config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} dataManager={dataManager} />
             </Col>
           )
         } else if (item.subtype === 'propcard') {
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index 9541ee1..73a4d2b 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -181,7 +181,12 @@
         }
       }
 
+      if (!component.setting) return component // 涓嶄娇鐢ㄧ郴缁熷嚱鏁版椂
       if (!component.format || (component.subtype === 'propcard' && component.wrap.datatype === 'static')) return component // 娌℃湁鍔ㄦ�佹暟鎹�  鏁版嵁鏍煎紡 array 鎴� object
+      if (component.setting.interType !== 'system') { // 涓嶄娇鐢ㄧ郴缁熷嚱鏁版椂
+        component.setting.sync = 'false'
+        return component
+      }
 
       let _customScript = ''
       component.scripts && component.scripts.forEach(script => {
@@ -193,36 +198,32 @@
       })
       delete component.scripts
 
-      if (component.setting && component.setting.interType === 'system') { // 浣跨敤绯荤粺鍑芥暟
-        component.setting.execute = component.setting.execute !== 'false'  // 榛樿sql鏄惁鎵ц锛岃浆涓篵oolean 缁熶竴鏍煎紡
-        component.setting.laypage = component.setting.laypage === 'true'   // 鏄惁鍒嗛〉锛岃浆涓篵oolean 缁熶竴鏍煎紡
+      component.setting.execute = component.setting.execute !== 'false'  // 榛樿sql鏄惁鎵ц锛岃浆涓篵oolean 缁熶竴鏍煎紡
+      component.setting.laypage = component.setting.laypage === 'true'   // 鏄惁鍒嗛〉锛岃浆涓篵oolean 缁熶竴鏍煎紡
 
-        if (!component.setting.execute) {
-          component.setting.dataresource = ''
-        }
-        if (/\s/.test(component.setting.dataresource)) {
-          component.setting.dataresource = '(' + component.setting.dataresource + ') tb'
-        }
-    
-        if (this.props.dataManager) { // 鏁版嵁鏉冮檺
-          component.setting.dataresource = component.setting.dataresource.replace(/\$@/ig, '/*')
-          component.setting.dataresource = component.setting.dataresource.replace(/@\$/ig, '*/')
-          _customScript = _customScript.replace(/\$@/ig, '/*')
-          _customScript = _customScript.replace(/@\$/ig, '*/')
-        } else {
-          component.setting.dataresource = component.setting.dataresource.replace(/@\$|\$@/ig, '')
-          _customScript = _customScript.replace(/@\$|\$@/ig, '')
-        }
+      if (!component.setting.execute) {
+        component.setting.dataresource = ''
+      }
+      if (/\s/.test(component.setting.dataresource)) {
+        component.setting.dataresource = '(' + component.setting.dataresource + ') tb'
+      }
+  
+      if (this.props.dataManager) { // 鏁版嵁鏉冮檺
+        component.setting.dataresource = component.setting.dataresource.replace(/\$@/ig, '/*')
+        component.setting.dataresource = component.setting.dataresource.replace(/@\$/ig, '*/')
+        _customScript = _customScript.replace(/\$@/ig, '/*')
+        _customScript = _customScript.replace(/@\$/ig, '*/')
+      } else {
+        component.setting.dataresource = component.setting.dataresource.replace(/@\$|\$@/ig, '')
+        _customScript = _customScript.replace(/@\$|\$@/ig, '')
       }
 
-      if (component.setting) {
-        component.setting.customScript = _customScript // 鏁寸悊鍚庤嚜瀹氫箟鑴氭湰
-      }
+      component.setting.customScript = _customScript // 鏁寸悊鍚庤嚜瀹氫箟鑴氭湰
 
       // floor    缁勪欢鐨勫眰绾�
       // dataName 绯荤粺鐢熸垚鐨勬暟鎹簮鍚嶇О
       // pageable 鏄惁鍒嗛〉锛岀粍浠跺睘鎬э紝涓嶅垎椤电殑缁勪欢鎵嶅彲浠ョ粺涓�鏌ヨ
-      if (component.floor === 1 && component.dataName && !component.pageable && component.setting.interType === 'system' && component.setting.onload === 'true' && component.setting.sync === 'true') {
+      if (component.floor === 1 && component.dataName && (!component.pageable || (component.pageable && !component.setting.laypage)) && component.setting.onload === 'true' && component.setting.sync === 'true') {
         let param = this.getDefaultParam(component, mainSearch)
         params.push(param)
       } else if (component.floor === 1) {
@@ -243,8 +244,14 @@
     if (search && search.length > 0) {
       searchlist = Utils.initMainSearch(search)
     }
+
     if (setting.useMSearch === 'true') {
-      searchlist = [...mainSearch, ...searchlist]
+      let keys = searchlist.map(item => item.key)
+      mainSearch.forEach(item => {
+        if (!keys.includes(item.key)) {
+          searchlist.push(item)
+        }
+      })
     }
 
     let arr_field = columns.map(col => col.field)
@@ -440,7 +447,7 @@
         if (item.subtype === 'datacard') {
           return (
             <Col span={item.width} key={item.uuid}>
-              <DataCard config={item} BID={BID} mainSearch={mainSearch} menuType={menuType} dataManager={dataManager} />
+              <DataCard config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} dataManager={dataManager} />
             </Col>
           )
         } else if (item.subtype === 'propcard') {
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index a276faa..894a4a9 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -17,7 +17,6 @@
 
 import './index.scss'
 
-// const { TabPane } = Tabs
 const { Panel } = Collapse
 const { confirm } = Modal
 const _locale = localStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS

--
Gitblit v1.8.0