Commit 875f2e49 by 吴斌

update:优化规则脚本触发的效果。浏览器的alert会阻塞,多次触发时,体验不好。改为通知。

parent 3d8dc5f6
...@@ -53,8 +53,6 @@ ...@@ -53,8 +53,6 @@
<div class="space-y-1 p-2 flex flex-col" v-show="ifSelectNode || ifSelectLink"> <div class="space-y-1 p-2 flex flex-col" v-show="ifSelectNode || ifSelectLink">
<div> <div>
<div class="text-[16px] font-bold text-black">属性</div> <div class="text-[16px] font-bold text-black">属性</div>
<el-checkbox v-model="horizontalFlip" @change="changeNodeFlip">水平翻转</el-checkbox>
<el-checkbox v-model="verticalFlip" @change="changeNodeFlip">竖直翻转</el-checkbox>
<div id="inspector-property"></div> <div id="inspector-property"></div>
<el-divider direction="horizontal"></el-divider> <el-divider direction="horizontal"></el-divider>
</div> </div>
...@@ -228,6 +226,24 @@ ...@@ -228,6 +226,24 @@
<el-form-item label="规则函数"> <el-form-item label="规则函数">
<el-input type="textarea" v-model="ruleDialog.data.func"></el-input> <el-input type="textarea" v-model="ruleDialog.data.func"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="触发通知">
<div>
<el-button type="primary" @click="addRuleAction">添加触发</el-button>
<div v-for="(action,index) in ruleDialog.data.actions" class="flex mt-2 space-x-1">
<div class="font-bold mr-2">{{index}}</div>
<el-select v-model="action['type']" class="flex-1">
<el-option
v-for="actionType in RuleActionType"
:key="actionType['key']"
:label="actionType['name']"
:value="actionType['key']"
/>
</el-select>
<el-input placeholder="填写触发通知内容" v-model="action['content']" class="flex-1"></el-input>
<el-button icon="Delete" type="danger" @click="deleteRuleAction(index)"></el-button>
</div>
</div>
</el-form-item>
</el-form> </el-form>
</el-scrollbar> </el-scrollbar>
<template #footer> <template #footer>
...@@ -268,7 +284,15 @@ import { ...@@ -268,7 +284,15 @@ import {
getExceedingDefectInfluenceCoefficient, getExceedingDefectInfluenceCoefficient,
getManagementSystemEvaluationCoefficient getManagementSystemEvaluationCoefficient
} from "./kit/core/Analyse.ts"; } from "./kit/core/Analyse.ts";
import {addRule, deleteRuleById, rules, runAllEnableRule, testRuleById, updateRule} from "./kit/rule/Rule"; import {
addRule,
deleteRuleById,
RuleActionType,
rules,
runAllEnableRule,
testRuleById,
updateRule
} from "./kit/rule/Rule";
import {diagramModelData} from "./kit/ModelData.ts"; import {diagramModelData} from "./kit/ModelData.ts";
// 变量定义 // 变量定义
// region // region
...@@ -328,6 +352,7 @@ const portTypeList =[ ...@@ -328,6 +352,7 @@ const portTypeList =[
{label:'下方', value:"0.5 1"}, {label:'下方', value:"0.5 1"},
] ]
// 线路分析结果的名称 // 线路分析结果的名称
const analyzePathsName = ref<Record<string, any>[][]>([]) const analyzePathsName = ref<Record<string, any>[][]>([])
...@@ -344,6 +369,7 @@ const ruleDialog = ref<Record<string, any>>({ ...@@ -344,6 +369,7 @@ const ruleDialog = ref<Record<string, any>>({
description:"", description:"",
inputs:[], inputs:[],
func:"", func:"",
actions:[],
} }
}) })
...@@ -352,10 +378,6 @@ const ruleDialog = ref<Record<string, any>>({ ...@@ -352,10 +378,6 @@ const ruleDialog = ref<Record<string, any>>({
// 用于计算左右面板滚动区域高度,主要是为了自适应 // 用于计算左右面板滚动区域高度,主要是为了自适应
let panelScrollAreaHeight = ref() let panelScrollAreaHeight = ref()
// 水平翻转控制
const horizontalFlip = ref(false)
// 垂直翻转控制
const verticalFlip = ref(false)
// endregion // endregion
onMounted(()=>{ onMounted(()=>{
...@@ -556,7 +578,6 @@ function freshSelectionNode(){ ...@@ -556,7 +578,6 @@ function freshSelectionNode(){
nodePortArray.value = [] nodePortArray.value = []
} }
triggerRef(nodePortArray) triggerRef(nodePortArray)
freshNodeFlip()
} }
function freshSelectionLink(){ function freshSelectionLink(){
...@@ -793,44 +814,7 @@ function analyzeData(){ ...@@ -793,44 +814,7 @@ function analyzeData(){
} }
} }
function changeNodeFlip(){
let node = myDiagram.findNodeForKey(selectedNode.value.data.key) as go.Node
let nodeData = node.data
if (horizontalFlip.value && verticalFlip.value) {
myDiagram.model.setDataProperty(nodeData, 'flip', 'FlipBoth')
console.log('both')
return
}else if(horizontalFlip.value){
myDiagram.model.setDataProperty(nodeData, 'flip', 'FlipHorizontal')
console.log('horizontal')
return
}else if(verticalFlip.value){
myDiagram.model.setDataProperty(nodeData, 'flip', 'FlipVertical')
console.log('vertical')
return
}else{
myDiagram.model.setDataProperty(nodeData, 'flip', 'None')
return
}
}
function freshNodeFlip(){
let node = myDiagram.findNodeForKey(selectedNode.value.data.key) as go.Node
let nodeData = node.data
if (nodeData.flip === 'FlipBoth'){
horizontalFlip.value = true
verticalFlip.value = true
}else if(nodeData.flip === 'FlipHorizontal'){
horizontalFlip.value = true
verticalFlip.value = false
}else if(nodeData.flip === 'FlipVertical'){
horizontalFlip.value = false
verticalFlip.value = true
}else{
horizontalFlip.value = false
verticalFlip.value = false
}
}
//endregion //endregion
...@@ -850,6 +834,7 @@ function showAddRuleDialog(){ ...@@ -850,6 +834,7 @@ function showAddRuleDialog(){
name: "", name: "",
inputs:[], inputs:[],
func:"", func:"",
actions:[]
} }
} }
...@@ -863,6 +848,11 @@ function addRuleParam(){ ...@@ -863,6 +848,11 @@ function addRuleParam(){
{key:"", valueKey:"", testData:""} {key:"", valueKey:"", testData:""}
) )
} }
function addRuleAction(){
ruleDialog.value.data.actions.push(
{type: 'success', content: ''}
)
}
function confirmAddRule(){ function confirmAddRule(){
let ruleData = ruleDialog.value.data let ruleData = ruleDialog.value.data
if(!ruleData.name) { if(!ruleData.name) {
...@@ -882,6 +872,10 @@ function deleteRuleParam(index:number){ ...@@ -882,6 +872,10 @@ function deleteRuleParam(index:number){
ruleDialog.value.data.inputs.splice(index, 1) ruleDialog.value.data.inputs.splice(index, 1)
} }
function deleteRuleAction(index:number){
ruleDialog.value.data.actions.splice(index, 1)
}
function runRuleWithTestData(id:string){ function runRuleWithTestData(id:string){
testRuleById(id) testRuleById(id)
} }
......
...@@ -2077,7 +2077,6 @@ export const diagramModelData = { ...@@ -2077,7 +2077,6 @@ export const diagramModelData = {
"key": -33, "key": -33,
"loc": "-4 -504", "loc": "-4 -504",
"size": "50 68.75", "size": "50 68.75",
"flip": "FlipBoth"
}, },
{ {
"name": "闸阀", "name": "闸阀",
...@@ -3109,7 +3108,6 @@ export const diagramModelData = { ...@@ -3109,7 +3108,6 @@ export const diagramModelData = {
"key": -59, "key": -59,
"loc": "-607 -705", "loc": "-607 -705",
"size": "50 68.75", "size": "50 68.75",
"flip": "FlipBoth"
}, },
{ {
"name": "三接口", "name": "三接口",
...@@ -7787,45 +7785,24 @@ export const diagramModelData = { ...@@ -7787,45 +7785,24 @@ export const diagramModelData = {
] ]
}, },
ruleData:[ ruleData:[
// {
// "id": "ffdb88cf1809049819226d3e617a1fbd4",
// "type": "js",
// "name": "1",
// "inputs": [
// {
// "key": -1,
// "valueKey": "name",
// "testData": ""
// },
// {
// "key": -2,
// "valueKey": "name",
// "testData": ""
// }
// ],
// "description": "1",
// "func": "return data[0]",
// "enable": false
// },
{ {
"id": "f3b59c21947034e6f81506812ccbaa2a8", "id": "ffaec6e554f7d4665bd0e9b07b7878640",
"type": "lua", "name": "监测脱硫塔",
"name": "2",
"inputs": [ "inputs": [
{ {
"key": -1,
"valueKey": "name",
"testData": ""
},
{
"key": -2, "key": -2,
"valueKey": "name", "valueKey": "failurePossibility",
"testData": "" "testData": "0.00000001"
} }
], ],
"description": "2", "description": "脱硫塔失效可能性是否小于0.001",
"func": "return data[1]", "func": "if (tonumber(data[0]) < 0.001) then \n return 0\n end",
"enable": true "enable": false,
"type": "lua",
"actions": [{
'type': 'error',
'content': '脱硫塔失效可能性过低'
}]
} }
] ]
} }
...@@ -13,7 +13,6 @@ export function makeSVGNode (stretch: typeof go.GraphObject.Fill = go.GraphObjec ...@@ -13,7 +13,6 @@ export function makeSVGNode (stretch: typeof go.GraphObject.Fill = go.GraphObjec
{name:"view", width:size, height:size, imageStretch: stretch}, {name:"view", width:size, height:size, imageStretch: stretch},
new go.Binding("source", "img"), new go.Binding("source", "img"),
new go.Binding('desiredSize', "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding('desiredSize', "size", go.Size.parse).makeTwoWay(go.Size.stringify),
new go.Binding('flip', 'flip', go.Binding.parseEnum(go.GraphObject, go.GraphObject.None)).makeTwoWay(go.Binding.toString),
) )
} }
...@@ -38,7 +37,6 @@ export function makeShapeNode (stretch: typeof go.GraphObject.Fill = go.GraphObj ...@@ -38,7 +37,6 @@ export function makeShapeNode (stretch: typeof go.GraphObject.Fill = go.GraphObj
new go.Binding("fill", "fill"), new go.Binding("fill", "fill"),
new go.Binding("stroke", "stroke"), new go.Binding("stroke", "stroke"),
new go.Binding('desiredSize', "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding('desiredSize', "size", go.Size.parse).makeTwoWay(go.Size.stringify),
new go.Binding('flip', 'flip', go.Binding.parseEnum(go.GraphObject, go.GraphObject.None)).makeTwoWay(go.Binding.toString),
) )
} }
......
import {uuid} from "vue3-uuid"; import {uuid} from "vue3-uuid";
import * as fengari from 'fengari-web'; import * as fengari from 'fengari-web';
import {ElNotification} from "element-plus";
export class RuleScriptType { export class RuleScriptType {
static Lua = 'lua' static Lua = 'lua'
static JS = 'js' static JS = 'js'
} }
export const RuleActionType = [
{key:'success', name:"正常" },
{key:'info', name:"通知" },
{key:'warning', name:"警告" },
{key:'error', name:"故障" },
]
/** /**
* { * {
...@@ -37,7 +44,7 @@ export var rules: Record<string, any>[] = [] ...@@ -37,7 +44,7 @@ export var rules: Record<string, any>[] = []
* @param actions 规则动作 * @param actions 规则动作
*/ */
export function addRule(name: string, description: string, inputs: any[], func: Function, actions:any[]=[]) { export function addRule(name: string, description: string, inputs: any[], func: Function, actions:any[]=[]) {
const ruleId = 'f' + uuid.v4().split('-').join('') const ruleId =uuid.v4()
rules.push({ rules.push({
id: ruleId, id: ruleId,
name: name, name: name,
...@@ -84,7 +91,7 @@ export function deleteRuleById(id: string) { ...@@ -84,7 +91,7 @@ export function deleteRuleById(id: string) {
*/ */
export function runRule(rule: any, deviceMap: Record<string, any>) { export function runRule(rule: any, deviceMap: Record<string, any>) {
let inputData = [] let inputData = []
let result = null let result = -1
if (rule) { if (rule) {
for (let input of rule.inputs) { for (let input of rule.inputs) {
inputData.push(deviceMap[input.key][input.valueKey]) inputData.push(deviceMap[input.key][input.valueKey])
...@@ -100,7 +107,8 @@ export function runRule(rule: any, deviceMap: Record<string, any>) { ...@@ -100,7 +107,8 @@ export function runRule(rule: any, deviceMap: Record<string, any>) {
alert('no such rule type' + rule['type']) alert('no such rule type' + rule['type'])
} }
} }
console.log('run rule result:', result) runRuleAction(rule, result)
return result return result
} }
...@@ -133,18 +141,24 @@ export function runRuleById(id: string, deviceMap: Record<string, any>) { ...@@ -133,18 +141,24 @@ export function runRuleById(id: string, deviceMap: Record<string, any>) {
*/ */
export function testRule(rule: any) { export function testRule(rule: any) {
let inputData = [] let inputData = []
let runFunc = null let result = -1
if (rule) { if (rule) {
for (let input of rule.inputs) { for (let input of rule.inputs) {
inputData.push(input['testData']) inputData.push(input['testData'])
} }
runFunc = new Function("return " + rule.func) switch (rule['type']) {
try { case RuleScriptType.Lua:
runFunc()(...inputData) result = runLua(rule, inputData)
} catch (e) { break
alert(e) case RuleScriptType.JS:
result = runJS(rule, inputData)
break
default:
alert('no such rule type' + rule['type'])
} }
} }
runRuleAction(rule, result)
return result
} }
/** /**
...@@ -156,6 +170,23 @@ export function testRuleById(id: string) { ...@@ -156,6 +170,23 @@ export function testRuleById(id: string) {
testRule(rule) testRule(rule)
} }
export function runRuleAction(rule:any, result:any){
try{
result = Number(result)
}catch(e){
alert("脚本的返回值必须是数字")
}
if (result>=0 && result<rule.actions.length){
let ruleType = rule.actions[result].type
let ruleContent = rule.actions[result].content
ElNotification({
title: rule['name'],
message: ruleContent,
type: ruleType,
})
}
}
export function runJS(rule: any, inputData: any) { export function runJS(rule: any, inputData: any) {
const funcBody = "(data)=>{ "+ rule['func']+"}" const funcBody = "(data)=>{ "+ rule['func']+"}"
const runFunc = new Function("return " + funcBody) const runFunc = new Function("return " + funcBody)
...@@ -169,17 +200,14 @@ export function runJS(rule: any, inputData: any) { ...@@ -169,17 +200,14 @@ export function runJS(rule: any, inputData: any) {
export function runLua(rule: any, inputData: any) { export function runLua(rule: any, inputData: any) {
try { try {
// 创建Lua状态 // 创建Lua状态
let codeString = `
let codestring = `
return function (data) return function (data)
${rule['func']} ${rule['func']}
end end
` `
let luaFunction = fengari.load(codestring) let luaFunction = fengari.load(codeString)
let result = luaFunction().call(inputData); return luaFunction().call(inputData)
return result
} catch (e) { } catch (e) {
alert(e) alert(e)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment