From 4590502dd26419fd190045d84fbf11eccb6093f7 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期六, 07 五月 2022 15:53:12 +0800
Subject: [PATCH] 2022-05-07

---
 src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx |  612 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 533 insertions(+), 79 deletions(-)

diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
index f16eb70..e32df92 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -1,19 +1,23 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Radio } from 'antd'
+import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Radio, Spin, Typography, Popconfirm } from 'antd'
+import { EditOutlined, StopOutlined, CheckCircleOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
-
+import SettingUtils from './utils.jsx'
 import ColumnForm from './columnform'
+import DataSource from './datasource'
+import CustomScript from './customscript'
 import CodeMirror from '@/templates/zshare/codemirror'
 import asyncComponent from '@/utils/asyncComponent'
 import './index.scss'
 
 const { TabPane } = Tabs
 const { confirm } = Modal
+const { Paragraph } = Typography
 const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
 
 class VerifyCard extends Component {
@@ -25,6 +29,8 @@
 
   state = {
     verify: {},
+    activeKey: 'setting',
+    systemScripts: [],
     defaultscript: '', // 鑷畾涔夎剼鏈�
     excelColumns: [
       {
@@ -109,6 +115,75 @@
           {value: 'false', text: '鍚�'}
         ]
       }
+    ],
+    scriptsColumns: [
+      {
+        title: 'SQL',
+        dataIndex: 'sql',
+        width: '60%',
+        render: (text) => {
+          let title = text.match(/^\s*\/\*.+\*\//)
+          title = title && title[0] ? title[0] : ''
+          let _text = title ? text.replace(title, '') : text
+
+          return (
+            <div>
+              {title ? <span style={{color: '#a50'}}>{title}<span style={{fontSize: '12px', marginLeft: '5px'}}>{_text.length}</span></span> : null}
+              <Paragraph copyable={{ text: text }} ellipsis={{ rows: 4, expandable: true }}>{_text}</Paragraph>
+            </div>
+          )
+        }
+      },
+      {
+        title: '鎵ц浣嶇疆',
+        dataIndex: 'position',
+        width: '10%',
+        render: (text, record) => {
+          if (record.position === 'init') {
+            return <span style={{color: 'orange'}}>鍒濆鍖�</span>
+          } else if (record.position === 'front') {
+            return <span style={{color: '#26C281'}}>sql鍓�</span>
+          } else {
+            return <span style={{color: '#1890ff'}}>sql鍚�</span>
+          }
+        }
+      },
+      {
+        title: '鐘舵��',
+        dataIndex: 'status',
+        width: '10%',
+        render: (text, record) => record.status === 'false' ?
+          (
+            <div style={{color: '#ff4d4f'}}>
+              {this.props.dict['model.status.forbidden']}
+              <StopOutlined style={{marginLeft: '5px'}} />
+            </div>
+          ) :
+          (
+            <div style={{color: '#26C281'}}>
+              {this.props.dict['model.status.open']}
+              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
+            </div>
+          )
+      },
+      {
+        title: '鎿嶄綔',
+        align: 'center',
+        width: '140px',
+        dataIndex: 'operation',
+        render: (text, record) =>
+          (<div style={{textAlign: 'center'}}>
+            <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><EditOutlined /></span>
+            <span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record, 'scripts')} style={{color: '#8E44AD'}}><SwapOutlined /></span>
+            <Popconfirm
+              overlayClassName="popover-confirm"
+              title={this.props.dict['model.query.delete']}
+              onConfirm={() => this.handleDelete(record, 'scripts')
+            }>
+              <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span>
+            </Popconfirm>
+          </div>)
+      }
     ]
   }
 
@@ -121,7 +196,9 @@
     }
 
     _verify.enable = _verify.enable || 'false'
+    _verify.dataType = _verify.dataType || 'default'
     _verify.columns = _verify.columns || []
+    _verify.scripts = _verify.scripts || []
 
     if (card.intertype !== 'system') {
       _verify.enable = 'false'
@@ -144,10 +221,138 @@
       defaultscript = `update ${config.setting.tableName || ''} set idefine5= idefine5+1 ,modifydate=getdate(),cdefine5='宸插鍑�',modifyuserid=@userid@ ${search}`
     }
 
+    let search = []
+
+    if (config.setting && config.setting.useMSearch === 'true' && window.GLOB.customMenu) {
+      let menu = fromJS(window.GLOB.customMenu).toJS()
+      let _search = null
+      let filterComponent = (box) => {
+        box.components.forEach(item => {
+          if (_search) return
+  
+          if (item.type === 'search') {
+            box.slist = [...box.slist, item.search]
+          } else if (item.uuid === config.uuid) {
+            _search = box.slist.pop()
+          } else if (item.type === 'group') {
+            item.components.forEach(m => {
+              if (m.uuid !== config.uuid) return
+              _search = box.slist.pop()
+            })
+          } else if (item.type === 'tabs') {
+            item.subtabs.forEach(tab => {
+              tab.slist = [...box.slist]
+              filterComponent(tab)
+            })
+          }
+        })
+      }
+      menu.slist = []
+      filterComponent(menu)
+  
+      if (_search) {
+        search = _search
+      } else {
+        menu.components.forEach(item => {
+          if (item.type !== 'search') return
+          search = item.search
+        })
+      }
+    }
+
+    let searches = fromJS(config.search || []).toJS()
+
+    if (search.length > 0) {
+      let keys = searches.map(item => (item.field ? item.field.toLowerCase() : ''))
+      search.forEach(item => {
+        if (item.field && !keys.includes(item.field.toLowerCase())) {
+          searches.push(item)
+        }
+      })
+    }
 
     this.setState({
       verify: _verify,
+      searches: searches,
+      activeKey: card.intertype === 'system' && _verify.dataType === 'custom' ? 'setting' : 'columns',
       defaultscript: defaultscript
+    })
+  }
+
+  componentDidMount () {
+    let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from聽 s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort`
+
+    _scriptSql = Utils.formatOptions(_scriptSql)
+
+    let _sParam = {
+      func: 'sPC_Get_SelectedList',
+      LText: _scriptSql,
+      obj_name: 'data',
+      arr_field: 'funcname,longparam'
+    }
+    
+    _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp)
+
+    _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 浜戠鏁版嵁楠岃瘉
+    
+    Api.getSystemConfig(_sParam).then(res => {
+      if (res.status) {
+        this.setState({
+          systemScripts: res.data.map(item => {
+            return {
+              name: item.funcname,
+              value: window.decodeURIComponent(window.atob(item.longparam))
+            }
+          })
+        })
+      } else {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  handleEdit = (record, type) => {
+    if (type === 'scripts') {
+      this.scriptsForm.edit(record)
+    }
+
+    let node = document.getElementById('verify-excelout-box-tab').parentNode
+
+    if (node && node.scrollTop) {
+      let inter = Math.ceil(node.scrollTop / 10)
+
+      let timer = setInterval(() => {
+        if (node.scrollTop - inter > 0) {
+          node.scrollTop = node.scrollTop - inter
+        } else {
+          node.scrollTop = 0
+          clearInterval(timer)
+        }
+      }, 10)
+    }
+  }
+
+  handleStatus = (record, type) => {
+    let verify = JSON.parse(JSON.stringify(this.state.verify))
+    record.status = record.status === 'false' ? 'true' : 'false'
+
+    if (type === 'scripts') {
+      verify.scripts = verify.scripts.map(item => {
+        if (item.uuid === record.uuid) {
+          return record
+        } else {
+          return item
+        }
+      })
+    }
+
+    this.setState({
+      verify: verify
     })
   }
 
@@ -296,7 +501,7 @@
   }
 
   handleConfirm = () => {
-    let verify = fromJS(this.state.verify).toJS()
+    const { activeKey, verify } = this.state
     
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     return new Promise((resolve, reject) => {
@@ -313,84 +518,168 @@
         return
       }
 
-      if (verify.enable === 'true') {
-        this.props.form.validateFieldsAndScroll((err, values) => {
-          if (!err) {
-            values.sql = values.sql || ''
+      if (activeKey === 'backscript' && verify.enable === 'true') {
+        this.checkScript(resolve, reject)
+      } else if (activeKey === 'setting') {
+        this.settingForm.handleConfirm().then(res => {
+          let _verify = {...verify, ...res}
+          this.setState({
+            verify: _verify
+          }, () => {
+            this.setState({loading: true})
+            this.sqlverify(() => { // 楠岃瘉鎴愬姛
+              this.setState({
+                loading: false
+              })
+              resolve(_verify)
+            }, () => {             // 楠岃瘉澶辫触
+              this.setState({
+                loading: false
+              })
+              reject()
+            }, verify.scripts)
+          })
+        })
+      } else if (activeKey === 'columns') {
+        if (this.columnRef && this.columnRef.state.editingKey) {
+          notification.warning({
+            top: 92,
+            message: '瀛楁鏈繚瀛橈紒',
+            duration: 5
+          })
+          return
+        }
 
-            let _quot = values.sql.match(/'{1}/g)
-            let _lparen = values.sql.match(/\({1}/g)
-            let _rparen = values.sql.match(/\){1}/g)
+        if (this.props.card.intertype !== 'system' || verify.dataType !== 'custom') {
+          resolve(verify)
+        } else {
+          this.setState({loading: true})
     
-            _quot = _quot ? _quot.length : 0
-            _lparen = _lparen ? _lparen.length : 0
-            _rparen = _rparen ? _rparen.length : 0
-    
-            if (_quot % 2 !== 0) {
-              notification.warning({
-                top: 92,
-                message: 'sql涓璡'蹇呴』鎴愬鍑虹幇',
-                duration: 5
-              })
-              return
-            } else if (_lparen !== _rparen) {
-              notification.warning({
-                top: 92,
-                message: 'sql涓�()蹇呴』鎴愬鍑虹幇',
-                duration: 5
-              })
-              return
-            } else if (/--/ig.test(values.sql)) {
-              notification.warning({
-                top: 92,
-                message: '鑷畾涔塻ql璇彞涓紝涓嶅彲鍑虹幇瀛楃 -- 锛屾敞閲婅鐢� /*鍐呭*/',
-                duration: 5
-              })
-              return
-            }
-    
-            let error = Utils.verifySql(values.sql, 'customscript')
-    
-            if (error) {
-              notification.warning({
-                top: 92,
-                message: 'sql涓笉鍙娇鐢�' + error,
-                duration: 5
-              })
-              return
-            }
-    
-            let param = {
-              func: 's_debug_sql',
-              exec_type: 'y',
-              LText: values.sql
-            }
-    
-            param.LText = param.LText.replace(/@\$|\$@/ig, '')
-    
-            param.LText = Utils.formatOptions(param.LText)
-            param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-            param.secretkey = Utils.encrypt('', param.timestamp)
-            
-            Api.getLocalConfig(param).then(res => {
-              if (res.status) {
-                resolve({...verify, script: values.sql})
-              } else {
-                Modal.error({
-                  title: res.message
-                })
-              }
+          this.sqlverify(() => { // 楠岃瘉鎴愬姛
+            this.setState({
+              loading: false
+            })
+            resolve(verify)
+          }, () => {             // 楠岃瘉澶辫触
+            this.setState({
+              loading: false
+            })
+            reject()
+          }, verify.scripts)
+        }
+      } else if (activeKey === 'scripts') {
+        if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) {
+          notification.warning({
+            top: 92,
+            message: '瀛樺湪鏈繚瀛樿剼鏈紝璇风偣鍑荤‘瀹氫繚瀛橈紝鎴栫偣鍑诲彇娑堟斁寮冧慨鏀癸紒',
+            duration: 5
+          })
+          return
+        }
+  
+        this.setState({loading: true})
+        this.sqlverify(() => { // 楠岃瘉鎴愬姛
+          this.setState({
+            loading: false
+          })
+          resolve(verify)
+        }, () => {             // 楠岃瘉澶辫触
+          this.setState({
+            loading: false
+          })
+          reject()
+        }, verify.scripts)
+      } else {
+        resolve(verify)
+      }
+    })
+  }
+
+  checkScript = (_resolve, _reject) => {
+    this.props.form.validateFieldsAndScroll((err, values) => {
+      if (!err) {
+        values.sql = values.sql || ''
+
+        let _quot = values.sql.match(/'{1}/g)
+        let _lparen = values.sql.match(/\({1}/g)
+        let _rparen = values.sql.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: 'sql涓璡'蹇呴』鎴愬鍑虹幇',
+            duration: 5
+          })
+          return
+        } else if (_lparen !== _rparen) {
+          notification.warning({
+            top: 92,
+            message: 'sql涓�()蹇呴』鎴愬鍑虹幇',
+            duration: 5
+          })
+          return
+        } else if (/--/ig.test(values.sql)) {
+          notification.warning({
+            top: 92,
+            message: '鑷畾涔塻ql璇彞涓紝涓嶅彲鍑虹幇瀛楃 -- 锛屾敞閲婅鐢� /*鍐呭*/',
+            duration: 5
+          })
+          return
+        }
+
+        let error = Utils.verifySql(values.sql, 'customscript')
+
+        if (error) {
+          notification.warning({
+            top: 92,
+            message: 'sql涓笉鍙娇鐢�' + error,
+            duration: 5
+          })
+          return
+        }
+
+        let param = {
+          func: 's_debug_sql',
+          exec_type: 'y',
+          LText: values.sql
+        }
+
+        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+
+        param.LText = Utils.formatOptions(param.LText)
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.secretkey = Utils.encrypt('', param.timestamp)
+        
+        this.setState({
+          loading: true
+        })
+        Api.getLocalConfig(param).then(res => {
+          this.setState({
+            loading: false
+          })
+          if (res.status) {
+            let verify = {...this.state.verify, script: values.sql}
+
+            this.setState({verify: verify}, () => {
+              _resolve(verify)
             })
           } else {
-            notification.warning({
-              top: 92,
-              message: '鑷畾涔夎剼鏈笉鍙负绌猴紒',
-              duration: 5
+            Modal.error({
+              title: res.message
             })
           }
         })
       } else {
-        resolve(verify)
+        notification.warning({
+          top: 92,
+          message: '鑷畾涔夎剼鏈笉鍙负绌猴紒',
+          duration: 5
+        })
+        _reject()
       }
     })
   }
@@ -470,9 +759,153 @@
     this.setState({verify: {...verify, columns}})
   }
 
+  // 鏍囩鍒囨崲
+  tabchange = (val) => {
+    const { card } = this.props
+    const { activeKey, verify } = this.state
+
+    if (activeKey === 'backscript' && verify.enable === 'true') {
+      this.checkScript(() => {
+        this.setState({
+          activeKey: val
+        })
+      }, () => {})
+    } else if (card.intertype !== 'system' || verify.dataType !== 'custom') {
+      this.setState({activeKey: val})
+      return
+    } else if (activeKey === 'setting') {
+      this.settingForm.handleConfirm().then(res => {
+        this.setState({
+          verify: {...verify, ...res}
+        }, () => {
+          this.setState({loading: true})
+          this.sqlverify(() => { // 楠岃瘉鎴愬姛
+            this.setState({
+              activeKey: val,
+              loading: false
+            })
+          }, () => {             // 楠岃瘉澶辫触
+            this.setState({
+              activeKey: val,
+              loading: false
+            })
+          }, verify.scripts)
+        })
+      })
+    } else if (activeKey === 'columns') {
+      if (this.columnRef && this.columnRef.state.editingKey) {
+        notification.warning({
+          top: 92,
+          message: '瀛楁鏈繚瀛橈紒',
+          duration: 5
+        })
+        return
+      }
+
+      this.setState({loading: true})
+
+      this.sqlverify(() => { // 楠岃瘉鎴愬姛
+        this.setState({
+          activeKey: val,
+          loading: false
+        })
+      }, () => {             // 楠岃瘉澶辫触
+        this.setState({
+          activeKey: val,
+          loading: false
+        })
+      }, verify.scripts)
+    } else if (activeKey === 'scripts') {
+      if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) {
+        notification.warning({
+          top: 92,
+          message: '瀛樺湪鏈繚瀛樿剼鏈紝璇风偣鍑荤‘瀹氫繚瀛橈紝鎴栫偣鍑诲彇娑堟斁寮冧慨鏀癸紒',
+          duration: 5
+        })
+        return
+      }
+
+      this.setState({loading: true})
+      this.sqlverify(() => { // 楠岃瘉鎴愬姛
+        this.setState({
+          activeKey: val,
+          loading: false
+        })
+      }, () => {             // 楠岃瘉澶辫触
+        this.setState({
+          activeKey: val,
+          loading: false
+        })
+      }, verify.scripts)
+    } else {
+      this.setState({
+        activeKey: val
+      })
+    }
+  }
+
+  scriptsChange = (values) => {
+    let verify = JSON.parse(JSON.stringify(this.state.verify))
+
+    if (values.uuid) {
+      verify.scripts = verify.scripts.map(item => {
+        if (item.uuid === values.uuid) {
+          return values
+        } else {
+          return item
+        }
+      })
+    } else {
+      values.uuid = Utils.getuuid()
+      verify.scripts.push(values)
+    }
+
+    this.setState({loading: true})
+
+    this.sqlverify(() => { // 楠岃瘉鎴愬姛
+      this.setState({
+        loading: false,
+        verify: verify
+      })
+    }, () => {             // 楠岃瘉澶辫触
+      this.setState({
+        loading: false
+      })
+    }, verify.scripts)
+  }
+
+  sqlverify = (_resolve, _reject, scripts) => {
+    const { searches, verify } = this.state
+
+    let sql = SettingUtils.getDebugSql(verify, scripts, searches, Utils)
+    let param = {
+      func: 's_debug_sql',
+      exec_type: 'y',
+      LText: sql
+    }
+    param.LText = Utils.formatOptions(param.LText)
+    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.secretkey = Utils.encrypt('', param.timestamp)
+
+    Api.getLocalConfig(param).then(result => {
+      if (result.status) {
+        _resolve()
+      } else {
+        _reject()
+        Modal.error({
+          title: result.message
+        })
+      }
+    })
+  }
+
+  updateDataType = (val) => {
+    this.setState({verify: {...this.state.verify, dataType: val}})
+  }
+
   render() {
     const { card } = this.props
-    const { verify, excelColumns, defaultscript } = this.state
+    const { verify, excelColumns, defaultscript, scriptsColumns, activeKey, loading } = this.state
     const { getFieldDecorator } = this.props.form
     const formItemLayout = {
       labelCol: {
@@ -487,13 +920,17 @@
 
     return (
       <div id="verify-excelout-box-tab">
-        <Tabs defaultActiveKey="1" className="excelout-verify-card-box" onChange={this.tabchange}>
+        {loading && <Spin size="large" />}
+        <Tabs activeKey={activeKey} className="excelout-verify-card-box" onChange={this.tabchange}>
+          {card.intertype === 'system' ? <TabPane tab="鍩虹楠岃瘉" key="setting">
+            <DataSource setting={verify} updateDataType={this.updateDataType} wrappedComponentRef={(inst) => this.settingForm = inst}/>
+          </TabPane> : null}
           <TabPane tab={
             <span>
               Excel瀵煎嚭鍒�
               {verify.columns.length ? <span className="count-tip">{verify.columns.length}</span> : null}
             </span>
-          } key="1">
+          } key="columns">
             <ColumnForm dict={this.props.dict} columnChange={this.columnChange}/>
             <Button className="excel-col-add mk-green" title="娣诲姞鏄剧ず鍒楀瓧娈�" onClick={this.columnFieldInput}>
               鍚屾鏄剧ず鍒�
@@ -502,14 +939,31 @@
               娓呯┖Excel鍒�
             </Button>
             <div style={{color: '#959595', fontSize: '13px', paddingLeft: '10px'}}>濡傞渶瀵煎嚭搴忓彿锛岃浣跨敤瀛楁 $Index銆�</div>
-            <EditTable actions={['edit', 'move', 'copy', 'del']} type="excelcolumn" data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
+            <EditTable actions={['edit', 'move', 'copy', 'del']} type="excelcolumn" wrappedComponentRef={(inst) => this.columnRef = inst} data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
           </TabPane>
+          {card.intertype === 'system' ? <TabPane tab={
+            <span>
+              鑷畾涔夎剼鏈�
+              {verify.scripts.length ? <span className="count-tip">{verify.scripts.length}</span> : null}
+            </span>
+          } key="scripts" disabled={verify.dataType !== 'custom'}>
+            <CustomScript
+              btn={card}
+              sheet={verify.tableName}
+              usefulfields={verify.columns}
+              scripts={verify.scripts}
+              systemScripts={this.state.systemScripts}
+              scriptsChange={this.scriptsChange}
+              wrappedComponentRef={(inst) => this.scriptsForm = inst}
+            />
+            <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/>
+          </TabPane> : null}
           {card.intertype === 'system' ? <TabPane tab={
             <span>
               鍥炶皟鑴氭湰
               {verify.enable === 'true' ? <span className="count-tip">1</span> : null}
             </span>
-          } key="6">
+          } key="backscript">
             <Form {...formItemLayout} className="verify-form">
               <Row gutter={24}>
                 <Col span={8}>
@@ -537,7 +991,7 @@
               </Row>
             </Form>
           </TabPane> : null}
-          <TabPane tab="淇℃伅鎻愮ず" key="7">
+          <TabPane tab="淇℃伅鎻愮ず" key="message">
             <Form {...formItemLayout}>
               <Row gutter={24}>
                 <Col offset={6} span={6}>

--
Gitblit v1.8.0