src/menu/actioncomponent/formconfig.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/menu/actioncomponent/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/menu/components/chart/antv-bar/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/menu/datasource/verifycard/settingform/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/tabviews/zshare/actionList/newpagebutton/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/templates/sharecomponent/columncomponent/dragcolumn/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/templates/sharecomponent/settingcomponent/settingform/datasource/index.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/templates/sharecomponent/settingcomponent/settingform/datasource/utils.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/menu/actioncomponent/formconfig.jsx
@@ -395,7 +395,15 @@ value: 'false', text: '非必填' }] } }, // { // type: 'select', // key: 'linkcomponents', // label: '', // initVal: card.Ot || 'requiredSgl', // required: true, // options: [] // } ] if (type === 'chart') { src/menu/actioncomponent/index.jsx
@@ -28,7 +28,6 @@ type: PropTypes.string, // 菜单类型,主表或子表 menu: PropTypes.object, // 菜单信息(菜单id,菜单参数,菜单名称) config: PropTypes.object, // 菜单配置信息 usefulFields: PropTypes.array, // 自定义函数可用字段 tabs: PropTypes.array, // 所有标签 setSubConfig: PropTypes.func, // 设置子配置信息 updateaction: PropTypes.func // 菜单配置更新 @@ -84,8 +83,7 @@ * @description 按钮编辑,获取按钮表单信息 */ handleAction = (card) => { const { menu } = this.props const { config } = this.props const { menu, config } = this.props let ableField = menu.permFuncField ? menu.permFuncField.join(', ') : '' let functip = <div> @@ -104,6 +102,23 @@ }) } // let modules = [] // menu.components.forEach(item => { // if (item.uuid === config.uuid) return // modules.push({ // value: item.uuid, // text: item.setting.name // }) // }) // if (supModule && supModule !== 'empty') { // if (modules.filter(item => item.value === supModule).length === 0) { // supModule = '' // } // } if (menu.fstMenuList && card.linkmenu && card.linkmenu.length > 0) { let _param = { func: 'sPC_Get_FunMenu', src/menu/components/chart/antv-bar/index.jsx
@@ -590,7 +590,6 @@ menu={config} config={card} tabs={[]} usefulFields={config.permFuncField || []} // setSubConfig={(_btn) => this.setSubConfig(_btn, 'button')} updateaction={this.updateComponent} /> src/menu/datasource/verifycard/settingform/index.jsx
@@ -24,12 +24,12 @@ } UNSAFE_componentWillMount () { const { menu, setting } = this.props const { menu, setting, config } = this.props let supModule = setting.supModule || '' let modules = [] menu.components.forEach(item => { if (!item.switchable || !item.setting || !item.setting.name) return if (!item.switchable || !item.setting || !item.setting.name || item.uuid === config.uuid) return modules.push({ value: item.uuid, src/tabviews/zshare/actionList/newpagebutton/index.jsx
@@ -108,9 +108,11 @@ } else if (btn.pageTemplate === 'custom') { let url = btn.url if (btn.Ot === 'requiredSgl' && btn.joint !== 'false') { url = url + `?id=${Id}&appkey=${window.GLOB.appkey}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}` url = url + `?id=${Id}&appkey=${window.GLOB.appkey}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}` } else if (btn.Ot === 'requiredSgl' && btn.joint === 'false') { url = url + `?id=${Id}` } else if (btn.joint !== 'false') { url = url + `?appkey=${window.GLOB.appkey}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}` url = url + `?appkey=${window.GLOB.appkey}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}` } window.open(url) src/templates/sharecomponent/columncomponent/dragcolumn/index.jsx
@@ -2,7 +2,7 @@ import { useDrop } from 'react-dnd' import { is, fromJS } from 'immutable' import update from 'immutability-helper' import { Icon } from 'antd' import { Icon, Popover } from 'antd' import Utils from '@/utils/utils.js' import Card from './card' import './index.scss' @@ -153,16 +153,21 @@ /> ))} {i === (columns.length - 1) && gridBtn && gridBtn.display ? <div className="page-card" style={{flex: gridBtn.Width}}> <div style={{cursor: 'default'}}> <span className="ant-table-header-column"> <div className="ant-table-column-sorters" title={gridBtn.label} style={{textAlign: gridBtn.Align}}> <span className="ant-table-column-title">{gridBtn.label}</span> </div> </span> <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ <div className="mk-popover-control"> <Icon className="edit" type="edit" onClick={handleGridBtn}/> </div> <Icon className="edit" type="edit" onClick={handleGridBtn}/> </div> : null } trigger="hover"> <div className="page-card" style={{flex: gridBtn.Width}}> <div style={{cursor: 'default'}}> <span className="ant-table-header-column"> <div className="ant-table-column-sorters" title={gridBtn.label} style={{textAlign: gridBtn.Align}}> <span className="ant-table-column-title">{gridBtn.label}</span> </div> </span> </div> </div> </Popover> : null } </div> ))} src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx
New file @@ -0,0 +1,297 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { Form, Row, Col, Input, Radio, Tooltip, Icon, notification } 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, // 字典项 menuId: PropTypes.string, // 菜单Id permFuncField: PropTypes.any, // 菜单Id setting: PropTypes.object, // 数据源配置 columns: PropTypes.array, // 列设置 scripts: PropTypes.array, // 自定义脚本 } state = { interType: this.props.setting.interType || 'inner', } handleConfirm = () => { const { setting } = this.props // 表单提交时检查输入值是否正确 return new Promise((resolve, reject) => { this.props.form.validateFieldsAndScroll((err, values) => { if (!err) { // 数据源前端验证 if (values.interType === 'inner' && !values.innerFunc && values.execute !== 'false' && !values.dataresource) { notification.warning({ top: 92, message: '请填写内部函数或数据源!', duration: 5 }) reject() return } else if (values.interType === 'inner' && !values.innerFunc && values.execute !== '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 === 'inner' && !values.innerFunc && values.execute !== '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 } 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 }) } } render() { const { setting, permFuncField } = this.props const { getFieldDecorator } = this.props.form const { interType } = this.state const formItemLayout = { labelCol: { xs: { span: 24 }, sm: { span: 8 } }, wrapperCol: { xs: { span: 24 }, sm: { span: 16 } } } 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"> <Form {...formItemLayout} className="model-setting-form"> <Row gutter={24}> <Col span={8}> <Form.Item label="表名"> {getFieldDecorator('tableName', { initialValue: setting.tableName, rules: [ { required: true, message: this.props.dict['form.required.input'] + '表名!' }, ] })(<Input placeholder={''} autoComplete="off" />)} </Form.Item> </Col> <Col span={8}> <Form.Item label="接口类型"> {getFieldDecorator('interType', { initialValue: interType, rules: [ { required: true, message: this.props.dict['form.required.select'] + '接口类型!' }, ] })( <Radio.Group onChange={(e) => {this.onRadioChange(e, 'interType')}}> <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}> <Icon type="question-circle" /> 内部函数 </Tooltip> : '内部函数' }> {getFieldDecorator('innerFunc', { initialValue: setting.innerFunc || '', rules: rules })(<Input placeholder={''} autoComplete="off" />)} </Form.Item> </Col> : null} {interType === 'outer' ? <Col span={8}> <Form.Item label="接口地址"> {getFieldDecorator('interface', { initialValue: setting.interface || '', rules: [ { required: true, message: this.props.dict['form.required.input'] + '接口地址!' }, ] })(<Input placeholder={''} autoComplete="off" />)} </Form.Item> </Col> : null} {interType === 'outer' ? <Col span={8}> <Form.Item label="外部函数"> {getFieldDecorator('outerFunc', { initialValue: setting.outerFunc || '', rules: [ ] })(<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={ <Tooltip placement="topLeft" title={'使用系统函数时,需填写数据源。注:数据权限替换符 $@ -> /* 或 \'\'、 @$ -> */ 或 \'\''}> <Icon type="question-circle" /> 数据源 </Tooltip> }> {getFieldDecorator('dataresource', { initialValue: setting.dataresource || '' })(<CodeMirror />)} </Form.Item> </Col> : null} {interType === 'inner' ? <Col span={8}> <Form.Item label={ <Tooltip placement="topLeft" title={'查询时,搜索条件以where条件拼接进入sql,统计时,将数据源中以“@+搜索字段+@”的内容,以搜索条件中的值进行替换后,提交查询,注:查询类型仅在使用系统函数时有效。'}> <Icon type="question-circle" /> 查询类型 </Tooltip> }> {getFieldDecorator('queryType', { initialValue: setting.queryType || 'query' })( <Radio.Group> <Radio value="query">查询</Radio> <Radio value="statistics">统计</Radio> </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}> <Form.Item label="默认sql"> {getFieldDecorator('execute', { initialValue: setting.execute || 'true' })( <Radio.Group> <Radio value="true">执行</Radio> <Radio value="false">不执行</Radio> </Radio.Group>)} </Form.Item> </Col> : null} <Col span={8}> <Form.Item label="初始化"> {getFieldDecorator('onload', { initialValue: setting.onload || 'true' })( <Radio.Group> <Radio value="true">加载数据</Radio> <Radio value="false">不加载数据</Radio> </Radio.Group>)} </Form.Item> </Col> </Row> </Form> </div> ) } } export default Form.create()(SettingForm) src/templates/sharecomponent/settingcomponent/settingform/datasource/index.scss
New file @@ -0,0 +1,22 @@ .model-datasource-setting-form-box { position: relative; .model-setting-form { .data-source { .ant-form-item-label { width: 11%; } .ant-form-item-control-wrapper { width: 89%; } .CodeMirror { height: 150px; } } .anticon-question-circle { color: #c49f47; margin-right: 3px; } } } src/templates/sharecomponent/settingcomponent/settingform/datasource/utils.jsx
New file @@ -0,0 +1,84 @@ export default class SettingUtils { /** * @description 生成页面查询语句 * @return {String} arr_field 显示列字段 * @return {String} search 搜索条件 * @return {Object} setting 页面设置 * @return {Array} regoptions 搜索条件正则替换 */ static getDebugSql (setting, arr_field, regoptions, search) { let sql = '' let _dataresource = setting.dataresource let _customScript = setting.customScript if (setting.interType === 'inner' && !setting.innerFunc && setting.default === 'false') { _dataresource = '' } if (_dataresource) { _dataresource = _dataresource.replace(/@\$|\$@/ig, '') } if (_customScript) { _customScript = _customScript.replace(/@\$|\$@/ig, '') } // 正则替换 let _regoptions = regoptions.map(item => { return { reg: new RegExp('@' + item.key + '@', 'ig'), 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 }) } _regoptions.forEach(item => { _customScript = _customScript.replace(item.reg, item.value) }) } // 数据源处理, 存在显示列时 if (arr_field && _dataresource) { if (/\s/.test(_dataresource)) { _dataresource = '(' + _dataresource + ') tb' } _dataresource = `select ${setting.laypage !== 'false' ? 'top 10' : ''} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${setting.order}) as rows from ${_dataresource} ${_search}) tmptable ${setting.laypage !== 'false' ? 'where rows > 0' : ''} order by tmptable.rows` } if (_customScript) { sql = `${_customScript} ${_dataresource} aaa: if @ErrorCode!='' insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@ ` } else { sql = _dataresource } return sql } }