From f45b2ad61211cf2821cdaab07676c7906c96410a Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期三, 05 七月 2023 18:23:56 +0800 Subject: [PATCH] 2023-07-05 --- src/menu/datasource/verifycard/index.jsx | 289 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 225 insertions(+), 64 deletions(-) diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx index ec62f40..2fe9dae 100644 --- a/src/menu/datasource/verifycard/index.jsx +++ b/src/menu/datasource/verifycard/index.jsx @@ -1,9 +1,10 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { fromJS } from 'immutable' -import { Form, Tabs, Popconfirm, notification, Modal, Typography, Spin, message, Button } from 'antd' +import { Form, Tabs, Popconfirm, notification, Modal, Typography, Spin, message, Button, Input } from 'antd' import { StopOutlined, CheckCircleOutlined, EditOutlined, SwapOutlined, DeleteOutlined, CopyOutlined, BorderOutlined, SnippetsOutlined } from '@ant-design/icons' import moment from 'moment' +import md5 from 'md5' import Api from '@/api' import Utils from '@/utils/utils.js' @@ -14,11 +15,13 @@ import SettingForm from './settingform' import PasteForm from '@/templates/zshare/pasteform' import SettingUtils from './utils' +import MKEmitter from '@/utils/events.js' import MinView from '@/assets/img/minview.png' import './index.scss' const { TabPane } = Tabs const { Paragraph } = Typography +const { Search } = Input const CodeMirror = asyncComponent(() => import('@/templates/zshare/codemirror')) const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent')) @@ -31,13 +34,17 @@ state = { columns: [], + debugId: '', + subColumns: [], activeKey: 'setting', loading: false, + searchKey: '', initsql: '', // sql楠岃瘉鏃跺彉閲忓0鏄庡強璧嬪�� usefulfields: '', defaultsql: '', // 榛樿Sql defaultSearch: '', systemScripts: [], + median: {}, visible: false, pvisible: false, reload: false, @@ -57,6 +64,7 @@ inputType: 'input', editable: true, unique: true, + strict: true, copy: true, rules: [{ pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig, @@ -191,13 +199,22 @@ _search = _search.replace(/@\$@/ig, '') _search = _search ? 'where ' + _search : '' + let columns = config.columns ? fromJS(config.columns).toJS() : [] + let subColumns = config.subColumns ? fromJS(config.subColumns).toJS() : [] + + columns.reverse() + subColumns.reverse() this.setState({ scripts, - columns: config.columns ? fromJS(config.columns).toJS() : [], + columns: columns, + subColumns: subColumns, setting: _setting, + median: _setting, searches: search, - defaultSearch: _search + defaultSearch: _search, + searchKey: '', + debugId: _setting.debugId || '' }) this.getsysScript() @@ -268,7 +285,27 @@ values.uuid = Utils.getuuid() - this.setState({ columns: [...columns, values] }) + this.setState({ columns: [values, ...columns] }) + } + + subColumnChange = (values, resolve) => { + const { subColumns } = this.state + + let fields = subColumns.map(item => item.field.toLowerCase()) + if (fields.includes(values.field.toLowerCase())) { + notification.warning({ + top: 92, + message: '瀛楁宸插瓨鍦紒', + duration: 5 + }) + return + } + + resolve() + + values.uuid = Utils.getuuid() + + this.setState({ subColumns: [values, ...subColumns] }) } deleteScript = (record) => { @@ -354,6 +391,7 @@ } else { values.uuid = Utils.getuuid() scripts.push(values) + MKEmitter.emit('editLineId', values.uuid) } this.setState({ scripts }) @@ -418,6 +456,23 @@ loading: false }) this.getdefaultSql() + } else if (activeKey === 'subcolumns') { + if (this.subdatasource && this.subdatasource.state.editingKey) { + notification.warning({ + top: 92, + message: '瀛楁鏈繚瀛橈紝璇蜂繚瀛樺悗鍒囨崲锛�', + duration: 5 + }) + this.setState({ + loading: false + }) + return + } + + this.setState({ + activeKey: val, + loading: false + }) } else if (activeKey === 'scripts') { let _loading = false if (this.scriptsForm && this.scriptsForm.state.editItem) { @@ -429,13 +484,9 @@ if (_loading) { notification.warning({ top: 92, - message: '瀛樺湪鏈繚瀛樿剼鏈紝璇风偣鍑荤‘瀹氫繚瀛橈紝鎴栫偣鍑诲彇娑堟斁寮冧慨鏀癸紒', + message: '瀛樺湪鏈繚瀛樿剼鏈紒', duration: 5 }) - this.setState({ - loading: false - }) - return } this.setState({ @@ -514,7 +565,26 @@ submitDataSource = () => { const { config, mainSearch } = this.props - const { activeKey, setting, columns, scripts } = this.state + const { activeKey, setting, columns, subColumns, scripts } = this.state + + if (config.subtype === 'dualdatacard') { + let arr = columns.map(col => col.field.toLowerCase()) + let _arr = [] + subColumns.forEach(col => { + if (arr.includes(col.field.toLowerCase())) { + _arr.push(col.field) + } + }) + + if (_arr.length > 0) { + notification.warning({ + top: 92, + message: '瀛愯〃涓瓧娈�' + _arr.join('銆�') + '涓庝富琛ㄥ瓧娈甸噸澶嶏紒', + duration: 5 + }) + return Promise.reject() + } + } return new Promise((resolve, reject) => { if (activeKey === 'setting') { @@ -536,7 +606,7 @@ defaultSearch: _search, setting: res }, () => { - this.sqlverify(() => { resolve({setting: res, columns, scripts }) }, reject, false) + this.sqlverify(() => { resolve({setting: res, columns, subColumns, scripts }) }, reject, false) }) }, () => { reject() @@ -551,7 +621,18 @@ reject() return } - this.sqlverify(() => { resolve({setting, columns, scripts }) }, reject, false) + this.sqlverify(() => { resolve({setting, columns, subColumns, scripts }) }, reject, false) + } else if (activeKey === 'subcolumns') { + if (this.subdatasource && this.subdatasource.state.editingKey) { + notification.warning({ + top: 92, + message: '瀛楁鏈繚瀛橈紝璇蜂繚瀛樺悗鎻愪氦锛�', + duration: 5 + }) + reject() + return + } + this.sqlverify(() => { resolve({setting, columns, subColumns, scripts }) }, reject, false) } else if (activeKey === 'scripts') { let _loading = false if (this.scriptsForm && this.scriptsForm.state.editItem) { @@ -570,13 +651,14 @@ return } - this.sqlverify(() => { resolve({setting, columns, scripts }) }, reject, false) + this.sqlverify(() => { resolve({setting, columns, subColumns, scripts }) }, reject, false) } }) } sqlverify = (resolve, reject, change = false, testScripts) => { - const { columns, setting, scripts, searches, defaultSearch } = this.state + const { config } = this.props + const { columns, setting, scripts, searches, defaultSearch, debugId } = this.state let _scripts = scripts.filter(item => item.status !== 'false') @@ -593,9 +675,21 @@ return } + if (change && columns.length === 0) { + reject() + return + } + if ((setting.interType === 'system' && setting.execute !== 'false') || _scripts.length > 0) { let timestamp = moment().format('YYYY-MM-DD HH:mm:ss') - let r = SettingUtils.getDebugSql(setting, _scripts, columns, searches, defaultSearch, timestamp) + let r = SettingUtils.getDebugSql(setting, _scripts, columns, searches, defaultSearch, config.type, '2023-04-20 15:29:37') + + let _debugId = md5(r.sql) + + if (debugId === _debugId) { + resolve() + return + } if (r.errors) { notification.warning({ @@ -631,7 +725,9 @@ if (sumParam) { Api.genericInterface(sumParam).then(res => { if (res.status) { - resolve() + this.setState({debugId: _debugId}, () => { + resolve() + }) } else { reject() Modal.error({ @@ -640,7 +736,9 @@ } }) } else { - resolve() + this.setState({debugId: _debugId}, () => { + resolve() + }) } } else { reject() @@ -696,18 +794,15 @@ }) } + updateSubfields = (columns) => { + this.setState({ + subColumns: columns + }) + } + copyDatasource = () => { const { config } = this.props - const { columns, scripts } = this.state - - if (columns.length === 0) { - notification.warning({ - top: 92, - message: '璇锋坊鍔犲瓧娈甸泦!', - duration: 5 - }) - return - } + const { columns, subColumns, scripts } = this.state this.settingForm.handleConfirm().then(res => { delete res.supModule @@ -716,7 +811,7 @@ let source = { key: 'interface', type: 'line', - data: {setting: res, columns, scripts, pageable: false, format: 'array', name: res.name, status: 'false', type: 'interface', uuid: '' } + data: {setting: res, columns, subColumns, scripts, pageable: false, format: 'array', name: res.name, status: 'false', type: 'interface', uuid: '' } } try { @@ -764,6 +859,15 @@ } if (config.subtype !== 'basetable') { + let subColumns = [] + + if (config.subtype === 'dualdatacard' && res.data.subColumns) { + subColumns = res.data.subColumns.map(col => { + col.uuid = Utils.getuuid() + return col + }) + } + this.setState({ scripts: res.data.scripts.map(col => { col.uuid = Utils.getuuid() @@ -773,7 +877,9 @@ col.uuid = Utils.getuuid() return col }), + subColumns: subColumns, setting: res.data.setting, + median: res.data.setting, reload: true, pvisible: false }, () => { @@ -786,6 +892,7 @@ return col }), setting: res.data.setting, + median: res.data.setting, reload: true, pvisible: false }, () => { @@ -801,7 +908,28 @@ let n = [] columns.forEach(col => { - m.push(`${col.field}(${col.label})`) + m.push(`${col.field} ${col.datatype}`) + n.push(col.field) + }) + + let oInput = document.createElement('input') + oInput.value = `/*${m.join(',')}*/ + ${n.join(',')}` + document.body.appendChild(oInput) + oInput.select() + document.execCommand('Copy') + document.body.removeChild(oInput) + + message.success('澶嶅埗鎴愬姛銆�') + } + + copySubColumns = () => { + const { subColumns } = this.state + let m = [] + let n = [] + + subColumns.forEach(col => { + m.push(`${col.field} ${col.datatype}`) n.push(col.field) }) @@ -827,7 +955,7 @@ render() { const { config } = this.props - const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql, visible, pvisible, reload, script, scriptValue } = this.state + const { columns, subColumns, median, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql, visible, pvisible, reload, script, scriptValue, searchKey } = this.state return ( <div className="model-data-source-wrap"> @@ -837,15 +965,15 @@ <TabPane tab={ <span> 鏁版嵁婧� - {config.type !== 'interface' ? <CopyOutlined title="澶嶅埗鏁版嵁婧�" className="mk-copy-datasource" onClick={this.copyDatasource}/> : null} - {config.type !== 'interface' ? <SnippetsOutlined title="瀵煎叆鏁版嵁婧�" className="mk-paste-datasource" onClick={() => this.setState({pvisible: true})}/> : null} </span> } key="setting"> {!reload ? <SettingForm config={config} columns={columns} + subColumns={subColumns} setting={setting} scripts={scripts} + updateStatus={(res) => this.setState({median: {...res}})} wrappedComponentRef={(inst) => this.settingForm = inst} /> : null} </TabPane> @@ -853,23 +981,41 @@ <span> 瀛楁闆� {columns.length ? <span className="count-tip">{columns.length}</span> : null} - <CopyOutlined title="浠ラ�楀彿鎷兼帴褰㈠紡澶嶅埗瀛楁" className="mk-copy-fields" onClick={this.copyColumns}/> </span> } key="columns"> <ColForm columnChange={this.columnChange}/> <FieldsComponent - config={{...config, columns}} + config={{columns}} type="fields" updatefield={this.updatefields} /> - <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} type="datasourcefield" wrappedComponentRef={(inst) => this.datasource = inst} data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/> + <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.datasource = inst} data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/> + </TabPane> : null} + {config.subtype === 'dualdatacard' ? <TabPane tab={ + <span> + 瀛愯〃瀛楁闆� + {subColumns.length ? <span className="count-tip">{subColumns.length}</span> : null} + </span> + } key="subcolumns"> + <ColForm columnChange={this.subColumnChange}/> + <FieldsComponent + config={{columns: subColumns}} + type="fields" + updatefield={this.updateSubfields} + /> + <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.subdatasource = inst} data={subColumns} columns={colColumns} onChange={(subColumns) => this.setState({subColumns})}/> </TabPane> : null} <TabPane tab={ <span> 鑷畾涔夎剼鏈� {scripts.length ? <span className="count-tip">{scripts.length}</span> : null} + {config.type !== 'interface' && activeKey === 'setting' ? <CopyOutlined title="澶嶅埗鏁版嵁婧�" className="mk-copy-datasource" onClick={(e) => {e.stopPropagation();this.copyDatasource()}}/> : null} + {config.type !== 'interface' && activeKey === 'setting' ? <SnippetsOutlined title="瀵煎叆鏁版嵁婧�" className="mk-paste-datasource" onClick={(e) => {e.stopPropagation();this.setState({pvisible: true})}}/> : null} + {activeKey === 'columns' ? <CopyOutlined title="浠ラ�楀彿鎷兼帴褰㈠紡澶嶅埗瀛楁" className="mk-copy-fields" onClick={(e) => {e.stopPropagation();this.copyColumns()}}/> : null} + {activeKey === 'subcolumns' ? <CopyOutlined title="浠ラ�楀彿鎷兼帴褰㈠紡澶嶅埗瀛楁" className="mk-copy-fields" onClick={(e) => {e.stopPropagation();this.copySubColumns()}}/> : null} + {activeKey === 'subcolumns' || activeKey === 'columns' ? <span onClick={(e) => {e.stopPropagation()}}><Search className="mk-search-fields" defaultValue={searchKey} allowClear onSearch={(val, e) => {e.stopPropagation();this.setState({searchKey: val})}} /></span> : null} </span> - } key="scripts" id="mk-scripts-tabpane"> + } key="scripts" disabled={median.interType !== 'system'} id="mk-scripts-tabpane"> {scripts.length ? <BorderOutlined className="full-scripts" onClick={() => { if (this.scriptsForm && (this.scriptsForm.state.editItem || (this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))))) { notification.warning({ @@ -882,6 +1028,7 @@ this.setState({visible: true, script: null, scriptValue: ''}) }}/> : null} <CustomScriptsForm + type={config.type} setting={setting} searches={searches} defaultsql={defaultsql} @@ -910,36 +1057,50 @@ title = title && title[0] ? title[0] : '' let _text = title ? item.sql.replace(title, '') : item.sql - return ( - <div className={'script-item ' + (script && script.uuid === item.uuid ? 'active' : '') } key={item.uuid}> - <div style={{cursor: 'pointer'}} onClick={() => { - this.setState({script: item, scriptValue: item.sql}) - }}> - {title ? <div style={{color: '#a50', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{title}</div> : null} - <Paragraph copyable={{ text: item.sql }} ellipsis={{ rows: 4 }}>{_text}</Paragraph> - <div>{item.status === 'false' ? - <span style={{color: '#ff4d4f', marginLeft: '20px'}}> - 绂佺敤 - <StopOutlined style={{marginLeft: '5px'}} /> - </span> : - <span style={{color: '#26C281', marginLeft: '20px'}}> - 鍚敤 - <CheckCircleOutlined style={{marginLeft: '5px'}}/> - </span>} + if (item.status === 'false') { + return ( + <div className="script-item" key={item.uuid}> + <div style={{cursor: 'not-allowed'}}> + {title ? <div style={{color: '#a50', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{title}</div> : null} + <Paragraph copyable={{ text: item.sql }} ellipsis={{ rows: 4 }}>{_text}</Paragraph> + <div> + <span style={{color: '#ff4d4f', marginLeft: '20px'}}> + 绂佺敤 + <StopOutlined style={{marginLeft: '5px'}} /> + </span> + </div> + </div> + <div style={{height: '24px'}}></div> + </div> + ) + } else { + return ( + <div className={'script-item ' + (script && script.uuid === item.uuid ? 'active' : '') } key={item.uuid}> + <div style={{cursor: 'pointer'}} onClick={() => { + this.setState({script: item, scriptValue: item.sql}) + }}> + {title ? <div style={{color: '#a50', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{title}</div> : null} + <Paragraph copyable={{ text: item.sql }} ellipsis={{ rows: 4 }}>{_text}</Paragraph> + <div> + <span style={{color: '#26C281', marginLeft: '20px'}}> + 鍚敤 + <CheckCircleOutlined style={{marginLeft: '5px'}}/> + </span> + </div> + </div> + <div style={{textAlign: 'right'}}> + <span className="operation-btn" onClick={() => this.handleStatus(item)} style={{color: '#8E44AD'}}><SwapOutlined /></span> + <Popconfirm + overlayClassName="popover-confirm" + title="纭畾鍒犻櫎鍚�?" + onConfirm={() => this.deleteScript(item) + }> + <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span> + </Popconfirm> </div> </div> - <div style={{textAlign: 'right'}}> - <span className="operation-btn" onClick={() => this.handleStatus(item)} style={{color: '#8E44AD'}}><SwapOutlined /></span> - <Popconfirm - overlayClassName="popover-confirm" - title="纭畾鍒犻櫎鍚�?" - onConfirm={() => this.deleteScript(item) - }> - <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span> - </Popconfirm> - </div> - </div> - ) + ) + } })} </div> <div className="script-button"> -- Gitblit v1.8.0