From e36eb1999794bd71e76482b92a0b0b20f49d0032 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期五, 05 三月 2021 19:37:03 +0800 Subject: [PATCH] 2021-03-05 --- src/menu/datasource/verifycard/index.jsx | 417 ++++++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 284 insertions(+), 133 deletions(-) diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx index 99a1ff7..18aba05 100644 --- a/src/menu/datasource/verifycard/index.jsx +++ b/src/menu/datasource/verifycard/index.jsx @@ -1,7 +1,7 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { fromJS } from 'immutable' -import { Form, Tabs, Table, Popconfirm, Icon, notification, Modal, Typography, Spin } from 'antd' +import { Form, Tabs, Popconfirm, Icon, notification, Modal, Typography, Spin } from 'antd' import moment from 'moment' import Api from '@/api' @@ -18,6 +18,7 @@ const { Paragraph } = Typography const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent')) +const EditTable = asyncComponent(() => import('@/templates/zshare/editTable')) class VerifyCard extends Component { static propTpyes = { @@ -32,58 +33,82 @@ loading: false, initsql: '', // sql楠岃瘉鏃跺彉閲忓0鏄庡強璧嬪�� usefulfields: '', - defaultsql: '', // 榛樿Sql - systemScripts: [{ - name: '榛樿sql', - value: '' - }], + defaultsql: '', // 榛樿Sql + systemScripts: [], colColumns: [ { title: '鍚嶇О', dataIndex: 'label', - width: '25%' + inputType: 'input', + editable: true, + width: '28%' }, { title: '瀛楁', dataIndex: 'field', - width: '25%' + inputType: 'input', + editable: true, + unique: true, + width: '28%' }, { title: '鏁版嵁绫诲瀷', dataIndex: 'datatype', + inputType: 'select', + options: [ + { value: 'Nvarchar(50)', text: 'Nvarchar(50)' }, + { value: 'Nvarchar(100)', text: 'Nvarchar(100)' }, + { value: 'Nvarchar(512)', text: 'Nvarchar(512)' }, + { value: 'Nvarchar(1024)', text: 'Nvarchar(1024)' }, + { value: 'Nvarchar(2048)', text: 'Nvarchar(2048)' }, + { value: 'Nvarchar(max)', text: 'Nvarchar(max)' }, + { value: 'Int', text: 'Int' }, + { value: 'Decimal(18,0)', text: 'Decimal(18,0)' }, + { value: 'Decimal(18,1)', text: 'Decimal(18,1)' }, + { value: 'Decimal(18,2)', text: 'Decimal(18,2)' }, + { value: 'Decimal(18,3)', text: 'Decimal(18,3)' }, + { value: 'Decimal(18,4)', text: 'Decimal(18,4)' }, + { value: 'Decimal(18,5)', text: 'Decimal(18,5)' }, + { value: 'Decimal(18,6)', text: 'Decimal(18,6)' }, + { value: 'Decimal(18,7)', text: 'Decimal(18,7)' }, + { value: 'Decimal(18,8)', text: 'Decimal(18,8)' }, + { value: 'Decimal(18,9)', text: 'Decimal(18,9)' }, + { value: 'Decimal(18,10)', text: 'Decimal(18,10)' }, + { value: 'Decimal(18,11)', text: 'Decimal(18,11)' }, + { value: 'Decimal(18,12)', text: 'Decimal(18,12)' }, + { value: 'Decimal(18,13)', text: 'Decimal(18,13)' }, + { value: 'Decimal(18,14)', text: 'Decimal(18,14)' }, + { value: 'Decimal(18,15)', text: 'Decimal(18,15)' }, + { value: 'Decimal(18,16)', text: 'Decimal(18,16)' }, + { value: 'Decimal(18,17)', text: 'Decimal(18,17)' }, + { value: 'Decimal(18,18)', text: 'Decimal(18,18)' }, + ], + editable: true, width: '25%', - }, - { - title: '鎿嶄綔', - align: 'center', - width: '25%', - dataIndex: 'operation', - render: (text, record) => - (<div> - <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record, 'columns')} style={{color: '#1890ff'}}><Icon type="edit" /></span> - <Popconfirm - overlayClassName="popover-confirm" - title={this.props.dict['model.query.delete']} - onConfirm={() => this.deleteColumn(record) - }> - <span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span> - </Popconfirm> - </div>) } ], scriptsColumns: [ { title: 'SQL', dataIndex: 'sql', - width: '65%', - render: (text) => ( - <Paragraph copyable ellipsis={{ rows: 4, expandable: true }}>{text}</Paragraph> - ) + width: '72%', + render: (text) => { + let title = text.match(/^\s*\/\*.+\*\//) + title = title && title[0] ? title[0] : '' + text = title ? text.replace(title, '') : text + + return ( + <div> + {title ? <span style={{color: '#a50'}}>{title}</span> : null} + <Paragraph copyable ellipsis={{ rows: 4, expandable: true }}>{text}</Paragraph> + </div> + ) + } }, { title: '鐘舵��', dataIndex: 'status', - width: '15%', + width: '13%', render: (text, record) => record.status === 'false' ? ( <div> @@ -101,13 +126,11 @@ { title: '鎿嶄綔', align: 'center', - width: '20%', + width: '15%', dataIndex: 'operation', render: (text, record) => - (<div> - <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><Icon type="edit" /></span> - <span className="operation-btn" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> - <span className="operation-btn" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> + (<div style={{textAlign: 'center'}}> + <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record)} style={{color: '#1890ff'}}><Icon type="edit" /></span> <span className="operation-btn" title={this.props.dict['model.status.change']} onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><Icon type="swap" /></span> <Popconfirm overlayClassName="popover-confirm" @@ -122,12 +145,61 @@ } UNSAFE_componentWillMount() { - const { config } = this.props + const { config, mainSearch, menu } = this.props + + let search = config.search || [] + + 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.type === 'group') { + item.components.forEach(cell => { + if (cell.uuid !== conf.uuid && cell.setting && cell.setting.varMark) { + Marks.push(cell.setting.varMark.toLowerCase()) + } + }) + } else if (item.uuid !== conf.uuid && item.setting && item.setting.varMark) { + Marks.push(item.setting.varMark.toLowerCase()) + } + }) + } else if (conf.parentId === box.parentId && conf.tabId === box.uuid) { + box.components.forEach(item => { + if (item.type === 'group') { + item.components.forEach(cell => { + if (cell.uuid !== conf.uuid && cell.setting && cell.setting.varMark) { + Marks.push(cell.setting.varMark.toLowerCase()) + } + }) + } else if (item.uuid !== conf.uuid && item.setting && item.setting.varMark) { + Marks.push(item.setting.varMark.toLowerCase()) + } + }) + } 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() this.setState({ columns: fromJS(config.columns).toJS(), - setting: fromJS(config.setting).toJS(), - scripts: fromJS(config.scripts).toJS() + setting: _setting, + scripts: fromJS(config.scripts).toJS(), + searches: search, + varMarks: Marks }) this.getsysScript() @@ -157,14 +229,14 @@ res.data.forEach(item => { let _item = { name: item.funcname, - value: Utils.UnformatOptions(item.longparam) + value: window.decodeURIComponent(window.atob(item.longparam)) } _scripts.push(_item) }) this.setState({ - systemScripts: [...this.state.systemScripts, ..._scripts] + systemScripts: _scripts }) } else { notification.warning({ @@ -177,40 +249,31 @@ } columnChange = (values) => { - let columns = fromJS(this.state.columns).toJS() + const { columns } = this.state - if (values.uuid) { - columns = columns.map(item => { - if (item.uuid === values.uuid) { - return values - } else { - return item - } + let fields = columns.map(item => item.field.toLowerCase()) + if (fields.includes(values.field.toLowerCase())) { + notification.warning({ + top: 92, + message: '瀛楁宸插瓨鍦紒', + duration: 5 }) - } else { - values.uuid = Utils.getuuid() - columns.push(values) + return } - this.setState({ columns }) - } + values.uuid = Utils.getuuid() - deleteColumn = (record) => { - this.setState({ columns: this.state.columns.filter(item => item.uuid !== record.uuid) }) + this.setState({ columns: [...columns, values] }) } deleteScript = (record) => { this.setState({ scripts: this.state.scripts.filter(item => item.uuid !== record.uuid) }) } - handleEdit = (record, type) => { - if (type === 'scripts') { - this.scriptsForm.edit(record) - } else if (type === 'columns') { - this.contrastForm.edit(record) - } - - let node = document.getElementById('model-verify-card-box-tab').parentNode + handleEdit = (record) => { + this.scriptsForm.edit(record) + + let node = document.getElementById('model-data-source-wrap').parentNode if (node && node.scrollTop) { let inter = Math.ceil(node.scrollTop / 10) @@ -241,30 +304,6 @@ this.setState({ scripts }) } - handleUpDown = (record, direction) => { - let scripts = fromJS(this.state.scripts).toJS() - let index = 0 - - scripts = scripts.filter((item, i) => { - if (item.uuid === record.uuid) { - index = i - } - - return item.uuid !== record.uuid - }) - if ((index === 0 && direction === 'up') || (index === scripts.length && direction === 'down')) { - return - } - - if (direction === 'up') { - scripts.splice(index - 1, 0, record) - } else { - scripts.splice(index + 1, 0, record) - } - - this.setState({ scripts }) - } - scriptsChange = (values) => { let scripts = fromJS(this.state.scripts).toJS() @@ -283,6 +322,10 @@ return new Promise((resolve, reject) => { this.sqlverify(resolve, reject, false, scripts) }) + } + + changeScripts = (scripts) => { + this.setState({ scripts }) } scriptSubmit = (values) => { @@ -305,12 +348,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.toLowerCase())) { + notification.warning({ + top: 92, + message: '鍙橀噺鏍囪瘑涓嶅彲閲嶅锛�', + duration: 5 + }) + this.setState({ + loading: false + }) + return + } + this.setState({ + searches: search, setting: res }, () => { this.sqlverify(() => { // 楠岃瘉鎴愬姛 @@ -318,10 +381,13 @@ activeKey: val, loading: false }) + this.getdefaultSql() }, () => { // 楠岃瘉澶辫触 this.setState({ + activeKey: val, loading: false }) + this.getdefaultSql() }, true) }) }, () => { @@ -332,11 +398,12 @@ activeKey: val, loading: false }) + this.getdefaultSql() } else if (activeKey === 'scripts') { 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') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { _loading = true } @@ -356,27 +423,112 @@ activeKey: val, loading: false }) - - // this.sqlverify(() => { // 楠岃瘉鎴愬姛 - // this.setState({ - // activeKey: val, - // loading: false - // }) - // }, () => { // 楠岃瘉澶辫触 - // this.setState({ - // loading: false - // }) - // }, true) } } + getdefaultSql = () => { + const { columns, searches, setting } = this.state + let defaultsql = '' + let arr_field = columns.map(col => col.field).join(',') + + let _search = this.formatSearch(searches) + _search = Utils.joinMainSearchkey(_search) + + _search = _search.replace(/@\$@/ig, '') + _search = _search ? 'where ' + _search : '' + + if (setting.dataresource) { + let _dataresource = setting.dataresource + + if (/\s/.test(_dataresource)) { + _dataresource = '(' + _dataresource + ') tb' + } + + defaultsql = `select top @pageSize@ ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by @orderBy@) as rows from ${_dataresource} ${_search}) tmptable where rows > (@pageSize@ * (@pageIndex@ - 1)) order by tmptable.rows` + } + + this.setState({defaultsql}) + } + + /** + * @description 鑾峰彇鍏ㄩ儴鎼滅储鏉′欢 + * @param {Array} searches 鎼滅储鏉′欢鏁扮粍 + */ + formatSearch (searches) { + if (!searches || searches.length === 0) return [] + + let newsearches = [] + searches.forEach(search => { + if (!search.field) return + + let item = { + key: search.field, + match: search.match, + type: search.type, + label: search.label, + value: search.initval, + required: search.required === 'true' + } + if (item.type === 'group') { + let copy = fromJS(item).toJS() + copy.key = search.datefield + + item.value = search.initval && search.initval[0] ? search.initval[0] : '@$@' + item.match = '=' + + copy.type = 'daterange' + copy.match = 'between' + copy.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')] + + if (search.transfer === 'true') { + newsearches.push(item) + } + newsearches.push(copy) + return + } else if (item.type === 'date') { + item.value = moment().format('YYYY-MM-DD') + } else if (item.type === 'datemonth') { + item.value = moment().format('YYYY-MM') + } else if (item.type === 'dateweek') { + item.value = [moment().startOf('week').format('YYYY-MM-DD'), moment().endOf('week').format('YYYY-MM-DD')] + } else if (item.type === 'daterange') { + item.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')] + } else if (item.type === 'multiselect') { + item.value = ['@$@'] + } else { + item.value = '@$@' + } + newsearches.push(item) + }) + + return newsearches + } + 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.toLowerCase())) { + notification.warning({ + top: 92, + message: '鍙橀噺鏍囪瘑涓嶅彲閲嶅锛�', + duration: 5 + }) + reject() + return + } + this.setState({ + searches: search, setting: res }, () => { this.sqlverify(() => { resolve({setting: res, columns, scripts }) }, reject, false) @@ -390,7 +542,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') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { _loading = true } @@ -410,8 +562,7 @@ } sqlverify = (resolve, reject, change = false, testScripts) => { - const { config } = this.props - const { columns, setting, scripts } = this.state + const { columns, setting, scripts, searches } = this.state let _scripts = scripts.filter(item => item.status !== 'false') @@ -429,13 +580,26 @@ } 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, config.search) + exec_type: 'y', + LText: result.sql } param.LText = Utils.formatOptions(param.LText) param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') - param.secretkey = Utils.encrypt(param.LText, param.timestamp) + param.secretkey = Utils.encrypt('', param.timestamp) Api.getLocalConfig(param).then(result => { if (result.status) { @@ -469,12 +633,12 @@ render() { const { menu, config } = this.props - const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading } = this.state + const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql } = this.state return ( - <div id="model-verify-card-box-tab"> + <div id="model-data-source-wrap"> {loading && <Spin size="large" />} - <Tabs activeKey={activeKey} className="verify-card-box" onChange={this.changeTab}> + <Tabs activeKey={activeKey} className="data-source-card-box" onChange={this.changeTab}> <TabPane tab="鏁版嵁婧�" key="setting"> <SettingForm menu={menu} @@ -487,30 +651,24 @@ /> </TabPane> <TabPane tab="瀛楁闆�" key="columns"> - <ColForm - dict={this.props.dict} - columnChange={this.columnChange} - wrappedComponentRef={(inst) => this.contrastForm = inst} - /> + <ColForm dict={this.props.dict} columnChange={this.columnChange}/> <FieldsComponent config={{...config, columns}} type="fields" - tableFields={menu.tableFields} updatefield={this.updatefields} /> - <Table - bordered - rowKey="uuid" - className="custom-table" - dataSource={columns} - columns={colColumns} - pagination={false} - /> + <EditTable actions={['edit', 'move', 'copy', 'del']} type="datasourcefield" data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/> </TabPane> - <TabPane tab="鑷畾涔夎剼鏈�" key="scripts"> + <TabPane tab={ + <span> + 鑷畾涔夎剼鏈� + {scripts.length ? <span className="count-tip">{scripts.length}</span> : null} + </span> + } key="scripts"> <CustomScriptsForm setting={setting} - searches={config.search} + searches={searches} + defaultsql={defaultsql} initsql={this.state.initsql} dict={this.props.dict} customScripts={scripts} @@ -519,14 +677,7 @@ scriptSubmit={this.scriptSubmit} wrappedComponentRef={(inst) => this.scriptsForm = inst} /> - <Table - bordered - rowKey="uuid" - className="custom-table" - dataSource={scripts} - columns={scriptsColumns} - pagination={false} - /> + <EditTable actions={['move']} data={scripts} columns={scriptsColumns} onChange={this.changeScripts}/> </TabPane> </Tabs> </div> -- Gitblit v1.8.0