feat()规则引擎

dev-1
王熙朝 2024-05-06 14:33:29 +08:00
parent 7e498b07b9
commit f6ad3142f9
6 changed files with 196 additions and 180 deletions

View File

@ -53,6 +53,7 @@
"screenfull": "5.0.2", "screenfull": "5.0.2",
"sortablejs": "1.10.2", "sortablejs": "1.10.2",
"vue": "2.6.12", "vue": "2.6.12",
"vue-codemirror": "^4.0.6",
"vue-count-to": "1.0.13", "vue-count-to": "1.0.13",
"vue-cropper": "0.5.5", "vue-cropper": "0.5.5",
"vue-meta": "2.4.0", "vue-meta": "2.4.0",

View File

@ -9,6 +9,14 @@ export function listConfig(query) {
}) })
} }
// 查询引擎列表
export function listConfigEs(ruleId) {
return request({
url: '/goods/config/listConfigEs/' + ruleId,
method: 'post'
})
}
// 查询引擎详细 // 查询引擎详细
export function getConfig(id) { export function getConfig(id) {
return request({ return request({
@ -42,3 +50,18 @@ export function delConfig(id) {
method: 'delete' method: 'delete'
}) })
} }
// 测试
export function textData(data) {
return request({
url: '/goods/config/testData',
method: 'post',
data
})
}
// 通过引擎作用域编号获取引擎配置作用域信息
export function getScopeInfo(id) {
return request({
url: '/goods/config/getScopeInfo/' + id,
method: 'post'
})
}

View File

@ -1,35 +1,35 @@
<template> <template>
<div style="height: 800px"> <div style="height: 800px">
<codemirror ref="codeMirror" :value="code" :options="cmOptions" style="height: 800px"></codemirror> <codemirror ref="codeMirror" v-model="code" :options="cmOptions" style="height: 800px"/>
</div> </div>
</template> </template>
<script> <script>
import { codemirror } from 'vue-codemirror'
// import 'codemirror/mode/clike/clike'; import 'codemirror/mode/clike/clike';
// // cm-setting.js // cm-setting.js
// // //
// import 'codemirror/lib/codemirror.css'; import 'codemirror/lib/codemirror.css';
// // //
// import 'codemirror/theme/eclipse.css'; import 'codemirror/theme/eclipse.css';
// import 'codemirror/theme/monokai.css'; // import 'codemirror/theme/monokai.css';
// // html // html
// import 'codemirror/mode/htmlmixed/htmlmixed.js'; import 'codemirror/mode/htmlmixed/htmlmixed.js';
// //
// import 'codemirror/mode/javascript/javascript.js'; //
// import 'codemirror/mode/css/css.js'; import 'codemirror/mode/javascript/javascript.js';
// import 'codemirror/mode/xml/xml.js'; import 'codemirror/mode/css/css.js';
// // import 'codemirror/mode/xml/xml.js';
// import 'codemirror/addon/fold/foldcode.js'; //
// import 'codemirror/addon/fold/foldgutter.js'; import 'codemirror/addon/fold/foldcode.js';
// import 'codemirror/addon/fold/foldgutter.css'; import 'codemirror/addon/fold/foldgutter.js';
// import 'codemirror/addon/fold/brace-fold.js'; import 'codemirror/addon/fold/foldgutter.css';
// jsjsjson, import 'codemirror/addon/fold/brace-fold.js';
// import from ',
export default { export default {
// import使" components: {
components: { codemirror }, codemirror,
},
props: { props: {
value: { value: {
default: "", default: "",
@ -40,58 +40,47 @@ export default {
type: Boolean type: Boolean
} }
}, },
name: "Encoding",
data() { data() {
// "
return { return {
codemirror: null, codemirror: null,
code:this.value, code: this.value,
cmOptions: { cmOptions: {
autoRefresh: true, autoRefresh: true, // true
value: '', value: '', //
mode: 'text/x-java', mode: 'text/x-java', //Java
tabSize: 4, tabSize: 4, // tab
styleActiveLine: true, styleActiveLine: true, // true/false
lineNumbers: true, lineNumbers: true, //
theme: 'eclipse', theme: 'eclipse', //cobalt/monokai
readOnly: this.readOnly, // json: true,
lineWrapping: true, readOnly: this.readOnly, // true/false;"nocursor"
lineWrapping: false,
foldGutter: true,
gutters: [ gutters: [
'CodeMirror-lint-markers', // 'CodeMirror-lint-markers', //
'CodeMirror-linenumbers', 'CodeMirror-linenumbers',
'CodeMirror-foldgutter', // 'CodeMirror-foldgutter', //
] ],
} },
}
},
watch:{
code:{
handler(val){
this.$emit('input', val);
},
immediate:true
} }
}, },
// data",
computed: {},
// data",
watch: {},
// ",
methods: {},
// - 访this",
created() { created() {
}, },
// - 访DOM", methods: {}
mounted() {
},
beforeCreate() {
}, // - ",
beforeMount() {
}, // - ",
beforeUpdate() {
}, // - ",
updated() {
}, // - ",
beforeDestroy() {
}, // - ",
destroyed() {
}, // - ",
activated() {
} // keep-alive",
} }
</script> </script>
<style scoped>
<style>
.CodeMirror { .CodeMirror {
font-family: 'JetBrainsMono-Medium', monospace; font-family: 'JetBrainsMono-Medium', monospace;
height: 800px; height: 800px;

View File

@ -18,7 +18,8 @@
</div> </div>
<el-tabs type="border-card" v-model="codeCardStatus"> <el-tabs type="border-card" v-model="codeCardStatus">
<el-tab-pane v-for="scope in scopeList" :label="scope.type" :name="scope.val"> <el-tab-pane v-for="scope in scopeList" :label="scope.type" :name="scope.val">
<encoding v-if="codeCardStatus === scope.val" style="height: 800px" v-model="scope.code" :read-only="true">{{scope.code}}</encoding> <encoding v-if="codeCardStatus === scope.val" style="height: 800px" v-model="scope.code" :read-only="true">
</encoding>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-card> </el-card>
@ -30,9 +31,10 @@
// jsjsjson, // jsjsjson,
// import from ', // import from ',
import { listCope } from '@/api/goods/cope' import { listCope } from '@/api/goods/cope'
import Encoding from "@/components/Encoding/index.vue";
export default { export default {
// import使" // import使"
components: { }, components: { Encoding },
props: {}, props: {},
data() { data() {
// " // "

View File

@ -342,7 +342,7 @@ export default {
}); });
}, },
toEngineVersion(row){ toEngineVersion(row){
this.$router.push( {path: `/engine/version/${row.ruleId}`}); this.$router.push( {path: `version/${row.ruleId}`});
// selectRuleEngineByRuleId(row.ruleId).then(res => { // selectRuleEngineByRuleId(row.ruleId).then(res => {
// this.engine = res.data // this.engine = res.data
// this.cisid = true; // this.cisid = true;

View File

@ -6,117 +6,81 @@
<el-button style="float: right" @click="goBack" size="medium" type="text">返回</el-button> <el-button style="float: right" @click="goBack" size="medium" type="text">返回</el-button>
</div> </div>
<el-descriptions border :column="3"> <el-descriptions border :column="3">
<el-descriptions-item label="主键">{{ruleInfo.ruleId}}</el-descriptions-item>
<el-descriptions-item label="规则名称">{{ruleInfo.ruleName}}</el-descriptions-item> <el-descriptions-item label="规则名称">{{ruleInfo.ruleName}}</el-descriptions-item>
<el-descriptions-item label="引擎编码">{{ruleInfo.ruleCode}}</el-descriptions-item> <el-descriptions-item label="引擎编码">{{ruleInfo.ruleCode}}</el-descriptions-item>
<el-descriptions-item label="规则级别">{{ruleInfo.ruleLevel}}</el-descriptions-item> <el-descriptions-item label="规则级别">{{ruleInfo.ruleLevel}}</el-descriptions-item>
<el-descriptions-item label="规则类型">{{ruleInfo.ruleType}}</el-descriptions-item> <el-descriptions-item label="规则类型">{{ruleInfo.ruleType}}</el-descriptions-item>
<el-descriptions-item label="是否激活">{{ruleInfo.ruleIsActivate}}</el-descriptions-item> <el-descriptions-item label="是否激活">
<el-descriptions-item label="规则状态">{{ruleInfo.ruleStatus}}</el-descriptions-item> <el-tag size="small" v-if="ruleInfo.ruleIsActivate === 'Y'"></el-tag>
<el-descriptions-item label="代码文本">{{ruleInfo.description}}</el-descriptions-item> <el-tag size="small" v-if="ruleInfo.ruleIsActivate === 'N'"></el-tag>
<el-descriptions-item label="备注">{{ruleInfo.remark}}</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="规则状态">
<el-tag size="small" v-if="ruleInfo.ruleStatus === 'Y'"></el-tag>
<el-tag size="small" v-if="ruleInfo.ruleStatus === 'N'"></el-tag>
</el-descriptions-item>
</el-descriptions> </el-descriptions>
</el-card> </el-card>
<el-card :body-style="{ padding: '0.3px' }" class="versionContainer" style="width: 95%;margin-left: 35px;margin-top: 10px"> <el-card :body-style="{ padding: '0.3px' }" class="versionContainer" style="width: 95%;margin-left: 35px;margin-top: 10px">
<el-row :gutter="10" class="mb8"> <div slot="header" class="clearfix">
<el-col :span="1.5"> <span>规则内容</span>
<el-button <el-button style="float: right;margin-left: 5px" @click="handleDel" size="medium" type="text">删除此版本</el-button>
type="primary" <el-button style="float: right;margin-left: 5px" @click="handleAdd" size="medium" type="text">新增版本</el-button>
plain <el-button style="float: right;margin-left: 5px" @click="()=>{this.visible=true;}" size="medium" type="text">测试规则</el-button>
icon="el-icon-plus" <el-button style="float: right;margin-left: 5px" @click="saveContent" size="medium" type="text">保存此版本</el-button>
size="mini" </div>
@click="handleAdd" <div style="padding: 0!important;overflow: hidden;position: relative;">
v-hasPermi="['goods:config:add']" <el-empty v-if="versionList.length===0" description="暂无规则内容" style="height: 450px"></el-empty>
>新增</el-button> <el-tabs v-else type="border-card" v-model="activeName" >
</el-col> <el-tab-pane :key="index" v-for="(scope,index) in versionList" :label="scope.versionCode" :name="index+''">
<el-col :span="1.5"> <encoding v-if="activeName===index.toString()" style="height: 600px" v-model="scope.ruleContent" ></encoding>
<el-button </el-tab-pane>
type="success" </el-tabs>
plain <el-drawer
icon="el-icon-edit" title="规则测试"
size="mini" :visible.sync="visible"
:disabled="single" :before-close="handleClose"
@click="handleUpdate" :lockScroll="false"
v-hasPermi="['goods:config:edit']" :modal="false"
>修改</el-button> direction="rtl"
</el-col> style="position: absolute;"
<el-col :span="1.5"> >
<el-button <el-form >
type="danger" <el-form-item label="测试数据" style="margin-left: 5px">
plain <el-input type="textarea" v-model="testData" ></el-input>
icon="el-icon-delete" </el-form-item>
size="mini" <el-form-item label="测试结果" style="margin-left: 5px">
:disabled="multiple" <el-input type="textarea" v-model="resData" ></el-input>
@click="handleDelete" </el-form-item>
v-hasPermi="['goods:config:remove']" <el-form-item style="margin-left: 5px">
>删除</el-button> <el-button type="primary" size="small" @click="handleTest"></el-button>
</el-col> </el-form-item>
<el-col :span="1.5"> </el-form>
<el-button </el-drawer>
type="warning" </div>
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['goods:config:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="版本编码" align="center" prop="versionCode" />
<el-table-column label="规则内容" align="center" prop="ruleContent" />
<el-table-column label="维护编号" align="center" prop="ruleId" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['goods:config:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['goods:config:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改引擎对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="版本编码" prop="versionCode">
<el-input v-model="form.versionCode" placeholder="请输入版本编码" />
</el-form-item>
<el-form-item label="规则内容">
<editor v-model="form.ruleContent" :min-height="192"/>
</el-form-item>
<el-form-item label="维护编号" prop="ruleId">
<el-input v-model="form.ruleId" placeholder="请输入维护编号" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</el-card> </el-card>
<!-- 添加或修改引擎规则配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="版本编码" prop="versionCode">
<el-input v-model="form.versionCode" placeholder="请输入版本编码" />
</el-form-item>
<el-form-item label="新增依据" prop="newBasis">
<el-select v-model="form.newBasis" placeholder="请选择新增依据" style="width: 100%" @change="handlerChange">
<el-option :key="-1" label="克隆公共配置" value="-1"></el-option>
<el-option
v-for="(item,index) in versionList"
:key="index"
:label="'克隆'+item.versionCode+'版本'"
:value="index">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
@ -124,18 +88,20 @@
// jsjsjson, // jsjsjson,
// import from ', // import from ',
import { selectRuleEngineByRuleId } from "@/api/goods/engine"; import { selectRuleEngineByRuleId } from "@/api/goods/engine";
// import Encoding from "@/components/Encoding/index.vue"; import Encoding from "@/components/Encoding/index.vue";
import { listConfig, getConfig, addConfig, updateConfig, delConfig } from "@/api/goods/config"; import { listConfigEs, getConfig, addConfig, updateConfig, delConfig, textData, getScopeInfo } from "@/api/goods/config";
export default { export default {
// import使" // import使"
components: {}, components: { Encoding },
props: {}, props: {},
data() { data() {
// " // "
return { return {
visible: false, visible: false,
ruleId: 1, // configId: this.$route.params && this.$route.params.configId,
ruleId: this.$route.params && this.$route.params.ruleId,
// ruleId: 1,
ruleInfo: {}, ruleInfo: {},
// //
loading: true, loading: true,
@ -174,8 +140,11 @@ export default {
{ required: true, message: "新增依据不能为空", trigger: "blur" } { required: true, message: "新增依据不能为空", trigger: "blur" }
], ],
}, },
testData:'1424587994@163com,2949451835@qq.com',
activeName: '0', activeName: '0',
versionList: [] baseRuleContent:'',
versionList: [],
resData: ''
} }
}, },
// data", // data",
@ -188,9 +157,13 @@ export default {
selectRuleEngineByRuleId(this.ruleId).then(res => { selectRuleEngineByRuleId(this.ruleId).then(res => {
this.ruleInfo = res.data this.ruleInfo = res.data
}) })
listConfig().then(res => { listConfigEs(this.ruleId).then(res => {
this.versionList = res.data this.versionList = res.data
}) })
getScopeInfo(0).then(res => {
console.log(res.data)
this.baseRuleContent = res.data.code
})
}, },
// //
cancel() { cancel() {
@ -207,10 +180,21 @@ export default {
}; };
this.resetForm("form"); this.resetForm("form");
}, },
//
handlerChange(val){
if(val!=='-1'){
this.form.ruleContent=this.versionList[Number(val)].ruleContent;
}else {
this.form.ruleContent=this.baseRuleContent;
}
},
goBack() {
this.$router.go(-1);
},
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery() {
this.queryParams.pageNum = 1; this.queryParams.pageNum = 1;
this.getList(); this.init();
}, },
/** 重置按钮操作 */ /** 重置按钮操作 */
resetQuery() { resetQuery() {
@ -227,6 +211,7 @@ export default {
handleAdd() { handleAdd() {
this.reset(); this.reset();
this.open = true; this.open = true;
this.form.ruleId=this.ruleInfo.ruleId;
this.title = "添加引擎"; this.title = "添加引擎";
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
@ -247,33 +232,49 @@ export default {
updateConfig(this.form).then(response => { updateConfig(this.form).then(response => {
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.init();
}); });
} else { } else {
addConfig(this.form).then(response => { addConfig(this.form).then(response => {
console.log(this.form)
this.$modal.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.init();
}); });
} }
} }
}); });
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDel(row) {
const ids = row.id || this.ids; const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除引擎编号为"' + ids + '"的数据项?').then(function() { let data = this.versionList[Number(this.activeName)]
return delConfig(ids); this.$modal.confirm('是否确认删除引擎版本为"' + data.versionCode + '"的数据项?').then(function() {
return delConfig(data.id);
}).then(() => { }).then(() => {
this.getList(); this.init();
this.$modal.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).catch(() => {}); }).catch(() => {});
}, },
saveContent() {
updateConfig(this.versionList[Number(this.activeName)]).then(response => {
this.$message.success("保存成功");
})
},
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.download('system/config/export', { this.download('system/config/export', {
...this.queryParams ...this.queryParams
}, `config_${new Date().getTime()}.xlsx`) }, `config_${new Date().getTime()}.xlsx`)
},
handleTest() {
textData({id:this.versionList[Number(this.activeName)].id,list:this.testData.split(',')}).then(response=>{
this.resData=response.data;
this.$message.success("测试成功");
})
},
handleClose() {
this.visible=false;
} }
}, },
// - 访this", // - 访this",