| | |
| | | </div> |
| | | } style={{ width: '100%' }}> |
| | | <SettingComponent |
| | | type="main" |
| | | config={config} |
| | | MenuID={this.props.menu.MenuID} |
| | | permFuncField={this.props.permFuncField} |
| | |
| | | primaryKey: '', |
| | | order: '', |
| | | dataresource: '', |
| | | interType: 'inner', |
| | | interType: 'system', |
| | | sysInterface: 'false', |
| | | innerFunc: '', |
| | | interface: '', |
| | |
| | | import DevUtils from '@/utils/devutils.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import { getSettingForm } from '@/templates/zshare/formconfig' |
| | | |
| | | import SettingForm from './settingform' |
| | | import CreateFunc from '@/templates/zshare/createfunc' |
| | |
| | | |
| | | class SettingComponent extends Component { |
| | | static propTpyes = { |
| | | type: PropTypes.string, // 菜单类型 |
| | | mainsearch: PropTypes.any, // 主表的搜索条件,当子表设置接收主表条件时有效 |
| | | MenuID: PropTypes.string, // 菜单ID |
| | | config: PropTypes.object, // 菜单配置信息 |
| | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | menu: null, // 菜单信息 |
| | | search: null, // 搜索条件,包括主表搜索 |
| | | formlist: null, // 表单信息 |
| | | visible: false, // 模态框控制 |
| | | loading: false // 设置信息验证保存中 |
| | |
| | | * @description 全局设置触发 |
| | | */ |
| | | changeSetting = () => { |
| | | const { MenuID, config, type, permFuncField, mainsearch } = this.props |
| | | const { MenuID, config, mainsearch } = this.props |
| | | let menu = {MenuID: MenuID, MenuName: config.MenuName, MenuNo: config.MenuNo} |
| | | let _columns = fromJS(config.columns).toJS() |
| | | let primaryKey = config.setting.primaryKey || '' |
| | | |
| | | if (!primaryKey || _columns.filter(column => column.field === primaryKey).length === 0) { |
| | | _columns.forEach(col => { |
| | | if (col.field.toLowerCase() === 'id') { |
| | | primaryKey = col.field |
| | | } |
| | | }) |
| | | } |
| | | _columns = _columns.filter(item => item.field && item.type !== 'colspan') |
| | | _columns = _columns.map(item => { |
| | | return { |
| | | value: item.field, |
| | | text: item.label |
| | | } |
| | | }) |
| | | |
| | | // _columns.unshift({value: '', text: '未设置'}) |
| | | |
| | | let _config = fromJS(config).toJS() |
| | | let _search = fromJS(config.search).toJS() |
| | | |
| | | if (mainsearch) { // 综合主页搜索及子表搜索条件 |
| | | _config.search = [..._config.search, ...mainsearch] |
| | | _search = [...mainsearch, ..._search] |
| | | } |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | formlist: getSettingForm(config.setting, permFuncField, MenuID, primaryKey, _columns, type), |
| | | menu: menu, |
| | | config: _config |
| | | search: _search, |
| | | menu: menu |
| | | }) |
| | | } |
| | | |
| | |
| | | visible: false, |
| | | loading: false |
| | | }) |
| | | |
| | | delete res.customScript // 清除整理后的自定义脚本 |
| | | res.actionfixed = res.actionfixed === 'true' |
| | | res.columnfixed = res.columnfixed === 'true' |
| | | |
| | | this.props.updatesetting({...config, setting: res}) |
| | | }, () => { |
| | |
| | | const { config } = this.props |
| | | const { menu } = this.state |
| | | |
| | | this.settingRef.handleConfirm().then(setting => { |
| | | |
| | | if (!(setting.interType === 'inner') || !setting.innerFunc) { |
| | | this.settingRef.handleConfirm(true).then(setting => { |
| | | if (setting.interType !== 'inner' || !setting.innerFunc) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '接口类型为-内部,且存在内部函数时,才可以创建存储过程!', |
| | | 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 |
| | | |
| | |
| | | * @description 创建表格接口(读出) |
| | | */ |
| | | tableCreatInterface = () => { |
| | | const { config, type } = this.props |
| | | const { config } = this.props |
| | | const { menu } = this.state |
| | | |
| | | this.settingRef.handleConfirm().then(setting => { |
| | | if (setting.interType !== 'inner' || setting.innerFunc) { |
| | | this.settingRef.handleConfirm(true).then(setting => { |
| | | if (setting.interType !== 'system') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '接口类型为-内部,且不存在内部函数时,才可以创建接口!', |
| | | message: '使用系统接口时,才可以创建接口!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | |
| | | |
| | | let _config = {...config, setting: setting} |
| | | let _menu = { |
| | | type: type, |
| | | type: config.Template === 'CommonTable' ? 'main' : 'subtable', |
| | | MenuID: menu.MenuID, |
| | | menuName: menu.MenuName, |
| | | menuNo: menu.MenuNo |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { type } = this.props |
| | | const { dict, visible, config } = this.state |
| | | const { config, permFuncField } = this.props |
| | | const { dict, visible, search, menu } = this.state |
| | | |
| | | return ( |
| | | <div className="model-menu-setting"> |
| | |
| | | maskClosable={false} |
| | | onCancel={() => { this.setState({ visible: false, loading: false })}} |
| | | footer={[ |
| | | <CreateInterface key="interface" dict={dict} ref="tableCreatInterface" trigger={this.tableCreatInterface}/>, |
| | | <CreateInterface key="interface" loading={this.state.interloading} 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, loading: 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> |
| | |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | type={type} |
| | | type={config.Template === 'CommonTable' ? 'main' : 'subtable'} |
| | | dict={dict} |
| | | menu={menu} |
| | | config={config} |
| | | menu={this.state.menu} |
| | | search={search} |
| | | permFuncField={permFuncField} |
| | | inputSubmit={this.settingSave} |
| | | formlist={this.state.formlist} |
| | | wrappedComponentRef={(inst) => this.settingRef = inst} |
| | | /> |
| | | </Modal> |
| | |
| | | .ant-modal-body { |
| | | max-height: calc(100vh - 190px); |
| | | overflow-y: auto; |
| | | // .ant-empty { |
| | | // margin: 15vh 8px; |
| | | // } |
| | | padding-top: 10px; |
| | | } |
| | | .ant-modal-body::-webkit-scrollbar { |
| | | width: 7px; |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Button, notification, Modal, Select } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | |
| | | setting: PropTypes.object, // 设置 |
| | | searches: PropTypes.array, // 搜索条件 |
| | | swhere: PropTypes.string, // where条件 |
| | | defaultSql: PropTypes.string, // 默认sql |
| | | arr_field: PropTypes.string, // 列字段 |
| | | regoptions: PropTypes.array, // 正则替换 |
| | | systemScripts: PropTypes.array, // 系统脚本 |
| | |
| | | return |
| | | } |
| | | |
| | | let _customScript = '' |
| | | setting.scripts && setting.scripts.forEach(script => { |
| | | if (this.state.editItem && this.state.editItem.uuid === script.uuid) { |
| | | _customScript += ` |
| | | ${values.sql} |
| | | ` |
| | | } else if (script.status !== 'false') { |
| | | _customScript += ` |
| | | ${script.sql} |
| | | ` |
| | | let scripts = fromJS(this.props.scripts).toJS() |
| | | |
| | | if (values.uuid) { |
| | | scripts = scripts.map(item => { |
| | | if (item.uuid === values.uuid) { |
| | | return values |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | |
| | | if (!this.state.editItem) { |
| | | _customScript += ` |
| | | ${values.sql} |
| | | ` |
| | | } else { |
| | | scripts.push(values) |
| | | } |
| | | |
| | | if (_customScript) { |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg ='' |
| | | ${_customScript} |
| | | ` |
| | | } |
| | | |
| | | let _setting = {...setting, customScript: _customScript} |
| | | |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | LText: SettingUtils.getDebugSql(_setting, arr_field, regoptions, swhere) |
| | | LText: SettingUtils.getDebugSql(setting, scripts, arr_field, regoptions, swhere) |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(param.LText) |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { systemScripts, setting, type } = this.props |
| | | const { systemScripts, setting, type, defaultSql } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { usefulFields } = this.state |
| | | const formItemLayout = { |
| | |
| | | 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> |
| | | )} |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Radio, Tooltip, Icon, notification } from 'antd' |
| | | import { Form, Row, Col, Input, Radio, Tooltip, Icon, notification, Select } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | type: PropTypes.string, // 菜单类型,main或subtable |
| | | dict: PropTypes.object, // 字典项 |
| | | menuId: PropTypes.string, // 菜单Id |
| | | permFuncField: PropTypes.any, // 菜单Id |
| | | menu: PropTypes.object, // 菜单信息 |
| | | permFuncField: PropTypes.any, // 存储过程可用开始字符 |
| | | setting: PropTypes.object, // 数据源配置 |
| | | columns: PropTypes.array, // 列设置 |
| | | scripts: PropTypes.array, // 自定义脚本 |
| | | } |
| | | |
| | | state = { |
| | | interType: this.props.setting.interType || 'inner', |
| | | 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 = () => { |
| | |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | // 数据源前端验证 |
| | | if (values.interType === 'inner' && !values.innerFunc && values.execute !== 'false' && !values.dataresource) { |
| | | if (values.interType === 'system' && values.default !== 'false' && !values.dataresource) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请填写内部函数或数据源!', |
| | | message: '请填写数据源!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } else if (values.interType === 'inner' && !values.innerFunc && values.execute !== 'false' && values.dataresource) { |
| | | } 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) |
| | |
| | | |
| | | // 数据源保存 |
| | | if ( |
| | | values.interType === 'inner' && !values.innerFunc && values.execute !== 'false' && |
| | | 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.menuId |
| | | MenuID: this.props.menu.MenuID |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(param.LText) |
| | |
| | | this.setState({ |
| | | interType: value |
| | | }) |
| | | } else if (key === 'sysInterface') { |
| | | if (value === 'true') { |
| | | this.props.form.setFieldsValue({ |
| | | interface: window.GLOB.mainSystemApi || '' |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | primaryKeyChange = (val) => { |
| | | if (val) { |
| | | this.props.form.setFieldsValue({ |
| | | order: `${val} desc` |
| | | }) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { setting, permFuncField } = this.props |
| | | const { setting, dict, menu, type, columns } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { interType } = this.state |
| | | const { interType, funcRules, funcTooltip } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | |
| | | } |
| | | } |
| | | |
| | | 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 |
| | | }) |
| | | } |
| | | |
| | | return ( |
| | | <div className="model-datasource-setting-form-box"> |
| | | <div className="model-table-datasource-setting-form-box"> |
| | | <Form {...formItemLayout} className="model-setting-form"> |
| | | <Row gutter={24}> |
| | | <Col span={8}> |
| | | <Col span={12}> |
| | | <Form.Item label="表名"> |
| | | {getFieldDecorator('tableName', { |
| | | initialValue: setting.tableName, |
| | | initialValue: setting.tableName || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '表名!' |
| | | message: dict['form.required.input'] + '表名!' |
| | | }, |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={8}> |
| | | <Form.Item label="接口类型"> |
| | | <Col span={12}> |
| | | <Form.Item label="表格属性"> |
| | | {getFieldDecorator('tableType', { |
| | | initialValue: setting.tableType |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="">不可选</Radio> |
| | | <Radio value="radio">单选</Radio> |
| | | <Radio value="checkbox">多选</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={dict['header.form.intertype']}> |
| | | {getFieldDecorator('interType', { |
| | | initialValue: interType, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.select'] + '接口类型!' |
| | | 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 === 'inner' ? <Col span={8}> |
| | | <Form.Item label={tooltip ? |
| | | <Tooltip placement="topLeft" title={tooltip}> |
| | | {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> : '内部函数' |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('innerFunc', { |
| | | initialValue: setting.innerFunc || '', |
| | | rules: rules |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: dict['form.required.input'] + '内部函数!' |
| | | }, |
| | | { |
| | | max: formRule.func.max, |
| | | message: formRule.func.maxMessage |
| | | }, |
| | | ...funcRules |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {interType === 'outer' ? <Col span={8}> |
| | | {interType === 'outer' ? <Col span={12}> |
| | | <Form.Item label="接口地址"> |
| | | {getFieldDecorator('interface', { |
| | | initialValue: setting.interface || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '接口地址!' |
| | | message: dict['form.required.input'] + '接口地址!' |
| | | }, |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {interType === 'outer' ? <Col span={8}> |
| | | {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" />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {interType === 'inner' ? <Col span={24} className="data-source" style={{paddingLeft: '7px'}}> |
| | | <Form.Item labelCol={{xs: { span: 24 }, sm: { span: 2 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 22 }} } label={ |
| | | {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" /> |
| | | 数据源 |
| | |
| | | })(<CodeMirror />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {interType === 'inner' ? <Col span={8}> |
| | | {interType === 'system' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'查询时,搜索条件以where条件拼接进入sql,统计时,将数据源中以“@+搜索字段+@”的内容,以搜索条件中的值进行替换后,提交查询,注:查询类型仅在使用系统函数时有效。'}> |
| | | <Icon type="question-circle" /> |
| | |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {/* <Col span={8}> |
| | | <Form.Item label="主键"> |
| | | {getFieldDecorator('primaryKey', { |
| | | initialValue: setting.primaryKey || '' |
| | | })( |
| | | <Select> |
| | | {columns.map((option, i) => |
| | | <Select.Option key={i} value={option.field}> |
| | | {option.label} |
| | | </Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> */} |
| | | {interType === 'inner' ? <Col span={8}> |
| | | {interType === 'system' ? <Col span={12}> |
| | | <Form.Item label="默认sql"> |
| | | {getFieldDecorator('execute', { |
| | | initialValue: setting.execute || 'true' |
| | | {getFieldDecorator('default', { |
| | | initialValue: setting.default || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">执行</Radio> |
| | |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={8}> |
| | | <Col span={12}> |
| | | <Form.Item label="主键"> |
| | | {getFieldDecorator('primaryKey', { |
| | | initialValue: setting.primaryKey || '' |
| | | })( |
| | | <Select onChange={this.primaryKeyChange}> |
| | | <Select.Option key="empty" value="">未设置</Select.Option> |
| | | {columns.map((option, i) => |
| | | <Select.Option key={i} value={option.value}> |
| | | {option.text} |
| | | </Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </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" />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="是否分页"> |
| | | {getFieldDecorator('laypage', { |
| | | initialValue: setting.laypage || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">{dict['model.true']}</Radio> |
| | | <Radio value="false">{dict['model.false']}</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="初始化"> |
| | | {getFieldDecorator('onload', { |
| | | initialValue: setting.onload || 'true' |
| | |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | {type === 'main' ? <Col span={12}> |
| | | <Form.Item label="按钮固定"> |
| | | {getFieldDecorator('actionfixed', { |
| | | initialValue: setting.actionfixed === 'true' || setting.actionfixed === true ? 'true' : 'false' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">{dict['model.true']}</Radio> |
| | | <Radio value="false">{dict['model.false']}</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {type === 'main' ? <Col span={12}> |
| | | <Form.Item label="表头固定"> |
| | | {getFieldDecorator('columnfixed', { |
| | | initialValue: setting.columnfixed === 'true' || setting.columnfixed === true ? 'true' : 'false' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">{dict['model.true']}</Radio> |
| | | <Radio value="false">{dict['model.false']}</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | |
| | | .model-datasource-setting-form-box { |
| | | .model-table-datasource-setting-form-box { |
| | | position: relative; |
| | | |
| | | .model-setting-form { |
| | | .data-source { |
| | | .ant-form-item-label { |
| | | width: 11%; |
| | | width: 16.5%; |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | width: 89%; |
| | | width: 83.5%; |
| | | } |
| | | .CodeMirror { |
| | | height: 150px; |
| | |
| | | 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, Icon, notification, Modal, Spin, Tabs, Table, Popconfirm, Typography } 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 './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | const { confirm } = Modal |
| | | const { TabPane } = Tabs |
| | | const { Paragraph } = Typography |
| | | |
| | | class SettingForm extends Component { |
| | |
| | | dict: PropTypes.object, // 字典项 |
| | | menu: PropTypes.object, // 菜单信息 |
| | | config: PropTypes.object, // 页面配置信息 |
| | | formlist: PropTypes.array, // 表单信息 |
| | | permFuncField: PropTypes.array, // 自定义函数可用字段 |
| | | search: PropTypes.array, // 搜索条件 |
| | | inputSubmit: PropTypes.any // 回车提交事件 |
| | | } |
| | | |
| | | state = { |
| | | formlist: [], |
| | | btnloading: false, |
| | | activeKey: 'setting', |
| | | search: '', |
| | | arr_field: '', |
| | | regoptions: [], |
| | | setting: null, |
| | | view: 'normal', |
| | | systemScripts: [{ |
| | | name: '默认sql', |
| | | value: '' |
| | | }], |
| | | defaultSql: '', |
| | | systemScripts: [], |
| | | scriptsColumns: [ |
| | | { |
| | | title: 'SQL', |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | const { config } = this.props |
| | | const { config, search } = this.props |
| | | |
| | | let _formlist = fromJS(this.props.formlist).toJS() |
| | | let interType = 'inner' |
| | | let _setting = fromJS(config.setting).toJS() |
| | | let _scripts = _setting.scripts || [] |
| | | |
| | | _formlist.forEach(item => { |
| | | if (item.key === 'interType') { |
| | | interType = item.initVal |
| | | _setting.default = _setting.default || 'true' // 默认sql |
| | | _setting.sysInterface = _setting.sysInterface || 'false' // 是否为系统接口 |
| | | _setting.interface = _setting.sysInterface === 'true' ? (window.GLOB.mainSystemApi || '') : (_setting.interface || '') |
| | | |
| | | if (_setting.interType === 'inner' && !_setting.innerFunc) { // 修改已有数据 |
| | | _setting.interType = 'system' |
| | | } |
| | | }) |
| | | |
| | | let _setting = fromJS(this.props.config.setting).toJS() |
| | | _setting.scripts = _setting.scripts || [] |
| | | _setting.default = _setting.default || 'true' |
| | | |
| | | delete _setting.subtabs |
| | | |
| | | // 搜索条件 |
| | | let allSearch = Utils.initMainSearch(config.search) |
| | | allSearch = Utils.getAllSearchOptions(allSearch) |
| | | |
| | | // 显示列字段,用于查询 |
| | | let columns = [] |
| | | let arr_field = [] |
| | | config.columns.forEach(col => { |
| | | if (col.field) { |
| | | columns.push({ |
| | | value: col.field, |
| | | text: col.label |
| | | }) |
| | | arr_field.push(col.field) |
| | | } |
| | | if (col.nameField) { // 链接的名称字段 |
| | | arr_field.push(col.nameField) |
| | | } |
| | | }) |
| | | arr_field = arr_field.join(',') |
| | | |
| | | let _search = this.formatSearch(config.search) |
| | | if (_setting.primaryKey && !arr_field.includes(_setting.primaryKey)) { |
| | | _setting.primaryKey = '' |
| | | } |
| | | if (!_setting.primaryKey && arr_field.length > 0) { |
| | | arr_field.forEach(field => { |
| | | if (field.toLowerCase() === 'id') { |
| | | _setting.primaryKey = field |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 搜索条件,正则替换 |
| | | let allSearch = Utils.initMainSearch(search) |
| | | allSearch = Utils.getAllSearchOptions(allSearch) |
| | | |
| | | // 搜索的where条件 |
| | | let _search = this.formatSearch(search) |
| | | _search = Utils.joinMainSearchkey(_search) |
| | | |
| | | _search = _search.replace(/@\$@/ig, '') |
| | |
| | | this.setState({ |
| | | setting: _setting, |
| | | search: _search, |
| | | arr_field: arr_field, |
| | | arr_field: arr_field.join(','), |
| | | regoptions: allSearch, |
| | | formlist: _formlist.map(item => { |
| | | if (interType === 'inner' && ['sysInterface', 'interface', 'outerFunc'].includes(item.key)) { |
| | | item.hidden = true |
| | | } else if (interType === 'outer' && ['innerFunc', 'dataresource', 'queryType', 'default'].includes(item.key)) { |
| | | item.hidden = true |
| | | } |
| | | |
| | | return item |
| | | }) |
| | | columns: columns, |
| | | scripts: _scripts |
| | | }) |
| | | } |
| | | |
| | |
| | | name: item.funcname, |
| | | value: Utils.UnformatOptions(item.longparam) |
| | | } |
| | | |
| | | return _item |
| | | }) |
| | | |
| | | this.setState({ |
| | | systemScripts: [...this.state.systemScripts, ..._scripts] |
| | | systemScripts: _scripts |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | |
| | | }) |
| | | } |
| | | |
| | | handleConfirm = (otype) => { |
| | | const { menu, type } = this.props |
| | | const { view, setting } = this.state |
| | | handleConfirm = (trigger) => { |
| | | const { activeKey, setting, scripts } = this.state |
| | | |
| | | if (trigger) { |
| | | this.setState({loading: true}) |
| | | } |
| | | |
| | | // 表单提交时检查输入值是否正确 |
| | | |
| | | if (view !== 'custom') { |
| | | if (activeKey === 'setting') { |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | if (type === 'main') { |
| | | values.actionfixed = values.actionfixed === 'true' |
| | | values.columnfixed = values.columnfixed === 'true' |
| | | } |
| | | |
| | | values = {...setting, ...values} |
| | | |
| | | // 数据源前端验证 |
| | | if (values.interType === 'inner' && !values.innerFunc && values.default !== 'false' && !values.dataresource) { |
| | | this.settingForm.handleConfirm().then(res => { |
| | | if (res.interType === 'system' && res.default === 'false' && scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请填写内部函数或数据源!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } else if (values.interType === 'inner' && !values.innerFunc && 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: '数据源中,不可出现字符 -- ,注释请用 /*内容*/', |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | | 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 === '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, |
| | | setting: res |
| | | }, () => { |
| | | resolve() |
| | | }) |
| | | } else { |
| | | values.customScript = this.getCustomScript(values) |
| | | |
| | | this.sqlverify(values, resolve, reject) |
| | | } |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } 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() { |
| | | this.sqlverify(() => { |
| | | this.setState({loading: false}) |
| | | resolve({...res, scripts}) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | reject() |
| | | } |
| | | }, true) |
| | | }) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | }) |
| | | }) |
| | | } else { |
| | | this.sqlverify(_setting, resolve, reject) |
| | | 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) |
| | | } |
| | | }) |
| | | } |
| | |
| | | return _customScript |
| | | } |
| | | |
| | | sqlverify = (_setting, _resolve, _reject, isChange = false) => { |
| | | const { arr_field, regoptions, search } = this.state |
| | | sqlverify = (_resolve, _reject, force) => { |
| | | const { setting, scripts, arr_field, regoptions, search } = this.state |
| | | |
| | | if (!isChange && _setting.interType === 'inner' && !_setting.innerFunc && _setting.default === 'false' && !_setting.customScript) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | _reject() |
| | | return |
| | | if (setting.interType !== 'system') { // 不使用系统接口时,不需要sql验证 |
| | | _resolve() |
| | | } |
| | | |
| | | if (_setting.interType === 'inner' && !_setting.innerFunc && _setting.default !== 'false') { |
| | | if (force || (setting.interType === 'system' && setting.default !== 'false')) { |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | LText: SettingUtils.getDebugSql(_setting, arr_field, regoptions, search) |
| | | 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' |
| | |
| | | |
| | | 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` |
| | | }) |
| | | } |
| | | } |
| | | |
| | | 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', 'default'].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 |
| | | }) |
| | | }) |
| | | _resolve() |
| | | } |
| | | } |
| | | |
| | |
| | | return newsearches |
| | | } |
| | | |
| | | changeView = () => { |
| | | const { view, arr_field, regoptions, search } = 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)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用外部接口或内部接口的自定义函数,不可添加自定义设置!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _search = search |
| | | |
| | | let _dataresource = setting.dataresource |
| | | |
| | | if (/\s/.test(_dataresource)) { |
| | | _dataresource = '(' + _dataresource + ') tb' |
| | | } |
| | | |
| | | if (setting.queryType === 'statistics') { // 统计数据源,内容替换 |
| | | // 正则替换 |
| | | let _regoptions = regoptions.map(item => { |
| | | return { |
| | | reg: new RegExp('@' + item.key + '@', 'ig'), |
| | | value: `'${item.value}'` |
| | | } |
| | | }) |
| | | _regoptions.forEach(item => { |
| | | _dataresource = _dataresource.replace(item.reg, item.value) |
| | | }) |
| | | |
| | | _search = '' |
| | | } |
| | | |
| | | let LText = `select ${setting.laypage !== 'false' ? 'top @pageSize@' : ''} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by @orderBy@) as rows from ${_dataresource} ${_search}) tmptable ${setting.laypage !== 'false' ? 'where rows > (@pageSize@ * (@pageIndex@ - 1))' : ''} 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({ |
| | | view: 'custom', |
| | | btnloading: false, |
| | | systemScripts: _scripts |
| | | }) |
| | | this.scrolltop() |
| | | }, () => { |
| | | this.setState({ |
| | | btnloading: false |
| | | }) |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | let _loading = false |
| | | |
| | | if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) { |
| | | _loading = true |
| | | } |
| | | |
| | | if (_loading) { |
| | | confirm({ |
| | | content: `存在未保存项,确定切换吗?`, |
| | | onOk() { |
| | | _this.setState({ |
| | | view: 'normal' |
| | | }) |
| | | |
| | | _this.scrolltop() |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } else { |
| | | _this.setState({ |
| | | view: 'normal' |
| | | }) |
| | | |
| | | _this.scrolltop() |
| | | } |
| | | } |
| | | } |
| | | |
| | | 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="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 === 'textarea') { |
| | | fields.push( |
| | | <Col span={20} offset={4} key={index}> |
| | | <Form.Item className="text-area"> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<TextArea rows={4} />)} |
| | | </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) => { |
| | |
| | | } |
| | | |
| | | handleUpDown = (record, direction) => { |
| | | let scripts = fromJS(this.state.setting.scripts).toJS() |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | let index = 0 |
| | | |
| | | scripts = scripts.filter((item, i) => { |
| | |
| | | scripts.splice(index + 1, 0, record) |
| | | } |
| | | |
| | | this.setState({ |
| | | setting: {...this.state.setting, scripts: scripts} |
| | | }) |
| | | this.setState({scripts}) |
| | | } |
| | | |
| | | handleStatus = (record) => { |
| | | let scripts = fromJS(this.state.setting.scripts).toJS() |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | record.status = record.status === 'false' ? 'true' : 'false' |
| | | |
| | | scripts = scripts.map(item => { |
| | |
| | | } |
| | | }) |
| | | |
| | | this.setState({ |
| | | setting: {...this.state.setting, scripts: scripts} |
| | | }) |
| | | this.setState({scripts}) |
| | | } |
| | | |
| | | handleDelete = (record) => { |
| | | let scripts = fromJS(this.state.setting.scripts).toJS() |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | scripts = scripts.filter(item => item.uuid !== record.uuid) |
| | | |
| | | this.setState({ setting: {...this.state.setting, scripts: scripts} }) |
| | | this.setState({ scripts }) |
| | | } |
| | | |
| | | scriptsChange = (values) => { |
| | | let scripts = fromJS(this.state.setting.scripts).toJS() |
| | | let scripts = fromJS(this.state.scripts).toJS() |
| | | |
| | | if (values.uuid) { |
| | | scripts = scripts.map(item => { |
| | |
| | | scripts.push(values) |
| | | } |
| | | |
| | | this.setState({ |
| | | setting: {...this.state.setting, scripts: scripts} |
| | | 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') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用系统接口时,才可以设置自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | setting: res |
| | | }, () => { |
| | | 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.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | activeKey: val, |
| | | defaultSql: _defaultSql, |
| | | loading: false |
| | | }) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | }) |
| | | }) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | }) |
| | | } else if (activeKey === 'scripts') { |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) { |
| | | _loading = true |
| | | } |
| | | |
| | | if (_loading) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | activeKey: val |
| | | }) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { config, type } = this.props |
| | | const { formlist, view, setting, scriptsColumns, systemScripts, arr_field, regoptions, search, btnloading } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | const { type, menu, dict, permFuncField } = this.props |
| | | const { loading, activeKey, setting, scriptsColumns, systemScripts, arr_field, defaultSql, regoptions, search, columns, scripts } = this.state |
| | | |
| | | return ( |
| | | <div className="model-table-setting-form-box" id="model-table-setting-form-box"> |
| | | {view ==='custom' ? <div> |
| | | <Icon className="setting-custom-back" onClick={this.changeView} type="arrow-left" /> |
| | | {loading && <Spin size="large" />} |
| | | <Tabs activeKey={activeKey} className="verify-card-box" onChange={this.changeTab}> |
| | | <TabPane tab="数据源" key="setting"> |
| | | <DataSource |
| | | type={type} |
| | | menu={menu} |
| | | dict={dict} |
| | | columns={columns} |
| | | setting={setting} |
| | | scripts={scripts} |
| | | permFuncField={permFuncField} |
| | | wrappedComponentRef={(inst) => this.settingForm = inst} |
| | | /> |
| | | </TabPane> |
| | | <TabPane tab="自定义脚本" key="scripts"> |
| | | <CustomScript |
| | | type={type} |
| | | setting={setting} |
| | | dict={dict} |
| | | swhere={search} |
| | | setting={setting} |
| | | scripts={scripts} |
| | | arr_field={arr_field} |
| | | defaultSql={defaultSql} |
| | | regoptions={regoptions} |
| | | dict={this.props.dict} |
| | | searches={config.search} |
| | | searches={this.props.search} |
| | | systemScripts={systemScripts} |
| | | scriptsChange={this.scriptsChange} |
| | | wrappedComponentRef={(inst) => this.scriptsForm = inst} |
| | |
| | | bordered |
| | | rowKey="uuid" |
| | | className="custom-table" |
| | | dataSource={setting.scripts} |
| | | dataSource={scripts} |
| | | columns={scriptsColumns} |
| | | pagination={false} |
| | | /> |
| | | </div> : null } |
| | | <Form {...formItemLayout} className="model-table-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> |
| | | </TabPane> |
| | | </Tabs> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | .model-table-setting-form-box { |
| | | position: relative; |
| | | |
| | | >.ant-spin { |
| | | position: absolute; |
| | | top: 150px; |
| | | left: calc(50% - 16px); |
| | | } |
| | | .model-table-setting-form { |
| | | .textarea { |
| | | .ant-form-item-label { |
| | |
| | | * @return {Object} setting 页面设置 |
| | | * @return {Array} regoptions 搜索条件正则替换 |
| | | */ |
| | | static getDebugSql (setting, arr_field, regoptions, search) { |
| | | static getDebugSql (setting, scripts, arr_field, regoptions, search) { |
| | | let sql = '' |
| | | let _dataresource = setting.dataresource |
| | | let _customScript = setting.customScript |
| | | let _customScript = '' |
| | | scripts && scripts.forEach(script => { |
| | | if (script.status !== 'false') { |
| | | _customScript += ` |
| | | ${script.sql} |
| | | ` |
| | | } |
| | | }) |
| | | |
| | | if (setting.interType === 'inner' && !setting.innerFunc && setting.default === 'false') { |
| | | if (_customScript) { |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg ='' |
| | | ${_customScript} |
| | | ` |
| | | } |
| | | |
| | | if (setting.interType === 'system' && setting.default === 'false') { |
| | | _dataresource = '' |
| | | } |
| | | |
| | |
| | | value: `'${item.value}'` |
| | | } |
| | | }) |
| | | let _search = search |
| | | |
| | | if (setting.queryType === 'statistics' && _dataresource) { |
| | | _regoptions.forEach(item => { |
| | | _dataresource = _dataresource.replace(item.reg, item.value) |
| | | }) |
| | | |
| | | _search = '' |
| | | } |
| | | |
| | | if (_customScript) { |
| | | _regoptions.push({ |
| | | reg: new RegExp('@orderBy@', 'ig'), |
| | | value: setting.order |
| | | }) |
| | | if (setting.laypage !== 'false') { |
| | | _regoptions.push({ |
| | | }, { |
| | | reg: new RegExp('@pageSize@', 'ig'), |
| | | value: 10 |
| | | }, { |
| | | reg: new RegExp('@pageIndex@', 'ig'), |
| | | value: 1 |
| | | }) |
| | | |
| | | let _search = search |
| | | |
| | | if (setting.queryType === 'statistics' && _dataresource) { |
| | | _regoptions.forEach(item => { |
| | | _dataresource = _dataresource.replace(item.reg, item.value) |
| | | }) |
| | | _search = '' |
| | | } |
| | | |
| | | if (_customScript) { |
| | | _regoptions.forEach(item => { |
| | | _customScript = _customScript.replace(item.reg, item.value) |
| | | }) |
| | |
| | | </div> |
| | | } style={{ width: '100%' }}> |
| | | <SettingComponent |
| | | type="subtable" |
| | | config={config} |
| | | mainsearch={!this.props.editSubTab && this.props.editTab.mainsearch ? this.props.editTab.mainsearch : ''} |
| | | MenuID={config.uuid} |
| | |
| | | primaryKey: '', |
| | | order: '', |
| | | dataresource: '', |
| | | interType: 'inner', |
| | | interType: 'system', |
| | | innerFunc: '', |
| | | interface: '', |
| | | outerFunc: '' |
| | |
| | | } |
| | | }) |
| | | |
| | | let _customScript = '' |
| | | config.setting.scripts && config.setting.scripts.forEach(script => { |
| | | if (script.status !== 'false') { |
| | | _customScript += ` |
| | | ${script.sql} |
| | | ` |
| | | } |
| | | }) |
| | | |
| | | if (_customScript) { |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg ='' |
| | | ${_customScript} |
| | | ` |
| | | } |
| | | |
| | | let param = { |
| | | func: 's_get_para_for_out', |
| | | Menuid: menu.MenuID, |
| | |
| | | Ltextsearchparam: _search.join(' union all '), |
| | | AppendWhere: config.setting.queryType === 'query' ? searchText.join(' AND ') : '', |
| | | WhereType: config.setting.queryType === 'statistics' ? 'Statistics' : 'query', |
| | | custom_script: config.setting.customScript || '', |
| | | custom_script: _customScript, |
| | | default_sql: config.setting.default || 'true', |
| | | OrderCol: config.setting.order |
| | | } |
| | |
| | | const Formdict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | |
| | | /** |
| | | * @description 获取页面设置表单配置信息 |
| | | * @param {object} setting // 菜单全局设置信息 |
| | | * @param {array} usefulFields // 内部函数可用的开头字符 |
| | | * @param {string} MenuID // 菜单ID |
| | | * @param {string} primaryKey // 主键 |
| | | * @param {zrray} columns // 显示列 |
| | | * @param {string} type // 菜单类型,main(主表) |
| | | */ |
| | | export function getSettingForm (setting, usefulFields = [], MenuID, primaryKey, columns, type) { |
| | | let str = '^(' + usefulFields.join('|') + ')' |
| | | let _patten = new RegExp(str + formRule.func.innerPattern + '$', 'g') |
| | | |
| | | return [ |
| | | { |
| | | type: 'text', |
| | | key: 'tableName', |
| | | label: '表名', |
| | | initVal: setting.tableName || '', |
| | | required: true, |
| | | readonly: false, |
| | | rules: [ |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'tableType', |
| | | label: '表格属性', |
| | | initVal: setting.tableType, |
| | | required: false, |
| | | readonly: false, |
| | | options: [ |
| | | { value: '', text: '不可选' }, |
| | | { value: 'radio', text: '单选' }, |
| | | { value: 'checkbox', text: '多选' } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'interType', |
| | | label: Formdict['header.form.intertype'], |
| | | initVal: setting.interType || 'inner', |
| | | required: false, |
| | | readonly: false, |
| | | options: [ |
| | | { value: 'inner', text: Formdict['header.form.interface.inner'] }, |
| | | { value: 'outer', text: Formdict['header.form.interface.outer'] } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'sysInterface', |
| | | label: Formdict['header.form.sysInterface'], |
| | | initVal: setting.sysInterface || 'false', |
| | | required: false, |
| | | readonly: false, |
| | | options: [ |
| | | { value: 'true', text: Formdict['model.true'] }, |
| | | { value: 'false', text: Formdict['model.false'] } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'interface', |
| | | label: Formdict['header.form.interface'], |
| | | initVal: setting.sysInterface === 'true' ? (window.GLOB.mainSystemApi || '') : (setting.interface || ''), |
| | | required: true, |
| | | readonly: setting.sysInterface === 'true', |
| | | rules: [ |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'outerFunc', |
| | | label: Formdict['header.form.outerFunc'], |
| | | initVal: setting.outerFunc || '', |
| | | required: false, |
| | | readonly: false, |
| | | rules: [ |
| | | { |
| | | pattern: formRule.func.pattern, |
| | | message: formRule.func.message |
| | | }, { |
| | | max: formRule.func.max, |
| | | message: formRule.func.maxMessage |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'innerFunc', |
| | | label: Formdict['header.form.innerFunc'], |
| | | initVal: setting.innerFunc || '', |
| | | tooltip: '开头可用字符:' + usefulFields.join(', '), |
| | | required: false, |
| | | readonly: false, |
| | | rules: [ |
| | | { |
| | | pattern: _patten, |
| | | message: formRule.func.innerMessage |
| | | }, { |
| | | max: formRule.func.max, |
| | | message: formRule.func.maxMessage |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'datasource', |
| | | key: 'dataresource', |
| | | label: '数据源', |
| | | initVal: setting.dataresource || '', |
| | | tooltip: '使用系统函数时,需填写数据源。注:数据权限替换符 $@ -> /* 或 \'\'、 @$ -> */ 或 \'\'', |
| | | help: '数据ID:' + MenuID, |
| | | required: false, |
| | | readonly: false, |
| | | rules: [ |
| | | { |
| | | pattern: _patten, |
| | | message: formRule.func.innerMessage |
| | | }, { |
| | | max: formRule.func.max, |
| | | message: formRule.func.maxMessage |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'primaryKey', |
| | | label: '主键', |
| | | initVal: primaryKey, |
| | | required: false, |
| | | readonly: false, |
| | | options: columns |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'order', |
| | | label: '默认排序', |
| | | initVal: setting.order || (primaryKey ? primaryKey + ' desc' : ''), |
| | | placeholder: 'ID asc, UID desc', |
| | | required: true, |
| | | readonly: false, |
| | | rules: [ |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'queryType', |
| | | label: Formdict['header.form.queryType'], |
| | | initVal: setting.queryType || 'query', |
| | | tooltip: '查询时,搜索条件以where条件拼接进入sql,统计时,将数据源中以“@+搜索字段+@”的内容,以搜索条件中的值进行替换后,提交查询,注:查询类型仅在使用系统函数时有效。', |
| | | required: false, |
| | | readonly: false, |
| | | options: [ |
| | | { value: 'query', text: Formdict['header.form.query'] }, |
| | | { value: 'statistics', text: Formdict['header.form.statistics'] } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'actionfixed', |
| | | label: '按钮固定', |
| | | initVal: setting.actionfixed ? 'true' : 'false', |
| | | required: false, |
| | | readonly: false, |
| | | forbid: type !== 'main', |
| | | options: [ |
| | | { value: 'true', text: Formdict['model.true'] }, |
| | | { value: 'false', text: Formdict['model.false'] } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'columnfixed', |
| | | label: '表头固定', |
| | | initVal: setting.columnfixed ? 'true' : 'false', |
| | | required: false, |
| | | readonly: false, |
| | | forbid: type !== 'main', |
| | | options: [ |
| | | { value: 'true', text: Formdict['model.true'] }, |
| | | { value: 'false', text: Formdict['model.false'] } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'onload', |
| | | label: '初始化', |
| | | initVal: setting.onload || 'true', |
| | | required: false, |
| | | readonly: false, |
| | | options: [ |
| | | { value: 'true', text: '加载数据' }, |
| | | { value: 'false', text: '不加载数据' } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'laypage', |
| | | label: '是否分页', |
| | | initVal: setting.laypage || 'true', |
| | | required: false, |
| | | readonly: false, |
| | | options: [ |
| | | { value: 'true', text: Formdict['model.true'] }, |
| | | { value: 'false', text: Formdict['model.false'] } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'default', |
| | | label: '默认sql', |
| | | initVal: setting.default || 'true', |
| | | required: false, |
| | | readonly: false, |
| | | options: [ |
| | | { value: 'true', text: '执行' }, |
| | | { value: 'false', text: '不执行' } |
| | | ] |
| | | }, |
| | | ] |
| | | } |
| | | |
| | | /** |
| | | * @description 获取树形页面设置表单配置信息 |
| | | * @param {object} setting // 菜单全局设置信息 |
| | | * @param {array} usefulFields // 可用开始字符 |