<template> <a-modal :title="title" :width="1000" :visible="visible" :confirmLoading="confirmLoading" @ok="handleOk" @cancel="handleCancel" cancelText="关闭"> <a-spin :spinning="confirmLoading"> <a-form-model ref="form" :model="model" :rules="validatorRules"> <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="规则名称" prop="ruleName"> <a-input placeholder="请输入规则名称" v-model="model.ruleName"/> </a-form-model-item> <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="规则Code" prop="ruleCode"> <a-input placeholder="请输入规则Code" v-model="model.ruleCode"/> </a-form-model-item> <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="规则描述" prop="ruleDescription"> <a-textarea placeholder="请输入规则描述" v-model="model.ruleDescription"/> </a-form-model-item> </a-form-model> <!-- 规则设计 --> <a-tabs v-model="tabs.activeKey"> <a-tab-pane tab="局部规则" :key="tabs.design.key" forceRender> <a-alert type="info" showIcon message="局部规则按照你输入的位数有序的校验。"/> <j-editable-table ref="designTable" dragSort rowNumber :maxHeight="240" :columns="tabs.design.columns" :dataSource="tabs.design.dataSource" style="margin-top: 8px;"> <template #action="props"> <my-action-button :rowEvent="props"/> </template> </j-editable-table> </a-tab-pane> <a-tab-pane tab="全局规则" :key="tabs.global.key" forceRender> <j-editable-table ref="globalTable" dragSort rowNumber actionButton :maxHeight="240" :columns="tabs.global.columns" :dataSource="tabs.global.dataSource"> <template #actionButtonAfter> <a-alert type="info" showIcon message="全局规则可校验用户输入的所有字符;全局规则的优先级比局部规则的要高。" style="margin-bottom: 8px;"/> </template> <template #action="props"> <my-action-button :rowEvent="props" allowEmpty/> </template> </j-editable-table> </a-tab-pane> </a-tabs> </a-spin> </a-modal> </template> <script> import pick from 'lodash.pick' import {httpAction} from '@/api/manage' import {validateDuplicateValue, alwaysResolve, failedSymbol} from '@/utils/util' import {FormTypes} from '@/utils/JEditableTableUtil' import JEditableTable from '@comp/jeecg/JEditableTable' export default { name: 'SysCheckRuleModal', components: { JEditableTable, 'my-action-button': { props: {rowEvent: Object, allowEmpty: Boolean}, methods: { confirmIsShow() { const {index, allValues: {inputValues}} = this.rowEvent let value = inputValues[index] return value.digits || value.pattern }, handleLineAdd() { const {target} = this.rowEvent target.add() }, handleLineDelete() { const {rowId, target} = this.rowEvent target.removeRows(rowId) }, renderDeleteButton() { if (this.allowEmpty || this.rowEvent.index > 0) { if (this.confirmIsShow()) { return ( <a-popconfirm title="确定要删除吗?" onConfirm={this.handleLineDelete}> <a-button icon="minus"/> </a-popconfirm> ) } else { return ( <a-button icon="minus" onClick={this.handleLineDelete}/> ) } } return '' }, }, render() { return ( <div> <a-button onClick={this.handleLineAdd} icon="plus"/> {this.renderDeleteButton()} </div> ) } } }, data() { return { title: '操作', visible: false, model: {}, labelCol: { xs: {span: 24}, sm: {span: 5}, }, wrapperCol: { xs: {span: 24}, sm: {span: 16}, }, confirmLoading: false, validatorRules: { ruleName: [{required: true, message: '请输入规则名称!'}], ruleCode: [ {required: true, message: '请输入规则Code!'}, {validator: (rule, value, callback) => validateDuplicateValue('sys_check_rule', 'rule_code', value, this.model.id, callback)} ], }, tabs: { activeKey: 'design', global: { key: 'global', columns: [ { title: '优先级', key: 'priority', width: '15%', type: FormTypes.select, defaultValue: '1', options: [ {title: '优先运行', value: '1'}, {title: '最后运行', value: '0'}, ], validateRules: [] }, { title: '规则(正则表达式)', key: 'pattern', width: '50%', type: FormTypes.input, validateRules: [ {required: true, message: '规则不能为空'}, {handler: this.validatePatternHandler}, ] }, { title: '提示文本', key: 'message', width: '20%', type: FormTypes.input, validateRules: [ {required: true, message: '${title}不能为空'}, ] }, { title: '操作', key: 'action', width: '15%', slotName: 'action', type: FormTypes.slot } ], dataSource: [], }, design: { key: 'design', columns: [ { title: '位数', key: 'digits', width: '15%', type: FormTypes.inputNumber, validateRules: [ {required: true, message: '${title}不能为空'}, {pattern: /^[1-9]\d*$/, message: '请输入零以上的正整数'}, ] }, { title: '规则(正则表达式)', key: 'pattern', width: '50%', type: FormTypes.input, validateRules: [ {required: true, message: '规则不能为空'}, {handler: this.validatePatternHandler} ] }, { title: '提示文本', key: 'message', width: '20%', type: FormTypes.input, validateRules: [ {required: true, message: '${title}不能为空'}, ] }, { title: '操作', key: 'action', width: '15%', slotName: 'action', type: FormTypes.slot }, ], dataSource: [], } }, url: { add: '/sys/checkRule/add', edit: '/sys/checkRule/edit', }, } }, created() { }, methods: { validatePatternHandler(type, value, row, column, callback, target) { if (type === 'blur' || type === 'getValues') { try { new RegExp(value) callback(true) } catch (e) { callback(false, '请输入正确的正则表达式') } } else { callback(true) // 不填写或者填写 null 代表不进行任何操作 } }, add() { this.edit({}) }, edit(record) { this.tabs.activeKey = this.tabs.design.key this.tabs.global.dataSource = [] this.tabs.design.dataSource = [{digits: '', pattern: '', message: ''}] this.visible = true this.$nextTick(() => { this.$refs.form.resetFields() this.model = Object.assign({}, record) // 子表数据 let ruleJson = this.model.ruleJson if (ruleJson) { let ruleList = JSON.parse(ruleJson) // 筛选出全局规则和局部规则 let global = [], design = [], priority = '1' ruleList.forEach(rule => { if (rule.digits === '*') { global.push(Object.assign(rule, {priority})) } else { priority = '0' design.push(rule) } }) this.tabs.global.dataSource = global this.tabs.design.dataSource = design } }) }, close() { this.$emit('close') this.visible = false }, handleOk() { Promise.all([ // 主表单校验 alwaysResolve(new Promise((resolve, reject) => { this.$refs.form.validate((ok, err) => ok ? resolve(this.model) : reject(err)) })), // 局部规则子表校验 alwaysResolve(this.$refs.designTable.getValuesPromise), // 全局规则子表校验 alwaysResolve(this.$refs.globalTable.getValuesPromise), ]).then(results => { let [mainResult, designResult, globalResult] = results if (mainResult.type === failedSymbol) { return Promise.reject('主表校验未通过') } else if (designResult.type === failedSymbol) { this.tabs.activeKey = this.tabs.design.key return Promise.reject('局部规则子表校验未通过') } else if (globalResult.type === failedSymbol) { this.tabs.activeKey = this.tabs.global.key return Promise.reject('全局规则子表校验未通过') } else { // 所有校验已通过,这一步是整合数据 let mainValues = mainResult.data, globalValues = globalResult.data, designValues = designResult.data // 整合两个子表的数据 let firstGlobal = [], afterGlobal = [] globalValues.forEach(v => { v.digits = '*' if (v.priority === '1') { firstGlobal.push(v) } else { afterGlobal.push(v) } }) let concatValues = firstGlobal.concat(designValues).concat(afterGlobal) let subValues = concatValues.map(i => pick(i, 'digits', 'pattern', 'message')) // 生成 formData,用于传入后台 let ruleJson = JSON.stringify(subValues) let formData = Object.assign(this.model, mainValues, {ruleJson}) // 判断请求方式和请求地址,并发送请求 let method = 'post', httpUrl = this.url.add if (this.model.id) { method = 'put' httpUrl = this.url.edit } this.confirmLoading = true return httpAction(httpUrl, formData, method) } }).then((res) => { if (res.success) { this.$message.success(res.message) this.$emit('ok') this.close() } else { this.$message.warning(res.message) } }).catch(e => { console.error(e) }).finally(() => { this.confirmLoading = false }) }, handleCancel() { this.close() }, } } </script> <style lang="less" scoped></style>