1 文件已重命名
18个文件已修改
5个文件已删除
5个文件已添加
| | |
| | | MenuNo: 'bd_msn_sms_tempM', |
| | | MenuName: '大于短信模板', |
| | | text: '大于短信模板' |
| | | }, { |
| | | src: '', |
| | | PageParam: {OpenType: 'newtab', Template: 'ManageTable'}, |
| | | type: 'ManageTable', |
| | | MenuID: '1599613340050c8nu6rbst9d4emnnbsq', |
| | | MenuNo: 's_sms_qxM', |
| | | MenuName: '奇云短信模板', |
| | | text: '奇云短信模板' |
| | | }] |
| | | }, { |
| | | MenuID: 'systemPayManage', |
| | |
| | | return item |
| | | }) |
| | | |
| | | // 整理数据源自定义脚本 |
| | | let _customScript = '' |
| | | config.scripts && config.scripts.forEach(script => { |
| | | if (script.status !== 'false') { |
| | | _customScript += ` |
| | | ${script.sql} |
| | | ` |
| | | } |
| | | }) |
| | | |
| | | config.setting.customScript = _customScript |
| | | |
| | | // 数据源 |
| | | if (config.setting.interType === 'inner' && !config.setting.innerFunc) { |
| | | config.setting.interType = 'system' |
| | | } |
| | | |
| | | if (config.setting.interType === 'system') { |
| | | // 整理数据源自定义脚本 |
| | | let _customScript = '' |
| | | config.scripts && config.scripts.forEach(script => { |
| | | if (script.status !== 'false') { |
| | | _customScript += ` |
| | | ${script.sql} |
| | | ` |
| | | } |
| | | }) |
| | | |
| | | if (/\s/.test(config.setting.dataresource)) { |
| | | config.setting.dataresource = '(' + config.setting.dataresource + ') tb' |
| | | } |
| | | |
| | | if (this.props.dataManager) { // 数据权限 |
| | | config.setting.dataresource = config.setting.dataresource.replace(/\$@/ig, '/*') |
| | | config.setting.dataresource = config.setting.dataresource.replace(/@\$/ig, '*/') |
| | | _customScript = _customScript.replace(/\$@/ig, '/*') |
| | | _customScript = _customScript.replace(/@\$/ig, '*/') |
| | | } else { |
| | | config.setting.dataresource = config.setting.dataresource.replace(/@\$|\$@/ig, '') |
| | | _customScript = _customScript.replace(/@\$|\$@/ig, '') |
| | | } |
| | | |
| | | config.setting.customScript = _customScript |
| | | } |
| | | |
| | | this.setState({ |
| | |
| | | const { arr_field, search, setting, config, calendarYear } = this.state |
| | | |
| | | let _search = Utils.joinMainSearchkey(search) |
| | | |
| | | _search = _search ? 'where ' + _search : '' |
| | | |
| | | let param = { |
| | | func: 'sPC_Get_TableData', |
| | | obj_name: 'data', |
| | | arr_field: arr_field, |
| | | custom_script: setting.customScript || '', |
| | | default_sql: setting.default || 'true' |
| | | custom_script: setting.customScript, |
| | | default_sql: setting.execute || 'true' |
| | | } |
| | | |
| | | let _dataresource = setting.dataresource |
| | | |
| | | if (/\s/.test(_dataresource)) { |
| | | _dataresource = '(' + _dataresource + ') tb' |
| | | } |
| | | |
| | | if (this.props.dataManager) { // 数据权限 |
| | | _dataresource = _dataresource.replace(/\$@/ig, '/*') |
| | | _dataresource = _dataresource.replace(/@\$/ig, '*/') |
| | | param.custom_script = param.custom_script.replace(/\$@/ig, '/*') |
| | | param.custom_script = param.custom_script.replace(/@\$/ig, '*/') |
| | | } else { |
| | | _dataresource = _dataresource.replace(/@\$|\$@/ig, '') |
| | | param.custom_script = param.custom_script.replace(/@\$|\$@/ig, '') |
| | | } |
| | | |
| | | let regoptions = null |
| | | if (setting.queryType === 'statistics' || param.custom_script) { |
| | | let allSearch = Utils.getAllSearchOptions(search) |
| | |
| | | }) |
| | | } |
| | | |
| | | if (setting.queryType === 'statistics' && setting.default !== 'false') { // 统计数据源,内容替换 |
| | | if (setting.queryType === 'statistics' && setting.execute !== 'false') { // 统计数据源,内容替换 |
| | | regoptions.forEach(item => { |
| | | _dataresource = _dataresource.replace(item.reg, item.value) |
| | | }) |
| | |
| | | |
| | | let LText = '' |
| | | |
| | | if (setting.default !== 'false') { |
| | | if (setting.execute !== 'false') { |
| | | LText = `select ${arr_field} from ${_dataresource} ${_search}` |
| | | } |
| | | |
| | |
| | | config.setting.execute = config.setting.default !== 'false' // 默认sql是否执行,转为boolean 统一格式 |
| | | config.setting.customScript = '' // 自定义脚本 |
| | | |
| | | if (config.setting.scripts && config.setting.scripts.length > 0) { |
| | | let _customScript = '' |
| | | config.setting.scripts.forEach(item => { |
| | | if (item.status === 'false') return |
| | | _customScript += ` |
| | | ${item.sql} |
| | | ` |
| | | }) |
| | | config.setting.customScript = _customScript |
| | | // 数据源 |
| | | if (config.setting.interType === 'inner' && !config.setting.innerFunc) { |
| | | config.setting.interType = 'system' |
| | | } |
| | | |
| | | if (!config.setting.execute) { // 默认sql 不执行时 置空 |
| | | config.setting.dataresource = '' |
| | | } else { |
| | | config.setting.dataresource = config.setting.dataresource || '' |
| | | } |
| | | if (/\s/.test(config.setting.dataresource)) { |
| | | config.setting.dataresource = '(' + config.setting.dataresource + ') tb' |
| | | } |
| | | |
| | | if (this.props.dataManager) { // 数据权限 |
| | | config.setting.dataresource = config.setting.dataresource.replace(/\$@/ig, '/*') |
| | | config.setting.dataresource = config.setting.dataresource.replace(/@\$/ig, '*/') |
| | | config.setting.customScript = config.setting.customScript.replace(/\$@/ig, '/*') |
| | | config.setting.customScript = config.setting.customScript.replace(/@\$/ig, '*/') |
| | | } else { |
| | | config.setting.dataresource = config.setting.dataresource.replace(/@\$|\$@/ig, '') |
| | | config.setting.customScript = config.setting.customScript.replace(/@\$|\$@/ig, '') |
| | | if (config.setting.interType === 'system') { |
| | | if (config.setting.scripts && config.setting.scripts.length > 0) { |
| | | let _customScript = '' |
| | | config.setting.scripts.forEach(item => { |
| | | if (item.status === 'false') return |
| | | _customScript += ` |
| | | ${item.sql} |
| | | ` |
| | | }) |
| | | config.setting.customScript = _customScript |
| | | } |
| | | |
| | | if (!config.setting.execute) { // 默认sql 不执行时 置空 |
| | | config.setting.dataresource = '' |
| | | } else { |
| | | config.setting.dataresource = config.setting.dataresource || '' |
| | | } |
| | | if (/\s/.test(config.setting.dataresource)) { |
| | | config.setting.dataresource = '(' + config.setting.dataresource + ') tb' |
| | | } |
| | | |
| | | if (this.props.dataManager) { // 数据权限 |
| | | config.setting.dataresource = config.setting.dataresource.replace(/\$@/ig, '/*') |
| | | config.setting.dataresource = config.setting.dataresource.replace(/@\$/ig, '*/') |
| | | config.setting.customScript = config.setting.customScript.replace(/\$@/ig, '/*') |
| | | config.setting.customScript = config.setting.customScript.replace(/@\$/ig, '*/') |
| | | } else { |
| | | config.setting.dataresource = config.setting.dataresource.replace(/@\$|\$@/ig, '') |
| | | config.setting.customScript = config.setting.customScript.replace(/@\$|\$@/ig, '') |
| | | } |
| | | } |
| | | |
| | | this.setState({ |
| | |
| | | pasteContent: null |
| | | }) |
| | | }) |
| | | } else if (res.type === 'replace') { |
| | | let config = fromJS(this.state.config).toJS() |
| | | |
| | | if (res.repType === 'field') { |
| | | let origin = res.origin.toLowerCase() |
| | | let value = res.value |
| | | |
| | | config.search = config.search.map(item => { |
| | | if (item.field && item.field.toLowerCase() === origin) { |
| | | item.field = value |
| | | } else if (item.datefield && item.datefield.toLowerCase() === origin) { |
| | | item.datefield = value |
| | | } |
| | | return item |
| | | }) |
| | | config.columns = config.columns.map(item => { |
| | | if (item.field && item.field.toLowerCase() === origin) { |
| | | item.field = value |
| | | } else if (item.nameField && item.nameField.toLowerCase() === origin) { |
| | | item.nameField = value |
| | | } |
| | | return item |
| | | }) |
| | | } |
| | | |
| | | notification.success({ |
| | | top: 92, |
| | | message: '替换成功。', |
| | | duration: 2 |
| | | }) |
| | | this.setState({ config }) |
| | | } |
| | | } |
| | | |
| | |
| | | import { queryTableSql } from '@/utils/option.js' |
| | | |
| | | import ModalForm from '@/templates/zshare/modalform' |
| | | import PasteForm from '@/templates/zshare/pasteform' |
| | | import DragElement from './dragelement' |
| | | import SourceElement from './dragelement/source' |
| | | import SettingForm from './settingform' |
| | | import GroupForm from './groupform' |
| | | import EditCard from './editcard' |
| | | import MenuForm from './menuform' |
| | | import EditComponent from '@/templates/zshare/editcomponent' |
| | | import { BaseConfig, SearchItems } from './source' |
| | | import './index.scss' |
| | | |
| | |
| | | curgroup: null, // 当前组,新建或编辑 |
| | | optionLibs: null, // 自定义下拉选项库 |
| | | sources: null, // 表单类型 |
| | | pasteVisible: null, // 表单粘贴 |
| | | sqlVerifing: false, // sql验证 |
| | | openEdition: '' // 编辑版本标记,防止多人操作 |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | pasteSubmit = () => { |
| | | let _config = JSON.parse(JSON.stringify(this.state.config)) |
| | | |
| | | this.pasteFormRef.handleConfirm().then(res => { |
| | | if (res.copyType === 'form') { |
| | | if (_config.groups.length > 0) { |
| | | _config.groups.forEach(group => { |
| | | if (group.default) { |
| | | group.sublist.push(res) |
| | | } |
| | | }) |
| | | } else { |
| | | _config.fields.push(res) |
| | | } |
| | | |
| | | if (!this.props.editTab && res.type === 'linkMain') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不支持此表单类型!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | config: _config, |
| | | pasteVisible: null |
| | | }, () => { |
| | | this.handleForm(res, 'edit') |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '配置信息格式错误!', |
| | | duration: 10 |
| | | }) |
| | | } |
| | | }) |
| | | /** |
| | | * @description 编辑功能完成更新,包括解冻按钮、粘贴、替换等 |
| | | */ |
| | | updateConfig = (res) => { |
| | | if (res.type === 'paste') { |
| | | this.setState({ |
| | | config: res.content |
| | | }) |
| | | } |
| | | } |
| | | |
| | | render () { |
| | |
| | | <div className="setting"> |
| | | <Card title={this.state.dict['header.menu.form.configurable']} bordered={false} extra={ |
| | | <div> |
| | | <EditComponent dict={this.state.dict} type="form" config={this.state.config} refresh={this.updateConfig}/> |
| | | <Button type="primary" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['model.save']}</Button> |
| | | <Button onClick={this.cancelConfig}>{this.state.dict['model.back']}</Button> |
| | | </div> |
| | |
| | | <div className="ant-modal-title">{config.setting.title}</div> |
| | | </div> |
| | | <div className="ant-modal-body"> |
| | | <Icon className="paste-Icon" type="snippets" title={this.state.dict['header.form.paste']} onClick={() => {this.setState({pasteVisible: true})}} /> |
| | | <div className="modal-form"> |
| | | {config.groups.length > 0 && |
| | | config.groups.map(group => { |
| | |
| | | group={this.state.curgroup} |
| | | inputSubmit={this.handleGroupSave} |
| | | wrappedComponentRef={(inst) => this.groupRef = inst} |
| | | /> |
| | | </Modal> |
| | | {/* 按钮配置信息粘贴复制 */} |
| | | <Modal |
| | | title={this.state.dict['header.form.paste']} |
| | | visible={this.state.pasteVisible} |
| | | width={600} |
| | | maskClosable={false} |
| | | onOk={this.pasteSubmit} |
| | | onCancel={() => {this.setState({pasteVisible: null})}} |
| | | destroyOnClose |
| | | > |
| | | <PasteForm |
| | | dict={this.state.dict} |
| | | wrappedComponentRef={(inst) => this.pasteFormRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Tabs, Table, Popconfirm, Icon, notification, Modal, Typography, Spin } from 'antd' |
| | | import { Form, Tabs, Table, Popconfirm, Icon, notification, Modal, Spin } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import ColForm from './columnform' |
| | | import CustomScriptsForm from './customscript' |
| | | import CustomScript from '@/templates/zshare/customscript' |
| | | import SettingForm from './settingform' |
| | | import SettingUtils from './utils' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | const { Paragraph } = Typography |
| | | |
| | | const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent')) |
| | | |
| | |
| | | columns: [], |
| | | activeKey: 'setting', |
| | | loading: false, |
| | | initsql: '', // sql验证时变量声明及赋值 |
| | | usefulfields: '', |
| | | defaultsql: '', // 默认Sql |
| | | systemScripts: [{ |
| | | name: '默认sql', |
| | | value: '' |
| | | }], |
| | | colColumns: [ |
| | | { |
| | | title: '名称', |
| | |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | (<div> |
| | | <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record, 'columns')} style={{color: '#1890ff'}}><Icon type="edit" /></span> |
| | | <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record)} style={{color: '#1890ff'}}><Icon type="edit" /></span> |
| | | <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | | onConfirm={() => this.deleteColumn(record) |
| | | }> |
| | | <span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | </div>) |
| | | } |
| | | ], |
| | | scriptsColumns: [ |
| | | { |
| | | title: 'SQL', |
| | | dataIndex: 'sql', |
| | | width: '60%', |
| | | render: (text) => ( |
| | | <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph> |
| | | ) |
| | | }, |
| | | { |
| | | title: '状态', |
| | | dataIndex: 'status', |
| | | width: '20%', |
| | | render: (text, record) => record.status === 'false' ? |
| | | ( |
| | | <div> |
| | | {this.props.dict['model.status.forbidden']} |
| | | <Icon style={{marginLeft: '5px'}} type="stop" theme="twoTone" twoToneColor="#ff4d4f" /> |
| | | </div> |
| | | ) : |
| | | ( |
| | | <div> |
| | | {this.props.dict['model.status.open']} |
| | | <Icon style={{marginLeft: '5px'}} type="check-circle" theme="twoTone" twoToneColor="#52c41a" /> |
| | | </div> |
| | | ) |
| | | }, |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | width: '20%', |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | (<div> |
| | | <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><Icon type="edit" /></span> |
| | | <span className="operation-btn" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <span className="operation-btn" title={this.props.dict['model.status.change']} onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><Icon type="swap" /></span> |
| | | <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | | onConfirm={() => this.deleteScript(record) |
| | | }> |
| | | <span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | |
| | | UNSAFE_componentWillMount() { |
| | | const { config } = this.props |
| | | |
| | | let _setting = fromJS(config.setting).toJS() |
| | | if (_setting.interType === 'inner' && !_setting.innerFunc) { |
| | | _setting.interType = 'system' |
| | | } |
| | | |
| | | this.setState({ |
| | | setting: _setting, |
| | | setting: fromJS(config.setting).toJS(), |
| | | columns: fromJS(config.columns).toJS(), |
| | | scripts: fromJS(config.scripts).toJS() |
| | | }) |
| | | |
| | | this.getsysScript() |
| | | } |
| | | |
| | | getsysScript = () => { |
| | | let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort` |
| | | |
| | | _scriptSql = Utils.formatOptions(_scriptSql) |
| | | |
| | | let _sParam = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: _scriptSql, |
| | | obj_name: 'data', |
| | | arr_field: 'funcname,longparam' |
| | | } |
| | | |
| | | _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp) |
| | | _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 云端数据验证 |
| | | |
| | | Api.getSystemConfig(_sParam).then(res => { |
| | | if (res.status) { |
| | | let _scripts = [] |
| | | |
| | | res.data.forEach(item => { |
| | | let _item = { |
| | | name: item.funcname, |
| | | value: Utils.UnformatOptions(item.longparam) |
| | | } |
| | | |
| | | _scripts.push(_item) |
| | | }) |
| | | |
| | | this.setState({ |
| | | systemScripts: [...this.state.systemScripts, ..._scripts] |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | |
| | | this.setState({ columns: this.state.columns.filter(item => item.uuid !== record.uuid) }) |
| | | } |
| | | |
| | | deleteScript = (record) => { |
| | | this.setState({ scripts: this.state.scripts.filter(item => item.uuid !== record.uuid) }) |
| | | } |
| | | handleEdit = (record) => { |
| | | this.contrastForm.edit(record) |
| | | |
| | | handleEdit = (record, type) => { |
| | | if (type === 'scripts') { |
| | | this.scriptsForm.edit(record) |
| | | } else if (type === 'columns') { |
| | | this.contrastForm.edit(record) |
| | | } |
| | | |
| | | let node = document.getElementById('model-verify-card-box-tab').parentNode |
| | | let node = document.getElementById('model-setting-form-body').parentNode |
| | | |
| | | if (node && node.scrollTop) { |
| | | let inter = Math.ceil(node.scrollTop / 10) |
| | |
| | | } |
| | | } |
| | | |
| | | handleStatus = (record) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | record.status = record.status === 'false' ? 'true' : 'false' |
| | | |
| | | scripts = scripts.map(item => { |
| | | if (item.uuid === record.uuid) { |
| | | return record |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | |
| | | this.setState({ scripts }) |
| | | } |
| | | |
| | | handleUpDown = (record, direction) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | let index = 0 |
| | | |
| | | scripts = scripts.filter((item, i) => { |
| | | if (item.uuid === record.uuid) { |
| | | index = i |
| | | } |
| | | |
| | | return item.uuid !== record.uuid |
| | | }) |
| | | if ((index === 0 && direction === 'up') || (index === scripts.length && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | scripts.splice(index - 1, 0, record) |
| | | } else { |
| | | scripts.splice(index + 1, 0, record) |
| | | } |
| | | |
| | | this.setState({ scripts }) |
| | | } |
| | | |
| | | scriptsChange = (values) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | |
| | | if (values.uuid) { |
| | | scripts = scripts.map(item => { |
| | | if (item.uuid === values.uuid) { |
| | | return values |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } else { |
| | | scripts.push(values) |
| | | } |
| | | |
| | | return new Promise((resolve, reject) => { |
| | | this.sqlverify(resolve, reject, false, scripts) |
| | | }) |
| | | } |
| | | |
| | | scriptSubmit = (values) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | |
| | | if (values.uuid) { |
| | | scripts = scripts.map(item => { |
| | | if (item.uuid === values.uuid) { |
| | | return values |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } else { |
| | | values.uuid = Utils.getuuid() |
| | | scripts.push(values) |
| | | } |
| | | |
| | | this.setState({ scripts }) |
| | | } |
| | | |
| | | changeTab = (val) => { |
| | | const { activeKey, setting } = this.state |
| | | |
| | | this.setState({loading: true}) |
| | | if (activeKey === 'setting') { |
| | | this.settingForm.handleConfirm().then(res => { |
| | | if (res.interType !== 'system' && val === 'scripts') { |
| | |
| | | message: '使用系统接口时,才可以设置自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | return |
| | | } |
| | | |
| | |
| | | setting: res |
| | | }, () => { |
| | | if (res.interType === 'system') { // 系统接口,sql验证 |
| | | this.setState({loading: true}) |
| | | |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | activeKey: val, |
| | |
| | | }, activeKey) |
| | | } else { |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | activeKey: val |
| | | }) |
| | | } |
| | | }) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | }) |
| | | } else if (activeKey === 'columns') { |
| | | if (setting.interType !== 'system' && val === 'scripts') { |
| | |
| | | message: '使用系统接口时,才可以设置自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | return |
| | | } else if (setting.interType !== 'system') { |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | }, activeKey) |
| | | this.setState({ |
| | | activeKey: val |
| | | }) |
| | | } else if (activeKey === 'scripts') { |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({loading: true}) |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | activeKey: val, |
| | |
| | | sqlverify = (resolve, reject, type, testScripts) => { |
| | | const { searches } = this.props |
| | | const { columns, setting, scripts } = this.state |
| | | |
| | | if (setting.interType !== 'system') { // 不使用系统接口时,不需要sql验证 |
| | | resolve() |
| | | return |
| | | } |
| | | |
| | | let _scripts = [] |
| | | |
| | | if (testScripts) { |
| | |
| | | _scripts = scripts.filter(item => item.status !== 'false') |
| | | } |
| | | |
| | | if (type === 'submit' && setting.interType === 'system' && setting.execute === 'false' && _scripts.length === 0) { |
| | | if (type === 'submit' && setting.execute === 'false' && _scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | |
| | | } |
| | | |
| | | // 不使用默认sql切换 |
| | | if (type === 'setting' && setting.interType === 'system' && setting.execute === 'false') { |
| | | if (type === 'setting' && setting.execute === 'false') { |
| | | resolve() |
| | | } else if (type === 'scripts' && _scripts.length === 0) { |
| | | resolve() |
| | | } else if (setting.interType === 'system' && (setting.execute !== 'false' || _scripts.length > 0)) { |
| | | } else if (setting.execute !== 'false' || _scripts.length > 0) { |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | LText: SettingUtils.getDebugSql(setting, _scripts, columns, searches) |
| | |
| | | }) |
| | | } |
| | | |
| | | // 自定义脚本修改 |
| | | scriptsChange = (scripts) => { |
| | | return new Promise((resolve, reject) => { |
| | | this.sqlverify(resolve, reject, 'verify', scripts) |
| | | }) |
| | | } |
| | | |
| | | // 自定义脚本更新 |
| | | scriptsUpdate = (scripts) => { |
| | | this.setState({scripts}) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新 |
| | | */ |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading } = this.state |
| | | const { columns, setting, scripts, colColumns, activeKey, loading } = this.state |
| | | |
| | | return ( |
| | | <div id="model-verify-card-box-tab"> |
| | | <div className="model-verify-card-box-tab" id="model-setting-form-body"> |
| | | {loading && <Spin size="large" />} |
| | | <Tabs activeKey={activeKey} className="verify-card-box" onChange={this.changeTab}> |
| | | <TabPane tab="数据源" key="setting"> |
| | |
| | | /> |
| | | </TabPane> |
| | | <TabPane tab="自定义脚本" key="scripts"> |
| | | <CustomScriptsForm |
| | | setting={setting} |
| | | searches={this.props.searches} |
| | | initsql={this.state.initsql} |
| | | <CustomScript |
| | | dict={this.props.dict} |
| | | customScripts={scripts} |
| | | systemScripts={this.state.systemScripts} |
| | | setting={setting} |
| | | scripts={scripts} |
| | | defaultSql={this.state.defaultsql} |
| | | searches={this.props.searches} |
| | | scriptsChange={this.scriptsChange} |
| | | scriptSubmit={this.scriptSubmit} |
| | | scriptsUpdate={this.scriptsUpdate} |
| | | wrappedComponentRef={(inst) => this.scriptsForm = inst} |
| | | /> |
| | | <Table |
| | | bordered |
| | | rowKey="uuid" |
| | | className="custom-table" |
| | | dataSource={scripts} |
| | | columns={scriptsColumns} |
| | | pagination={false} |
| | | /> |
| | | </TabPane> |
| | | </Tabs> |
| | |
| | | #model-verify-card-box-tab { |
| | | .model-verify-card-box-tab { |
| | | .ant-spin { |
| | | position: absolute; |
| | | left: calc(50% - 16px); |
| | |
| | | ` |
| | | } |
| | | |
| | | if (setting.interType === 'inner' && !setting.innerFunc && setting.execute !== 'false') { |
| | | if (setting.execute !== 'false') { |
| | | _dataresource = setting.dataresource |
| | | } |
| | | |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Modal, Button, notification } from 'antd' |
| | | import { Icon, Modal, Button } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import DevUtils from '@/utils/devutils.js' |
| | |
| | | const { config } = this.props |
| | | const { menu } = this.state |
| | | |
| | | this.settingRef.handleConfirm(true).then(setting => { |
| | | if (setting.interType !== 'inner' || !setting.innerFunc) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用内部接口,且存在内部函数时,才可以创建存储过程!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.settingRef.handleConfirm('func').then(setting => { |
| | | let _config = {...config, setting: setting} |
| | | |
| | | let newLText = Utils.formatOptions(DevUtils.getTableFunc(setting, menu, _config)) // 创建存储过程sql |
| | | let DelText = Utils.formatOptions(DevUtils.dropfunc(setting.innerFunc)) // 删除存储过程sql |
| | | |
| | |
| | | const { config } = this.props |
| | | const { menu } = this.state |
| | | |
| | | this.settingRef.handleConfirm(true).then(setting => { |
| | | if (setting.interType !== 'system') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用系统接口时,才可以创建接口!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.settingRef.handleConfirm('interface').then(setting => { |
| | | let _config = {...config, setting: setting} |
| | | let _menu = { |
| | | type: config.Template === 'CommonTable' ? 'main' : 'subtable', |
| | |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | type={config.Template === 'CommonTable' ? 'main' : 'subtable'} |
| | | dict={dict} |
| | | menu={menu} |
| | | config={config} |
| | | search={search} |
| | | permFuncField={permFuncField} |
| | | inputSubmit={this.settingSave} |
| | | wrappedComponentRef={(inst) => this.settingRef = inst} |
| | | /> |
| | | </Modal> |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Icon, notification, Modal, Spin, Tabs, Table, Popconfirm, Typography } from 'antd' |
| | | import { Form, notification, Modal, Spin, Tabs } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import SettingUtils from './utils.jsx' |
| | | import CustomScript from './customscript' |
| | | import CustomScript from '@/templates/zshare/customscript' |
| | | import DataSource from './datasource' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | const { Paragraph } = Typography |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | type: PropTypes.string, // 菜单类型 |
| | | dict: PropTypes.object, // 字典项 |
| | | menu: PropTypes.object, // 菜单信息 |
| | | config: PropTypes.object, // 页面配置信息 |
| | | permFuncField: PropTypes.array, // 自定义函数可用字段 |
| | | search: PropTypes.array, // 搜索条件 |
| | | inputSubmit: PropTypes.any // 回车提交事件 |
| | | search: PropTypes.array // 搜索条件 |
| | | } |
| | | |
| | | state = { |
| | |
| | | arr_field: '', |
| | | regoptions: [], |
| | | setting: null, |
| | | view: 'normal', |
| | | defaultSql: '', |
| | | systemScripts: [], |
| | | scriptsColumns: [ |
| | | { |
| | | title: 'SQL', |
| | | dataIndex: 'sql', |
| | | width: '70%', |
| | | render: (text) => ( |
| | | <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph> |
| | | ) |
| | | }, |
| | | { |
| | | title: '状态', |
| | | dataIndex: 'status', |
| | | width: '10%', |
| | | render: (text, record) => record.status === 'false' ? |
| | | ( |
| | | <div> |
| | | {this.props.dict['model.status.forbidden']} |
| | | <Icon style={{marginLeft: '5px'}} type="stop" theme="twoTone" twoToneColor="#ff4d4f" /> |
| | | </div> |
| | | ) : |
| | | ( |
| | | <div> |
| | | {this.props.dict['model.status.open']} |
| | | <Icon style={{marginLeft: '5px'}} type="check-circle" theme="twoTone" twoToneColor="#52c41a" /> |
| | | </div> |
| | | ) |
| | | }, |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | width: '20%', |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | (<div> |
| | | <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record)} style={{color: '#1890ff'}}><Icon type="edit" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><Icon type="swap" /></span> |
| | | <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | | onConfirm={() => this.handleDelete(record) |
| | | }> |
| | | <span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | </div>) |
| | | } |
| | | ] |
| | | defaultSql: '' |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | this.getsysScript() |
| | | } |
| | | |
| | | getsysScript = () => { |
| | | let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort` |
| | | |
| | | _scriptSql = Utils.formatOptions(_scriptSql) |
| | | |
| | | let _sParam = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: _scriptSql, |
| | | obj_name: 'data', |
| | | arr_field: 'funcname,longparam' |
| | | } |
| | | |
| | | _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp) |
| | | _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 云端数据验证 |
| | | |
| | | Api.getSystemConfig(_sParam).then(res => { |
| | | if (res.status) { |
| | | let _scripts = res.data.map(item => { |
| | | let _item = { |
| | | name: item.funcname, |
| | | value: Utils.UnformatOptions(item.longparam) |
| | | } |
| | | return _item |
| | | }) |
| | | |
| | | this.setState({ |
| | | systemScripts: _scripts |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | handleConfirm = (trigger) => { |
| | | const { activeKey, setting, scripts } = this.state |
| | | |
| | | if (trigger) { |
| | | this.setState({loading: true}) |
| | | } |
| | | |
| | | // 表单提交时检查输入值是否正确 |
| | | if (activeKey === 'setting') { |
| | | return new Promise((resolve, reject) => { |
| | | this.settingForm.handleConfirm().then(res => { |
| | | if (res.interType === 'system' && res.default === 'false' && scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | setting: res |
| | | }, () => { |
| | | this.sqlverify(() => { |
| | | this.setState({loading: false}) |
| | | resolve({...res, scripts}) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | reject() |
| | | }, true) |
| | | }) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | }) |
| | | }) |
| | | } else { |
| | | return new Promise((resolve, reject) => { |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) { |
| | | _loading = true |
| | | } |
| | | |
| | | if (_loading) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | reject() |
| | | } else if (setting.interType === 'system' && setting.default === 'false' && scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | reject() |
| | | } else { |
| | | this.sqlverify(() => { |
| | | this.setState({loading: false}) |
| | | resolve({...setting, scripts}) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | reject() |
| | | }, true) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | getCustomScript = (setting) => { |
| | | let _customScript = '' |
| | | if (setting.scripts && setting.scripts.length > 0) { |
| | | setting.scripts.forEach(item => { |
| | | if (item.status === 'false') return |
| | | _customScript += ` |
| | | ${item.sql} |
| | | ` |
| | | }) |
| | | } |
| | | |
| | | if (_customScript) { |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg ='' |
| | | ${_customScript} |
| | | ` |
| | | } |
| | | |
| | | return _customScript |
| | | } |
| | | |
| | | sqlverify = (_resolve, _reject, force) => { |
| | | const { setting, scripts, arr_field, regoptions, search } = this.state |
| | | |
| | | if (setting.interType !== 'system') { // 不使用系统接口时,不需要sql验证 |
| | | _resolve() |
| | | } |
| | | if (force || (setting.interType === 'system' && setting.default !== 'false')) { |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | LText: SettingUtils.getDebugSql(setting, scripts, arr_field, regoptions, search) |
| | | } |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | | |
| | | Api.getLocalConfig(param).then(result => { |
| | | if (result.status) { |
| | | _resolve() |
| | | } else { |
| | | _reject() |
| | | Modal.error({ |
| | | title: result.message |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | _resolve() |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 获取全部搜索条件 |
| | | * @param {Array} searches 搜索条件数组 |
| | |
| | | return newsearches |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | handleConfirm = (trigger) => { |
| | | const { activeKey, setting, scripts } = this.state |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | if (trigger) { |
| | | this.setState({loading: true}) |
| | | } |
| | | } |
| | | |
| | | handleEdit = (record) => { |
| | | this.scriptsForm.edit(record) |
| | | let _scripts = scripts.filter(script => script.status !== 'false') |
| | | |
| | | this.scrolltop() |
| | | } |
| | | // 表单提交时检查输入值是否正确 |
| | | if (activeKey === 'setting') { |
| | | return new Promise((resolve, reject) => { |
| | | this.settingForm.handleConfirm().then(res => { |
| | | if (trigger === 'func' && res.interType !== 'inner') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用内部接口,才可以创建存储过程!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | reject() |
| | | return |
| | | } else if (trigger === 'interface' && res.interType !== 'system') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用系统接口时,才可以创建接口!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | reject() |
| | | return |
| | | } else if (res.interType === 'system' && res.default === 'false' && _scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | |
| | | scrolltop = () => { |
| | | let node = document.getElementById('model-table-setting-form-box').parentNode |
| | | |
| | | if (node && node.scrollTop) { |
| | | let inter = Math.ceil(node.scrollTop / 10) |
| | | |
| | | let timer = setInterval(() => { |
| | | if (node.scrollTop - inter > 0) { |
| | | node.scrollTop = node.scrollTop - inter |
| | | } else { |
| | | node.scrollTop = 0 |
| | | clearInterval(timer) |
| | | this.setState({ |
| | | setting: res |
| | | }, () => { |
| | | this.sqlverify(() => { |
| | | this.setState({loading: false}) |
| | | resolve({...res, scripts}) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | reject() |
| | | }, 'submit') |
| | | }) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | reject() |
| | | }) |
| | | }) |
| | | } else { |
| | | return new Promise((resolve, reject) => { |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) { |
| | | _loading = true |
| | | } |
| | | }, 10) |
| | | |
| | | if (trigger === 'func' && setting.interType !== 'inner') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用内部接口,才可以创建存储过程!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | reject() |
| | | } else if (_loading) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | reject() |
| | | } else if (setting.interType === 'system' && setting.default === 'false' && _scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | reject() |
| | | } else { |
| | | this.sqlverify(() => { |
| | | this.setState({loading: false}) |
| | | resolve({...setting, scripts}) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | reject() |
| | | }, 'submit') |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | handleUpDown = (record, direction) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | let index = 0 |
| | | sqlverify = (_resolve, _reject, type, uscripts) => { |
| | | const { setting, scripts, arr_field, regoptions, search } = this.state |
| | | |
| | | scripts = scripts.filter((item, i) => { |
| | | if (item.uuid === record.uuid) { |
| | | index = i |
| | | } |
| | | |
| | | return item.uuid !== record.uuid |
| | | }) |
| | | if ((index === 0 && direction === 'up') || (index === scripts.length && direction === 'down')) { |
| | | if (setting.interType !== 'system') { // 不使用系统接口时,不需要sql验证 |
| | | _resolve() |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | scripts.splice(index - 1, 0, record) |
| | | let _scripts = [] |
| | | if (uscripts) { // 过滤禁用的脚本 |
| | | _scripts = uscripts.filter(script => script.status !== 'false') |
| | | } else { |
| | | scripts.splice(index + 1, 0, record) |
| | | _scripts = scripts.filter(script => script.status !== 'false') |
| | | } |
| | | |
| | | this.setState({scripts}) |
| | | } |
| | | |
| | | handleStatus = (record) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | record.status = record.status === 'false' ? 'true' : 'false' |
| | | |
| | | scripts = scripts.map(item => { |
| | | if (item.uuid === record.uuid) { |
| | | return record |
| | | } else { |
| | | return item |
| | | if (type === 'setting' && setting.default === 'false') { |
| | | _resolve() |
| | | } else if (type === 'scripts' && _scripts.length === 0) { |
| | | _resolve() |
| | | } else { // type 为 submit 、 verify ,以及其他需要验证的场景 |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | LText: SettingUtils.getDebugSql(setting, _scripts, arr_field, regoptions, search) |
| | | } |
| | | }) |
| | | |
| | | this.setState({scripts}) |
| | | } |
| | | |
| | | handleDelete = (record) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | scripts = scripts.filter(item => item.uuid !== record.uuid) |
| | | |
| | | this.setState({ scripts }) |
| | | } |
| | | |
| | | scriptsChange = (values) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | |
| | | if (values.uuid) { |
| | | scripts = scripts.map(item => { |
| | | if (item.uuid === values.uuid) { |
| | | return values |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | | |
| | | Api.getLocalConfig(param).then(result => { |
| | | if (result.status) { |
| | | _resolve() |
| | | } else { |
| | | return item |
| | | _reject() |
| | | Modal.error({ |
| | | title: result.message |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | values.uuid = Utils.getuuid() |
| | | scripts.push(values) |
| | | } |
| | | |
| | | this.setState({scripts}) |
| | | } |
| | | |
| | | // 标签切换 |
| | | changeTab = (val) => { |
| | | const { activeKey, search, arr_field } = this.state |
| | | |
| | | if (activeKey === 'setting') { |
| | | this.setState({loading: true}) |
| | | |
| | | let _defaultSql = '' |
| | | this.settingForm.handleConfirm().then(res => { |
| | | if (res.interType !== 'system') { |
| | |
| | | message: '使用系统接口时,才可以设置自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | return |
| | | } |
| | | |
| | | if (res.dataresource) { |
| | | let _dataresource = res.dataresource |
| | | |
| | | if (/\s/.test(_dataresource)) { |
| | | _dataresource = '(' + _dataresource + ') tb' |
| | | } |
| | | |
| | | _defaultSql = `select top @pageSize@ ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by @orderBy@) as rows from ${_dataresource} ${search}) tmptable where rows > (@pageSize@ * (@pageIndex@ - 1)) order by tmptable.rows` |
| | | } |
| | | |
| | | this.setState({ |
| | | setting: res |
| | | setting: res, |
| | | defaultSql: _defaultSql |
| | | }, () => { |
| | | if (res.dataresource) { |
| | | let _dataresource = res.dataresource |
| | | |
| | | if (/\s/.test(_dataresource)) { |
| | | _dataresource = '(' + _dataresource + ') tb' |
| | | } |
| | | |
| | | _defaultSql = `select top @pageSize@ ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by @orderBy@) as rows from ${_dataresource} ${search}) tmptable where rows > (@pageSize@ * (@pageIndex@ - 1)) order by tmptable.rows` |
| | | } |
| | | |
| | | this.setState({loading: true}) |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | activeKey: val, |
| | | defaultSql: _defaultSql, |
| | | loading: false |
| | | }) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | }) |
| | | }, activeKey) |
| | | }) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | }) |
| | | } else if (activeKey === 'scripts') { |
| | | let _loading = false |
| | |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | activeKey: val |
| | | }) |
| | | |
| | | this.setState({loading: true}) |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | }, activeKey) |
| | | } |
| | | } |
| | | |
| | | // 自定义脚本修改 |
| | | scriptsChange = (scripts) => { |
| | | return new Promise((resolve, reject) => { |
| | | this.sqlverify(resolve, reject, 'verify', scripts) |
| | | }) |
| | | } |
| | | |
| | | // 自定义脚本更新 |
| | | scriptsUpdate = (scripts) => { |
| | | this.setState({scripts}) |
| | | } |
| | | |
| | | render() { |
| | | const { type, menu, dict, permFuncField } = this.props |
| | | const { loading, activeKey, setting, scriptsColumns, systemScripts, arr_field, defaultSql, regoptions, search, columns, scripts } = this.state |
| | | const { config, menu, dict, permFuncField } = this.props |
| | | const { loading, activeKey, setting, defaultSql, columns, scripts } = this.state |
| | | |
| | | return ( |
| | | <div className="model-table-setting-form-box" id="model-table-setting-form-box"> |
| | | <div className="model-table-setting-form-box" id="model-setting-form-body"> |
| | | {loading && <Spin size="large" />} |
| | | <Tabs activeKey={activeKey} className="verify-card-box" onChange={this.changeTab}> |
| | | <TabPane tab="数据源" key="setting"> |
| | | <DataSource |
| | | type={type} |
| | | type={config.Template === 'CommonTable' ? 'main' : ''} |
| | | menu={menu} |
| | | dict={dict} |
| | | columns={columns} |
| | |
| | | </TabPane> |
| | | <TabPane tab="自定义脚本" key="scripts"> |
| | | <CustomScript |
| | | type={type} |
| | | dict={dict} |
| | | swhere={search} |
| | | setting={setting} |
| | | scripts={scripts} |
| | | arr_field={arr_field} |
| | | defaultSql={defaultSql} |
| | | regoptions={regoptions} |
| | | searches={this.props.search} |
| | | systemScripts={systemScripts} |
| | | scriptsChange={this.scriptsChange} |
| | | scriptsUpdate={this.scriptsUpdate} |
| | | wrappedComponentRef={(inst) => this.scriptsForm = inst} |
| | | /> |
| | | <Table |
| | | bordered |
| | | rowKey="uuid" |
| | | className="custom-table" |
| | | dataSource={scripts} |
| | | columns={scriptsColumns} |
| | | pagination={false} |
| | | /> |
| | | </TabPane> |
| | | </Tabs> |
| | |
| | | let _dataresource = setting.dataresource |
| | | let _customScript = '' |
| | | scripts && scripts.forEach(script => { |
| | | if (script.status !== 'false') { |
| | | _customScript += ` |
| | | ${script.sql} |
| | | ` |
| | | } |
| | | _customScript += ` |
| | | ${script.sql} |
| | | ` |
| | | }) |
| | | |
| | | if (_customScript) { |
| | |
| | | ` |
| | | } |
| | | |
| | | if (setting.interType === 'system' && setting.default === 'false') { |
| | | if (setting.default === 'false') { |
| | | _dataresource = '' |
| | | } |
| | | |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Icon, Modal, Button, notification } from 'antd' |
| | | import { Icon, Modal } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import DevUtils from '@/utils/devutils.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import { getTreeSettingForm } from '@/templates/zshare/formconfig' |
| | | |
| | | import SettingForm from './settingform' |
| | | import CreateFunc from '@/templates/zshare/createfunc' |
| | | import CreateInterface from '@/templates/zshare/createinterface' |
| | | |
| | | import './index.scss' |
| | | |
| | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | menu: null, // 菜单信息 |
| | | formlist: null, // 表单信息 |
| | | visible: false, // 模态框控制 |
| | | loading: false // 设置信息验证保存中 |
| | | } |
| | |
| | | * @description 全局设置触发 |
| | | */ |
| | | changeSetting = () => { |
| | | const { MenuID, config, permFuncField } = this.props |
| | | const { MenuID, config } = this.props |
| | | let menu = {MenuID: MenuID, MenuName: config.MenuName, MenuNo: config.MenuNo} |
| | | |
| | | let _config = fromJS(config).toJS() |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | formlist: getTreeSettingForm(config.setting, permFuncField, MenuID), |
| | | menu: menu, |
| | | config: _config |
| | | menu: menu |
| | | }) |
| | | } |
| | | |
| | |
| | | loading: false |
| | | }) |
| | | |
| | | delete res.customScript // 清除整理后的自定义脚本 |
| | | |
| | | this.props.updatesetting({...config, setting: res}) |
| | | }, () => { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 创建表格存储过程 |
| | | */ |
| | | tableCreatFunc = () => { |
| | | const { config } = this.props |
| | | const { menu } = this.state |
| | | |
| | | this.settingRef.handleConfirm().then(setting => { |
| | | |
| | | if (!(setting.interType === 'inner') || !setting.innerFunc) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '接口类型为-内部,且存在内部函数时,才可以创建存储过程!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _config = {...config, setting: setting} |
| | | let newLText = Utils.formatOptions(DevUtils.getTableFunc(setting, menu, _config)) // 创建存储过程sql |
| | | let DelText = Utils.formatOptions(DevUtils.dropfunc(setting.innerFunc)) // 删除存储过程sql |
| | | |
| | | this.refs.funcCreatComponent.exec(setting.innerFunc, newLText, DelText).then(result => { |
| | | if (result === 'success') { |
| | | this.props.updatesetting(_config) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 创建表格接口(读出) |
| | | */ |
| | | tableCreatInterface = () => { |
| | | const { config } = this.props |
| | | const { menu } = this.state |
| | | |
| | | this.settingRef.handleConfirm().then(setting => { |
| | | if (setting.interType !== 'inner' || setting.innerFunc) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '接口类型为-内部,且不存在内部函数时,才可以创建接口!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _config = {...config, setting: setting} |
| | | let _menu = { |
| | | type: 'main', |
| | | MenuID: menu.MenuID, |
| | | menuName: menu.MenuName, |
| | | menuNo: menu.MenuNo |
| | | } |
| | | |
| | | this.refs.tableCreatInterface.triggerOutInterface(_menu, _config) |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { dict, visible, config } = this.state |
| | | const { config } = this.props |
| | | const { dict, visible, loading } = this.state |
| | | |
| | | return ( |
| | | <div className="model-tree-menu-setting"> |
| | |
| | | width={900} |
| | | maskClosable={false} |
| | | onCancel={() => { this.setState({ visible: false })}} |
| | | footer={[ |
| | | <CreateInterface key="interface" dict={dict} ref="tableCreatInterface" trigger={this.tableCreatInterface}/>, |
| | | <CreateFunc key="create" dict={dict} ref="funcCreatComponent" trigger={this.tableCreatFunc}/>, |
| | | <Button key="cancel" onClick={() => { this.setState({ visible: false }) }}>{this.state.dict['model.cancel']}</Button>, |
| | | <Button key="confirm" type="primary" loading={this.state.loading} onClick={this.settingSave}>{this.state.dict['model.confirm']}</Button> |
| | | ]} |
| | | confirmLoading={loading} |
| | | onOk={this.settingSave} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | |
| | | config={config} |
| | | menu={this.state.menu} |
| | | inputSubmit={this.settingSave} |
| | | formlist={this.state.formlist} |
| | | permFuncField={this.props.permFuncField} |
| | | wrappedComponentRef={(inst) => this.settingRef = inst} |
| | | /> |
| | | </Modal> |
| | |
| | | .ant-modal-body { |
| | | max-height: calc(100vh - 190px); |
| | | overflow-y: auto; |
| | | padding-top: 10px; |
| | | } |
| | | .ant-modal-body::-webkit-scrollbar { |
| | | width: 7px; |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Radio, Tooltip, Icon, notification, InputNumber } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | | import { formRule } from '@/utils/option.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import CodeMirror from '@/templates/zshare/codemirror' |
| | | import './index.scss' |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | menu: PropTypes.object, // 菜单信息 |
| | | permFuncField: PropTypes.any, // 存储过程可用开始字符 |
| | | setting: PropTypes.object, // 数据源配置 |
| | | inputSubmit: PropTypes.func // 触发提交 |
| | | } |
| | | |
| | | state = { |
| | | interType: 'system', |
| | | funcTooltip: '', |
| | | funcRules: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { setting, permFuncField } = this.props |
| | | |
| | | let tooltip = null |
| | | let rules = [] |
| | | |
| | | if (permFuncField && permFuncField.length > 0) { |
| | | tooltip = '开头可用字符:' + permFuncField.join(', ') |
| | | let str = '^(' + permFuncField.join('|') + ')' |
| | | let _patten = new RegExp(str + formRule.func.innerPattern + '$', 'g') |
| | | |
| | | rules.push({ |
| | | pattern: _patten, |
| | | message: formRule.func.innerMessage |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | interType: setting.interType || 'system', |
| | | funcTooltip: tooltip, |
| | | funcRules: rules |
| | | }) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | const { setting } = this.props |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | // 数据源前端验证 |
| | | if (values.interType === 'system' && values.default !== 'false' && !values.dataresource) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请填写数据源!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } else if (values.interType === 'system' && values.default !== 'false' && values.dataresource) { |
| | | let _quot = values.dataresource.match(/'{1}/g) |
| | | let _lparen = values.dataresource.match(/\({1}/g) |
| | | let _rparen = values.dataresource.match(/\){1}/g) |
| | | |
| | | _quot = _quot ? _quot.length : 0 |
| | | _lparen = _lparen ? _lparen.length : 0 |
| | | _rparen = _rparen ? _rparen.length : 0 |
| | | |
| | | if (_quot % 2 !== 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '数据源中\'必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } else if (_lparen !== _rparen) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '数据源中()必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } else if (/--/ig.test(values.dataresource)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '数据源中,不可出现字符 -- ,注释请用 /*内容*/', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | |
| | | let error = Utils.verifySql(values.dataresource) |
| | | |
| | | if (error) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '数据源中不可使用' + error, |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | } |
| | | |
| | | // 数据源保存 |
| | | if ( |
| | | values.interType === 'system' && values.default !== 'false' && |
| | | /[^\s]+\s+[^\s]+/ig.test(values.dataresource) && setting.dataresource !== values.dataresource |
| | | ) { |
| | | let param = { |
| | | func: 's_DataSrc_Save', |
| | | LText: values.dataresource, |
| | | MenuID: this.props.menu.MenuID |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | | |
| | | Api.getLocalConfig(param) |
| | | } |
| | | |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | onRadioChange = (e, key) => { |
| | | let value = e.target.value |
| | | |
| | | if (key === 'interType') { |
| | | this.setState({ |
| | | interType: value |
| | | }) |
| | | } else if (key === 'sysInterface') { |
| | | if (value === 'true') { |
| | | this.props.form.setFieldsValue({ |
| | | interface: window.GLOB.mainSystemApi || '' |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { setting, dict, menu } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { interType, funcRules, funcTooltip } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="model-table-datasource-setting-form-box"> |
| | | <Form {...formItemLayout} className="model-setting-form"> |
| | | <Row gutter={24}> |
| | | <Col span={12}> |
| | | <Form.Item label="表名"> |
| | | {getFieldDecorator('tableName', { |
| | | initialValue: setting.tableName || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + '表名!' |
| | | }, |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit}/>)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="标题"> |
| | | {getFieldDecorator('title', { |
| | | initialValue: setting.title || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + '标题!' |
| | | }, |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={dict['header.form.intertype']}> |
| | | {getFieldDecorator('interType', { |
| | | initialValue: interType, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.select'] + dict['header.form.intertype'] + '!' |
| | | } |
| | | ] |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.onRadioChange(e, 'interType')}}> |
| | | <Radio value="system">系统</Radio> |
| | | <Radio value="inner">内部</Radio> |
| | | <Radio value="outer">外部</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | {interType === 'outer' ? <Col span={12}> |
| | | <Form.Item label={dict['header.form.sysInterface']}> |
| | | {getFieldDecorator('sysInterface', { |
| | | initialValue: setting.sysInterface || 'false', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.select'] + dict['header.form.sysInterface'] + '!' |
| | | }, |
| | | ] |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.onRadioChange(e, 'sysInterface')}}> |
| | | <Radio value="true">{dict['model.true']}</Radio> |
| | | <Radio value="false">{dict['model.false']}</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {interType === 'inner' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={funcTooltip}> |
| | | <Icon type="question-circle" /> |
| | | 内部函数 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('innerFunc', { |
| | | initialValue: setting.innerFunc || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + '内部函数!' |
| | | }, |
| | | { |
| | | max: formRule.func.max, |
| | | message: formRule.func.maxMessage |
| | | }, |
| | | ...funcRules |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {interType === 'outer' ? <Col span={12}> |
| | | <Form.Item label="接口地址"> |
| | | {getFieldDecorator('interface', { |
| | | initialValue: setting.interface || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + '接口地址!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {interType === 'outer' ? <Col span={12}> |
| | | <Form.Item label="外部函数"> |
| | | {getFieldDecorator('outerFunc', { |
| | | initialValue: setting.outerFunc || '', |
| | | rules: [ |
| | | { |
| | | pattern: formRule.func.pattern, |
| | | message: formRule.func.message |
| | | }, { |
| | | max: formRule.func.max, |
| | | message: formRule.func.maxMessage |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {interType === 'system' ? <Col span={24} className="data-source" style={{paddingLeft: '7px'}}> |
| | | <Form.Item help={'数据ID:' + menu.MenuID} labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } label={ |
| | | <Tooltip placement="topLeft" title={'使用系统函数时,需填写数据源。注:数据权限替换符 $@ -> /* 或 \'\'、 @$ -> */ 或 \'\''}> |
| | | <Icon type="question-circle" /> |
| | | 数据源 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('dataresource', { |
| | | initialValue: setting.dataresource || '' |
| | | })(<CodeMirror />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'数据值字段。'}> |
| | | <Icon type="question-circle" /> |
| | | Value |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('valueField', { |
| | | initialValue: setting.valueField || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + 'Value!' |
| | | }, |
| | | { |
| | | pattern: formRule.field.pattern, |
| | | message: formRule.field.message |
| | | }, { |
| | | max: formRule.field.max, |
| | | message: formRule.field.maxMessage |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'显示文字字段。'}> |
| | | <Icon type="question-circle" /> |
| | | Label |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('labelField', { |
| | | initialValue: setting.labelField || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + 'Label!' |
| | | }, |
| | | { |
| | | pattern: formRule.field.pattern, |
| | | message: formRule.field.message |
| | | }, { |
| | | max: formRule.field.max, |
| | | message: formRule.field.maxMessage |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'父级字段。'}> |
| | | <Icon type="question-circle" /> |
| | | Parent |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('parentField', { |
| | | initialValue: setting.parentField || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + 'Label!' |
| | | }, |
| | | { |
| | | pattern: formRule.field.pattern, |
| | | message: formRule.field.message |
| | | }, { |
| | | max: formRule.field.max, |
| | | message: formRule.field.maxMessage |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="排序"> |
| | | {getFieldDecorator('order', { |
| | | initialValue: setting.order || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + '排序!' |
| | | }, |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | } |
| | | ] |
| | | })(<Input placeholder={'ID asc, UID desc'} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'父级字段值与顶级标识(默认值为空)相同时,视为顶级节点。'}> |
| | | <Icon type="question-circle" /> |
| | | 顶级标识 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('mark', { |
| | | initialValue: setting.mark || '', |
| | | rules: [ |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'每行分为24份,树形比例可设置为2-12(最大50%)'}> |
| | | <Icon type="question-circle" /> |
| | | 宽度 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('width', { |
| | | initialValue: setting.width || 5, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + '宽度!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={2} max={12} precision={0} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="搜索"> |
| | | {getFieldDecorator('searchable', { |
| | | initialValue: setting.searchable || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">显示</Radio> |
| | | <Radio value="false">隐藏</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | {interType === 'system' ? <Col span={12}> |
| | | <Form.Item label="默认sql"> |
| | | {getFieldDecorator('default', { |
| | | initialValue: setting.default || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">执行</Radio> |
| | | <Radio value="false">不执行</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={12}> |
| | | <Form.Item label="显示图标"> |
| | | {getFieldDecorator('showIcon', { |
| | | initialValue: setting.showIcon || 'false' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">是</Radio> |
| | | <Radio value="false">否</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="显示分割线"> |
| | | {getFieldDecorator('showLine', { |
| | | initialValue: setting.showLine || 'false' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">是</Radio> |
| | | <Radio value="false">否</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
New file |
| | |
| | | .model-table-datasource-setting-form-box { |
| | | position: relative; |
| | | |
| | | .model-setting-form { |
| | | .data-source { |
| | | .ant-form-item-label { |
| | | width: 16.5%; |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | width: 83.5%; |
| | | } |
| | | .CodeMirror { |
| | | height: 150px; |
| | | } |
| | | } |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Input, Radio, Select, Tooltip, Icon, notification, InputNumber, Modal, Table, Popconfirm, Typography, Button } from 'antd' |
| | | import { Form, notification, Modal, Spin, Tabs } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import SettingUtils from './utils.jsx' |
| | | import CustomScript from './customscript' |
| | | import CodeMirror from '@/templates/zshare/codemirror' |
| | | import DataSource from './datasource' |
| | | import CustomScript from '@/templates/zshare/customscript' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | const { Paragraph } = Typography |
| | | const { TabPane } = Tabs |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | type: PropTypes.string, // 菜单类型 |
| | | dict: PropTypes.object, // 字典项 |
| | | menu: PropTypes.object, // 菜单信息 |
| | | config: PropTypes.object, // 页面配置信息 |
| | | formlist: PropTypes.array, // 表单信息 |
| | | inputSubmit: PropTypes.any // 回车提交事件 |
| | | dict: PropTypes.object, // 字典项 |
| | | menu: PropTypes.object, // 菜单信息 |
| | | config: PropTypes.object, // 页面配置信息 |
| | | permFuncField: PropTypes.array, // 存储过程可用字段 |
| | | inputSubmit: PropTypes.any // 回车提交事件 |
| | | } |
| | | |
| | | state = { |
| | | formlist: [], |
| | | btnloading: false, |
| | | loading: false, |
| | | setting: null, |
| | | view: 'normal', |
| | | systemScripts: [{ |
| | | name: '默认sql', |
| | | value: '' |
| | | }], |
| | | scriptsColumns: [ |
| | | { |
| | | title: 'SQL', |
| | | dataIndex: 'sql', |
| | | width: '70%', |
| | | render: (text) => ( |
| | | <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph> |
| | | ) |
| | | }, |
| | | { |
| | | title: '状态', |
| | | dataIndex: 'status', |
| | | width: '10%', |
| | | render: (text, record) => record.status === 'false' ? |
| | | ( |
| | | <div> |
| | | {this.props.dict['model.status.forbidden']} |
| | | <Icon style={{marginLeft: '5px'}} type="stop" theme="twoTone" twoToneColor="#ff4d4f" /> |
| | | </div> |
| | | ) : |
| | | ( |
| | | <div> |
| | | {this.props.dict['model.status.open']} |
| | | <Icon style={{marginLeft: '5px'}} type="check-circle" theme="twoTone" twoToneColor="#52c41a" /> |
| | | </div> |
| | | ) |
| | | }, |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | width: '20%', |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | (<div> |
| | | <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record)} style={{color: '#1890ff'}}><Icon type="edit" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><Icon type="swap" /></span> |
| | | <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | | onConfirm={() => this.handleDelete(record) |
| | | }> |
| | | <span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | </div>) |
| | | } |
| | | ] |
| | | defaultsql: '', |
| | | activeKey: 'setting', |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | let _formlist = fromJS(this.props.formlist).toJS() |
| | | let interType = 'inner' |
| | | const { config } = this.props |
| | | |
| | | _formlist.forEach(item => { |
| | | if (item.key === 'interType') { |
| | | interType = item.initVal |
| | | } |
| | | }) |
| | | |
| | | let _setting = fromJS(this.props.config.setting).toJS() |
| | | _setting.scripts = _setting.scripts || [] |
| | | _setting.default = _setting.default || 'true' |
| | | let _setting = fromJS(config.setting).toJS() |
| | | let _scripts = _setting.scripts || [] |
| | | |
| | | this.setState({ |
| | | setting: _setting, |
| | | formlist: _formlist.map(item => { |
| | | if (interType === 'inner' && ['sysInterface', 'interface', 'outerFunc'].includes(item.key)) { |
| | | item.hidden = true |
| | | } else if (interType === 'outer' && ['innerFunc', 'dataresource', 'queryType'].includes(item.key)) { |
| | | item.hidden = true |
| | | } |
| | | |
| | | return item |
| | | }) |
| | | scripts: _scripts |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | this.getsysScript() |
| | | } |
| | | |
| | | getsysScript = () => { |
| | | let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort` |
| | | |
| | | _scriptSql = Utils.formatOptions(_scriptSql) |
| | | |
| | | let _sParam = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: _scriptSql, |
| | | obj_name: 'data', |
| | | arr_field: 'funcname,longparam' |
| | | } |
| | | handleConfirm = () => { |
| | | const { activeKey, setting, scripts } = this.state |
| | | |
| | | _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp) |
| | | _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 云端数据验证 |
| | | |
| | | Api.getSystemConfig(_sParam).then(res => { |
| | | if (res.status) { |
| | | let _scripts = res.data.map(item => { |
| | | let _item = { |
| | | name: item.funcname, |
| | | value: Utils.UnformatOptions(item.longparam) |
| | | } |
| | | let _scripts = scripts.filter(script => script.status !== 'false') |
| | | |
| | | return _item |
| | | }) |
| | | |
| | | this.setState({ |
| | | systemScripts: [...this.state.systemScripts, ..._scripts] |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | handleConfirm = (otype) => { |
| | | const { menu } = this.props |
| | | const { view, setting } = this.state |
| | | // 表单提交时检查输入值是否正确 |
| | | |
| | | if (view !== 'custom') { |
| | | if (activeKey === 'setting') { |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | values = {...setting, ...values} |
| | | |
| | | // 数据源前端验证 |
| | | if (values.interType === 'inner' && !values.innerFunc && values.default !== 'false' && !values.dataresource) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请填写内部函数或数据源!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } else if (values.interType === 'inner' && !values.innerFunc && values.default !== 'false' && values.dataresource) { |
| | | let error = Utils.verifySql(values.dataresource) |
| | | |
| | | if (error) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '数据源中不可使用' + error, |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | } |
| | | |
| | | // 数据源保存 |
| | | if ( |
| | | values.interType === 'inner' && !values.innerFunc && |
| | | values.default !== 'false' && |
| | | /[^\s]+\s+[^\s]+/ig.test(values.dataresource) && |
| | | this.props.config.setting.dataresource !== values.dataresource |
| | | ) { |
| | | let param = { |
| | | func: 's_DataSrc_Save', |
| | | LText: values.dataresource, |
| | | MenuID: menu.MenuID |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | | |
| | | Api.getLocalConfig(param) |
| | | } |
| | | |
| | | if (otype === 'change') { |
| | | this.setState({ |
| | | setting: values, |
| | | }, () => { |
| | | resolve() |
| | | }) |
| | | } else { |
| | | values.customScript = this.getCustomScript(values) |
| | | |
| | | this.sqlverify(values, resolve, reject) |
| | | } |
| | | } else { |
| | | reject(err) |
| | | this.settingForm.handleConfirm().then(res => { |
| | | if (res.interType === 'system' && res.default === 'false' && _scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | setting: res |
| | | }, () => { |
| | | this.sqlverify(() => { resolve({...res, scripts}) }, reject, 'submit') |
| | | }) |
| | | }, () => { |
| | | reject() |
| | | }) |
| | | }) |
| | | } else { |
| | | let _setting = fromJS(this.state.setting).toJS() |
| | | _setting.customScript = this.getCustomScript(_setting) |
| | | |
| | | let _this = this |
| | | |
| | | return new Promise((resolve, reject) => { |
| | | if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) { |
| | | confirm({ |
| | | content: `存在未保存项,确定提交吗?`, |
| | | onOk() { |
| | | _this.sqlverify(_setting, resolve, reject) |
| | | }, |
| | | onCancel() { |
| | | reject() |
| | | } |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) { |
| | | _loading = true |
| | | } |
| | | |
| | | if (_loading) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | } else if (setting.interType === 'system' && setting.default === 'false' && _scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | } else { |
| | | this.sqlverify(_setting, resolve, reject) |
| | | this.sqlverify(() => { |
| | | resolve({...setting, scripts}) |
| | | }, () => { |
| | | reject() |
| | | }, 'submit') |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | getCustomScript = (setting) => { |
| | | let _customScript = '' |
| | | if (setting.scripts && setting.scripts.length > 0) { |
| | | setting.scripts.forEach(item => { |
| | | if (item.status === 'false') return |
| | | _customScript += ` |
| | | ${item.sql} |
| | | ` |
| | | }) |
| | | } |
| | | sqlverify = (_resolve, _reject, type, uscripts) => { |
| | | const { setting, scripts } = this.state |
| | | |
| | | if (_customScript) { |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg ='' |
| | | ${_customScript} |
| | | ` |
| | | } |
| | | |
| | | return _customScript |
| | | } |
| | | |
| | | sqlverify = (_setting, _resolve, _reject, isChange = false) => { |
| | | if (!isChange && _setting.interType === 'inner' && !_setting.innerFunc && _setting.default === 'false' && !_setting.customScript) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | _reject() |
| | | if (setting.interType !== 'system') { // 不使用系统接口时,不需要sql验证 |
| | | _resolve() |
| | | return |
| | | } |
| | | |
| | | if (_setting.interType === 'inner' && !_setting.innerFunc && _setting.default !== 'false') { |
| | | let _scripts = [] |
| | | if (uscripts) { // 过滤禁用的脚本 |
| | | _scripts = uscripts.filter(script => script.status !== 'false') |
| | | } else { |
| | | _scripts = scripts.filter(script => script.status !== 'false') |
| | | } |
| | | |
| | | if (type === 'setting' && setting.default === 'false') { |
| | | _resolve() |
| | | } else if (type === 'scripts' && _scripts.length === 0) { |
| | | _resolve() |
| | | } else { // type 为 submit 、 verify ,以及其他需要验证的场景 |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | LText: SettingUtils.getDebugSql(_setting) |
| | | LText: SettingUtils.getDebugSql(setting, _scripts) |
| | | } |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | |
| | | |
| | | Api.getLocalConfig(param).then(result => { |
| | | if (result.status) { |
| | | _resolve(_setting) |
| | | _resolve() |
| | | } else { |
| | | _reject() |
| | | Modal.error({ |
| | |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | _resolve(_setting) |
| | | } |
| | | } |
| | | |
| | | selectChange = (key, val) => { |
| | | if (key === 'primaryKey' && val) { |
| | | this.props.form.setFieldsValue({ |
| | | order: `${val} desc` |
| | | }) |
| | | } |
| | | } |
| | | changeTab = (val) => { |
| | | const { activeKey } = this.state |
| | | |
| | | onRadioChange = (e, key) => { |
| | | let value = e.target.value |
| | | let _formlist = fromJS(this.state.formlist).toJS() |
| | | |
| | | if (key === 'interType') { |
| | | this.setState({ |
| | | formlist: _formlist.map(item => { |
| | | item.hidden = false |
| | | |
| | | if (value === 'inner' && ['sysInterface', 'interface', 'outerFunc'].includes(item.key)) { |
| | | item.initVal = this.props.form.getFieldValue(item.key) |
| | | item.hidden = true |
| | | } else if (value === 'outer' && ['innerFunc', 'dataresource', 'queryType'].includes(item.key)) { |
| | | item.initVal = this.props.form.getFieldValue(item.key) |
| | | item.hidden = true |
| | | } |
| | | |
| | | return item |
| | | }) |
| | | }) |
| | | } else if (key === 'sysInterface') { |
| | | if (value === 'true') { |
| | | this.props.form.setFieldsValue({ |
| | | interface: window.GLOB.mainSystemApi || '' |
| | | }) |
| | | } |
| | | this.setState({ |
| | | formlist: _formlist.map(item => { |
| | | if (item.key === 'interface') { |
| | | item.readonly = value === 'true' |
| | | } |
| | | |
| | | return item |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | changeView = () => { |
| | | const { view } = this.state |
| | | let _this = this |
| | | |
| | | if (view === 'normal') { |
| | | this.handleConfirm('change').then(() => { |
| | | const { setting } = this.state |
| | | |
| | | if (setting.interType !== 'inner' || (setting.interType === 'inner' && setting.innerFunc)) { |
| | | if (activeKey === 'setting') { |
| | | this.settingForm.handleConfirm().then(res => { |
| | | if (res.interType !== 'system') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用外部接口或内部接口的自定义函数,不可添加自定义设置!', |
| | | message: '使用系统接口时,才可以设置自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _dataresource = setting.dataresource |
| | | let _defaultSql = '' |
| | | if (res.dataresource) { |
| | | let _dataresource = res.dataresource |
| | | let arr_field = `${res.valueField},${res.labelField},${res.parentField}` |
| | | |
| | | if (/\s/.test(_dataresource)) { |
| | | _dataresource = '(' + _dataresource + ') tb' |
| | | if (/\s/.test(_dataresource)) { |
| | | _dataresource = '(' + _dataresource + ') tb' |
| | | } |
| | | |
| | | _defaultSql = ` select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${res.order}) as rows from ${_dataresource}) tmptable order by tmptable.rows ` |
| | | } |
| | | |
| | | let arr_field = `${setting.valueField}, ${setting.labelField}, ${setting.parentField}` |
| | | |
| | | let LText = `select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by @orderBy@) as rows from ${_dataresource}) tmptable order by tmptable.rows` |
| | | let _scripts = fromJS(this.state.systemScripts).toJS() |
| | | _scripts[0].value = LText |
| | | |
| | | |
| | | if (setting.default === 'false') { |
| | | this.setState({ |
| | | view: 'custom', |
| | | btnloading: false, |
| | | systemScripts: _scripts |
| | | }) |
| | | this.scrolltop() |
| | | } else { |
| | | this.setState({ |
| | | btnloading: true |
| | | }) |
| | | new Promise((resolve, reject) => { |
| | | this.sqlverify(setting, resolve, reject, true) |
| | | }).then(() => { |
| | | this.setState({ |
| | | setting: res, |
| | | defaultsql: _defaultSql |
| | | }, () => { |
| | | this.setState({loading: true}) |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | view: 'custom', |
| | | btnloading: false, |
| | | systemScripts: _scripts |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | this.scrolltop() |
| | | }, () => { |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | btnloading: false |
| | | loading: false |
| | | }) |
| | | }) |
| | | } |
| | | }, activeKey) |
| | | }) |
| | | }) |
| | | } else { |
| | | let _loading = false |
| | | |
| | | if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) { |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) { |
| | | _loading = true |
| | | } |
| | | |
| | | if (_loading) { |
| | | confirm({ |
| | | content: `存在未保存项,确定切换吗?`, |
| | | onOk() { |
| | | _this.setState({ |
| | | view: 'normal' |
| | | }) |
| | | |
| | | _this.scrolltop() |
| | | }, |
| | | onCancel() {} |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | duration: 5 |
| | | }) |
| | | } else { |
| | | _this.setState({ |
| | | view: 'normal' |
| | | return |
| | | } |
| | | this.setState({loading: true}) |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | |
| | | _this.scrolltop() |
| | | } |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | }, activeKey) |
| | | } |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | getFields(formlist) { |
| | | const { getFieldDecorator } = this.props.form |
| | | const fields = [] |
| | | |
| | | formlist.forEach((item, index) => { |
| | | if (item.hidden || item.forbid) return |
| | | |
| | | if (item.type === 'text') { // 文本搜索 |
| | | let rules = item.rules || [] |
| | | |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement={item.placement || 'topLeft'} title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal || '', |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | }, |
| | | ...rules |
| | | ] |
| | | })(<Input placeholder={item.placeholder || ''} autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'number') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal || 6, |
| | | rules: [ |
| | | { |
| | | required: item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={item.min} max={item.max} precision={0} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'select') { // 下拉搜索 |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.label}> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal || '', |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | } |
| | | ] |
| | | })( |
| | | <Select |
| | | showSearch |
| | | filterOption={(input, option) => { |
| | | return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 || |
| | | option.props.value.toLowerCase().indexOf(input.toLowerCase()) >= 0 |
| | | }} |
| | | onChange={(value) => {this.selectChange(item.key, value)}} |
| | | getPopupContainer={() => document.getElementById('model-table-setting-form')} |
| | | > |
| | | {item.options.map((option, i) => |
| | | <Select.Option id={i} key={i} value={option.value}> |
| | | {option.text} |
| | | </Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'radio') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | } |
| | | ] |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.onRadioChange(e, item.key)}}> |
| | | { |
| | | item.options.map((option, i) => { |
| | | return ( |
| | | <Radio key={i} value={option.value}>{option.text}</Radio> |
| | | ) |
| | | }) |
| | | } |
| | | </Radio.Group>, |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'datasource') { |
| | | fields.push( |
| | | <Col span={24} key={index} style={{paddingLeft: '7px'}}> |
| | | <Form.Item className="text-area" labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } help={item.help} label={ |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal |
| | | })(<CodeMirror />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'multiselect') { // 多选 |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.label}> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal || [] |
| | | })( |
| | | <Select |
| | | showSearch |
| | | mode="multiple" |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | > |
| | | {item.options.map((option, i) => |
| | | <Select.Option id={i} key={i} value={option.value}>{option.text}</Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } |
| | | }) |
| | | |
| | | return fields |
| | | } |
| | | |
| | | handleEdit = (record) => { |
| | | this.scriptsForm.edit(record) |
| | | |
| | | this.scrolltop() |
| | | } |
| | | |
| | | scrolltop = () => { |
| | | let node = document.getElementById('model-tree-setting-form-box').parentNode |
| | | |
| | | if (node && node.scrollTop) { |
| | | let inter = Math.ceil(node.scrollTop / 10) |
| | | |
| | | let timer = setInterval(() => { |
| | | if (node.scrollTop - inter > 0) { |
| | | node.scrollTop = node.scrollTop - inter |
| | | } else { |
| | | node.scrollTop = 0 |
| | | clearInterval(timer) |
| | | } |
| | | }, 10) |
| | | } |
| | | } |
| | | |
| | | handleUpDown = (record, direction) => { |
| | | let scripts = fromJS(this.state.setting.scripts).toJS() |
| | | let index = 0 |
| | | |
| | | scripts = scripts.filter((item, i) => { |
| | | if (item.uuid === record.uuid) { |
| | | index = i |
| | | } |
| | | |
| | | return item.uuid !== record.uuid |
| | | }) |
| | | if ((index === 0 && direction === 'up') || (index === scripts.length && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | scripts.splice(index - 1, 0, record) |
| | | } else { |
| | | scripts.splice(index + 1, 0, record) |
| | | } |
| | | |
| | | this.setState({ |
| | | setting: {...this.state.setting, scripts: scripts} |
| | | // 自定义脚本修改 |
| | | scriptsChange = (scripts) => { |
| | | return new Promise((resolve, reject) => { |
| | | this.sqlverify(resolve, reject, 'verify', scripts) |
| | | }) |
| | | } |
| | | |
| | | handleStatus = (record) => { |
| | | let scripts = fromJS(this.state.setting.scripts).toJS() |
| | | record.status = record.status === 'false' ? 'true' : 'false' |
| | | |
| | | scripts = scripts.map(item => { |
| | | if (item.uuid === record.uuid) { |
| | | return record |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | |
| | | this.setState({ |
| | | setting: {...this.state.setting, scripts: scripts} |
| | | }) |
| | | } |
| | | |
| | | handleDelete = (record) => { |
| | | let scripts = fromJS(this.state.setting.scripts).toJS() |
| | | scripts = scripts.filter(item => item.uuid !== record.uuid) |
| | | |
| | | this.setState({ setting: {...this.state.setting, scripts: scripts} }) |
| | | } |
| | | |
| | | scriptsChange = (values) => { |
| | | let scripts = fromJS(this.state.setting.scripts).toJS() |
| | | |
| | | if (values.uuid) { |
| | | scripts = scripts.map(item => { |
| | | if (item.uuid === values.uuid) { |
| | | return values |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } else { |
| | | values.uuid = Utils.getuuid() |
| | | scripts.push(values) |
| | | } |
| | | |
| | | this.setState({ |
| | | setting: {...this.state.setting, scripts: scripts} |
| | | }) |
| | | // 自定义脚本更新 |
| | | scriptsUpdate = (scripts) => { |
| | | this.setState({scripts}) |
| | | } |
| | | |
| | | render() { |
| | | const { config, type } = this.props |
| | | const { formlist, view, setting, scriptsColumns, systemScripts, btnloading } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | const { menu } = this.props |
| | | const { activeKey, setting, loading, scripts } = this.state |
| | | |
| | | return ( |
| | | <div className="model-tree-setting-form-box" id="model-tree-setting-form-box"> |
| | | {view ==='custom' ? <div> |
| | | <Icon className="setting-custom-back" onClick={this.changeView} type="arrow-left" /> |
| | | <CustomScript |
| | | type={type} |
| | | setting={setting} |
| | | dict={this.props.dict} |
| | | searches={config.search} |
| | | systemScripts={systemScripts} |
| | | scriptsChange={this.scriptsChange} |
| | | wrappedComponentRef={(inst) => this.scriptsForm = inst} |
| | | /> |
| | | <Table |
| | | bordered |
| | | rowKey="uuid" |
| | | className="custom-table" |
| | | dataSource={setting.scripts} |
| | | columns={scriptsColumns} |
| | | pagination={false} |
| | | /> |
| | | </div> : null } |
| | | <Form {...formItemLayout} className="model-tree-setting-form" id="model-table-setting-form"> |
| | | {view !=='custom' ? <Row gutter={24}>{this.getFields(formlist)}</Row> : null} |
| | | <Row gutter={24}> |
| | | {view !=='custom' ? <Button onClick={this.changeView} className="to-custom-script" loading={btnloading}>自定义设置<Icon style={{marginLeft: 5}} type="right" /></Button> : null} |
| | | {view ==='custom' ? <span onClick={this.changeView} style={{float: 'left', color: '#1890ff', marginLeft: 12, marginTop: 15, cursor: 'pointer'}}><Icon style={{marginRight: 5}} type="left" />基础设置</span> : null} |
| | | </Row> |
| | | </Form> |
| | | <div className="model-tree-setting-form-box" id="model-setting-form-body"> |
| | | {loading && <Spin size="large" />} |
| | | <Tabs activeKey={activeKey} className="verify-card-box" onChange={this.changeTab}> |
| | | <TabPane tab="数据源" key="setting"> |
| | | <DataSource |
| | | menu={menu} |
| | | dict={this.props.dict} |
| | | setting={setting} |
| | | permFuncField={this.props.permFuncField} |
| | | inputSubmit={this.props.inputSubmit} |
| | | wrappedComponentRef={(inst) => this.settingForm = inst} |
| | | /> |
| | | </TabPane> |
| | | <TabPane tab="自定义脚本" key="scripts"> |
| | | <CustomScript |
| | | dict={this.props.dict} |
| | | setting={setting} |
| | | scripts={scripts} |
| | | defaultSql={this.state.defaultsql} |
| | | searches={[]} |
| | | scriptsChange={this.scriptsChange} |
| | | scriptsUpdate={this.scriptsUpdate} |
| | | wrappedComponentRef={(inst) => this.scriptsForm = inst} |
| | | /> |
| | | </TabPane> |
| | | </Tabs> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | .model-tree-setting-form-box { |
| | | position: relative; |
| | | >.ant-spin { |
| | | position: absolute; |
| | | top: 150px; |
| | | left: calc(50% - 16px); |
| | | } |
| | | .model-tree-setting-form { |
| | | .text-area { |
| | | .CodeMirror { |
| | |
| | | border: 0; |
| | | box-shadow: unset; |
| | | } |
| | | |
| | | .verify-card-box .ant-tabs-nav-scroll { |
| | | text-align: center; |
| | | } |
| | | } |
| | |
| | | export default class SettingUtils { |
| | | /** |
| | | * @description 生成页面查询语句 |
| | | * @return {String} scripts 自定义脚本 |
| | | * @return {Object} setting 页面设置 |
| | | */ |
| | | static getDebugSql (setting) { |
| | | static getDebugSql (setting, scripts) { |
| | | let arr_field = `${setting.valueField},${setting.labelField},${setting.parentField}` |
| | | let sql = '' |
| | | let _dataresource = setting.dataresource |
| | | let _customScript = setting.customScript |
| | | let _dataresource = setting.dataresource || '' |
| | | let _customScript = '' |
| | | |
| | | if (setting.interType === 'inner' && !setting.innerFunc && setting.default === 'false') { |
| | | scripts && scripts.forEach(script => { |
| | | _customScript += ` |
| | | ${script.sql} |
| | | ` |
| | | }) |
| | | |
| | | if (_customScript) { |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg ='' |
| | | ${_customScript} |
| | | ` |
| | | } |
| | | |
| | | if (setting.default === 'false') { |
| | | _dataresource = '' |
| | | } |
| | | |
| | | if (_dataresource) { |
| | | _dataresource = _dataresource.replace(/@\$|\$@/ig, '') |
| | | } |
| | | if (_customScript) { |
| | | _customScript = _customScript.replace(/@\$|\$@/ig, '') |
| | | } |
| | | _dataresource = _dataresource.replace(/@\$|\$@/ig, '') |
| | | _customScript = _customScript.replace(/@\$|\$@/ig, '') |
| | | |
| | | // 正则替换 |
| | | let _regoptions = [ |
| | | { |
| | | reg: new RegExp('@orderBy@', 'ig'), |
| | | value: setting.order |
| | | } |
| | | ] |
| | | |
| | | if (_customScript) { |
| | | _customScript = _customScript.replace(/@orderBy@/ig, setting.order) |
| | | } |
| | | _regoptions.forEach(item => { |
| | | _customScript = _customScript.replace(item.reg, item.value) |
| | | }) |
| | | |
| | | // 数据源处理 |
| | | if (_dataresource) { |
| | |
| | | _dataresource = '(' + _dataresource + ') tb' |
| | | } |
| | | |
| | | let arr_field = `${setting.valueField}, ${setting.labelField}, ${setting.parentField}` |
| | | |
| | | _dataresource = `select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${setting.order}) as rows from ${_dataresource}) tmptable order by tmptable.rows` |
| | | _dataresource = ` select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${setting.order}) as rows from ${_dataresource}) tmptable order by tmptable.rows ` |
| | | } |
| | | |
| | | if (_customScript) { |
| | |
| | | }) |
| | | } |
| | | |
| | | // 数据源 |
| | | if (_config.setting.interType === 'inner' && !_config.setting.innerFunc) { |
| | | _config.setting.interType = 'system' |
| | | } |
| | | |
| | | this.setState({ |
| | | config: _config, |
| | | openEdition: menu.open_edition || '', |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Icon, Button, notification, Select, Table, Popconfirm, Typography } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | // import SettingUtils from '../utils.jsx' |
| | | import Api from '@/api' |
| | | import CodeMirror from '@/templates/zshare/codemirror' |
| | | import './index.scss' |
| | | |
| | | const { Paragraph } = Typography |
| | | |
| | | class CustomForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | setting: PropTypes.object, // 设置 |
| | | scripts: PropTypes.array, // 自定义脚本列表 |
| | | searches: PropTypes.array, // 搜索条件 |
| | | defaultSql: PropTypes.string, // 默认sql |
| | | scriptsChange: PropTypes.func, // 自定义脚本切换时验证 |
| | | scriptsUpdate: PropTypes.func // 表单 |
| | | } |
| | | |
| | | state = { |
| | | editItem: null, |
| | | loading: false, |
| | | usefulFields: '', |
| | | systemScripts: [], |
| | | scriptsColumns: [ |
| | | { |
| | | title: 'SQL', |
| | | dataIndex: 'sql', |
| | | width: '70%', |
| | | render: (text) => ( |
| | | <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph> |
| | | ) |
| | | }, |
| | | { |
| | | title: '状态', |
| | | dataIndex: 'status', |
| | | width: '10%', |
| | | render: (text, record) => record.status === 'false' ? |
| | | ( |
| | | <div> |
| | | {this.props.dict['model.status.forbidden']} |
| | | <Icon style={{marginLeft: '5px'}} type="stop" theme="twoTone" twoToneColor="#ff4d4f" /> |
| | | </div> |
| | | ) : |
| | | ( |
| | | <div> |
| | | {this.props.dict['model.status.open']} |
| | | <Icon style={{marginLeft: '5px'}} type="check-circle" theme="twoTone" twoToneColor="#52c41a" /> |
| | | </div> |
| | | ) |
| | | }, |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | width: '20%', |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | (<div> |
| | | <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record)} style={{color: '#1890ff'}}><Icon type="edit" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><Icon type="swap" /></span> |
| | | <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | | onConfirm={() => this.handleDelete(record) |
| | | }> |
| | | <span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | </div>) |
| | | } |
| | | ] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | const { searches, scripts } = this.props |
| | | |
| | | let _usefulFields = [] |
| | | searches.forEach(item => { |
| | | if (item.type === 'group') { |
| | | if (item.transfer === 'true') { |
| | | _usefulFields.push(item.field) |
| | | } |
| | | _usefulFields.push(item.datefield) |
| | | _usefulFields.push(item.datefield + '1') |
| | | } else if (['dateweek', 'datemonth', 'daterange'].includes(item.type)) { |
| | | _usefulFields.push(item.field) |
| | | _usefulFields.push(item.field + '1') |
| | | } else if (_usefulFields.includes(item.field)) { |
| | | _usefulFields.push(item.field + '1') |
| | | } else { |
| | | _usefulFields.push(item.field) |
| | | } |
| | | }) |
| | | |
| | | this.setState({ |
| | | usefulFields: _usefulFields.join(', '), |
| | | scripts: fromJS(scripts).toJS() |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | this.getsysScript() |
| | | } |
| | | |
| | | getsysScript = () => { |
| | | let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort` |
| | | |
| | | _scriptSql = Utils.formatOptions(_scriptSql) |
| | | |
| | | let _sParam = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: _scriptSql, |
| | | obj_name: 'data', |
| | | arr_field: 'funcname,longparam' |
| | | } |
| | | |
| | | _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp) |
| | | _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 云端数据验证 |
| | | |
| | | Api.getSystemConfig(_sParam).then(res => { |
| | | if (res.status) { |
| | | let _scripts = res.data.map(item => { |
| | | let _item = { |
| | | name: item.funcname, |
| | | value: Utils.UnformatOptions(item.longparam) |
| | | } |
| | | return _item |
| | | }) |
| | | |
| | | this.setState({ |
| | | systemScripts: _scripts |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | |
| | | |
| | | handleCancel = () => { |
| | | this.setState({ |
| | | editItem: null |
| | | }) |
| | | this.props.form.setFieldsValue({ |
| | | sql: '' |
| | | }) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | const { scripts, editItem } = this.state |
| | | |
| | | let _sql = this.props.form.getFieldValue('sql') |
| | | |
| | | if (!_sql) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请填写自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (/^\s+$/.test(_sql)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '自定义脚本不可为空!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let values = { |
| | | uuid: editItem && editItem.uuid ? editItem.uuid : Utils.getuuid(), |
| | | sql: _sql |
| | | } |
| | | |
| | | let _quot = values.sql.match(/'{1}/g) |
| | | let _lparen = values.sql.match(/\({1}/g) |
| | | let _rparen = values.sql.match(/\){1}/g) |
| | | |
| | | _quot = _quot ? _quot.length : 0 |
| | | _lparen = _lparen ? _lparen.length : 0 |
| | | _rparen = _rparen ? _rparen.length : 0 |
| | | |
| | | if (_quot % 2 !== 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中\'必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (_lparen !== _rparen) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中()必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (/--/ig.test(values.sql)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '自定义sql语句中,不可出现字符 -- ,注释请用 /*内容*/', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let error = Utils.verifySql(values.sql, 'customscript') |
| | | |
| | | if (error) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中不可使用' + error, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _scripts = fromJS(scripts).toJS() |
| | | |
| | | if (editItem && editItem.uuid) { |
| | | _scripts = _scripts.map(item => { |
| | | if (item.uuid === values.uuid) { |
| | | return values |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } else { |
| | | _scripts.push(values) |
| | | } |
| | | |
| | | this.setState({loading: true}) |
| | | this.props.scriptsChange(_scripts).then(res => { |
| | | this.setState({ |
| | | loading: false, |
| | | scripts: _scripts, |
| | | editItem: null |
| | | }) |
| | | |
| | | this.props.scriptsUpdate(_scripts) |
| | | this.props.form.setFieldsValue({ |
| | | sql: '' |
| | | }) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | }) |
| | | } |
| | | |
| | | selectScript = (value, option) => { |
| | | let _sql = this.props.form.getFieldValue('sql') |
| | | if (_sql) { |
| | | _sql = _sql + ` |
| | | |
| | | ` |
| | | } |
| | | |
| | | _sql = _sql.replace(/\s{6}$/, '') |
| | | _sql = _sql + `/*${option.props.children}*/ |
| | | ` |
| | | _sql = _sql.replace(/\s{4}$/, '') |
| | | _sql = _sql + value |
| | | |
| | | this.props.form.setFieldsValue({ |
| | | sql: _sql |
| | | }) |
| | | } |
| | | |
| | | handleEdit = (record) => { |
| | | this.setState({ |
| | | editItem: record |
| | | }) |
| | | |
| | | this.props.form.setFieldsValue({ |
| | | sql: record.sql |
| | | }) |
| | | |
| | | this.scrolltop() |
| | | } |
| | | |
| | | scrolltop = () => { |
| | | let node = document.getElementById('model-setting-form-body').parentNode |
| | | |
| | | if (node && node.scrollTop) { |
| | | let inter = Math.ceil(node.scrollTop / 10) |
| | | |
| | | let timer = setInterval(() => { |
| | | if (node.scrollTop - inter > 0) { |
| | | node.scrollTop = node.scrollTop - inter |
| | | } else { |
| | | node.scrollTop = 0 |
| | | clearInterval(timer) |
| | | } |
| | | }, 10) |
| | | } |
| | | } |
| | | |
| | | handleUpDown = (record, direction) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | let index = 0 |
| | | |
| | | scripts = scripts.filter((item, i) => { |
| | | if (item.uuid === record.uuid) { |
| | | index = i |
| | | } |
| | | |
| | | return item.uuid !== record.uuid |
| | | }) |
| | | if ((index === 0 && direction === 'up') || (index === scripts.length && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | scripts.splice(index - 1, 0, record) |
| | | } else { |
| | | scripts.splice(index + 1, 0, record) |
| | | } |
| | | |
| | | this.setState({scripts}) |
| | | this.props.scriptsUpdate(scripts) |
| | | } |
| | | |
| | | handleStatus = (record) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | record.status = record.status === 'false' ? 'true' : 'false' |
| | | |
| | | scripts = scripts.map(item => { |
| | | if (item.uuid === record.uuid) { |
| | | return record |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | |
| | | this.setState({scripts}) |
| | | this.props.scriptsUpdate(scripts) |
| | | } |
| | | |
| | | handleDelete = (record) => { |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | scripts = scripts.filter(item => item.uuid !== record.uuid) |
| | | |
| | | this.setState({ scripts }) |
| | | this.props.scriptsUpdate(scripts) |
| | | } |
| | | |
| | | render() { |
| | | const { setting, defaultSql, scripts } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { usefulFields, scriptsColumns, systemScripts } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div> |
| | | <Form {...formItemLayout} className="modal-menu-setting-script"> |
| | | <Row gutter={24}> |
| | | {setting.tableName ? <Col span={8}> |
| | | <Form.Item label={'表名'} style={{whiteSpace: 'nowrap', margin: 0}}> |
| | | {setting.tableName} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={16}> |
| | | <Form.Item label={'报错字段'} style={{margin: 0}}> |
| | | ErrorCode, retmsg |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24} className="sqlfield"> |
| | | <Form.Item label={'可用字段'}> |
| | | id, bid, loginuid, sessionuid, userid, appkey, time_id, orderBy{setting.laypage === 'true' ? ', pageSize, pageIndex': ''}{usefulFields ? ', ' + usefulFields : ''} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={10} className="quick-add"> |
| | | <Form.Item label={'快捷添加'} style={{marginBottom: 0}}> |
| | | <Select |
| | | showSearch |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | onChange={this.selectScript} |
| | | > |
| | | <Select.Option key="default" value={defaultSql}>默认sql</Select.Option> |
| | | {systemScripts.map((option, i) => |
| | | <Select.Option style={{whiteSpace: 'normal'}} key={i} value={option.value}>{option.name}</Select.Option> |
| | | )} |
| | | </Select> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={6} className="add"> |
| | | <Button onClick={this.handleConfirm} loading={this.state.loading} className="mk-green" style={{marginTop: 5, marginBottom: 15, marginLeft: 30}}> |
| | | 保存 |
| | | </Button> |
| | | <Button onClick={this.handleCancel} style={{marginTop: 5, marginBottom: 15, marginLeft: 10}}> |
| | | 取消 |
| | | </Button> |
| | | </Col> |
| | | <Col span={24} className="sql"> |
| | | <Form.Item label={'sql'}> |
| | | {getFieldDecorator('sql', { |
| | | initialValue: '' |
| | | })(<CodeMirror />)} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | <Table |
| | | bordered |
| | | rowKey="uuid" |
| | | className="custom-table" |
| | | dataSource={scripts} |
| | | columns={scriptsColumns} |
| | | pagination={false} |
| | | /> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(CustomForm) |
File was renamed from src/templates/sharecomponent/settingcalcomponent/verifycard/customscript/index.scss |
| | |
| | | width: 89.5%; |
| | | } |
| | | } |
| | | .quick-add { |
| | | .ant-col-sm-8 { |
| | | width: 26%; |
| | | } |
| | | .ant-col-sm-16 { |
| | | width: 74%; |
| | | } |
| | | } |
| | | .sql { |
| | | .ant-col-sm-8 { |
| | | width: 10.5%; |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Menu, Dropdown, Icon, Modal, Spin, notification } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import PasteForm from '@/templates/zshare/pasteform' |
| | | import ReplaceForm from '@/templates/zshare/replaceform' |
| | | import TransferForm from '@/templates/zshare/basetransferform' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | thawVisible: false, |
| | | thawbtnlist: null, |
| | | pasteVisible: false |
| | | pasteVisible: false, |
| | | replaceVisible: false |
| | | } |
| | | |
| | | handleMenuClick = e => { |
| | |
| | | this.handleThaw() |
| | | } else if (e.key === 'paste') { |
| | | this.setState({pasteVisible: true}) |
| | | } else if (e.key === 'replace') { |
| | | this.setState({replaceVisible: true}) |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | pasteSubmit = () => { |
| | | const { config } = this.props |
| | | const { config, type } = this.props |
| | | |
| | | this.pasteFormRef.handleConfirm().then(res => { |
| | | if (res.copyType === 'action') { |
| | | if (['maintable', 'subtable'].includes(type) && res.copyType === 'action') { |
| | | if (this.props.type === 'subtable' && !['pop', 'prompt', 'exec', 'excelIn', 'excelOut', 'popview'].includes(res.OpenType)) { |
| | | notification.warning({ |
| | | top: 92, |
| | |
| | | content: res |
| | | }) |
| | | }) |
| | | } else if (res.copyType === 'search') { |
| | | } else if (['maintable', 'subtable'].includes(type) && res.copyType === 'search') { |
| | | this.setState({ |
| | | pasteVisible: false |
| | | }, () => { |
| | |
| | | content: res |
| | | }) |
| | | }) |
| | | } else if (res.copyType === 'columns') { |
| | | } else if (['maintable', 'subtable'].includes(type) && res.copyType === 'columns') { |
| | | let _columns = config.columns.filter(col => !col.origin) |
| | | if (_columns.length > 0) { |
| | | notification.warning({ |
| | |
| | | content: res |
| | | }) |
| | | }) |
| | | } else if (['form'].includes(type) && res.copyType === 'form') { |
| | | if (res.type === 'linkMain') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不支持此表单类型!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _config = fromJS(config).toJS() |
| | | let fieldrepet = false |
| | | let labelrepet = false |
| | | |
| | | if (_config.groups.length > 0) { |
| | | _config.groups.forEach(group => { |
| | | group.sublist.forEach(item => { |
| | | if (item.uuid === res.uuid) { |
| | | fieldrepet = true |
| | | } else if (item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | }) |
| | | }) |
| | | } else { |
| | | _config.fields.forEach(item => { |
| | | if (item.uuid === res.uuid) { |
| | | fieldrepet = true |
| | | } else if (item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (fieldrepet) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段已存在!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (labelrepet) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '名称已存在!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | if (_config.groups.length > 0) { |
| | | _config.groups.forEach(group => { |
| | | if (group.default) { |
| | | group.sublist.push(res) |
| | | } |
| | | }) |
| | | } else { |
| | | _config.fields.push(res) |
| | | } |
| | | |
| | | this.setState({ |
| | | pasteVisible: false |
| | | }, () => { |
| | | this.props.refresh({ |
| | | type: 'paste', |
| | | content: _config |
| | | }) |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | |
| | | }) |
| | | } |
| | | |
| | | replaceSubmit = () => { |
| | | this.replaceFormRef.handleConfirm().then(res => { |
| | | this.props.refresh({ |
| | | type: 'replace', |
| | | ...res |
| | | }) |
| | | this.setState({ |
| | | replaceVisible: false |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { type } = this.props |
| | | const { dict } = this.state |
| | | const menu = ( |
| | | <Menu onClick={this.handleMenuClick}> |
| | | {this.props.type !== 'TreePage' ? <Menu.Item key="thaw"><Icon type="unlock" />{dict['header.form.thawbutton']}</Menu.Item> : null} |
| | | <Menu.Item key="paste"><Icon type="snippets" />{dict['header.form.paste']}</Menu.Item> |
| | | {['maintable', 'subtable'].includes(type) ? <Menu.Item key="thaw"><Icon type="unlock" />{dict['header.form.thawbutton']}</Menu.Item> : null} |
| | | {['maintable', 'subtable', 'form'].includes(type) ? <Menu.Item key="paste"><Icon type="snippets" />{dict['header.form.paste']}</Menu.Item> : null} |
| | | {/* <Menu.Item key="replace"><Icon type="retweet" />替换</Menu.Item> */} |
| | | </Menu> |
| | | ) |
| | |
| | | wrappedComponentRef={(inst) => this.pasteFormRef = inst} |
| | | /> |
| | | </Modal> |
| | | {/* 替换 */} |
| | | <Modal |
| | | title={'替换'} |
| | | visible={this.state.replaceVisible} |
| | | width={600} |
| | | maskClosable={false} |
| | | onOk={this.replaceSubmit} |
| | | onCancel={() => {this.setState({replaceVisible: false})}} |
| | | destroyOnClose |
| | | > |
| | | <ReplaceForm |
| | | dict={dict} |
| | | inputSubmit={this.replaceSubmit} |
| | | wrappedComponentRef={(inst) => this.replaceFormRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Radio } from 'antd' |
| | | import './index.scss' |
| | | |
| | | class MainSearch extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | inputSubmit: PropTypes.func // 提交 |
| | | } |
| | | |
| | | componentDidMount () { |
| | | try { |
| | | let _form = document.getElementById('origin') |
| | | if (_form && _form.select) { |
| | | _form.select() |
| | | } |
| | | } catch { |
| | | console.warn('Form focusing error!') |
| | | } |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | let origin = this.props.form.getFieldValue('origin') |
| | | let value = this.props.form.getFieldValue('value') |
| | | |
| | | if (!origin) { |
| | | const input = document.getElementById('origin') |
| | | if (input) { |
| | | input.focus() |
| | | } |
| | | } else if (!value) { |
| | | const input = document.getElementById('value') |
| | | if (input) { |
| | | input.focus() |
| | | } |
| | | } else { |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { dict } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 12 } |
| | | } |
| | | } |
| | | return ( |
| | | <Form {...formItemLayout} className="config-replace-form"> |
| | | <Row gutter={24}> |
| | | <Col span={24}> |
| | | <Form.Item label="类型"> |
| | | {getFieldDecorator('repType', { |
| | | initialValue: 'field' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="label">名称</Radio> |
| | | <Radio value="field">字段</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item label="原值"> |
| | | {getFieldDecorator('origin', { |
| | | initialValue: '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + '原值!' |
| | | }, |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item label="目标值"> |
| | | {getFieldDecorator('value', { |
| | | initialValue: '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + '目标值!' |
| | | }, |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(MainSearch) |
New file |
| | |
| | | .config-replace-form { |
| | | min-height: 150px; |
| | | } |