Commit 875f2e49 by 吴斌

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

parent 3d8dc5f6
......@@ -53,8 +53,6 @@
<div class="space-y-1 p-2 flex flex-col" v-show="ifSelectNode || ifSelectLink">
<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>
<el-divider direction="horizontal"></el-divider>
</div>
......@@ -228,6 +226,24 @@
<el-form-item label="规则函数">
<el-input type="textarea" v-model="ruleDialog.data.func"></el-input>
</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-scrollbar>
<template #footer>
......@@ -268,7 +284,15 @@ import {
getExceedingDefectInfluenceCoefficient,
getManagementSystemEvaluationCoefficient
} 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";
// 变量定义
// region
......@@ -328,6 +352,7 @@ const portTypeList =[
{label:'下方', value:"0.5 1"},
]
// 线路分析结果的名称
const analyzePathsName = ref<Record<string, any>[][]>([])
......@@ -344,6 +369,7 @@ const ruleDialog = ref<Record<string, any>>({
description:"",
inputs:[],
func:"",
actions:[],
}
})
......@@ -352,10 +378,6 @@ const ruleDialog = ref<Record<string, any>>({
// 用于计算左右面板滚动区域高度,主要是为了自适应
let panelScrollAreaHeight = ref()
// 水平翻转控制
const horizontalFlip = ref(false)
// 垂直翻转控制
const verticalFlip = ref(false)
// endregion
onMounted(()=>{
......@@ -556,7 +578,6 @@ function freshSelectionNode(){
nodePortArray.value = []
}
triggerRef(nodePortArray)
freshNodeFlip()
}
function freshSelectionLink(){
......@@ -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
......@@ -850,6 +834,7 @@ function showAddRuleDialog(){
name: "",
inputs:[],
func:"",
actions:[]
}
}
......@@ -863,6 +848,11 @@ function addRuleParam(){
{key:"", valueKey:"", testData:""}
)
}
function addRuleAction(){
ruleDialog.value.data.actions.push(
{type: 'success', content: ''}
)
}
function confirmAddRule(){
let ruleData = ruleDialog.value.data
if(!ruleData.name) {
......@@ -882,6 +872,10 @@ function deleteRuleParam(index:number){
ruleDialog.value.data.inputs.splice(index, 1)
}
function deleteRuleAction(index:number){
ruleDialog.value.data.actions.splice(index, 1)
}
function runRuleWithTestData(id:string){
testRuleById(id)
}
......
......@@ -2077,7 +2077,6 @@ export const diagramModelData = {
"key": -33,
"loc": "-4 -504",
"size": "50 68.75",
"flip": "FlipBoth"
},
{
"name": "闸阀",
......@@ -3109,7 +3108,6 @@ export const diagramModelData = {
"key": -59,
"loc": "-607 -705",
"size": "50 68.75",
"flip": "FlipBoth"
},
{
"name": "三接口",
......@@ -7787,45 +7785,24 @@ export const diagramModelData = {
]
},
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",
"type": "lua",
"name": "2",
"id": "ffaec6e554f7d4665bd0e9b07b7878640",
"name": "监测脱硫塔",
"inputs": [
{
"key": -1,
"valueKey": "name",
"testData": ""
},
{
"key": -2,
"valueKey": "name",
"testData": ""
"valueKey": "failurePossibility",
"testData": "0.00000001"
}
],
"description": "2",
"func": "return data[1]",
"enable": true
"description": "脱硫塔失效可能性是否小于0.001",
"func": "if (tonumber(data[0]) < 0.001) then \n return 0\n end",
"enable": false,
"type": "lua",
"actions": [{
'type': 'error',
'content': '脱硫塔失效可能性过低'
}]
}
]
}
......@@ -13,7 +13,6 @@ export function makeSVGNode (stretch: typeof go.GraphObject.Fill = go.GraphObjec
{name:"view", width:size, height:size, imageStretch: stretch},
new go.Binding("source", "img"),
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
new go.Binding("fill", "fill"),
new go.Binding("stroke", "stroke"),
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 * as fengari from 'fengari-web';
import {ElNotification} from "element-plus";
export class RuleScriptType {
static Lua = 'lua'
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>[] = []
* @param actions 规则动作
*/
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({
id: ruleId,
name: name,
......@@ -84,7 +91,7 @@ export function deleteRuleById(id: string) {
*/
export function runRule(rule: any, deviceMap: Record<string, any>) {
let inputData = []
let result = null
let result = -1
if (rule) {
for (let input of rule.inputs) {
inputData.push(deviceMap[input.key][input.valueKey])
......@@ -100,7 +107,8 @@ export function runRule(rule: any, deviceMap: Record<string, any>) {
alert('no such rule type' + rule['type'])
}
}
console.log('run rule result:', result)
runRuleAction(rule, result)
return result
}
......@@ -133,18 +141,24 @@ export function runRuleById(id: string, deviceMap: Record<string, any>) {
*/
export function testRule(rule: any) {
let inputData = []
let runFunc = null
let result = -1
if (rule) {
for (let input of rule.inputs) {
inputData.push(input['testData'])
}
runFunc = new Function("return " + rule.func)
try {
runFunc()(...inputData)
} catch (e) {
alert(e)
switch (rule['type']) {
case RuleScriptType.Lua:
result = runLua(rule, inputData)
break
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) {
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) {
const funcBody = "(data)=>{ "+ rule['func']+"}"
const runFunc = new Function("return " + funcBody)
......@@ -169,17 +200,14 @@ export function runJS(rule: any, inputData: any) {
export function runLua(rule: any, inputData: any) {
try {
// 创建Lua状态
let codestring = `
let codeString = `
return function (data)
${rule['func']}
end
`
let luaFunction = fengari.load(codestring)
let result = luaFunction().call(inputData);
return result
let luaFunction = fengari.load(codeString)
return luaFunction().call(inputData)
} catch (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