From d891a5169bef4e64ca8acd354bfe5eab75dbbb4d Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期三, 18 十月 2023 17:33:14 +0800 Subject: [PATCH] Merge branch 'develop' --- src/tabviews/zshare/actionList/index.scss | 8 src/views/systemproc/proc/index.jsx | 2 src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx | 12 src/templates/zshare/modalform/index.jsx | 245 ++++ src/templates/zshare/editTable/index.jsx | 75 + src/templates/modalconfig/settingform/index.scss | 4 src/menu/components/table/base-table/columns/editColumn/formconfig.jsx | 12 src/menu/components/form/simple-form/index.jsx | 66 - src/views/tabledesign/source.jsx | 24 src/menu/components/table/base-table/index.scss | 3 src/menu/components/table/normal-table/index.scss | 3 src/templates/modalconfig/index.jsx | 67 - src/tabviews/zshare/topSearch/index.scss | 2 src/mob/modalconfig/index.jsx | 67 - src/tabviews/zshare/actionList/normalbutton/index.jsx | 7 src/tabviews/zshare/mutilform/mkPopSelect/index.scss | 64 + src/menu/components/table/edit-table/columns/editColumn/index.jsx | 62 + src/templates/modalconfig/dragelement/card.jsx | 4 src/templates/zshare/editTable/index.scss | 13 src/menu/sysinterface/index.jsx | 6 src/views/systemproc/transfer/index.jsx | 289 +++++ src/menu/datasource/verifycard/index.jsx | 53 + src/assets/css/main.scss | 19 src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx | 12 src/menu/components/table/edit-table/index.scss | 5 src/menu/components/share/pastecomponent/index.jsx | 16 src/menu/components/form/step-form/index.jsx | 64 - src/templates/modalconfig/settingform/index.jsx | 33 src/templates/zshare/formconfig.jsx | 324 ++++++ src/menu/components/form/tab-form/index.jsx | 64 - src/menu/components/share/actioncomponent/index.jsx | 10 src/menu/modulecell/index.jsx | 4 src/tabviews/zshare/actionList/printbutton/index.jsx | 7 src/tabviews/zshare/mutilform/mkPopSelect/index.jsx | 372 +++++++ src/tabviews/custom/components/chart/antv-X6/nodeupdate/index.scss | 7 src/tabviews/zshare/mutilform/index.jsx | 187 ++- /dev/null | 14 src/menu/modalconfig/index.scss | 15 src/menu/modalconfig/index.jsx | 71 - src/menu/components/table/normal-table/index.jsx | 16 src/menu/components/table/normal-table/columns/index.jsx | 34 src/templates/zshare/modalform/modaleditable/index.jsx | 519 +++++---- src/views/systemproc/transfer/index.scss | 18 src/templates/zshare/modalform/modaleditable/index.scss | 12 src/templates/sharecomponent/searchcomponent/searchform/index.jsx | 66 + 45 files changed, 2,211 insertions(+), 766 deletions(-) diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss index 25d2b93..9200e4f 100644 --- a/src/assets/css/main.scss +++ b/src/assets/css/main.scss @@ -321,6 +321,25 @@ .ant-modal { max-width: 95vw; top: 70px; + + .ant-modal-title { + height: 22px; + .mk-modal-icon-def { + margin-right: 10px; + background: transparent!important; + } + .mk-modal-icon-circle { + display: inline-block; + border-radius: 30px; + margin-right: 10px; + margin-top: -5px; + color: #ffffff!important; + width: 30px; + height: 30px; + text-align: center; + line-height: 30px; + } + } } .ant-modal-body { max-height: calc(100vh - 205px); diff --git a/src/menu/components/form/simple-form/index.jsx b/src/menu/components/form/simple-form/index.jsx index ba3c39c..f267c58 100644 --- a/src/menu/components/form/simple-form/index.jsx +++ b/src/menu/components/form/simple-form/index.jsx @@ -1,10 +1,9 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { is, fromJS } from 'immutable' -import { Popover, Modal, Button, Switch, notification, message } from 'antd' +import { Popover, Modal, Button, Switch, message } from 'antd' import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons' -import Api from '@/api' import asyncComponent from '@/utils/asyncComponent' import asyncIconComponent from '@/utils/asyncIconComponent' import { getModalForm } from '@/templates/zshare/formconfig' @@ -399,68 +398,33 @@ * 3銆侀�氳繃loading鍒锋柊 */ handleSubmit = () => { - this.formRef.handleConfirm().then(res => { - let _config = fromJS(this.state.card).toJS() - let fieldrepet = false // 瀛楁閲嶅 + let _config = fromJS(this.state.card).toJS() + this.formRef.handleConfirm(_config.subcards[0].fields).then(res => { _config.subcards[0].fields = _config.subcards[0].fields.map(item => { - if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) { - fieldrepet = true - } - delete item.focus - if (item.uuid === res.uuid) { - if (item.style) { - res.style = item.style - } - return res + if (item.uuid === res.values.uuid) { + return res.values } else { return item } }) - if (fieldrepet) { - notification.warning({ - top: 92, - message: '瀛楁宸插瓨鍦紒', - duration: 10 - }) - return - } - - window.GLOB.formId = res.uuid - - if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) { + if (res.loading) { this.setState({ sqlVerifing: true }) - let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20) - ${res.dataSource}` - - sql = sql.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'1949-10-01 15:00:00'`) - - let rduri = '' - if (window.GLOB.mainSystemApi && res.database === 'sso') { - rduri = window.GLOB.mainSystemApi - } - - Api.sDebug(sql, rduri).then(result => { - if (result.status || result.ErrCode === '-2') { - this.setState({ - sqlVerifing: false, - editform: null, - visible: false - }) - this.updateComponent(_config) - } else { - this.setState({sqlVerifing: false}) - - Modal.error({ - title: result.message - }) - } + res.promise().then(() => { + this.setState({ + sqlVerifing: false, + editform: null, + visible: false + }) + this.updateComponent(_config) + }, () => { + this.setState({sqlVerifing: false}) }) } else { this.setState({ diff --git a/src/menu/components/form/step-form/index.jsx b/src/menu/components/form/step-form/index.jsx index bfa2708..f4f7947 100644 --- a/src/menu/components/form/step-form/index.jsx +++ b/src/menu/components/form/step-form/index.jsx @@ -4,7 +4,6 @@ import { Popover, Modal, Button, Switch, notification, message } from 'antd' import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons' -import Api from '@/api' import asyncComponent from '@/utils/asyncComponent' import asyncIconComponent from '@/utils/asyncIconComponent' import { getModalForm } from '@/templates/zshare/formconfig' @@ -501,68 +500,33 @@ * 3銆侀�氳繃loading鍒锋柊 */ handleSubmit = () => { - this.formRef.handleConfirm().then(res => { - let _config = fromJS(this.state.group).toJS() - let fieldrepet = false // 瀛楁閲嶅 + let _config = fromJS(this.state.group).toJS() + this.formRef.handleConfirm(_config.fields).then(res => { _config.fields = _config.fields.map(item => { - if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) { - fieldrepet = true - } - delete item.focus - if (item.uuid === res.uuid) { - if (item.style) { - res.style = item.style - } - return res + if (item.uuid === res.values.uuid) { + return res.values } else { return item } }) - if (fieldrepet) { - notification.warning({ - top: 92, - message: '瀛楁宸插瓨鍦紒', - duration: 10 - }) - return - } - - window.GLOB.formId = res.uuid - - if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) { + if (res.loading) { this.setState({ sqlVerifing: true }) - let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20) - ${res.dataSource}` - - sql = sql.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'1949-10-01 15:00:00'`) - - let rduri = '' - if (window.GLOB.mainSystemApi && res.database === 'sso') { - rduri = window.GLOB.mainSystemApi - } - - Api.sDebug(sql, rduri).then(result => { - if (result.status || result.ErrCode === '-2') { - this.setState({ - sqlVerifing: false, - editform: null, - visible: false - }) - this.updateGroup(_config) - } else { - this.setState({sqlVerifing: false}) - - Modal.error({ - title: result.message - }) - } + res.promise().then(() => { + this.setState({ + sqlVerifing: false, + editform: null, + visible: false + }) + this.updateGroup(_config) + }, () => { + this.setState({sqlVerifing: false}) }) } else { this.setState({ diff --git a/src/menu/components/form/tab-form/index.jsx b/src/menu/components/form/tab-form/index.jsx index 0d6e367..847f7af 100644 --- a/src/menu/components/form/tab-form/index.jsx +++ b/src/menu/components/form/tab-form/index.jsx @@ -4,7 +4,6 @@ import { Popover, Modal, Button, Switch, notification, message } from 'antd' import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons' -import Api from '@/api' import asyncComponent from '@/utils/asyncComponent' import asyncIconComponent from '@/utils/asyncIconComponent' import { getModalForm } from '@/templates/zshare/formconfig' @@ -506,68 +505,33 @@ * 3銆侀�氳繃loading鍒锋柊 */ handleSubmit = () => { - this.formRef.handleConfirm().then(res => { - let _config = fromJS(this.state.group).toJS() - let fieldrepet = false // 瀛楁閲嶅 + let _config = fromJS(this.state.group).toJS() + this.formRef.handleConfirm(_config.fields).then(res => { _config.fields = _config.fields.map(item => { - if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) { - fieldrepet = true - } - delete item.focus - if (item.uuid === res.uuid) { - if (item.style) { - res.style = item.style - } - return res + if (item.uuid === res.values.uuid) { + return res.values } else { return item } }) - if (fieldrepet) { - notification.warning({ - top: 92, - message: '瀛楁宸插瓨鍦紒', - duration: 10 - }) - return - } - - window.GLOB.formId = res.uuid - - if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) { + if (res.loading) { this.setState({ sqlVerifing: true }) - - let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20) - ${res.dataSource}` - sql = sql.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'1949-10-01 15:00:00'`) - - let rduri = '' - if (window.GLOB.mainSystemApi && res.database === 'sso') { - rduri = window.GLOB.mainSystemApi - } - - Api.sDebug(sql, rduri).then(result => { - if (result.status || result.ErrCode === '-2') { - this.setState({ - sqlVerifing: false, - editform: null, - visible: false - }) - this.updateGroup(_config) - } else { - this.setState({sqlVerifing: false}) - - Modal.error({ - title: result.message - }) - } + res.promise().then(() => { + this.setState({ + sqlVerifing: false, + editform: null, + visible: false + }) + this.updateGroup(_config) + }, () => { + this.setState({sqlVerifing: false}) }) } else { this.setState({ diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx index 3599e68..a66f2fa 100644 --- a/src/menu/components/share/actioncomponent/index.jsx +++ b/src/menu/components/share/actioncomponent/index.jsx @@ -407,10 +407,11 @@ btn.style = item.style || {} if (btn.class) { if (btn.class !== item.class || btn.show !== item.show || !btn.style.color || (item.focus && !btn.style.color)) { - if (btn.show === 'icon') { - btn.style.color = color[btn.class] - btn.style.backgroundColor = 'transparent' - } else if (btn.class === 'default') { + // if (btn.show === 'icon') { + // btn.style.color = color[btn.class] + // btn.style.backgroundColor = 'transparent' + // } + if (btn.class === 'default') { btn.style.color = 'rgba(0, 0, 0, 0.65)' btn.style.backgroundColor = '#fff' btn.style.borderColor = '#d9d9d9' @@ -419,6 +420,7 @@ btn.style.color = color[_c] btn.style.backgroundColor = '#fff' btn.style.borderColor = color[_c] + btn.style.borderWidth = '1px' } else if (btn.class === 'gray') { btn.style.color = 'rgba(0, 0, 0, 0.65)' btn.style.backgroundColor = color[btn.class] diff --git a/src/menu/components/share/pastecomponent/index.jsx b/src/menu/components/share/pastecomponent/index.jsx index 5c2b417..d809808 100644 --- a/src/menu/components/share/pastecomponent/index.jsx +++ b/src/menu/components/share/pastecomponent/index.jsx @@ -170,11 +170,23 @@ let keys = config.cols.map(col => (col.field || '$empty')) + let cols = [] res.cols.forEach(col => { - if (!keys.includes(col.field)) { - config.cols.push(col) + if (!col.field || !keys.includes(col.field)) { + cols.push(col) } }) + + if (cols.length === 0) { + notification.warning({ + top: 92, + message: '鏄剧ず鍒楀凡瀛樺湪锛�', + duration: 5 + }) + return + } else { + config.cols.push(...cols) + } } this.props.updateConfig(config, type) diff --git a/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx index 0ebdd54..aed7101 100644 --- a/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx +++ b/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx @@ -33,6 +33,12 @@ value: 'number', text: '鏁板瓧' }, { + value: 'custom', + text: '鑷畾涔夊垪' + }, { + value: 'formula', + text: '鍏紡' + }, { value: 'picture', text: '鍥剧墖' }, { @@ -45,14 +51,8 @@ value: 'textarea', text: '澶氳鏂囨湰' }, { - value: 'custom', - text: '鑷畾涔夊垪' - }, { value: 'colspan', text: '鍚堝苟鍒�' - }, { - value: 'formula', - text: '鍏紡' }, { value: 'index', text: '搴忓彿' diff --git a/src/menu/components/table/base-table/index.scss b/src/menu/components/table/base-table/index.scss index 408f2e5..80333d5 100644 --- a/src/menu/components/table/base-table/index.scss +++ b/src/menu/components/table/base-table/index.scss @@ -47,6 +47,9 @@ padding-top: 10px; min-height: 55px; } + button { + min-width: 60px; + } } .model-menu-action-list:not(.length0):not(.length1):not(.length2):not(.length3):not(.length4):not(.length5):not(.length6):not(.length7):not(.length8):not(.length9) { margin-bottom: 20px; diff --git a/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx index 9b72d05..8d56325 100644 --- a/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx +++ b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx @@ -25,18 +25,18 @@ value: 'number', text: '鏁板瓧' }, { - value: 'textarea', - text: '澶氳鏂囨湰' - }, { value: 'custom', text: '鑷畾涔夊垪' }, { - value: 'colspan', - text: '鍚堝苟鍒�' - }, { value: 'formula', text: '鍏紡' }, { + value: 'textarea', + text: '澶氳鏂囨湰' + }, { + value: 'colspan', + text: '鍚堝苟鍒�' + }, { value: 'index', text: '搴忓彿' }] diff --git a/src/menu/components/table/edit-table/columns/editColumn/index.jsx b/src/menu/components/table/edit-table/columns/editColumn/index.jsx index bfc6cad..595109f 100644 --- a/src/menu/components/table/edit-table/columns/editColumn/index.jsx +++ b/src/menu/components/table/edit-table/columns/editColumn/index.jsx @@ -382,8 +382,19 @@ className = 'text-area' let linkSubFields = this.record.linkSubField || [] + + let columns = [] + + columns.push({ title: 'Value', key: 'Value', strict: true }) + columns.push({ title: 'Text', key: 'Text' }) + + linkSubFields.forEach(field => { + if (field === 'Value' || field === 'Text') return + + columns.push({ title: transfield[field] || field, key: field }) + }) - content = <EditTable type={'select'} module="form" transfield={transfield} linkSubFields={linkSubFields} onChange={this.changeOptions}/> + content = <EditTable columns={columns} module="form" onChange={this.changeOptions}/> } fields.push( @@ -403,6 +414,29 @@ ) }) return fields + } + + transfer = (options) => { + if (options.length === 0) return options + + let isNumber = true + options.forEach(item => { + if (!item.Value || isNaN(item.Value)) { + isNumber = false + } + }) + + if (isNumber) { + return options.map(item => { + item.Value = +item.Value + return item + }) + } else { + return options.map(item => { + item.Value = item.Value + '' + return item + }) + } } handleSubmit = () => { @@ -431,6 +465,32 @@ cols.forEach(col => { values.formula = values.formula.replace(col.reg, col.value) }) + } else if (values.type === 'text' && values.editable === 'true' && values.editType === 'select') { + if (values.resourceType === '0') { + values.options = values.options || [] + + values.options = this.transfer(values.options) + + if (values.options.filter(op => op.Text === '').length > 0) { + notification.warning({ + top: 92, + message: '鎻愮ず鏂囨湰锛圱ext锛変笉鍙负绌猴紒', + duration: 5 + }) + return + } else { + let arr = values.options.map(m => m.Value) + let _arr = Array.from(new Set(arr)) + if (arr.length > _arr.length) { + notification.warning({ + top: 92, + message: 'Value鍊间笉鍙噸澶嶏紒', + duration: 5 + }) + return + } + } + } } if (values.dataSource && /\s/.test(values.dataSource)) { diff --git a/src/menu/components/table/edit-table/index.scss b/src/menu/components/table/edit-table/index.scss index 60bc249..cfe7fcc 100644 --- a/src/menu/components/table/edit-table/index.scss +++ b/src/menu/components/table/edit-table/index.scss @@ -6,7 +6,7 @@ background-repeat: no-repeat; background-size: cover; min-height: 100px; - + .model-table-search-list { padding: 10px 0px 15px; min-height: 65px; @@ -73,6 +73,9 @@ padding-top: 10px; min-height: 55px; } + button { + min-width: 60px; + } } .ant-btn.mk-link { diff --git a/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx index f915309..8dd1c49 100644 --- a/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx +++ b/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx @@ -40,6 +40,12 @@ value: 'number', text: '鏁板瓧' }, { + value: 'custom', + text: '鑷畾涔夊垪' + }, { + value: 'formula', + text: '鍏紡' + }, { value: 'picture', text: '鍥剧墖' }, { @@ -52,14 +58,8 @@ value: 'textarea', text: '澶氳鏂囨湰' }, { - value: 'custom', - text: '鑷畾涔夊垪' - }, { value: 'colspan', text: '鍚堝苟鍒�' - }, { - value: 'formula', - text: '鍏紡' }, { value: 'index', text: '搴忓彿' diff --git a/src/menu/components/table/normal-table/columns/index.jsx b/src/menu/components/table/normal-table/columns/index.jsx index 02653b8..cae43f6 100644 --- a/src/menu/components/table/normal-table/columns/index.jsx +++ b/src/menu/components/table/normal-table/columns/index.jsx @@ -37,6 +37,32 @@ this.props.updateCol({...column, marks: vals}) } + copycolumn = () => { + const { column } = this.props + + let oInput = document.createElement('input') + let val = { + copyType: 'cols', + cols: [column] + } + + let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId') + if (srcid) { + val.$srcId = srcid + } + + oInput.value = window.btoa(window.encodeURIComponent(JSON.stringify(val))) + document.body.appendChild(oInput) + oInput.select() + document.execCommand('Copy') + oInput.className = 'oInput' + oInput.style.display = 'none' + + message.success('澶嶅埗鎴愬姛銆�') + + document.body.removeChild(oInput) + } + shouldComponentUpdate (nextProps, nextState) { if (this.props.rowSpan !== nextProps.rowSpan || this.props.colSpan !== nextProps.colSpan) { @@ -76,6 +102,7 @@ {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null} {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null} <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} /> + <CopyOutlined title="澶嶅埗鏄剧ず鍒�" style={{color: '#26C281'}} onClick={this.copycolumn} /> {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null} {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null} <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} /> @@ -597,6 +624,12 @@ }) } + addColumns = () => { + const { config } = this.props + + MKEmitter.emit('addColumns', config.uuid) + } + /** * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆 */ @@ -623,6 +656,7 @@ return ( <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType} ${config.wrap.mode || ''} table-vertical-${config.wrap.vertical || ''} table-col-${columns.length}`} id={tableId}> <div className="col-control"> + <PlusOutlined style={{color: '#26C281'}} title="娣诲姞鍒�" onClick={this.addColumns}/> <CopyOutlined title="澶嶅埗鏄剧ず鍒�" onClick={this.copycolumn} /> <MarkColumn columns={fields} type="line" marks={lineMarks} onSubmit={this.updateLineMarks} /> <FileSyncOutlined title="鍚屾瀛楁闆�" onClick={this.syncfield} /> diff --git a/src/menu/components/table/normal-table/index.jsx b/src/menu/components/table/normal-table/index.jsx index 4b011c7..5a6fd01 100644 --- a/src/menu/components/table/normal-table/index.jsx +++ b/src/menu/components/table/normal-table/index.jsx @@ -92,6 +92,7 @@ componentDidMount () { MKEmitter.addListener('completeSave', this.completeSave) + MKEmitter.addListener('addColumns', this.addColumns) } shouldComponentUpdate (nextProps, nextState) { @@ -106,6 +107,7 @@ return } MKEmitter.removeListener('completeSave', this.completeSave) + MKEmitter.removeListener('addColumns', this.addColumns) } completeSave = () => { @@ -210,12 +212,16 @@ this.updateComponent(_card) } - addColumns = () => { - let card = fromJS(this.state.card).toJS() + addColumns = (id) => { + const { card } = this.state - card.cols.push({ focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text' }) + if (id && id !== card.uuid) return - this.setState({card}) + let _card = fromJS(card).toJS() + + _card.cols.push({ focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text' }) + + this.setState({card: _card}) } addSearch = () => { @@ -365,7 +371,7 @@ <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/> <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ <div className="mk-popover-control"> - <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={this.addColumns}/> + <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.addColumns()}/> {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch}/> : null} <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton}/> <NormalForm title="琛ㄦ牸璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}> diff --git a/src/menu/components/table/normal-table/index.scss b/src/menu/components/table/normal-table/index.scss index c5c5f42..d14a40e 100644 --- a/src/menu/components/table/normal-table/index.scss +++ b/src/menu/components/table/normal-table/index.scss @@ -73,6 +73,9 @@ padding-top: 10px; min-height: 55px; } + button { + min-width: 60px; + } } .ant-btn.mk-link { diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx index 8da4cb7..1ef5833 100644 --- a/src/menu/datasource/verifycard/index.jsx +++ b/src/menu/datasource/verifycard/index.jsx @@ -678,6 +678,55 @@ resolve() }) } else { + if (/鍒楀悕\s*'[a-zA-Z0-9_-]+'\s*鏃犳晥/.test(result.message)) { + let tail = '' + let type = '' + searches.forEach(item => { + if (item.forbid) return + item.key.split(',').forEach(field => { + if (new RegExp(`'${field}'`).test(result.message)) { + tail = field + type = '鎼滅储鏉′欢' + } + }) + }) + + if (!tail) { + let keys = setting.order.replace(/\s+(asc|desc)/ig, '').replace(/\s+/g, '') + keys.split(',').forEach(field => { + if (new RegExp(`'${field}'`).test(result.message)) { + tail = field + type = '鎺掑簭' + } + }) + } + + if (!tail) { + columns.forEach(item => { + if (new RegExp(`'${item.field}'`).test(result.message)) { + tail = item.field + if (config.subtype === 'basetable') { + type = '鏄剧ず鍒�' + } else { + type = '瀛楁闆�' + } + } + }) + if (!tail && config.subtype === 'dualdatacard') { + subColumns.forEach(item => { + if (new RegExp(`'${item.field}'`).test(result.message)) { + tail = item.field + type = '瀛愯〃瀛楁闆�' + } + }) + } + } + + if (tail) { + result.message = result.message.replace(/ROLLBACK TRANSACTION 璇锋眰娌℃湁瀵瑰簲鐨� BEGIN TRANSACTION銆�/, '') + result.message = <>{result.message}<span style={{color: 'red'}}>娉細{type}涓瓨鍦ㄥ瓧娈祘tail}</span></> + } + } if (type === 'submit') { Modal.confirm({ title: result.message, @@ -1078,8 +1127,8 @@ <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 === 'setting' ? <CopyOutlined title="澶嶅埗鏁版嵁婧�" className="mk-copy-datasource" onClick={(e) => {e.stopPropagation();this.copyDatasource()}}/> : null} + {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} diff --git a/src/menu/modalconfig/index.jsx b/src/menu/modalconfig/index.jsx index ced3019..8bb149f 100644 --- a/src/menu/modalconfig/index.jsx +++ b/src/menu/modalconfig/index.jsx @@ -3,12 +3,10 @@ import { is, fromJS } from 'immutable' import { DndProvider } from 'react-dnd' import HTML5Backend from 'react-dnd-html5-backend' -import { Button, Card, Modal, Collapse, notification, Switch, message } from 'antd' +import { Button, Card, Modal, Collapse, Switch, message } from 'antd' import { SettingOutlined, CopyOutlined } from '@ant-design/icons' -import Api from '@/api' import { getModalForm } from '@/templates/zshare/formconfig' - import SourceElement from '@/templates/modalconfig/dragelement/source' import SettingForm from '@/templates/modalconfig/settingform' import asyncComponent from '@/utils/asyncComponent' @@ -18,6 +16,8 @@ const { Panel } = Collapse const { confirm } = Modal + +const MkIcon = asyncComponent(() => import('@/components/mk-icon')) const TableComponent = asyncComponent(() => import('./tablecomponent')) const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform')) const PasteForms = asyncComponent(() => import('@/menu/components/share/pasteforms')) @@ -225,68 +225,33 @@ * 3銆侀�氳繃loading鍒锋柊 */ handleSubmit = () => { - this.formRef.handleConfirm().then(res => { - let _config = fromJS(this.state.config).toJS() - let fieldrepet = false // 瀛楁閲嶅 + let _config = fromJS(this.state.config).toJS() + this.formRef.handleConfirm(_config.fields).then(res => { _config.fields = _config.fields.map(item => { - if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) { - fieldrepet = true - } - delete item.focus - if (item.uuid === res.uuid) { - if (item.style) { - res.style = item.style - } - return res + if (item.uuid === res.values.uuid) { + return res.values } else { return item } }) - if (fieldrepet) { - notification.warning({ - top: 92, - message: '瀛楁宸插瓨鍦紒', - duration: 10 - }) - return - } - - window.GLOB.formId = res.uuid - - if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) { + if (res.loading) { this.setState({ sqlVerifing: true }) - let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20) - ${res.dataSource}` - - sql = sql.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'1949-10-01 15:00:00'`) - - let rduri = '' - if (window.GLOB.mainSystemApi && res.database === 'sso') { - rduri = window.GLOB.mainSystemApi - } - - Api.sDebug(sql, rduri).then(result => { - if (result.status || result.ErrCode === '-2') { - this.setState({ - sqlVerifing: false, - config: _config, - card: null, - visible: false - }) - } else { - this.setState({sqlVerifing: false}) - - Modal.error({ - title: result.message - }) - } + res.promise().then(() => { + this.setState({ + sqlVerifing: false, + config: _config, + card: null, + visible: false + }) + }, () => { + this.setState({sqlVerifing: false}) }) } else { this.setState({ @@ -538,7 +503,7 @@ <SettingOutlined onClick={this.changeSetting} /> <div className="ant-modal-content" style={{width: config.setting.width > 100 ? config.setting.width : config.setting.width + '%'}}> <div className="ant-modal-header"> - <div className="ant-modal-title">{btn.label}</div> + <div className="ant-modal-title">{config.setting.icon ? <span className={'mk-modal-icon-' + config.setting.iconType} style={{background: config.setting.iconColor || 'unset', color: config.setting.iconColor || 'inherit'}}><MkIcon type={config.setting.icon}/></span> : null}{btn.label}</div> <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1鍒�</Button> <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2鍒�</Button> <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3鍒�</Button> diff --git a/src/menu/modalconfig/index.scss b/src/menu/modalconfig/index.scss index 723def0..d73bd57 100644 --- a/src/menu/modalconfig/index.scss +++ b/src/menu/modalconfig/index.scss @@ -120,6 +120,21 @@ padding-right: 80px; .ant-modal-title { display: inline-block; + height: 22px; + .mk-modal-icon-def { + margin-right: 10px; + background: transparent!important; + } + .mk-modal-icon-circle { + display: inline-block; + border-radius: 30px; + margin-right: 10px; + color: #ffffff!important; + width: 30px; + height: 30px; + text-align: center; + line-height: 30px; + } } .anticon-copy { position: absolute; diff --git a/src/menu/modulecell/index.jsx b/src/menu/modulecell/index.jsx index e88c740..e3825af 100644 --- a/src/menu/modulecell/index.jsx +++ b/src/menu/modulecell/index.jsx @@ -93,13 +93,13 @@ children: [ { subType: 'text', text: '鏂囨湰', type: 'col', $init: true }, { subType: 'number', text: '鏁板瓧', type: 'col', $init: true }, + { subType: 'custom', text: '鑷畾涔夊垪', type: 'col', $init: true }, + { subType: 'formula', text: '鍏紡', type: 'col', $init: true }, { subType: 'picture', text: '鍥剧墖', type: 'col', $init: true }, { subType: 'video', text: '瑙嗛', type: 'col', $init: true }, { subType: 'link', text: '閾炬帴', type: 'col', $init: true }, { subType: 'textarea', text: '澶氳鏂囨湰', type: 'col', $init: true }, - { subType: 'custom', text: '鑷畾涔夊垪', type: 'col', $init: true }, { subType: 'colspan', text: '鍚堝苟鍒�', type: 'col', $init: true }, - { subType: 'formula', text: '鍏紡', type: 'col', $init: true }, { subType: 'index', text: '搴忓彿', type: 'col', $init: true } ] } diff --git a/src/menu/sysinterface/index.jsx b/src/menu/sysinterface/index.jsx index 6c88dcc..1504093 100644 --- a/src/menu/sysinterface/index.jsx +++ b/src/menu/sysinterface/index.jsx @@ -176,7 +176,7 @@ let trimreg = /(from|update|insert\s+into)\s+(@db@)?/ig if (record.setting.interType === 'system') { - if (record.setting.execute !== 'false') { + if (record.setting.execute !== 'false' && record.setting.dataresource) { let tbs = record.setting.dataresource.match(cutreg) tbs && cuts.push(...tbs) } @@ -185,7 +185,7 @@ let tbs = script.sql.match(cutreg) tbs && cuts.push(...tbs) }) - } else { + } else if (record.setting.tableName) { let tb = record.setting.tableName.replace(/@db@|\s+/ig, '') if (/[a-z_]+/ig.test(tb)) { tables.push(tb) @@ -211,6 +211,8 @@ record.name = record.setting.name record.$tables = this.getTables(record) + delete record.subColumns + let interfaces = this.state.interfaces.map(item => { if (item.uuid !== record.uuid) { return item diff --git a/src/mob/modalconfig/index.jsx b/src/mob/modalconfig/index.jsx index a408c9a..803af96 100644 --- a/src/mob/modalconfig/index.jsx +++ b/src/mob/modalconfig/index.jsx @@ -3,12 +3,10 @@ import { is, fromJS } from 'immutable' import { DndProvider } from 'react-dnd' import HTML5Backend from 'react-dnd-html5-backend' -import { Button, Modal, Collapse, notification, Switch, message } from 'antd' +import { Button, Modal, Collapse, Switch, message } from 'antd' import { LeftOutlined } from '@ant-design/icons' -import Api from '@/api' import { getModalForm } from '@/templates/zshare/formconfig' - import SourceElement from '@/templates/modalconfig/dragelement/source' import SettingForm from '@/templates/modalconfig/settingform' import asyncComponent from '@/utils/asyncComponent' @@ -222,68 +220,33 @@ * 3銆侀�氳繃loading鍒锋柊 */ handleSubmit = () => { - this.formRef.handleConfirm().then(res => { - let _config = fromJS(this.state.config).toJS() - let fieldrepet = false // 瀛楁閲嶅 + let _config = fromJS(this.state.config).toJS() + this.formRef.handleConfirm(_config.fields).then(res => { _config.fields = _config.fields.map(item => { - if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) { - fieldrepet = true - } - delete item.focus - if (item.uuid === res.uuid) { - if (item.style) { - res.style = item.style - } - return res + if (item.uuid === res.values.uuid) { + return res.values } else { return item } }) - if (fieldrepet) { - notification.warning({ - top: 92, - message: '瀛楁宸插瓨鍦紒', - duration: 10 - }) - return - } - - window.GLOB.formId = res.uuid - - if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) { + if (res.loading) { this.setState({ sqlVerifing: true }) - let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20) - ${res.dataSource}` - - sql = sql.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'1949-10-01 15:00:00'`) - - let rduri = '' - if (window.GLOB.mainSystemApi && res.database === 'sso') { - rduri = window.GLOB.mainSystemApi - } - - Api.sDebug(sql, rduri).then(result => { - if (result.status || result.ErrCode === '-2') { - this.setState({ - sqlVerifing: false, - config: _config, - card: null, - visible: false - }) - } else { - this.setState({sqlVerifing: false}) - - Modal.error({ - title: result.message - }) - } + res.promise().then(() => { + this.setState({ + sqlVerifing: false, + config: _config, + card: null, + visible: false + }) + }, () => { + this.setState({sqlVerifing: false}) }) } else { this.setState({ diff --git a/src/tabviews/custom/components/chart/antv-X6/nodeupdate/index.scss b/src/tabviews/custom/components/chart/antv-X6/nodeupdate/index.scss index aa7ebb2..a161a64 100644 --- a/src/tabviews/custom/components/chart/antv-X6/nodeupdate/index.scss +++ b/src/tabviews/custom/components/chart/antv-X6/nodeupdate/index.scss @@ -171,6 +171,13 @@ } } } + .ant-transfer-operation { + margin: 0 15px; + + .ant-btn:first-child { + margin-bottom: 10px; + } + } } .member-modal { diff --git a/src/tabviews/zshare/actionList/index.scss b/src/tabviews/zshare/actionList/index.scss index 42c8bcc..1d31f09 100644 --- a/src/tabviews/zshare/actionList/index.scss +++ b/src/tabviews/zshare/actionList/index.scss @@ -1,17 +1,21 @@ .button-list.toolbar-button { position: relative; padding: 15px 0px 0px; - background: #ffffff; min-height: 55px; + background: transparent; button { - min-width: 65px; + min-width: 60px; margin-right: 15px; margin-bottom: 10px!important; overflow: hidden; min-height: 28px; height: auto; } + .ant-btn-icon-only { + width: auto; + padding: 0 15px; + } .loading-skeleton { background: -webkit-gradient(linear,left top,right top,color-stop(25%,#f5f5f5),color-stop(37%,#ffffff),color-stop(63%,#f5f5f5)); diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx index 816e450..4da4369 100644 --- a/src/tabviews/zshare/actionList/normalbutton/index.jsx +++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx @@ -3008,6 +3008,13 @@ container = () => document.getElementById(btn.ContainerId) } + if (btnconfig.setting.icon) { + title = <> + <span className={'mk-modal-icon-' + btnconfig.setting.iconType} style={{background: btnconfig.setting.iconColor || 'unset', color: btnconfig.setting.iconColor || 'inherit'}}><MkIcon type={btnconfig.setting.icon}/></span> + {title} + </> + } + return ( <Modal title={title} diff --git a/src/tabviews/zshare/actionList/printbutton/index.jsx b/src/tabviews/zshare/actionList/printbutton/index.jsx index 4bd500f..b55792d 100644 --- a/src/tabviews/zshare/actionList/printbutton/index.jsx +++ b/src/tabviews/zshare/actionList/printbutton/index.jsx @@ -2238,6 +2238,13 @@ clickouter = true } + if (btnconfig.setting.icon) { + title = <> + <span className={'mk-modal-icon-' + btnconfig.setting.iconType} style={{background: btnconfig.setting.iconColor || 'unset', color: btnconfig.setting.iconColor || 'inherit'}}><MkIcon type={btnconfig.setting.icon}/></span> + {title} + </> + } + return ( <Modal title={title} diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx index b1f23a7..d4b95fd 100644 --- a/src/tabviews/zshare/mutilform/index.jsx +++ b/src/tabviews/zshare/mutilform/index.jsx @@ -28,6 +28,7 @@ const MkFormula = asyncComponent(() => import('./mkFormula')) const MkCascader = asyncComponent(() => import('./mkCascader')) const MkVercode = asyncComponent(() => import('./mkVercode')) +const MKPopSelect = asyncComponent(() => import('./mkPopSelect')) const MKEditor = asyncComponent(() => import('@/components/editor')) class MutilFormComponent extends Component { @@ -125,7 +126,7 @@ item.precision = 'second' } - if (!item.field || !['text', 'number', 'switch', 'check', 'rate', 'select', 'link', 'cascader', 'linkMain', 'funcvar', 'date', 'datemonth', 'radio', 'checkbox', 'checkcard', 'fileupload', 'textarea', 'multiselect', 'brafteditor', 'color', 'vercode'].includes(item.type)) return false + if (!item.field || !['text', 'number', 'switch', 'check', 'rate', 'select', 'popSelect', 'link', 'cascader', 'linkMain', 'funcvar', 'date', 'datemonth', 'radio', 'checkbox', 'checkcard', 'fileupload', 'textarea', 'multiselect', 'brafteditor', 'color', 'vercode'].includes(item.type)) return false if (/^\s+$/.test(item.label)) { item.style = item.style || {} @@ -292,26 +293,31 @@ } } + item.rules = [] if (item.type === 'text') { item.initval = item.initval + '' - let _rules = [{ - pattern: /^[^']*$/ig, - message: '涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒' - }, { + + if (item.required === 'true') { + item.rules.push({ + required: true, + message: item.label + '涓嶅彲涓虹┖!' + }) + } + + item.rules.push({ validator: (rule, value, callback) => { - if (/--/ig.test(value)) { + if (/'/.test(value)) { + callback('涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒') + } else if (/--/.test(value)) { callback('涓嶅彲浣跨敤 -- 锛�') } else { callback() } } - }, { - required: item.required === 'true', - message: item.label + '涓嶅彲涓虹┖!' - }] - + }) + if (!item.lenControl || item.lenControl === 'limit') { - _rules.push({ + item.rules.push({ max: item.fieldlength, message: formRule.input.formMessage.replace('@max', item.fieldlength) }) @@ -323,7 +329,7 @@ if (item.regularExtra) { reg = new RegExp('^[0-9.-' + item.regularExtra.replace(/\.|-/g, '') + ']*$') } - _rules.push({ + item.rules.push({ pattern: reg, message: item.regularText || formRule.input.numbermsg }) @@ -332,7 +338,7 @@ if (item.regularExtra) { reg = new RegExp('^[a-zA-Z' + item.regularExtra + ']*$') } - _rules.push({ + item.rules.push({ pattern: reg, message: item.regularText || formRule.input.lettermsg }) @@ -341,7 +347,7 @@ if (item.regularExtra) { reg = new RegExp('^[a-zA-Z0-9' + item.regularExtra + ']*$') } - _rules.push({ + item.rules.push({ pattern: reg, message: item.regularText || '璇疯緭鍏ユ暟瀛楁垨瀛楁瘝' }) @@ -350,80 +356,113 @@ if (item.regularExtra) { reg = new RegExp('^[a-zA-Z0-9@_.' + item.regularExtra.replace(/\.|_|@/g, '') + ']*$') } - _rules.push({ + item.rules.push({ pattern: reg, message: item.regularText || '璇疯緭鍏ユ暟瀛椼�佸瓧姣嶄互鍙夽_.' }) } else if (item.regular === 'phone') { - _rules.push({ + item.rules.push({ pattern: /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/, message: item.regularText || '璇锋纭緭鍏ユ墜鏈哄彿' }) } else if (item.regular === 'email') { - _rules.push({ + item.rules.push({ pattern: /^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/, message: item.regularText || '璇锋纭緭鍏ラ偖绠卞湴鍧�' }) } } - - item.rules = _rules } else if (item.type === 'number') { item.rules = [{ required: true, message: item.label + '涓嶅彲涓虹┖!' - }, { - validator: (rule, value, callback) => this.handleConfirmPassword(rule, value, callback, item) }] - } else if (item.type === 'textarea') { - let _rules = [ - { - required: item.required === 'true', - message: item.label + '涓嶅彲涓虹┖!' - }, - { - max: item.fieldlength, - message: formRule.input.formMessage.replace('@max', item.fieldlength) - }, - { - pattern: /^[^']*$/ig, - message: '涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒' - }, { + + if (typeof(item.min) === 'number' || typeof(item.max) === 'number') { + item.rules.push({ validator: (rule, value, callback) => { - if (/--/ig.test(value)) { - callback('涓嶅彲浣跨敤 -- 锛�') + if (isNaN(value)) { + callback() + } else if (typeof(item.min) === 'number' && value < item.min) { + if (item.min < 1e-6) { + if (item.min === 1e-6) { + callback(item.label + '鏈�灏忓�间负 0.000001') + } else if (item.min === 1e-7) { + callback(item.label + '鏈�灏忓�间负 0.0000001') + } else if (item.min === 1e-8) { + callback(item.label + '鏈�灏忓�间负 0.00000001') + } else if (item.min === 1e-9) { + callback(item.label + '鏈�灏忓�间负 0.000000001') + } else if (item.min === 1e-10) { + callback(item.label + '鏈�灏忓�间负 0.0000000001') + } else if (item.min === 1e-11) { + callback(item.label + '鏈�灏忓�间负 0.00000000001') + } else { + callback(item.label + '鏈�灏忓�间负 ' + item.min) + } + } else { + callback(item.label + '鏈�灏忓�间负 ' + item.min) + } + } else if (typeof(item.max) === 'number' && value > item.max) { + callback(item.label + '鏈�澶у�间负 ' + item.max) } else { callback() } } + }) + } + } else if (item.type === 'textarea') { + if (item.required === 'true') { + item.rules.push({ + required: true, + message: item.label + '涓嶅彲涓虹┖!' + }) + } + + item.rules.push({ + validator: (rule, value, callback) => { + if (/'/.test(value)) { + callback('涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒') + } else if (/--/.test(value)) { + callback('涓嶅彲浣跨敤 -- 锛�') + } else { + callback() + } } - ] - item.rules = _rules + }, { + max: item.fieldlength, + message: formRule.input.formMessage.replace('@max', item.fieldlength) + }) } else if (item.type === 'brafteditor') { - item.rules = [ - { - required: item.required === 'true', + if (item.required === 'true') { + item.rules.push({ + required: true, message: item.label + '涓嶅彲涓虹┖!' - }, - { - max: item.fieldlength, - message: formRule.input.formMessage.replace('@max', item.fieldlength) - } - ] + }) + } + + item.rules.push({ + max: item.fieldlength, + message: formRule.input.formMessage.replace('@max', item.fieldlength) + }) } else if (item.type === 'linkMain' || item.type === 'vercode') { - item.rules = [ - { - required: item.required === 'true', + if (item.required === 'true') { + item.rules.push({ + required: true, message: item.label + '涓嶅彲涓虹┖!' - } - ] + }) + } } else { - item.rules = [ - { - required: item.required === 'true', + if (item.required === 'true') { + item.rules.push({ + required: true, message: '璇烽�夋嫨' + item.label + '!' - } - ] + }) + } + } + + if (item.rules.length === 0) { + item.rules = null } fieldMap.set(item.field, item) @@ -530,6 +569,18 @@ reFieldsVal[n.field] = val || '' }) } else if (item.type === 'fileupload') { + item.options = [] + item.subFields = [] + item.linkSubField.forEach(m => { + let n = fieldMap.get(m) + if (n && ['text', 'number', 'textarea'].includes(n.type)) { + item.subFields.push({ + uuid: n.uuid, + field: m + }) + } + }) + } else if (item.type === 'popSelect') { item.options = [] item.subFields = [] item.linkSubField.forEach(m => { @@ -1002,22 +1053,6 @@ }) } - handleConfirmPassword = (rule, value, callback, item) => { - let val = parseFloat(value) - - if (!isNaN(val)) { - if (typeof(item.min) === 'number' && val < item.min) { - callback(item.label + '鏈�灏忓�间负 ' + item.min) - } else if (typeof(item.max) === 'number' && val > item.max) { - callback(item.label + '鏈�澶у�间负 ' + item.max) - } else { - callback() - } - } else { - callback() - } - } - recordChange = (values, item) => { this.record = {...this.record, ...values} @@ -1124,6 +1159,8 @@ content = (<MKNumberInput config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val})} onSubmit={this.props.inputSubmit} />) } else if (item.type === 'select' || item.type === 'link' || item.type === 'multiselect') { content = (<MKSelect config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)} onSubmit={this.props.inputSubmit} />) + } else if (item.type === 'popSelect') { + content = (<MKPopSelect config={item} BID={this.props.BID} ID={this.state.ID} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)} onSubmit={this.props.inputSubmit} />) } else if (item.type === 'cascader') { content = (<MkCascader config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)}/>) } else if (item.type === 'color') { diff --git a/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx b/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx new file mode 100644 index 0000000..0181c89 --- /dev/null +++ b/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx @@ -0,0 +1,372 @@ +import React, {Component} from 'react' +import { is, fromJS } from 'immutable' +import { Select } from 'antd' +import { notification, Modal, Table, Input } from 'antd' +import moment from 'moment' +import { TableOutlined } from '@ant-design/icons' + +import Api from '@/api' +import Utils from '@/utils/utils.js' +import MKEmitter from '@/utils/events.js' +import './index.scss' + +const { Search } = Input + +class MKPopSelect extends Component { + constructor(props) { + super(props) + + let config = fromJS(props.config).toJS() + let value = config.initval + + let arrfield = config.columns.map(f => f.field) + + if (config.subFields && config.subFields.length > 0) { + config.subFields.forEach(n => { + if (!arrfield.includes(n.field)) { + arrfield.push(n.field) + } + }) + } + + if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺 + config.dataSource = config.dataSource.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'') + } else { + config.dataSource = config.dataSource.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'') + } + + config.dataSource = config.dataSource.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`) + config.dataSource = config.dataSource.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`) + config.dataSource = config.dataSource.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`) + config.dataSource = config.dataSource.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`) + + if (/\s/.test(config.dataSource)) { // 鎷兼帴鍒悕 + config.dataSource = '(' + config.dataSource + ') tb' + } + + let columns = [] + let labels = {} + config.columns.forEach(col => { + labels[col.field] = col.label + + if (col.Hide === 'true') return + + columns.push({ + dataIndex: col.field, + title: col.label, + sorter: col.IsSort === 'true', + width: 120 + }) + }) + + let placeholder = '' + if (!config.searchKey) { + config.onload = 'true' + } else { + placeholder = [] + config.searchKey.split(',').forEach(key => { + if (!labels[key]) { + placeholder = '' + } else if (placeholder) { + placeholder.push(labels[key]) + } + }) + + placeholder = placeholder ? placeholder.join('銆�') : '' + } + + this.state = { + config: config, + options: [], + columns, + value, + placeholder, + arr_field: arrfield.join(','), + searchKey: '', + pageIndex: 1, + pageSize: 10, + orderBy: '', + visible: false, + loading: false + } + + this.timer = null + } + + componentDidMount () { + const { config } = this.state + + if (config.onload === 'true') { + this.loadData() + } + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + componentWillUnmount () { + this.setState = () => { + return + } + } + + loadData () { + const { BID, ID } = this.props + const { config, pageIndex, pageSize, arr_field, searchKey, orderBy } = this.state + + this.setState({ + loading: true + }) + + let param = { + func: 'sPC_Get_TableData', + obj_name: 'data', + exec_type: 'y', + arr_field: arr_field, + default_sql: 'true', + custom_script: '', + menuname: config.label + } + + let sql = '' + let DateCount = '' + let _search = '' + let _orderBy = orderBy || config.order || '' + let _datasource = config.dataSource + + if (config.searchKey && searchKey) { + let fields = config.searchKey.split(',').map(field => field + ` like '%${searchKey}%'`) + _search = 'where ' + fields.join(' OR ') + } + + _datasource = _datasource.replace(/@BID@/ig, `'${BID || ''}'`) + _datasource = _datasource.replace(/@ID@/ig, `'${ID || ''}'`) + + if (config.laypage === 'true') { + sql = `/*system_query*/select top ${pageSize} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_datasource} ${_search}) tmptable where rows > ${pageSize * (pageIndex - 1)} order by tmptable.rows ` + DateCount = `/*system_query*/select count(1) as total from ${_datasource} ${_search}` + } else if (_orderBy) { + sql = `/*system_query*/select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_datasource} ${_search}) tmptable order by tmptable.rows ` + } else { + sql = `/*system_query*/select ${arr_field} from ${_datasource} ${_search} ` + } + + let departmentcode = sessionStorage.getItem('departmentcode') || '' + let organization = sessionStorage.getItem('organization') || '' + let mk_user_type = sessionStorage.getItem('mk_user_type') || '' + + sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20) + Select @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}' + ${sql}` + + // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞 + if (window.GLOB.debugger === true) { + console.info(`/*${config.label} 鏁版嵁婧�*/\n` + sql.replace(/\n\s{6}/ig, '\n')) + DateCount && console.info(`/*${config.label} 鎬绘暟鏌ヨ*/\n` + DateCount.replace(/\n\s{6}/ig, '\n')) + } + + param.LText = Utils.formatOptions(sql) + param.DateCount = Utils.formatOptions(DateCount) + + param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + param.secretkey = Utils.encrypt('', param.timestamp) + + param.username = sessionStorage.getItem('User_Name') || '' + param.fullname = sessionStorage.getItem('Full_Name') || '' + + Api.genericInterface(param).then(result => { + if (result.status) { + let options = result.data.map((item, index) => { + item.key = index + item.$$uuid = item[config.primaryKey] || '' + item.$label = item[config.showField] + + if (config.controlField && item[config.controlField] === 'true') { + item.$disabled = true + } + + return item + }) + + this.setState({ + options: options, + total: result.total || 0, + loading: false + }) + + if (result.message) { + if (result.ErrCode === 'Y') { + Modal.success({ + title: result.message + }) + } else if (result.ErrCode === 'S') { + notification.success({ + top: 92, + message: result.message, + duration: 2 + }) + } + } + } else { + this.setState({ + loading: false + }) + + if (!result.message) return + if (result.ErrCode === 'N') { + Modal.error({ + title: result.message, + }) + } else if (result.ErrCode !== '-2') { + notification.error({ + top: 92, + message: result.message, + duration: 10 + }) + } + } + }) + } + + searchOption = (val) => { + this.setState({searchKey: val}) + + if (this.timer) { + clearTimeout(this.timer) + } + + this.timer = setTimeout(() => { + this.loadData() + }, 500) + } + + selectChange = (val, record) => { + const { config } = this.state + let other = {} + + if (config.subFields) { + let option = record || null + + if (!option) { + option = this.state.options.filter(m => m.$$uuid === val)[0] + } + + option && config.subFields.forEach((n, i) => { + other[n.field] = option[n.field] + setTimeout(() => { + MKEmitter.emit('mkFC', 'input', n.uuid, option[n.field]) + }, i * 5) + }) + } + + this.props.onChange(val, other) + this.setState({value: val}, () => { + if (config.enter === 'tab') { + MKEmitter.emit('mkFC', 'focus', config.tabUuid) + } else if (config.enter === 'sub') { + if (config.subFields) { + setTimeout(() => { + this.props.onSubmit() + }, 1000) + } else { + this.props.onSubmit() + } + } + }) + } + + trigger = (e) => { + e.stopPropagation() + + this.setState({visible: true}) + } + + changeRow = (record) => { + + if (record.$disabled) return + + this.selectChange(record.$$uuid, record) + this.setState({visible: false}) + } + + changeTable = (pagination, filters, sorter) => { + let orderBy = '' + + if (sorter.field && sorter.order) { + if (sorter.order === 'ascend') { + orderBy = `${sorter.field} asc` + } else { + orderBy = `${sorter.field} desc` + } + } + + this.setState({ + pageIndex: pagination.current, + pageSize: pagination.pageSize, + orderBy: orderBy, + }, () => { + this.loadData() + }) + } + + render() { + const { value, config, options, visible, loading, total, pageIndex, pageSize, columns, placeholder } = this.state + + return <> + <Select + className="mk-pop-select" + showSearch={!!config.searchKey} + allowClear + value={value} + onSearch={(val) => val && this.searchOption(val)} + filterOption={false} + onChange={(val) => this.selectChange(val === undefined ? '' : val)} + disabled={config.readonly} + suffixIcon={<TableOutlined onClick={this.trigger}/>} + > + {options.map(option => + <Select.Option disabled={option.$disabled} key={option.key} value={option.$$uuid}>{option.$label}</Select.Option> + )} + </Select> + <Modal + wrapClassName='mk-pop-select-modal' + title={config.label} + visible={visible} + closable={true} + centered={true} + maskClosable={false} + cancelText="鍏抽棴" + width={config.popWidth < 100 ? config.popWidth + 'vw' : config.popWidth} + onCancel={() => this.setState({visible: false})} + destroyOnClose + > + {config.searchKey ? <Search placeholder={placeholder} onSearch={this.searchOption} enterButton /> : null} + <Table + rowKey="$$uuid" + bordered={true} + rowSelection={null} + columns={columns} + dataSource={options} + loading={loading} + onRow={(record) => { + return { + className: value === record.$$uuid ? ' ant-table-row-selected ' : '', + onClick: () => {this.changeRow(record)}, + } + }} + onChange={this.changeTable} + pagination={config.laypage === 'true' ? { + current: pageIndex, + pageSize: pageSize, + showSizeChanger: true, + total: total || 0, + showTotal: (total, range) => `${range[0]}-${range[1]} 鍏� ${total} 鏉 + } : false} + /> + </Modal> + </> + } +} + +export default MKPopSelect \ No newline at end of file diff --git a/src/tabviews/zshare/mutilform/mkPopSelect/index.scss b/src/tabviews/zshare/mutilform/mkPopSelect/index.scss new file mode 100644 index 0000000..245486d --- /dev/null +++ b/src/tabviews/zshare/mutilform/mkPopSelect/index.scss @@ -0,0 +1,64 @@ +.mk-pop-select { + .ant-select-selection__rendered { + margin-right: 30px; + } + .ant-select-selection__clear { + right: 35px; + } + .ant-select-arrow { + transform: translate(8px, -9px); + .ant-select-arrow-icon { + padding: 7px; + color: rgba(0, 0, 0, 0.25); + transition: color 0.2s; + font-size: 14px; + svg { + transition: none!important; + transform: none!important; + } + } + .ant-select-arrow-icon:hover { + color: var(--mk-sys-color); + } + } +} +.mk-pop-select-modal { + .ant-modal-body { + min-height: 200px; + max-height: calc(100vh - 210px); + overflow-y: auto; + + .ant-input-search { + max-width: 300px; + margin-bottom: 20px; + } + table { + tr:not(.ant-table-row-selected):hover > td { + background-color: var(--mk-sys-color1); + } + tr.ant-table-row-selected td { + background-color: var(--mk-sys-color3); + } + } + } + .ant-modal-body::-webkit-scrollbar { + width: 7px; + } + .ant-modal-body::-webkit-scrollbar-thumb { + border-radius: 5px; + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13); + background: rgba(0, 0, 0, 0.13); + } + .ant-modal-body::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); + border-radius: 3px; + border: 1px solid rgba(0, 0, 0, 0.07); + background: rgba(0, 0, 0, 0); + } + + .ant-modal-footer { + .ant-btn-primary { + display: none; + } + } +} \ No newline at end of file diff --git a/src/tabviews/zshare/topSearch/index.scss b/src/tabviews/zshare/topSearch/index.scss index 49746f8..cefe1d5 100644 --- a/src/tabviews/zshare/topSearch/index.scss +++ b/src/tabviews/zshare/topSearch/index.scss @@ -1,5 +1,5 @@ .mk-search-wrap { - background: #ffffff; + // background: #ffffff; .mk-search-col { display: inline-block; diff --git a/src/templates/modalconfig/dragelement/card.jsx b/src/templates/modalconfig/dragelement/card.jsx index 063f651..dcd142a 100644 --- a/src/templates/modalconfig/dragelement/card.jsx +++ b/src/templates/modalconfig/dragelement/card.jsx @@ -1,7 +1,7 @@ import React from 'react' import { useDrag, useDrop } from 'react-dnd' import { Select, DatePicker, Input, InputNumber, Button, Popover, Switch, Radio, Checkbox, Form, Rate } from 'antd' -import { QuestionCircleOutlined, UploadOutlined, EditOutlined, CopyOutlined, CloseOutlined, StarFilled, FontColorsOutlined } from '@ant-design/icons' +import { QuestionCircleOutlined, UploadOutlined, EditOutlined, CopyOutlined, CloseOutlined, StarFilled, SearchOutlined, FontColorsOutlined } from '@ant-design/icons' import moment from 'moment' import asyncComponent from '@/utils/asyncComponent' @@ -80,6 +80,8 @@ formItem = (<InputNumber value={card.initval} precision={card.decimal} />) } else if (card.type === 'multiselect' || card.type === 'select' || card.type === 'link' || card.type === 'cascader') { formItem = (<Select value={selectval}></Select>) + } else if (card.type === 'popSelect') { + formItem = (<Select value={card.initval} suffixIcon={<SearchOutlined />}></Select>) } else if (card.type === 'color') { formItem = (<ColorSketch value={card.initval || 'transparent'}/>) } else if (card.type === 'date') { diff --git a/src/templates/modalconfig/index.jsx b/src/templates/modalconfig/index.jsx index 669ef9e..5343768 100644 --- a/src/templates/modalconfig/index.jsx +++ b/src/templates/modalconfig/index.jsx @@ -8,7 +8,6 @@ import Api from '@/api' import { getModalForm } from '@/templates/zshare/formconfig' - import SourceElement from './dragelement/source' import SettingForm from './settingform' import MenuForm from './menuform' @@ -348,73 +347,35 @@ /** * @description 缂栬緫鍚庢彁浜� - * 1銆佽幏鍙栫紪杈戝悗鐨勮〃鍗曚俊鎭� - * 2銆佸幓闄ゅ彲鑳藉瓨鍦ㄧ殑绀轰緥琛ㄥ崟 - * 3銆侀�氳繃loading鍒锋柊 */ handleSubmit = () => { - this.formRef.handleConfirm().then(res => { - let _config = fromJS(this.state.config).toJS() - let fieldrepet = false // 瀛楁閲嶅 + let _config = fromJS(this.state.config).toJS() + this.formRef.handleConfirm(_config.fields).then(res => { _config.fields = _config.fields.map(item => { - if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) { - fieldrepet = true - } - - if (item.uuid === res.uuid) { - if (item.style) { - res.style = item.style - } - return res + if (item.uuid === res.values.uuid) { + return res.values } else { return item } }) - if (fieldrepet) { - notification.warning({ - top: 92, - message: '瀛楁宸插瓨鍦紒', - duration: 10 - }) - return - } - _config.fields = _config.fields.filter(item => !item.origin) - window.GLOB.formId = res.uuid - - if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) { + if (res.loading) { this.setState({ sqlVerifing: true }) - let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20) - ${res.dataSource}` - - sql = sql.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'1949-10-01 15:00:00'`) - - let rduri = '' - if (window.GLOB.mainSystemApi && res.database === 'sso') { - rduri = window.GLOB.mainSystemApi - } - - Api.sDebug(sql, rduri).then(result => { - if (result.status || result.ErrCode === '-2') { - this.setState({ - sqlVerifing: false, - config: _config, - card: null, - visible: false - }) - } else { - this.setState({sqlVerifing: false}) - - Modal.error({ - title: result.message - }) - } + res.promise().then(() => { + this.setState({ + sqlVerifing: false, + config: _config, + card: null, + visible: false + }) + }, () => { + this.setState({sqlVerifing: false}) }) } else { this.setState({ diff --git a/src/templates/modalconfig/settingform/index.jsx b/src/templates/modalconfig/settingform/index.jsx index b459117..4ac0090 100644 --- a/src/templates/modalconfig/settingform/index.jsx +++ b/src/templates/modalconfig/settingform/index.jsx @@ -5,7 +5,11 @@ // import { formRule } from '@/utils/option.js' import StyleInput from '@/menu/stylecontroller/styleInput' +import asyncComponent from '@/utils/asyncComponent' import './index.scss' + +const MkEditIcon = asyncComponent(() => import('@/components/mkIcon')) +const ColorSketch = asyncComponent(() => import('@/mob/colorsketch')) class SettingForm extends Component { static propTpyes = { @@ -18,6 +22,7 @@ fields: null, display: this.props.config.setting.display || 'modal', placement: this.props.config.setting.placement || 'right', + icon: this.props.config.setting.icon || '', appType: sessionStorage.getItem('appType'), viewType: sessionStorage.getItem('editMenuType') || '', dialogInput: false @@ -80,7 +85,7 @@ render() { const { config } = this.props - const { fields, appType, display, placement } = this.state + const { fields, appType, display, placement, icon } = this.state const { getFieldDecorator } = this.props.form const formItemLayout = { @@ -197,6 +202,32 @@ )} </Form.Item> </Col> : null} + {appType !== 'mob' && display === 'modal' ? <Col span={12}> + <Form.Item label="鍥炬爣"> + {getFieldDecorator('icon', { + initialValue: icon + })(<MkEditIcon onChange={(value) => this.setState({icon: value})} allowClear={true}/>)} + </Form.Item> + </Col> : null} + {appType !== 'mob' && display === 'modal' && icon ? <Col span={12}> + <Form.Item label="鍥炬爣鏍峰紡"> + {getFieldDecorator('iconType', { + initialValue: config.setting.iconType || 'def' + })( + <Radio.Group> + <Radio value="def">榛樿</Radio> + <Radio value="circle">鍦嗗舰</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> : null} + {appType !== 'mob' && display === 'modal' && icon ? <Col span={12}> + <Form.Item label="鍥炬爣棰滆壊"> + {getFieldDecorator('iconColor', { + initialValue: config.setting.iconColor || '' + })(<ColorSketch allowClear={true}/>)} + </Form.Item> + </Col> : null} {appType === 'mob' && display === 'drawer' ? <Col span={12}> <Form.Item label={ <Tooltip placement="topLeft" title="琛ㄥ崟鍏冪礌涓庡乏渚ц竟鐣岀殑璺濈銆�"> diff --git a/src/templates/modalconfig/settingform/index.scss b/src/templates/modalconfig/settingform/index.scss index 01a0a3a..a6e32ec 100644 --- a/src/templates/modalconfig/settingform/index.scss +++ b/src/templates/modalconfig/settingform/index.scss @@ -5,4 +5,8 @@ width: 16.5%; } } + .color-sketch-block { + position: relative; + top: 9px; + } } \ No newline at end of file diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx index 400b7d9..2acd0d3 100644 --- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx +++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx @@ -11,9 +11,8 @@ import './index.scss' const ColorSketch = asyncComponent(() => import('@/mob/colorsketch')) -const FieldsTable = asyncComponent(() => import('@/templates/zshare/modalform/fieldtable')) -const DataTable = asyncComponent(() => import('@/templates/zshare/modalform/datatable')) const EditTable = asyncComponent(() => import('@/templates/zshare/modalform/modaleditable')) +const FieldsTable = asyncComponent(() => import('@/templates/zshare/editTable')) const groupOptions = [ { @@ -190,6 +189,14 @@ } } else if (type === 'checkcard') { reRequired.fields = false + reOptions.multiple = [{ + value: 'false', + text: '鍗曢��' + }, { + value: 'true', + text: '澶氶��' + }] + if (this.record.display === 'picture') { if (this.record.resourceType === '0') { // 鑷畾涔夎祫婧� shows.push('options', 'fields', 'picratio') @@ -203,6 +210,20 @@ shows.push('dataSource', 'cardValField', 'colorField', 'fields', 'orderBy', 'orderType', 'database') } } else { + let appType = sessionStorage.getItem('appType') + if (appType === '') { + reOptions.multiple = [{ + value: 'false', + text: '鍗曢��' + }, { + value: 'true', + text: '澶氶��' + }, { + value: 'dropdown', + text: '涓嬫媺鑿滃崟' + }] + } + reRequired.fields = true if (this.record.resourceType === '0') { // 鑷畾涔夎祫婧� shows.push('options', 'fields', 'selectStyle', 'border') @@ -349,6 +370,9 @@ this.record.match = 'like' _fieldval.match = 'like' } + } else if (key === 'display') { + this.record.multiple = 'false' + _fieldval.multiple = 'false' } else if (key === 'items') { let _initval = this.props.form.getFieldValue('initval') if (_initval && !value.includes(_initval[0])) { @@ -552,12 +576,44 @@ let type = this.record.type if (type !== 'checkcard') { - content = <EditTable type={type} module="search" transfield={{}} linkSubFields={[]} onChange={this.changeOptions}/> + let columns = [] + + if (type === 'link') { + columns.push({ title: 'ParentID', key: 'ParentID', strict: true }) + } + + columns.push({ title: 'Value', key: 'Value', strict: true }) + columns.push({ title: 'Text', key: 'Text' }) + + content = <EditTable columns={columns} module="search" onChange={this.changeOptions}/> } else { if (this.record.linkField) { type = 'link' } - content = <DataTable type={type} multiple={this.record.multiple} display={this.record.display} linkSubFields={[]} transfield={{}} fields={this.record.fields || []} onChange={this.changeOptions}/> + + let columns = [] + let fields = this.record.fields || [] + let keys = ['ParentID', 'pid'] + + if (type === 'link') { + columns.push({ title: 'ParentID', key: 'ParentID', strict: true }) + } else if (this.record.multiple === 'dropdown' && this.record.display === 'text') { + columns.push({ title: 'pid', key: 'pid', strict: true }) + } + columns.push({ title: 'Value', key: '$value', strict: true }) + + if (this.record.display === 'picture') { + columns.push({ title: 'url', key: '$url', type: 'file' }) + } else if (this.record.display === 'color') { + columns.push({ title: 'Color', key: '$color' }) + } + + fields.forEach(item => { + keys.push(item.field) + columns.push({ title: item.field, key: item.field }) + }) + + content = <EditTable columns={columns} onChange={this.changeOptions}/> } } else if (item.type === 'fields') { span = 24 @@ -567,7 +623,7 @@ { required: item.required, message: '璇锋坊鍔�' + item.label + '!' } ] - content = <FieldsTable onChange={this.changeField}/> + content = <FieldsTable indexShow={false} actions={['edit', 'move', 'del', 'add']} columns={item.columns} data={this.record.fields || []} onChange={this.changeField}/> } else if (item.type === 'checkbox') { rules = [ { required: item.required, message: '璇烽�夋嫨' + item.label + '!' } diff --git a/src/templates/zshare/editTable/index.jsx b/src/templates/zshare/editTable/index.jsx index 60dd750..24902d3 100644 --- a/src/templates/zshare/editTable/index.jsx +++ b/src/templates/zshare/editTable/index.jsx @@ -3,7 +3,7 @@ import { is, fromJS } from 'immutable' import { DndProvider, DragSource, DropTarget } from 'react-dnd' import { Table, Input, InputNumber, Popconfirm, Form, Select, Radio, Cascader, notification, message, Modal, Typography } from 'antd' -import { CopyOutlined, EditOutlined, DeleteOutlined, SwapOutlined } from '@ant-design/icons' +import { CopyOutlined, EditOutlined, DeleteOutlined, SwapOutlined, PlusOutlined } from '@ant-design/icons' import Utils from '@/utils/utils.js' import ColorSketch from '@/mob/colorsketch' @@ -258,6 +258,7 @@ } UNSAFE_componentWillReceiveProps (nextProps) { + if (!is(fromJS(this.state.data), fromJS(nextProps.data))) { this.setState({data: nextProps.data, editingKey: ''}) } else if (!is(fromJS(this.props.columns), fromJS(nextProps.columns))) { @@ -518,6 +519,26 @@ return } + let forbid = false + + columns.forEach(col => { + if (!col.forbids || forbid) return + + let key = record[col.dataIndex].toLowerCase() + if (col.forbids.includes(key)) { + forbid = col.title + '涓嶅彲浣跨敤' + record[col.dataIndex] + } + }) + + if (forbid) { + notification.warning({ + top: 92, + message: forbid, + duration: 5 + }) + return + } + let unique = true columns.forEach(col => { if (col.unique !== true || !unique) return @@ -582,6 +603,26 @@ row = {...newData[index], ...row} } else { row.uuid = uuid + } + + let forbid = false + + columns.forEach(col => { + if (!col.forbids || forbid) return + + let key = row[col.dataIndex].toLowerCase() + if (col.forbids.includes(key)) { + forbid = col.title + '涓嶅彲浣跨敤' + row[col.dataIndex] + } + }) + + if (forbid) { + notification.warning({ + top: 92, + message: forbid, + duration: 5 + }) + return } let unique = true @@ -652,6 +693,37 @@ }) } + handleAdd = () => { + const { columns } = this.props + const { data } = this.state + + let _index = data.length + 1 + let item = { + uuid: Utils.getuuid() + } + + columns.forEach(col => { + if (!col.dataIndex) return + + item[col.dataIndex] = col.initval || '' + + if (col.unique) { + while (data.filter(cell => cell[col.dataIndex] === item[col.dataIndex]).length > 0) { + _index++ + item[col.dataIndex] = col.initval + _index + } + } + }) + + let _data = [...data, item] + + this.setState({ + data: _data + }, () => { + this.props.onChange(_data) + }) + } + render() { const { actions, indexShow, searchKey } = this.props const { editLineId } = this.state @@ -714,6 +786,7 @@ return ( <EditableContext.Provider value={this.props.form}> <div className="modal-edit-table"> + {actions.includes('add') ? <PlusOutlined className="add-row" onClick={this.handleAdd} /> : null} <DndProvider> <Table bordered diff --git a/src/templates/zshare/editTable/index.scss b/src/templates/zshare/editTable/index.scss index cac8205..564dc79 100644 --- a/src/templates/zshare/editTable/index.scss +++ b/src/templates/zshare/editTable/index.scss @@ -4,6 +4,7 @@ position: absolute; font-size: 12px; margin-top: -4px; + white-space: nowrap; } .color-sketch-block { width: 200px; @@ -112,5 +113,17 @@ color: #ff4d4f; } } + .ant-typography { + margin: 3px 0px; + } + .add-row { + position: absolute; + z-index: 1; + right: 10px; + top: -30px; + padding: 5px; + font-size: 18px; + color: #26C281; + } } diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx index f2373e3..6e13fc6 100644 --- a/src/templates/zshare/formconfig.jsx +++ b/src/templates/zshare/formconfig.jsx @@ -1,3 +1,4 @@ +import React from 'react' import { formRule, btnClasses } from '@/utils/option.js' /** @@ -549,18 +550,80 @@ }] }, { - type: 'fields', - key: 'fields', - label: '瀛楁闆�', - initVal: card.fields || [], - required: true - }, - { type: 'codemirror', key: 'dataSource', label: '鏁版嵁婧�', initVal: card.dataSource || '', + tooltip: '鏁版嵁鏉冮檺鏇挎崲绗� $@ -> /* 鎴� \'\'銆� @$ -> */ 鎴� \'\'', required: true + }, + { + type: 'fields', + key: 'fields', + label: '瀛楁闆�', + initVal: card.fields || [], + required: true, + columns: [ + { + title: '瀛楁鍚�', + dataIndex: 'field', + inputType: 'input', + editable: true, + unique: true, + strict: true, + forbids: ['value', 'parentid', 'pid'], + initval: 'field', + rules: [{ + pattern: /^[\u4E00-\u9FA50-9a-zA-Z_-]*$/ig, + message: '璇蜂娇鐢ㄦ暟瀛椼�佸瓧姣嶃�佹眽瀛椾互鍙奯-' + }], + width: '20%' + }, + { + title: '瀛椾綋棰滆壊', + dataIndex: 'color', + inputType: 'color', + editable: true, + initval: 'rgba(0, 0, 0, 0.85)', + width: '20%', + render: (text, record) => { + return <span style={{color: text}}>绀轰緥</span> + } + }, + { + title: '瀛椾綋澶у皬', + dataIndex: 'fontSize', + inputType: 'number', + min: 12, + max: 50, + editable: true, + initval: 14, + width: '20%', + }, + { + title: '瀵归綈鏂瑰紡', + dataIndex: 'align', + inputType: 'select', + editable: true, + width: '20%', + initval: 'left', + options: [ + {value: 'left', text: '灞呭乏'}, + {value: 'center', text: '灞呬腑'}, + {value: 'right', text: '灞呭彸'}, + // {value: 'justify', text: 'justify'} + ], + render: (text, record) => { + if (text === 'center') { + return '灞呬腑' + } else if (text === 'right') { + return '灞呭彸' + } else { + return '灞呭乏' + } + } + } + ] }, { type: 'options', @@ -644,7 +707,7 @@ required: false }, { - type: 'select', + type: 'radio', key: 'orderType', label: '鎺掑簭鏂瑰紡', initVal: card.orderType || 'asc', @@ -2567,6 +2630,9 @@ value: 'link', text: '鑱斿姩鑿滃崟' }, { + value: 'popSelect', + text: '閫夋嫨鍣�' + }, { value: 'switch', text: '寮�鍏�' }, { @@ -2904,12 +2970,210 @@ // }] // }, { + type: 'codemirror', + key: 'dataSource', + label: '鏁版嵁婧�', + initVal: card.dataSource || '', + tooltip: '鏁版嵁鏉冮檺鏇挎崲绗� $@ -> /* 鎴� \'\'銆� @$ -> */ 鎴� \'\'', + placeholder: '绯荤粺鍙橀噺锛歮k_departmentcode銆乵k_organization銆乵k_user_type銆傚叕鍏卞�硷細@ID@銆丂BID@銆�', + required: true, + readonly: false + }, + { type: 'fields', key: 'fields', label: '瀛楁闆�', initVal: card.fields || [], required: true, - readonly: false + readonly: false, + columns: [ + { + title: '瀛楁鍚�', + dataIndex: 'field', + inputType: 'input', + editable: true, + unique: true, + strict: true, + forbids: ['value', 'parentid', 'pid'], + initval: 'field', + rules: [{ + pattern: /^[\u4E00-\u9FA50-9a-zA-Z_-]*$/ig, + message: '璇蜂娇鐢ㄦ暟瀛椼�佸瓧姣嶃�佹眽瀛椾互鍙奯-' + }], + width: '20%' + }, + { + title: '瀛椾綋棰滆壊', + dataIndex: 'color', + inputType: 'color', + editable: true, + initval: 'rgba(0, 0, 0, 0.85)', + width: '20%', + render: (text, record) => { + return <span style={{color: text}}>绀轰緥</span> + } + }, + { + title: '瀛椾綋澶у皬', + dataIndex: 'fontSize', + inputType: 'number', + min: 12, + max: 50, + editable: true, + initval: 14, + width: '20%', + }, + { + title: '瀵归綈鏂瑰紡', + dataIndex: 'align', + inputType: 'select', + editable: true, + width: '20%', + initval: 'left', + options: [ + {value: 'left', text: '灞呭乏'}, + {value: 'center', text: '灞呬腑'}, + {value: 'right', text: '灞呭彸'}, + // {value: 'justify', text: 'justify'} + ], + render: (text, record) => { + if (text === 'center') { + return '灞呬腑' + } else if (text === 'right') { + return '灞呭彸' + } else { + return '灞呭乏' + } + } + } + ] + }, + { + type: 'fields', + key: 'columns', + label: '瀛楁闆�', + initVal: card.columns || [], + required: true, + readonly: false, + columns: [ + { + title: '鍚嶇О', + dataIndex: 'label', + inputType: 'input', + editable: true, + initval: 'label', + width: '20%' + }, + { + title: '瀛楁', + dataIndex: 'field', + inputType: 'input', + editable: true, + unique: true, + strict: true, + copy: true, + initval: 'field', + rules: [{ + pattern: /^[\u4E00-\u9FA50-9a-zA-Z_-]*$/ig, + message: '璇蜂娇鐢ㄦ暟瀛椼�佸瓧姣嶃�佹眽瀛椾互鍙奯-' + }], + width: '20%' + }, + { + title: '闅愯棌', + dataIndex: 'Hide', + inputType: 'radio', + editable: true, + width: '20%', + initval: 'false', + options: [ + {value: 'true', text: '鏄�'}, + {value: 'false', text: '鍚�'}, + ], + render: (text, record) => { + if (text === 'true') { + return '鏄�' + } else { + return '鍚�' + } + } + }, + { + title: '鎺掑簭', + dataIndex: 'IsSort', + inputType: 'radio', + editable: true, + width: '20%', + initval: 'false', + options: [ + {value: 'true', text: '鏄�'}, + {value: 'false', text: '鍚�'}, + ], + render: (text, record) => { + if (text === 'true') { + return '鏄�' + } else { + return '鍚�' + } + } + } + ] + }, + { + type: 'select', + key: 'primaryKey', + label: '涓婚敭', + initVal: card.primaryKey || '', + required: true, + readonly: false, + options: 'columns' + }, + { + type: 'text', + key: 'order', + label: '榛樿鎺掑簭', + initVal: card.order || '', + placeholder: 'ID asc', + required: true + }, + { + type: 'select', + key: 'showField', + label: '鏄剧ず瀛楁', + initVal: card.showField || '', + tooltip: '鐢ㄤ簬鎺у埗閫夋嫨妗嗕腑鐨勬樉绀哄唴瀹广��', + required: true, + options: 'columns' + }, + { + type: 'select', + key: 'controlField', + label: '绂佺敤瀛楁', + initVal: card.controlField || '', + tooltip: '鐢ㄤ簬鎺у埗琛屾暟鎹槸鍚﹀彲閫夋嫨銆傚瓧娈靛�间负true鏃讹紝閫夐」涓嶅彲閫夈��', + required: false, + allowClear: true, + options: 'columns' + }, + { + type: 'text', + key: 'searchKey', + label: '鎼滅储瀛楁', + initVal: card.searchKey || '', + tooltip: '澶氫釜鍊艰鐢ㄩ�楀彿鍒嗛殧銆�', + required: false, + rules: [{ + pattern: /^[0-9a-zA-Z,_-]*$/ig, + message: '瀛楁鍚嶅彧鍏佽鍖呭惈鏁板瓧銆佸瓧姣嶄互鍙奯-', + }] + }, + { + type: 'number', + key: 'popWidth', + label: '寮圭獥瀹藉害', + initVal: card.popWidth || 60, + tooltip: '灏忎簬100鏃朵负鐧惧垎鐜囷紝澶т簬100鏃朵负缁濆鍊笺��', + required: true }, { type: 'options', @@ -2920,13 +3184,33 @@ readonly: false }, { - type: 'codemirror', - key: 'dataSource', - label: '鏁版嵁婧�', - initVal: card.dataSource || '', - placeholder: '绯荤粺鍙橀噺锛歮k_departmentcode銆乵k_organization銆乵k_user_type銆傚叕鍏卞�硷細@ID@銆丂BID@銆�', - required: true, - readonly: false + type: 'radio', + key: 'laypage', + label: '鍒嗛〉', + initVal: card.laypage || 'true', + required: false, + options: [{ + value: 'true', + text: '鏄�' + }, { + value: 'false', + text: '鍚�' + }] + }, + { + type: 'radio', + key: 'onload', + label: '鍒濆鍖�', + initVal: card.onload || 'true', + tooltip: '褰撴病鏈夎缃悳绱㈠瓧娈垫椂锛屽垵濮嬪寲鍔犺浇鏁版嵁銆�', + required: false, + options: [{ + value: 'true', + text: '鍔犺浇' + }, { + value: 'false', + text: '涓嶅姞杞�' + }] }, { type: 'radio', @@ -2985,7 +3269,7 @@ readonly: false }, { - type: 'select', + type: 'radio', key: 'orderType', label: '鎺掑簭鏂瑰紡', initVal: card.orderType || 'asc', @@ -4016,7 +4300,11 @@ initVal: card.regularExtra || '', tooltip: '姝e垯楠岃瘉鏃跺厑璁告坊鍔犵殑鑷畾涔夊瓧绗︼紝鍖呮嫭~!@#$%^&*()_+:;{}<>,.-', required: false, - readonly: false + readonly: false, + rules: [{ + pattern: /^[~!@#$%^&*()_+:;{}<>,.-]*$/, + message: '鎵╁睍绗﹀寘鎷瑍!@#$%^&*()_+:;{}<>,.-' + }] }, { type: 'text', diff --git a/src/templates/zshare/modalform/datatable/index.jsx b/src/templates/zshare/modalform/datatable/index.jsx deleted file mode 100644 index 8f3e62b..0000000 --- a/src/templates/zshare/modalform/datatable/index.jsx +++ /dev/null @@ -1,502 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { is, fromJS } from 'immutable' -import { DndProvider, DragSource, DropTarget } from 'react-dnd' -import { Table, Input, Popconfirm, Form, notification, message } from 'antd' -import { PlusOutlined, EditOutlined, DeleteOutlined, SwapOutlined } from '@ant-design/icons' - -import Utils from '@/utils/utils.js' -import asyncComponent from '@/utils/asyncComponent' -// import FileUpload from '@/tabviews/zshare/fileupload' -import './index.scss' - -const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent')) -const EditableContext = React.createContext() -let dragingIndex = -1 - -class BodyRow extends React.Component { - render() { - const { isOver, moveAble, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props - let { className } = restProps - - if (isOver && moveAble) { - if (restProps.index > dragingIndex) { - className += ' drop-over-downward' - } - if (restProps.index < dragingIndex) { - className += ' drop-over-upward' - } - } - - if (moveAble) { - return connectDragSource( - connectDropTarget(<tr {...restProps} className={className} style={{...restProps.style, cursor: 'move'}} />), - ) - } else { - return (<tr {...restProps} className={className} style={restProps.style} />) - } - } -} - -const rowSource = { - beginDrag(props) { - dragingIndex = props.index - return { - index: props.index, - } - } -} - -const rowTarget = { - drop(props, monitor) { - const dragIndex = monitor.getItem().index - const hoverIndex = props.index - - if (dragIndex === hoverIndex) { - return - } - - props.moveRow(dragIndex, hoverIndex) - - monitor.getItem().index = hoverIndex - }, -} - -const DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({ - connectDropTarget: connect.dropTarget(), - isOver: monitor.isOver(), -}))( - DragSource('row', rowSource, connect => ({ - connectDragSource: connect.dragSource(), - }))(BodyRow), -) - -class EditableCell extends Component { - getInput = (form) => { - const { inputType, record } = this.props - if (inputType === 'file') { - return <SourceComponent initialValue={record ? (record.$url || '') : ''} type="" placement="right"/> - // return <FileUpload config={{ - // initval: record ? (record.$url || '') : '', - // suffix: '', - // maxfile: 1, - // fileType: 'picture-card' - // }}/> - } else { - return <Input onPressEnter={() => this.getValue(form)} /> - } - } - - getValue = (form) => { - const { record } = this.props - form.validateFields((error, row) => { - if (error) { - return - } - - this.props.onSave({...record, ...row}) - }) - } - - renderCell = (form) => { - const { getFieldDecorator } = form - const { - editing, - dataIndex, - title, - record, - inputType, - index, - children, - onSave, - ...restProps - } = this.props; - - let _val = '' - - if (record && dataIndex) { - _val = record[dataIndex] - } - - return ( - <td {...restProps}> - {editing ? ( - <Form.Item style={{ margin: '0 -5px 0 -5px' }}> - {getFieldDecorator(dataIndex, { - // rules: [ - // { - // required: dataIndex === '$value', - // message: `Please Input ${title}!`, - // }, - // ], - initialValue: _val, - })(this.getInput(form))} - </Form.Item> - ) : ( - children - )} - </td> - ) - } - - render() { - return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer> - } -} - -class EdiDataTable extends Component { - static propTpyes = { - transfield: PropTypes.object, // 瀛楁鍚嶇О - type: PropTypes.string, // 鏄惁涓哄叧鑱旇〃鍗� - display: PropTypes.string, // 鏁版嵁绫诲瀷锛屾枃鏈�佸浘鐗� - fields: PropTypes.array, // 瀛楁闆� - linkSubFields: PropTypes.array, // 濉厖瀛楁 - onChange: PropTypes.func // 鏁版嵁鍙樺寲 - } - - UNSAFE_componentWillMount () { - let data = this.props['data-__meta'].initialValue - - this.setState({ - data: data, - columns: this.getCloumns() - }) - } - - state = { - data: [], - editingKey: '', - columns: [] - } - - UNSAFE_componentWillReceiveProps (nextProps) { - if ( - !is(fromJS(this.props.fields), fromJS(nextProps.fields)) || - !is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) || - this.props.display !== nextProps.display || - (nextProps.multiple && this.props.multiple !== nextProps.multiple) || - this.props.type !== nextProps.type - ) { - this.setState({editingKey: ''}, () => { - this.setState({ - columns: this.getCloumns() - }) - }) - } - } - - getCloumns = () => { - const { display, fields, linkSubFields, transfield, type, multiple } = this.props - let columns = [] - let keys = ['ParentID', 'pid'] - - if (display === 'picture') { - columns.push({ - title: 'url', - dataIndex: '$url', - inputType: 'file', - // width: '40%', - editable: true, - render: (text) => { - if (!text) return '' - return <span style={{display: 'block', width: '70px', height: '70px'}}><img style={{width: '100%', height: '100%'}} src={text} alt="" /></span> - } - }) - } else if (display === 'color') { - columns.push({ - title: 'Color', - dataIndex: '$color', - inputType: 'text', - editable: true, - render: (text) => { - if (!text) return '' - return <div style={{height: '20px', background: text}}></div> - } - }) - } - - fields.forEach(item => { - keys.push(item.field) - columns.push({ - title: item.field, - dataIndex: item.field, - editable: true, - }) - }) - - if (linkSubFields.length > 0) { - linkSubFields.forEach(m => { - if (keys.includes(m)) return - - columns.push({ - title: transfield[m] || m, - dataIndex: m, - editable: true, - }) - }) - } - - columns.unshift({ - title: 'Value', - dataIndex: '$value', - editable: true, - }) - - if (multiple === 'dropdown' && display === 'text') { - columns.unshift({ - title: 'pid', - dataIndex: 'pid', - editable: true, - }) - } - - if (type === 'link') { - columns.unshift({ - title: 'ParentID', - dataIndex: 'ParentID', - editable: true, - }) - } - - columns.push({ - title: '鎿嶄綔', - dataIndex: 'operation', - align: 'center', - width: '18%', - render: (text, record) => { - const { editingKey } = this.state - const editable = this.isEditing(record) - return editable ? ( - <span> - <EditableContext.Consumer> - {form => ( - <span onClick={() => this.save(form, record.key)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}> - 淇濆瓨 - </span> - )} - </EditableContext.Consumer> - <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.key)}>鍙栨秷</span> - </span> - ) : ( - <div className={'operation-btn' + (editingKey !== '' ? ' disabled' : '')}> - <span className="primary" onClick={() => {editingKey === '' && this.edit(record.key)}}><EditOutlined /></span> - <span className="hide-control" title="鏄剧ず/闅愯棌" onClick={() => {editingKey === '' && this.handleHide(record.key)}}><SwapOutlined /></span> - {editingKey === '' ? <Popconfirm - overlayClassName="popover-confirm" - title="纭畾鍒犻櫎鍚�?" - onConfirm={() => this.handleDelete(record.key) - }> - <span className="danger"><DeleteOutlined /></span> - </Popconfirm> : null} - {editingKey !== '' ? <span className="danger"><DeleteOutlined /></span> : null} - </div> - ) - } - }) - - return columns - } - - isEditing = record => record.key === this.state.editingKey - - cancel = () => { - this.setState({ editingKey: '' }) - } - - onSave = (record) => { - const { type } = this.props - const newData = [...this.state.data] - const index = newData.findIndex(item => record.key === item.key) - - if (type === 'link') { - if (newData.filter(m => record.key !== m.key && record.$value === m.$value && record.ParentID === m.ParentID).length > 0) { - message.warning('鐩稿悓ParentID涓嬶紝姝alue鍊煎凡瀛樺湪锛�') - } - } else { - if (newData.filter(m => record.key !== m.key && record.$value === m.$value).length > 0) { - message.warning('姝alue鍊煎凡瀛樺湪锛�') - } - } - - if (index > -1) { - newData.splice(index, 1, record) - this.setState({ data: newData, editingKey: '' }, () => { - this.props.onChange(newData) - }) - } - } - - handleDelete = (key) => { - const { data } = this.state - let _data = data.filter(item => key !== item.key) - - this.setState({ - data: _data - }, () => { - this.props.onChange(_data) - }) - } - - save(form, key) { - const { type } = this.props - - form.validateFields((error, row) => { - if (error) { - return; - } - - const newData = [...this.state.data] - const index = newData.findIndex(item => key === item.key) - - if (type === 'link') { - if (newData.filter(m => key !== m.key && row.$value === m.$value && row.ParentID === m.ParentID).length > 0) { - message.warning('鐩稿悓ParentID涓嬶紝姝alue鍊煎凡瀛樺湪锛�') - } - } else { - if (newData.filter(m => key !== m.key && row.$value === m.$value).length > 0) { - message.warning('姝alue鍊煎凡瀛樺湪锛�') - } - } - - if (index > -1) { - const item = newData[index] - newData.splice(index, 1, { - ...item, - ...row, - }) - this.setState({ data: newData, editingKey: '' }, () => { - this.props.onChange(newData) - }) - } else { - newData.push(row); - this.setState({ data: newData, editingKey: '' }, () => { - this.props.onChange(newData) - }) - } - }) - } - - handleAdd = () => { - const { fields, display } = this.props - if (this.state.data.length >= 100) { - notification.warning({ - top: 92, - message: '鏈�澶氬彲娣诲姞100椤癸紒', - duration: 5 - }) - return - } - - let item = { key: Utils.getuuid(), $value: `${this.state.data.length + 1}`, ParentID: '' } - - if (display === 'picture') { - item.$url = '' - } else if (display === 'color') { - item.$color = '' - } - - fields.forEach(f => { - item[f.field] = `${this.state.data.length + 1}` - }) - - let data = [...this.state.data, item] - - this.setState({ data, editingKey: '' }, () => { - this.props.onChange(data) - }) - } - - edit(key) { - this.setState({ editingKey: key }) - } - - handleHide = (key) => { - let _data = this.state.data.map(item => { - if (item.key === key) { - item.Hide = !item.Hide - } - return item - }) - this.setState({ - data: _data - }, () => { - this.props.onChange(_data) - }) - } - - moveRow = (dragIndex, hoverIndex) => { - const { editingKey } = this.state - let _data = fromJS(this.state.data).toJS() - - if (editingKey) return - - _data.splice(hoverIndex, 0, ..._data.splice(dragIndex, 1)) - - this.setState({ - data: _data - }, () => { - this.props.onChange(_data) - }) - } - - render() { - const { display, fields } = this.props - - const components = { - body: { - row: DragableBodyRow, - cell: EditableCell - } - } - - const columns = this.state.columns.map(col => { - if (!col.editable) { - return col - } - return { - ...col, - onCell: record => ({ - record, - dataIndex: col.dataIndex, - inputType: col.inputType, - title: col.title, - editing: this.isEditing(record), - onSave: this.onSave, - }), - } - }) - - let addable = false - if (display === 'picture' || display === 'color') { - addable = true - } else if (fields && fields.length > 0) { - addable = true - } - - return ( - <EditableContext.Provider value={this.props.form}> - <div className="modal-card-data-table"> - {addable ? <PlusOutlined className="add-row" onClick={this.handleAdd} /> : null} - <DndProvider> - <Table - components={components} - bordered - rowKey="key" - dataSource={this.state.data} - columns={columns} - rowClassName={(record) => record.Hide ? 'editable-row hide' : 'editable-row'} - onRow={(record, index) => ({ - index, - moveAble: !this.state.editingKey, - moveRow: this.moveRow, - })} - pagination={false} - /> - </DndProvider> - </div> - </EditableContext.Provider> - ) - } -} - -export default Form.create()(EdiDataTable) \ No newline at end of file diff --git a/src/templates/zshare/modalform/datatable/index.scss b/src/templates/zshare/modalform/datatable/index.scss deleted file mode 100644 index ac76a17..0000000 --- a/src/templates/zshare/modalform/datatable/index.scss +++ /dev/null @@ -1,88 +0,0 @@ -.modal-card-data-table { - .add-row { - position: absolute; - z-index: 1; - right: 10px; - top: -30px; - padding: 5px; - font-size: 18px; - color: #26C281; - } - .editable-row { - .ant-form-explain { - position: absolute; - font-size: 12px; - margin-top: -4px; - } - .ant-form-item-control { - line-height: 1; - } - > td { - padding: 13px 10px; - word-break: break-all; - } - .fileupload-form-container .ant-upload-list-picture-card .ant-upload-list-item { - margin: 0; - padding: 2px; - .ant-upload-list-item-info > span { - height: 100%; - } - } - .ant-input { - padding: 0 5px; - } - } - .editable-row.hide { - td:not(:last-child) { - text-decoration: line-through; - } - } - .operation-btn { - font-size: 16px; - text-align: center; - span { - margin-right: 20px; - cursor: pointer; - } - span:last-child { - margin-right: 0px; - } - .primary { - color: #1890ff; - } - .hide-control { - color: rgb(142, 68, 173); - } - .danger { - color: #ff4d4f; - } - } - .operation-btn.disabled { - span { - cursor: default; - } - .primary { - color: rgba(0, 0, 0, .25); - } - .hide-control { - color: rgba(0, 0, 0, .25); - } - .danger { - color: rgba(0, 0, 0, .25); - } - } - tr.drop-over-downward td { - border-bottom: 2px dashed #1890ff; - } - tr.drop-over-upward td { - border-top: 2px dashed #1890ff; - } - .mk-source-wrap { - .ant-radio-button-wrapper + .ant-radio-button-wrapper { - border-radius: 0 4px 4px 0; - } - .ant-radio-button-wrapper:last-child { - display: none; - } - } -} diff --git a/src/templates/zshare/modalform/fieldtable/index.jsx b/src/templates/zshare/modalform/fieldtable/index.jsx deleted file mode 100644 index 3b607cf..0000000 --- a/src/templates/zshare/modalform/fieldtable/index.jsx +++ /dev/null @@ -1,169 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { notification } from 'antd' -import { PlusOutlined } from '@ant-design/icons' - -import asyncComponent from '@/utils/asyncComponent' -import Utils from '@/utils/utils.js' -import './index.scss' - -const EditTable = asyncComponent(() => import('@/templates/zshare/editTable')) - -class EdiFieldsTable extends Component { - static propTpyes = { - onChange: PropTypes.func // 鏁版嵁鍙樺寲 - } - - UNSAFE_componentWillMount () { - let data = this.props['data-__meta'].initialValue || [] - - this.setState({ - loading: false, - data: data.map(item => { - item.uuid = item.uuid || item.key - return item - }) - }) - } - - state = { - data: [], - columns: [ - { - title: '瀛楁鍚�', - dataIndex: 'field', - inputType: 'input', - editable: true, - width: '20%', - }, - { - title: '瀛椾綋棰滆壊', - dataIndex: 'color', - inputType: 'color', - editable: true, - width: '20%', - render: (text, record) => { - return <span style={{color: text}}>绀轰緥</span> - } - }, - { - title: '瀛椾綋澶у皬', - dataIndex: 'fontSize', - inputType: 'number', - min: 12, - max: 50, - editable: true, - width: '20%', - }, - { - title: '瀵归綈鏂瑰紡', - dataIndex: 'align', - inputType: 'select', - editable: true, - width: '20%', - options: [ - {value: 'left', text: '灞呭乏'}, - {value: 'center', text: '灞呬腑'}, - {value: 'right', text: '灞呭彸'}, - // {value: 'justify', text: 'justify'} - ], - render: (text, record) => { - if (text === 'center') { - return '灞呬腑' - } else if (text === 'right') { - return '灞呭彸' - } else { - return '灞呭乏' - } - } - } - ] - } - - handleAdd = () => { - let _index = this.state.data.length + 1 - let item = { - key: Utils.getuuid(), - field: `field${_index}`, - color: 'rgba(0, 0, 0, 0.85)', - align: 'left', - fontSize: 14, - } - - item.uuid = item.key - - while (this.state.data.filter(cell => cell.field === item.field).length > 0) { - _index++ - item.field = `field${_index}` - } - - let data = [...this.state.data, item] - - this.setState({ data }, () => { - this.props.onChange(data) - }) - } - - changeData = (data) => { - let fields = data.map(cell => cell.field) - fields = Array.from(new Set(fields)) - if (data.length > 1 && data.length > fields.length) { - notification.warning({ - top: 92, - message: '瀛楁鍚嶄笉鍙噸澶嶏紒', - duration: 5 - }) - this.setState({loading: true}, () => { - this.setState({loading: false}) - }) - return - } else if (fields.filter(f => f.toLowerCase() === 'value').length > 0) { - notification.warning({ - top: 92, - message: '瀛楁鍚嶄笉鍙娇鐢╲alue锛�', - duration: 5 - }) - this.setState({loading: true}, () => { - this.setState({loading: false}) - }) - return - } else if (fields.filter(f => f.toLowerCase() === 'parentid').length > 0) { - notification.warning({ - top: 92, - message: '瀛楁鍚嶄笉鍙娇鐢╬arentid锛�', - duration: 5 - }) - this.setState({loading: true}, () => { - this.setState({loading: false}) - }) - return - } else if (fields.filter(f => f.toLowerCase() === 'pid').length > 0) { - notification.warning({ - top: 92, - message: '瀛楁鍚嶄笉鍙娇鐢╬id锛�', - duration: 5 - }) - this.setState({loading: true}, () => { - this.setState({loading: false}) - }) - return - } - - this.setState({ data }, () => { - this.props.onChange(data) - }) - } - - render() { - const { data, columns, loading } = this.state - - return ( - <div className="modal-card-field-table"> - {data.length < 6 ? <PlusOutlined className="add-row" onClick={this.handleAdd} /> : null} - {!loading ? <EditTable indexShow={false} actions={['edit', 'move', 'del']} data={data} columns={columns} onChange={this.changeData}/> : null} - </div> - ) - } -} - -export default EdiFieldsTable \ No newline at end of file diff --git a/src/templates/zshare/modalform/fieldtable/index.scss b/src/templates/zshare/modalform/fieldtable/index.scss deleted file mode 100644 index 6e9832a..0000000 --- a/src/templates/zshare/modalform/fieldtable/index.scss +++ /dev/null @@ -1,14 +0,0 @@ -.modal-card-field-table { - .add-row { - position: absolute; - z-index: 1; - right: 10px; - top: -30px; - padding: 5px; - font-size: 18px; - color: #26C281; - } - .ant-empty { - margin: 0; - } -} diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx index 43d8efa..0c6a6b7 100644 --- a/src/templates/zshare/modalform/index.jsx +++ b/src/templates/zshare/modalform/index.jsx @@ -1,9 +1,10 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { fromJS } from 'immutable' -import { Form, Row, Col, Input, Select, Radio, notification, InputNumber, Tooltip, Checkbox, AutoComplete } from 'antd' +import { Form, Row, Col, Input, Select, Radio, notification, InputNumber, Tooltip, Checkbox, AutoComplete, Modal } from 'antd' import { QuestionCircleOutlined } from '@ant-design/icons' +import Api from '@/api' import { formRule } from '@/utils/option.js' import { dateOptions } from '@/utils/option.js' import Utils from '@/utils/utils.js' @@ -14,19 +15,18 @@ const { TextArea } = Input const ColorSketch = asyncComponent(() => import('@/mob/colorsketch')) -const FieldsTable = asyncComponent(() => import('./fieldtable')) -const DataTable = asyncComponent(() => import('./datatable')) +const FieldsTable = asyncComponent(() => import('@/templates/zshare/editTable')) const MkEditIcon = asyncComponent(() => import('@/components/mkIcon')) const modalTypeOptions = { text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'encryption', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder', 'place', 'marginTop', 'marginBottom', 'lenControl', 'inputType', 'constant'], number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline', 'place', 'marginTop', 'marginBottom'], - select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'], + select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'], checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'splitline', 'arrange', 'marginTop', 'marginBottom'], - radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'setAll', 'emptyText', 'splitline', 'arrange', 'marginTop', 'marginBottom'], + radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'splitline', 'arrange', 'marginTop', 'marginBottom'], checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'span', 'labelwidth', 'display', 'tooltip', 'extra', 'place', 'width', 'multiple', 'splitline', 'marginTop', 'marginBottom'], multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'marginTop', 'marginBottom', 'dropdown'], - link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkField', 'linkSubField', 'span', 'place', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'], + link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkField', 'linkSubField', 'span', 'place', 'labelwidth', 'tooltip', 'extra', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'], fileupload: ['readonly', 'required', 'hidden', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'linkSubField', 'tooltip', 'extra', 'compress', 'miniSet', 'splitline', 'marginTop', 'marginBottom', 'maxSize'], switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'linkSubField', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom'], check: ['initval', 'openVal', 'closeVal', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom', 'checkTip'], @@ -43,6 +43,7 @@ brafteditor: ['required', 'hidelabel', 'hidden', 'readin', 'fieldlength', 'readonly', 'span', 'labelwidth', 'tooltip', 'extra', 'encryption', 'marginTop', 'marginBottom'], funcvar: ['span', 'labelwidth', 'splitline', 'marginTop', 'marginBottom'], linkMain: ['readonly', 'required', 'hidden','declare', 'span', 'labelwidth', 'tooltip', 'interception', 'extra', 'place', 'marginTop', 'marginBottom'], + popSelect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'enter', 'dataSource', 'columns', 'primaryKey', 'order', 'controlField', 'laypage', 'onload', 'searchKey', 'showField', 'popWidth'], vercode: ['label', 'field', 'type', 'blacklist', 'supField', 'readonly', 'required', 'hidden', 'span', 'labelwidth', 'tooltip', 'marginTop', 'marginBottom', 'placeholder', 'enter', 'smsId', 'phoneField', 'sendType'] } @@ -429,41 +430,45 @@ this.record.readonly = 'false' } - if (this.record.options.length > 0) { - if (value === 'checkcard') { + if (value === 'checkcard') { + if (this.record.options.length > 0) { this.record.options = this.record.options.map(cell => { cell.$value = cell.Value || '' delete cell.Value return cell }) + } - if (this.record.options[0].Text) { - let key = Utils.getuuid() - - this.record.fields = [{ - $index: 1, - align: 'left', - color: 'rgba(0, 0, 0, 0.85)', - field: 'Text', - fontSize: 14, - key: key, - uuid: key - }] - } - } else if (['multiselect', 'select', 'link', 'radio', 'checkbox'].includes(value)) { + if (this.record.options[0] && this.record.options[0].Text) { + let key = Utils.getuuid() + + this.record.fields = [{ + $index: 1, + align: 'left', + color: 'rgba(0, 0, 0, 0.85)', + field: 'Text', + fontSize: 14, + key: key, + uuid: key + }] + } else { + this.record.fields = [] + } + } else if (['multiselect', 'select', 'link', 'radio', 'checkbox'].includes(value)) { + if (this.record.options.length > 0) { if (!this.record.options[0].Text && this.record.fields.length > 0) { let field = this.record.fields[0].field this.record.options = this.record.options.map(cell => { cell.Value = cell.Value || cell.$value || '' cell.Text = cell[field] || '' - + delete cell.$value return cell }) } else { this.record.options = this.record.options.map(cell => { cell.Value = cell.Value || cell.$value || '' - + delete cell.$value return cell }) } @@ -514,12 +519,8 @@ this.record[key] = value } - changeField = (data) => { - this.record.fields = data || [] - } - - changeOptions = (data) => { - this.record.options = data || [] + changeOptions = (data, key) => { + this.record[key] = data || [] } changeVal = (val, type) => { @@ -636,18 +637,15 @@ message: '涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒' } ] - if (item.key === 'field') { + if (item.rules) { + rules.push(...item.rules) + } else if (item.key === 'field') { rules.push({ pattern: formRule.field.pattern, message: formRule.field.message }, { max: formRule.field.max, message: formRule.field.maxMessage - }) - } else if (item.key === 'regularExtra') { - rules.push({ - pattern: /^[~!@#$%^&*()_+:;{}<>,.-]*$/, - message: '鎵╁睍绗﹀寘鎷瑍!@#$%^&*()_+:;{}<>,.-' }) } else if (item.max) { rules.push({ @@ -673,7 +671,7 @@ <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} /> </AutoComplete> } else { - content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} /> + content = <Input placeholder={item.placeholder || ''} autoComplete="off" onPressEnter={this.handleSubmit} /> } } else if (item.type === 'number') { rules = [ @@ -690,6 +688,12 @@ rules = [ { required: item.required, message: '璇烽�夋嫨' + item.label + '!' } ] + + let options = item.options + if (typeof(item.options) === 'string') { + options = this.record[item.options] || [] + } + content = <Select showSearch allowClear={item.allowClear === true} @@ -697,7 +701,7 @@ onChange={(value) => {this.optionChange(item.key, value)}} getPopupContainer={() => document.getElementById('modal-fields-form-box')} > - {item.options.map((option, i) => + {options.map((option, i) => <Select.Option key={`${i}`} value={option.value || option.field || ''}> {option.text || option.label} </Select.Option> @@ -778,7 +782,21 @@ linkSubFields = [] } } - content = <EditTable type={type} module="form" transfield={transfield} linkSubFields={linkSubFields} onChange={this.changeOptions}/> + + let columns = [] + if (type === 'link') { + columns.push({ title: 'ParentID', key: 'ParentID', strict: true }) + } + columns.push({ title: 'Value', key: 'Value', strict: true }) + columns.push({ title: 'Text', key: 'Text' }) + + linkSubFields.forEach(field => { + if (field === 'Value' || field === 'Text') return + + columns.push({ title: transfield[field] || field, key: field }) + }) + + content = <EditTable columns={columns} module="form" onChange={(data) => this.changeOptions(data, item.key)}/> } else { if (this.record.multiple === 'true') { linkSubFields = [] @@ -786,7 +804,34 @@ if (this.record.linkField) { type = 'link' } - content = <DataTable type={type} display={this.record.display} linkSubFields={linkSubFields} transfield={transfield} fields={this.record.fields || []} onChange={this.changeOptions}/> + + let columns = [] + let fields = this.record.fields || [] + let keys = ['ParentID', 'pid'] + + if (type === 'link') { + columns.push({ title: 'ParentID', key: 'ParentID', strict: true }) + } + columns.push({ title: 'Value', key: '$value', strict: true }) + + if (this.record.display === 'picture') { + columns.push({ title: 'url', key: '$url', type: 'file' }) + } else if (this.record.display === 'color') { + columns.push({ title: 'Color', key: '$color' }) + } + + fields.forEach(item => { + keys.push(item.field) + columns.push({ title: item.field, key: item.field }) + }) + + linkSubFields.forEach(m => { + if (keys.includes(m)) return + + columns.push({ title: transfield[m] || m, key: m }) + }) + + content = <EditTable columns={columns} onChange={(data) => this.changeOptions(data, item.key)}/> } } else if (item.type === 'fields') { span = 24 @@ -795,7 +840,7 @@ { required: item.required, message: '璇锋坊鍔�' + item.label + '!' } ] - content = <FieldsTable onChange={this.changeField}/> + content = <FieldsTable indexShow={false} actions={['edit', 'move', 'del', 'add']} columns={item.columns} data={this.record[item.key] || []} onChange={(data) => this.changeOptions(data, item.key)}/> } else if (item.type === 'color') { className = 'color-form-item' rules = [ @@ -836,7 +881,7 @@ let isNumber = true options.forEach(item => { - if (!/^([0-9]|[1-9]\d{0,2})$/.test(item.Value)) { + if (!item.Value || isNaN(item.Value)) { isNumber = false } }) @@ -877,12 +922,36 @@ } } - handleConfirm = () => { + handleConfirm = (fields) => { + const { card } = this.props // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� return new Promise((resolve, reject) => { this.props.form.validateFieldsAndScroll((err, values) => { if (!err) { - values.uuid = this.props.card.uuid + values.uuid = card.uuid + + if (card.style) { + values.style = card.style + } + + let fieldrepet = false // 瀛楁閲嶅 + + fields.forEach(item => { + if (item.uuid === card.uuid || !values.field || !item.field) return + if (item.field.toLowerCase() === values.field.toLowerCase()) { + fieldrepet = true + } + }) + + if (fieldrepet) { + notification.warning({ + top: 92, + message: '瀛楁宸插瓨鍦紒', + duration: 10 + }) + return + } + // 涓嬫媺鑿滃崟鎴栬仈鍔ㄨ彍鍗� if (['multiselect', 'select', 'link', 'radio', 'checkbox'].includes(values.type)) { if (values.resourceType === '0') { @@ -1020,7 +1089,93 @@ return } - resolve(values) + window.GLOB.formId = card.uuid + + if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(values.type) && values.resourceType === '1' && values.dataSource) { + let _option = Utils.getSelectQueryOptions(values) + + let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20) + ${_option.sql}` + + // LoginUID|SessionUid|UserID|Appkey 宸叉浛鎹� + sql = sql.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|time_id)@/ig, `'1949-10-01 15:00:00'`) + + let rduri = '' + if (window.GLOB.mainSystemApi && values.database === 'sso') { + rduri = window.GLOB.mainSystemApi + } + + resolve({values, loading: true, promise: () => new Promise((resolve, reject) => { + Api.sDebug(sql, rduri).then(result => { + if (result.status || result.ErrCode === '-2') { + resolve() + } else { + Modal.error({ + title: result.message + }) + reject() + } + }) + })}) + } else if (values.type === 'popSelect') { + let arrfield = values.columns.map(f => f.field) + + if (values.linkSubField && values.linkSubField.length > 0) { + values.linkSubField.forEach(n => { + if (!arrfield.includes(n)) { + arrfield.push(n) + } + }) + } + + let _datasource = values.dataSource + let sql = '' + + if (/\s/.test(_datasource)) { // 鎷兼帴鍒悕 + _datasource = '(' + _datasource + ') tb' + } + + arrfield = arrfield.join(',') + + let _search = '' + + if (values.searchKey) { + let fields = values.searchKey.split(',').map(field => field + ' like \'%mk%\'') + _search = 'where ' + fields.join(' OR ') + } + + if (values.laypage === 'true') { + sql = `/*system_query*/select top 10 ${arrfield} from (select ${arrfield} ,ROW_NUMBER() over(order by ${values.order}) as rows from ${_datasource} ${_search}) tmptable where rows > 0 order by tmptable.rows ` + } else if (values.order) { + sql = `/*system_query*/select ${arrfield} from (select ${arrfield} ,ROW_NUMBER() over(order by ${values.order}) as rows from ${_datasource} ${_search}) tmptable order by tmptable.rows ` + } else { + sql = `/*system_query*/select ${arrfield} from ${_datasource} ${_search} ` + } + + sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20) + ${sql}` + + sql = sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'') + sql = sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`) + sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`) + sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`) + sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`) + + resolve({values, loading: true, promise: () => new Promise((resolve, reject) => { + Api.sDebug(sql).then(result => { + if (result.status || result.ErrCode === '-2') { + resolve() + } else { + Modal.error({ + title: result.message + }) + reject() + } + }) + })}) + } else { + resolve({values}) + } } else { reject(err) } diff --git a/src/templates/zshare/modalform/modaleditable/index.jsx b/src/templates/zshare/modalform/modaleditable/index.jsx index b8ca161..0427a95 100644 --- a/src/templates/zshare/modalform/modaleditable/index.jsx +++ b/src/templates/zshare/modalform/modaleditable/index.jsx @@ -1,106 +1,138 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { is, fromJS } from 'immutable' -import { Table, Input, Popconfirm, Form, message } from 'antd' -import { ArrowUpOutlined, ArrowDownOutlined, DeleteOutlined, PlusOutlined, SwapOutlined } from '@ant-design/icons' +import { DndProvider, DragSource, DropTarget } from 'react-dnd' +import { Table, Input, Popconfirm, message } from 'antd' +import { DeleteOutlined, PlusOutlined, SwapOutlined, DragOutlined } from '@ant-design/icons' import Utils from '@/utils/utils.js' +import asyncComponent from '@/utils/asyncComponent' import './index.scss' -const EditableContext = React.createContext() +const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent')) -const EditableRow = ({ form, index, ...props }) => ( - <EditableContext.Provider value={form}> - <tr {...props} /> - </EditableContext.Provider> +class MoveTd extends React.Component { + render() { + const { connectDragSource, connectDropTarget } = this.props + + return connectDragSource( + connectDropTarget(<td className="mk-move-col"><DragOutlined /></td>), + ) + } +} + +const rowSource = { + beginDrag(props) { + return { + index: props.index, + } + } +} + +const rowTarget = { + drop(props, monitor) { + const dragIndex = monitor.getItem().index + const hoverIndex = props.index + + if (dragIndex === hoverIndex) { + return + } + + props.moveRow(dragIndex, hoverIndex) + + monitor.getItem().index = hoverIndex + }, +} + +const DragableTd = DropTarget('td', rowTarget, connect => ({ + connectDropTarget: connect.dropTarget(), +}))( + DragSource('td', rowSource, (connect, monitor) => ({ + connectDragSource: connect.dragSource(), + // isDragging: monitor.isDragging() + }))(MoveTd), ) - -const EditableFormRow = Form.create()(EditableRow) class EditableCell extends Component { state = { - editing: false + editing: false, + value: '' } - toggleEdit = () => { - const editing = !this.state.editing - this.setState({ editing }, () => { - if (editing && this.input && this.input.select) { + trigger = () => { + const { dataIndex, record } = this.props + + this.setState({ editing: true, value: record[dataIndex] }, () => { + if (this.input && this.input.select) { this.input.select() - } else if (editing && this.input && this.input.focus) { + } else if (this.input && this.input.focus) { this.input.focus() } }) } - save = e => { - const { record, handleSave } = this.props - this.form.validateFields((error, values) => { - handleSave({ ...record, ...values }) - if (error && error[e.currentTarget.id]) { - return - } - this.toggleEdit() - }) + save = () => { + const { record, handleSave, dataIndex } = this.props + const { value } = this.state + + handleSave({ ...record, [dataIndex]: value }) + + this.setState({ editing: false, value: '' }) } - renderCell = form => { - this.form = form - const { children, dataIndex, record } = this.props + changeUrl = (val) => { + const { record, handleSave, dataIndex } = this.props + + handleSave({ ...record, [dataIndex]: val }) + } + + renderCell = () => { + const { dataIndex, inputType, record } = this.props const { editing } = this.state - return editing ? ( - <Form.Item style={{ margin: '0 -5px 0 -5px' }}> - {form.getFieldDecorator(dataIndex, { - rules: [ - { - required: dataIndex === 'Text', - message: '涓嶅彲涓虹┖.', - } - ], - initialValue: record[dataIndex] - })(<Input ref={node => (this.input = node)} autoComplete="off" onPressEnter={this.save} onBlur={this.save} />)} - </Form.Item> - ) : ( - <div - className="editable-cell-value-wrap" - onClick={this.toggleEdit} - > - {children} - </div> - ) + if (inputType === 'file') { + return <SourceComponent initialValue={record[dataIndex]} type="" onChange={this.changeUrl} placement="right"/> + } + + if (!editing) { + return ( + <div + className="editable-cell-value-wrap" + onClick={this.trigger} + > + {record[dataIndex]} + </div> + ) + } else { + return <Input ref={node => (this.input = node)} defaultValue={record[dataIndex]} autoComplete="off" onChange={(e) => this.setState({value: e.target.value})} onPressEnter={this.save} onBlur={this.save} /> + } } render() { - const { - editable, - dataIndex, - title, - record, - index, - handleSave, - children, - ...restProps - } = this.props + const { editable, dataIndex, index } = this.props + + if (dataIndex === '$move') { + return (<DragableTd key={index} {...this.props} />) + } + + if (editable) { + return ( + <td>{this.renderCell()}</td> + ) + } + return ( - <td {...restProps}> - {editable ? ( - <EditableContext.Consumer style={{padding: 0}}>{this.renderCell}</EditableContext.Consumer> - ) : ( - children - )} - </td> + <td {...this.props}/> ) } } class EditTable extends Component { static propTpyes = { - type: PropTypes.string, // 琛ㄥ崟绫诲瀷 - module: PropTypes.string, // 鍏冪礌绫诲瀷 - linkSubFields: PropTypes.array, // 鍏宠仈瀛楁 - transfield: PropTypes.object, // 琛ㄥ崟瀛楁鍚嶇О - onChange: PropTypes.func // 鏁版嵁鍙樺寲 + type: PropTypes.any, + module: PropTypes.string, + columns: PropTypes.array, + onChange: PropTypes.func } state = { @@ -110,38 +142,40 @@ } UNSAFE_componentWillMount () { - const { linkSubFields, type } = this.props - let data = this.props['data-__meta'].initialValue || [] - - const { columns } = this.getColumns(type, linkSubFields, data) + const { columns, value } = this.props + let data = value || [] this.setState({ - columns: columns, - dataSource: data, + columns: this.getColumns(), + dataSource: data.map(item => { + columns.forEach(n => { + if (item[n.key] !== undefined) return + item[n.key] = ['ParentID', '$url', '$color', '$value'].includes(n.key) ? '' : item.Text || '' + }) + return item + }), count: data.length }) } - handleUpDown = (record, direction) => { + moveRow = (dragId, hoverId) => { const { dataSource } = this.state - let index = 0 - - let _data = dataSource.filter((item, i) => { - if (item.key === record.key) { - index = i + let dragIndex = -1 + let hoverIndex = -1 + + dataSource.forEach((item, i) => { + if (item.key === dragId) { + dragIndex = i + } else if (item.key === hoverId) { + hoverIndex = i } - - return item.key !== record.key }) - if ((index === 0 && direction === 'up') || (index === dataSource.length - 1 && direction === 'down')) { - return - } + + if (dragIndex === -1 || hoverIndex === -1) return - if (direction === 'up') { - _data.splice(index - 1, 0, record) - } else { - _data.splice(index + 1, 0, record) - } + let _data = fromJS(dataSource).toJS() + + _data.splice(hoverIndex, 0, ..._data.splice(dragIndex, 1)) this.setState({ dataSource: _data @@ -150,13 +184,14 @@ }) } - handleHide = (record) => { + handleHide = (key) => { let _data = this.state.dataSource.map(item => { - if (item.key === record.key) { + if (item.key === key) { item.Hide = !item.Hide } return item }) + this.setState({ dataSource: _data }, () => { @@ -164,7 +199,7 @@ }) } - handleDelete = key => { + handleDelete = (key) => { const { dataSource } = this.state let _data = dataSource.filter(item => item.key !== key) @@ -173,22 +208,26 @@ }) } - handleAdd = (e) => { - e.stopPropagation() - const { linkSubFields } = this.props + handleAdd = () => { + const { columns } = this.props const { count, dataSource } = this.state - const newData = { - key: Utils.getuuid(), - Value: `${count}`, - Text: `${count}`, - ParentID: '' - } - linkSubFields.forEach(m => { - newData[m] = newData[m] || '' + let item = { key: Utils.getuuid() } + + columns.forEach(m => { + item[m.key] = '' }) - let _data = [...dataSource, newData] + if (item.Value === '') { + item.Value = `${count + 1}` + } + if (item.$value === '') { + item.$value = `${count + 1}` + } + + item.Text = `${count + 1}` + + let _data = [...dataSource, item] this.setState({ dataSource: _data, @@ -199,18 +238,49 @@ } handleSave = row => { - const { type } = this.props + const { columns, type } = this.props const newData = [...this.state.dataSource] const index = newData.findIndex(item => row.key === item.key) const item = newData[index] - if (type === 'link') { - if (newData.filter(m => row.key !== m.key && row.Value === m.Value && row.ParentID === m.ParentID).length > 0) { - message.warning('鐩稿悓ParentID涓嬶紝姝alue鍊煎凡瀛樺湪锛�') - } + if (type === 'proc') { + // if (!row.origin || /^\s+$/.test(row.origin)) { + // message.warning(columns[0].title + '涓虹┖鏃舵棤鏁堬紒') + // } } else { - if (newData.filter(m => row.key !== m.key && row.Value === m.Value).length > 0) { - message.warning('姝alue鍊煎凡瀛樺湪锛�') + let val = '' + let repeat = false + let _type = '' + columns.forEach(col => { + if (!col.strict) return + + if (col.key === 'ParentID') { + _type = 'mutil' + } + + val += row[col.key] + }) + + newData.forEach(item => { + if (row.key === item.key) return + + let _val = '' + columns.forEach(col => { + if (!col.strict) return + + _val += item[col.key] + }) + + if (val === _val) { + repeat = true + } + }) + if (repeat) { + if (_type === 'mutil') { + message.warning('鐩稿悓ParentID涓嬶紝姝alue鍊煎凡瀛樺湪锛�') + } else { + message.warning('姝alue鍊煎凡瀛樺湪锛�') + } } } @@ -223,112 +293,83 @@ }) } - getColumns = (type, linkSubFields, dataSource) => { - const { transfield } = this.props + getColumns = () => { + const { columns } = this.props - let _dataSource = fromJS(dataSource).toJS() - let fields = [] - let subFields = linkSubFields.filter(m => m !== 'Value' && m !== 'Text') - - if (subFields.length > 0) { - _dataSource = _dataSource.map(data => { - subFields.forEach(n => { - if (data[n] !== undefined) return - data[n] = data.Text || '' - }) - return data + let fields = [{ + title: ' ', + width: '60px', + dataIndex: '$move', + onCell: (record) => ({ + index: record.key, + dataIndex: '$move', + moveRow: this.moveRow }) - - fields = subFields.map(field => { - return { - title: transfield[field] || field, - $title: transfield[field] || field, - dataIndex: field, + }] + columns.forEach(n => { + let col = { + title: n.title, + dataIndex: n.key, + onCell: record => ({ + record, editable: true, - } - }) - } - - let columns = [ - { - title: 'Value', - $title: 'Value', - dataIndex: 'Value', - editable: true - }, - { - title: 'Text', - $title: 'Text', - dataIndex: 'Text', - editable: true - }, - ...fields, - { - title: '鎿嶄綔', - align: 'center', - width: '20%', - dataIndex: 'operation', - render: (text, record) => - this.state.dataSource.length >= 1 ? ( - <div style={{fontSize: '15px'}}> - <span className="operation-btn" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><ArrowUpOutlined /></span> - <span className="operation-btn" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><ArrowDownOutlined /></span> - <span className="operation-btn" title="鏄剧ず/闅愯棌" onClick={() => this.handleHide(record)} style={{color: 'rgb(142, 68, 173)'}}><SwapOutlined /></span> - <Popconfirm - title="纭畾鍒犻櫎鍚楋紵" - overlayClassName="popover-confirm" - onConfirm={() => this.handleDelete(record.key) - }> - <span style={{color: '#ff4d4f', cursor: 'pointer'}}><DeleteOutlined /></span> - </Popconfirm> - </div> - ) : null, + inputType: n.type || 'text', + dataIndex: n.key, + handleSave: this.handleSave + }) } - ] - if (type === 'link') { - columns.unshift({ - title: 'ParentID', - $title: 'ParentID', - dataIndex: 'ParentID', - editable: true - }) - } + if (n.width) { + col.width = n.width + } + if (n.fixed) { + delete col.onCell + } - return { - columns: columns.map(col => { - if (col.dataIndex !== 'operation') { - col.title = <div> - {col.$title} + fields.push(col) + }) + + fields.push({ + title: '鎿嶄綔', + align: 'center', + width: '110px', + dataIndex: 'operation', + render: (text, record) => + ( + <div style={{fontSize: '15px'}}> + <span className="operation-btn" title="鏄剧ず/闅愯棌" onClick={() => this.handleHide(record.key)} style={{color: 'rgb(142, 68, 173)'}}><SwapOutlined /></span> + <Popconfirm + title="纭畾鍒犻櫎鍚楋紵" + overlayClassName="popover-confirm" + onConfirm={() => this.handleDelete(record.key) + }> + <span style={{color: '#ff4d4f', cursor: 'pointer'}}><DeleteOutlined /></span> + </Popconfirm> </div> - } - return col - }), - dataSource: _dataSource - } + ) + }) + + return fields } - handleEmpty = (e) => { - e.stopPropagation() - const { linkSubFields, module } = this.props + handleEmpty = () => { + const { columns, module } = this.props const { dataSource } = this.state if (dataSource.filter(item => item.Value === '').length > 0) { message.warning('Value涓虹┖宸插瓨鍦紒') return } - const newData = { - key: Utils.getuuid(), - Value: '', - Text: module === 'form' ? '绌�' : '鍏ㄩ儴', - ParentID: '' - } - linkSubFields.forEach(m => { - newData[m] = newData[m] || '' + let item = { key: Utils.getuuid() } + + columns.forEach(m => { + item[m.key] = '' }) - let _data = [newData, ...dataSource] + item.Text = module === 'form' ? '绌�' : '鍏ㄩ儴' + + let _data = [item, ...dataSource] this.setState({ dataSource: _data, @@ -337,65 +378,57 @@ }) } - resetColumn = (type, linkSubFields) => { - const { columns, dataSource } = this.getColumns(type, linkSubFields, this.state.dataSource) + resetColumn = () => { + const { columns, value } = this.props + + let data = fromJS(value).toJS().map(item => { + columns.forEach(n => { + if (item[n.key] !== undefined) return + item[n.key] = ['ParentID', '$url', '$color', '$value'].includes(n.key) ? '' : item.Text || '' + }) + return item + }) - if (!is(fromJS(dataSource), fromJS(this.state.dataSource))) { - this.setState({ - columns, - dataSource - }, () => { - this.props.onChange(dataSource) - }) - } else { - this.setState({ - columns - }) - } + this.setState({ + columns: this.getColumns(), + dataSource: data, + count: data.length + }, () => { + this.props.onChange(data) + }) } UNSAFE_componentWillReceiveProps (nextProps) { - if (!is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) || this.props.type !== nextProps.type) { - this.resetColumn(nextProps.type, nextProps.linkSubFields) + if (!is(fromJS(this.props.columns), fromJS(nextProps.columns))) { + this.setState({}, () => { + this.resetColumn() + }) } } render() { const { module } = this.props - const { dataSource } = this.state + const { dataSource, columns } = this.state const components = { body: { - row: EditableFormRow, cell: EditableCell } } - const columns = this.state.columns.map(col => { - if (!col.editable) { - return col - } - return { - ...col, - onCell: record => ({ - record, - editable: col.editable, - dataIndex: col.dataIndex, - title: col.title, - handleSave: this.handleSave - }) - } - }) + return ( <div className="common-modal-edit-table"> - <span className="add-row add-row-empty" onClick={this.handleEmpty}>{module === 'form' ? '绌�' : '鍏ㄩ儴'}</span> + {module ? <span className="add-row add-row-empty" onClick={this.handleEmpty}>{module === 'form' ? '绌�' : '鍏ㄩ儴'}</span> : null} <PlusOutlined className="add-row" onClick={this.handleAdd} /> - <Table - components={components} - rowClassName={(record) => record.Hide ? 'editable-row hide' : 'editable-row'} - bordered - dataSource={dataSource} - columns={columns} - pagination={false} - /> + <DndProvider> + <Table + components={components} + rowClassName={(record) => record.Hide ? 'editable-row hide' : 'editable-row'} + bordered + dataSource={dataSource} + columns={columns} + pagination={false} + /> + </DndProvider> </div> ) } diff --git a/src/templates/zshare/modalform/modaleditable/index.scss b/src/templates/zshare/modalform/modaleditable/index.scss index 7c097fd..3c93c9a 100644 --- a/src/templates/zshare/modalform/modaleditable/index.scss +++ b/src/templates/zshare/modalform/modaleditable/index.scss @@ -15,6 +15,15 @@ color: #1890ff; cursor: pointer; } + .mk-move-col { + text-align: center; + font-size: 16px; + cursor: move; + color: #c8c8c8; + } + .mk-source-wrap { + min-width: 150px; + } .ant-table-thead > tr > th { padding: 10px 16px; position: relative; @@ -23,7 +32,6 @@ position: absolute; right: 12px; font-size: 14px; - // top: 12px; color: #b8b8b8; } } @@ -52,7 +60,7 @@ } } .operation-btn { - margin-right: 10px; + margin-right: 15px; cursor: pointer; } .editable-row.hide { diff --git a/src/views/systemproc/proc/index.jsx b/src/views/systemproc/proc/index.jsx index 62ce63a..577e462 100644 --- a/src/views/systemproc/proc/index.jsx +++ b/src/views/systemproc/proc/index.jsx @@ -6,6 +6,7 @@ import Utils from '@/utils/utils.js' import Api from '@/api' import CodeMirror from '@/templates/zshare/codemirror' +import Transfer from '../transfer' import './index.scss' const { confirm } = Modal @@ -379,6 +380,7 @@ {!inputing ? <Search placeholder="璇疯緭鍏ュ瓨鍌ㄨ繃绋嬪悕绉�" defaultValue={procName} disabled={loading} enterButton="纭畾" onSearch={this.search}/> : null} </div> <div className="action-wrap"> + {!procName || loading || !content ? null : <Transfer procName={procName} content={content} />} <Button key="save" className="mk-btn mk-green" disabled={loading} onClick={() => this.save()}>淇濆瓨</Button> <Button key="prev" className="mk-btn mk-primary" disabled={!procName || loading} onClick={this.prev}>涓婁竴鐗堟湰</Button> <Button key="next" className="mk-btn mk-primary" disabled={!procName || loading} onClick={this.next}>涓嬩竴鐗堟湰</Button> diff --git a/src/views/systemproc/transfer/index.jsx b/src/views/systemproc/transfer/index.jsx new file mode 100644 index 0000000..1e44418 --- /dev/null +++ b/src/views/systemproc/transfer/index.jsx @@ -0,0 +1,289 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { DndProvider } from 'react-dnd' +import HTML5Backend from 'react-dnd-html5-backend' +import { Button, Modal, notification, Form, Select } from 'antd' + +import Utils from '@/utils/utils.js' +import Api from '@/api' +import asyncComponent from '@/utils/asyncComponent' +import './index.scss' + +const EditTable = asyncComponent(() => import('@/templates/zshare/modalform/modaleditable')) + +class TransferWrap extends Component { + static propTpyes = { + MenuID: PropTypes.string + } + + state = { + visible: false, + loading: false, + VersionName: '', + translist: [], + options: [] + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + verifySubmit = () => { + const { content, procName } = this.props + const { VersionName, options } = this.state + let value = content.replace(/^(\s*)|(\s*)$/ig, '') + + if (!VersionName) { + notification.warning({ + top: 92, + message: '璇烽�夋嫨浼犺緭鍙�', + duration: 5 + }) + return + } else if (!value) { + notification.warning({ + top: 92, + message: '瀛樺偍杩囩▼涓嶅彲涓虹┖', + duration: 5 + }) + return + } + + let regs = [] + options.forEach(item => { + if (item.origin && !/^\s+$/.test(item.origin) && item.origin !== item.value) { + regs.push({reg: new RegExp(item.origin, 'g'), value: item.value}) + } + }) + + regs.forEach(item => { + value = value.replace(item.reg, item.value) + }) + + let chars = [ + {key: 'drop', reg: /(^|\s)drop\s/ig}, + {key: 'alter', reg: /(^|\s)alter\s/ig}, + {key: 'object', reg: /(^|\s)object(\s|\()/ig}, + {key: 'kill', reg: /(^|\s)kill\s/ig}, + {key: '--', reg: /--/ig}, + {key: ',,', reg: /,,/ig} + ] + + let error = '' + + if (!/create(\s+)proc/ig.test(value)) { + error = '鑴氭湰涓繀椤讳娇鐢╟reate proc' + } + + chars.forEach(char => { + if (!error && char.reg.test(value)) { + error = '涓嶅彲浣跨敤' + char.key + } + }) + + if (error) { + notification.warning({ + top: 92, + message: error, + duration: 5 + }) + return + } + + let dropfunc = `IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('${procName}') AND type in (N'P', N'PC')) mdrpk PROCEDURE ${procName}` + + let dropParam = { + func: 's_sVersionDetail_Add', + BID: VersionName, + VType: 'VSQL', + VSQL: window.btoa(window.encodeURIComponent(dropfunc)) + } + + let addParam = { + func: 's_sVersionDetail_Add', + BID: VersionName, + VType: 'VSQL', + VSQL: window.btoa(window.encodeURIComponent(value)) + } + + this.setState({ + loading: true + }) + + Api.genericInterface(dropParam).then(result => { + if (!result.status) { + notification.warning({ + top: 92, + message: result.message, + duration: 5 + }) + this.setState({ + loading: false + }) + return + } + + delete result.status + delete result.message + delete result.ErrCode + delete result.ErrMesg + result.func = 's_sVersionDetail_CloudAdd' + + Api.genericInterface(addParam).then(res => { + if (!res.status) { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + this.setState({ + loading: false + }) + return + } + + delete res.status + delete res.message + delete res.ErrCode + delete res.ErrMesg + res.func = 's_sVersionDetail_CloudAdd' + + Api.getCloudConfig(result).then(re => { + if (!re.status) { + notification.warning({ + top: 92, + message: re.message, + duration: 5 + }) + this.setState({ + loading: false + }) + return + } + + Api.getCloudConfig(res).then(r => { + if (!r.status) { + notification.warning({ + top: 92, + message: r.message, + duration: 5 + }) + this.setState({ + loading: false + }) + return + } else { + notification.success({ + top: 92, + message: '娣诲姞鎴愬姛锛�', + duration: 3 + }) + this.setState({ + loading: false, + visible: false + }) + } + }) + }) + }) + }) + } + + getTransList = () => { + const { content } = this.props + let value = content.replace(/^(\s*)|(\s*)$/ig, '') + + if (!value) { + notification.warning({ + top: 92, + message: '瀛樺偍杩囩▼涓嶅彲涓虹┖', + duration: 5 + }) + return + } + + let param = { + func: 's_get_sVersion', + dataM: 'Y', + PageSize: 9999, + PageIndex: 1, + OrderCol: 'ID desc' + } + + let options = [] + + let list = value.match(/\s+[a-z0-9_]+\.(dbo)?\./ig) + list && list.forEach(str => { + str = str.replace(/^\s/, '') + options.push({ + key: Utils.getuuid(), + origin: str, + value: str + }) + }) + + this.setState({ + options: options, + VersionName: '', + visible: true, + loading: false + }) + + Api.getCloudConfig(param).then(result => { + if (result.status) { + this.setState({ + translist: result.data + }) + } else { + notification.warning({ + top: 92, + message: result.message, + duration: 5 + }) + } + }) + } + + changeOptions = (value) => { + this.setState({options: value}) + } + + render () { + const { visible, loading, translist, options } = this.state + const columns = [{ title: '鍘熶俊鎭�', key: 'origin', width: '50%', fixed: true }, { title: '鏇挎崲涓�', width: '50%', key: 'value' }] + + return ( + <> + <Button icon="pull-request" className="mk-border-green" onClick={this.getTransList}>浼犺緭鍙�</Button> + <Modal + title="鍔犲叆浼犺緭鍙�" + wrapClassName="proc-transfer" + visible={visible} + width={900} + maskClosable={false} + okText="纭畾" + onOk={this.verifySubmit} + onCancel={() => { this.setState({ visible: false }) }} + confirmLoading={loading} + destroyOnClose + > + <Form.Item label="浼犺緭鍙�"> + <Select onChange={(val) => this.setState({VersionName: val})}> + {translist.map(option => + <Select.Option key={option.VersionName} value={option.VersionName}>{`${option.ProgramName}(${option.VersionName})`}</Select.Option> + )} + </Select> + </Form.Item> + {options.length > 0 ? <DndProvider backend={HTML5Backend}> + <Form.Item label="鏇挎崲椤�"> + <EditTable type="proc" columns={columns} value={options} onChange={this.changeOptions}/> + </Form.Item> + </DndProvider> : null} + </Modal> + </> + ) + } +} + +export default TransferWrap \ No newline at end of file diff --git a/src/views/systemproc/transfer/index.scss b/src/views/systemproc/transfer/index.scss new file mode 100644 index 0000000..fbcf2ce --- /dev/null +++ b/src/views/systemproc/transfer/index.scss @@ -0,0 +1,18 @@ +.proc-transfer { + .ant-form-item { + display: flex; + .ant-form-item-control-wrapper { + flex: 10; + + .ant-select { + width: 300px; + } + } + } + .operation-btn { + display: none; + } + .add-row { + display: none; + } +} \ No newline at end of file diff --git a/src/views/tabledesign/source.jsx b/src/views/tabledesign/source.jsx index 5e43351..058c775 100644 --- a/src/views/tabledesign/source.jsx +++ b/src/views/tabledesign/source.jsx @@ -186,6 +186,18 @@ }, { type: 'col', + label: '鑷畾涔夊垪', + subType: 'custom', + $init: true + }, + { + type: 'col', + label: '鍏紡', + subType: 'formula', + $init: true + }, + { + type: 'col', label: '鍥剧墖', subType: 'picture', $init: true @@ -210,20 +222,8 @@ }, { type: 'col', - label: '鑷畾涔夊垪', - subType: 'custom', - $init: true - }, - { - type: 'col', label: '鍚堝苟鍒�', subType: 'colspan', - $init: true - }, - { - type: 'col', - label: '鍏紡', - subType: 'formula', $init: true }, { -- Gitblit v1.8.0