feat: 场景联动中告警按条件查询
* feat: 场景联动新增多条件 * feat: 优化告警绑定场景联动多条件 * feat: 兼容告警绑定场景联动多条件 * feat: 场景联动中告警按条件查询 * fix: 优化场景联动多条件回显
This commit is contained in:
parent
4600fcb4d7
commit
1c50005161
|
@ -42,7 +42,7 @@ export const detail = (id:string) => server.get(`/alarm/config/${id}`);
|
|||
/**
|
||||
* 解除场景联动绑定
|
||||
*/
|
||||
export const unbindScene = (id:string,data:any) => server.post(`/alarm/rule/bind/${id}/_delete`,data);
|
||||
export const unbindScene = (id:string,data:any, branchId: string) => server.post(`/alarm/rule/bind/${id}/_delete?branchIndex=${branchId}`,data);
|
||||
|
||||
/**
|
||||
* 保存关联场景
|
||||
|
|
|
@ -9,6 +9,8 @@ export const detail = (id: string) => server.get(`/scene/${id}`)
|
|||
|
||||
export const query = (data: any) => server.post('/scene/_query/',data);
|
||||
|
||||
export const queryBranch = (data: any, id: string) => server.post(`/scene/branch/query?alarmId=${id}`,data);
|
||||
|
||||
export const _delete = (id: string) => server.remove(`/scene/${id}/`);
|
||||
|
||||
export const _action = (id: string, type: '_disable' | '_enable') => server.put(`/scene/${id}/${type}`);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { defineStore } from 'pinia'
|
||||
import type { FormModelType } from '@/views/rule-engine/Scene/typings'
|
||||
import { detail } from '@/api/rule-engine/scene'
|
||||
import { cloneDeep, isArray } from 'lodash-es'
|
||||
import {cloneDeep, isArray, isObject} from 'lodash-es'
|
||||
import { randomString } from '@/utils/utils'
|
||||
|
||||
type DataType = {
|
||||
|
@ -54,6 +54,8 @@ export const defaultBranches = [
|
|||
alarmFirst: false,
|
||||
},
|
||||
then: [],
|
||||
executeAnyway: true,
|
||||
branchId: Math.floor(Math.random() * 100000000)
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -73,7 +75,7 @@ const defaultOptions = {
|
|||
export const useSceneStore = defineStore('scene', () => {
|
||||
const data = ref<FormModelType>({
|
||||
trigger: { type: ''},
|
||||
options: defaultOptions,
|
||||
options: [defaultOptions],
|
||||
branches: defaultBranches,
|
||||
description: '',
|
||||
name: '',
|
||||
|
@ -93,6 +95,14 @@ export const useSceneStore = defineStore('scene', () => {
|
|||
}
|
||||
}
|
||||
|
||||
const compatibleOldOptions = (options: any) => {
|
||||
if (isObject(options)) {
|
||||
return [options]
|
||||
} else {
|
||||
return options
|
||||
}
|
||||
}
|
||||
|
||||
const getDetail = async (id: string) => {
|
||||
refresh()
|
||||
const resp = await detail(id)
|
||||
|
@ -109,21 +119,48 @@ export const useSceneStore = defineStore('scene', () => {
|
|||
branches[0].when.length = []
|
||||
}
|
||||
} else {
|
||||
const branchesLength = branches.length;
|
||||
if (
|
||||
triggerType === 'device' &&
|
||||
((branchesLength === 1 && branches[0]?.when?.length) || // 有一组数据并且when有值
|
||||
(branchesLength > 1 && branches[branchesLength - 1]?.when?.length)) // 有多组否则数据,并且最后一组when有值
|
||||
) {
|
||||
branches.push(null);
|
||||
if (triggerType === 'device') {
|
||||
const len = branches.length
|
||||
const newBranches: any[] = []
|
||||
|
||||
|
||||
branches.forEach((item, index) => {
|
||||
|
||||
if (item?.executeAnyway && index > 0 && branches[index - 1]?.when?.length) {
|
||||
newBranches.push(null)
|
||||
newBranches.push(item)
|
||||
// branches.splice(index, 0 , null)
|
||||
} else {
|
||||
newBranches.push(item)
|
||||
}
|
||||
|
||||
|
||||
// if (item?.executeAnyway && index > 0 && branches[index - 1]?.when?.length) {
|
||||
// branches.splice(index, 0 , null)
|
||||
// }
|
||||
|
||||
if ( index === len - 1 && item?.when?.length) {
|
||||
newBranches.push(null)
|
||||
}
|
||||
console.log(branches)
|
||||
})
|
||||
|
||||
branches = [...newBranches]
|
||||
}
|
||||
// const branchesLength = branches.length;
|
||||
// if (
|
||||
// triggerType === 'device' &&
|
||||
// ((branchesLength === 1 && branches[0]?.when?.length) || // 有一组数据并且when有值
|
||||
// (branchesLength > 1 && branches[branchesLength - 1]?.when?.length)) // 有多组否则数据,并且最后一组when有值
|
||||
// ) {
|
||||
// branches.push(null);
|
||||
// }
|
||||
}
|
||||
console.log('result.options',branches)
|
||||
data.value = {
|
||||
...result,
|
||||
trigger: result.trigger || {},
|
||||
branches: cloneDeep(assignmentKey(branches)),
|
||||
options: result.options ? {...cloneDeep(defaultOptions), ...result.options } : cloneDeep(defaultOptions),
|
||||
options: result.options && Object.keys(result.options)?.length ? result.options : cloneDeep(defaultOptions),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,14 @@
|
|||
@ok="saveCorrelation"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<pro-search :columns="columns" @search="handleSearch" />
|
||||
<div v-if="type !== 'other'" style="padding: 0 24px">
|
||||
<j-steps :current="current" >
|
||||
<j-step title="选择场景"></j-step>
|
||||
<j-step title="选择条件"></j-step>
|
||||
</j-steps>
|
||||
</div>
|
||||
<template v-if="current === 0 || type === 'other' ">
|
||||
<pro-search :columns="columns" type="simple" @search="handleSearch"/>
|
||||
<div style="height: 500px; overflow-y: auto">
|
||||
<JProTable
|
||||
model="CARD"
|
||||
|
@ -79,6 +86,52 @@
|
|||
</template>
|
||||
</JProTable>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="current === 1">
|
||||
<div class="branch-terms-items">
|
||||
<j-tree
|
||||
v-if="branchGroup.length"
|
||||
defaultExpandAll
|
||||
checkable
|
||||
:treeData="branchGroup"
|
||||
@check="branchCheck"
|
||||
>
|
||||
|
||||
</j-tree>
|
||||
<!-- <CardBox-->
|
||||
<!-- v-for="(item, index) in branchGroup.branches"-->
|
||||
<!-- :showStatus="false"-->
|
||||
<!-- :active="branchActiveKey.includes(item.id)"-->
|
||||
<!-- @click="() => branchClick(item.id)"-->
|
||||
<!-- >-->
|
||||
<!-- <template #content>-->
|
||||
<!-- <div class="condition-name">-->
|
||||
<!-- 条件 {{ index + 1 }}-->
|
||||
<!-- </div>-->
|
||||
<!-- <div style="height: 80px">-->
|
||||
<!-- <j-scrollbar >-->
|
||||
<!-- <div v-for="(b, bIndex) in item">-->
|
||||
<!-- <div style="font-weight: bold">-->
|
||||
<!-- <span v-if="bIndex === 0">当</span>-->
|
||||
<!-- <span v-else>否则</span>-->
|
||||
<!-- <span>{{ b.condition }}</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div style="padding-left: 16px" v-for="action in b.actions">-->
|
||||
<!-- 执行 {{ action }}-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </j-scrollbar>-->
|
||||
<!-- </div>-->
|
||||
<!-- </template>-->
|
||||
<!-- </CardBox>-->
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<j-button v-if="current === 0" @click="closeModal">取消</j-button>
|
||||
<j-button v-if="current === 0" type="primary" @click="next">下一步</j-button>
|
||||
<j-button v-if="current === 1" @click="prev">上一步</j-button>
|
||||
<j-button v-if="current === 1" type="primary" @click="saveCorrelation">完成</j-button>
|
||||
</template>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
|
@ -86,6 +139,8 @@
|
|||
import {query} from '@/api/rule-engine/scene';
|
||||
import {bindScene} from '@/api/rule-engine/configuration';
|
||||
import {getImage, onlyMessage} from '@/utils/comm';
|
||||
import {handleSceneBranches} from './utils'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '场景名称',
|
||||
|
@ -176,15 +231,21 @@ const props = defineProps({
|
|||
type: String,
|
||||
},
|
||||
});
|
||||
|
||||
const current = ref(0)
|
||||
const branchGroup = ref<any[]>([])
|
||||
const branchActiveKey = ref([])
|
||||
const branchCheckKeys = ref([])
|
||||
|
||||
const terms = [
|
||||
{
|
||||
terms: [
|
||||
{
|
||||
column: 'id',
|
||||
termType: 'alarm-bind-rule$not',
|
||||
value: props.id,
|
||||
type: 'and',
|
||||
},
|
||||
// {
|
||||
// column: 'id',
|
||||
// termType: 'alarm-bind-rule$not',
|
||||
// value: props.id,
|
||||
// type: 'and',
|
||||
// },
|
||||
{
|
||||
column: 'triggerType',
|
||||
termType: 'eq',
|
||||
|
@ -222,6 +283,7 @@ const handleClick = (dt: any) => {
|
|||
} else {
|
||||
_selectedRowKeys.value = [..._selectedRowKeys.value, dt.id];
|
||||
}
|
||||
// _selectedRowKeys.value = [dt.id]
|
||||
};
|
||||
/**
|
||||
* 取消选择事件
|
||||
|
@ -229,31 +291,69 @@ const handleClick = (dt: any) => {
|
|||
const onSelectChange = (arr: any[]) => {
|
||||
_selectedRowKeys.value = arr
|
||||
};
|
||||
const log = () => {};
|
||||
log();
|
||||
|
||||
const branchClick = (id: string) => {
|
||||
const keys = new Set(branchActiveKey.value)
|
||||
|
||||
|
||||
}
|
||||
|
||||
const handleSearch = (e: any) => {
|
||||
params.value = e;
|
||||
};
|
||||
const emit = defineEmits(['closeSave', 'saveScene']);
|
||||
|
||||
const next = () => {
|
||||
if (_selectedRowKeys.value.length) {
|
||||
query({
|
||||
pageSize: 99,
|
||||
terms: [{column: 'id', termType: 'in', value: _selectedRowKeys.value.join(',')}]
|
||||
}).then(res => {
|
||||
if (res.success) {
|
||||
branchGroup.value = handleSceneBranches(res.result.data) || []
|
||||
|
||||
console.log(branchGroup.value)
|
||||
}
|
||||
})
|
||||
current.value += 1
|
||||
|
||||
} else {
|
||||
onlyMessage('请选择场景', 'warning')
|
||||
}
|
||||
}
|
||||
|
||||
const branchCheck = (checkedKeys: string[], { checkedNodes }) => {
|
||||
branchCheckKeys.value = checkedNodes.filter(item => item.branchId).map(item => ({
|
||||
branchIndex: item.branchId,
|
||||
ruleId: item.sceneId,
|
||||
alarmId: props.id,
|
||||
}))
|
||||
}
|
||||
|
||||
const prev = () => {
|
||||
current.value -= 1
|
||||
}
|
||||
/**
|
||||
* 保存选中关联场景
|
||||
*/
|
||||
const saveCorrelation = async () => {
|
||||
if (_selectedRowKeys.value.length > 0) {
|
||||
const list = _selectedRowKeys.value.map((item: any) => {
|
||||
if (_selectedRowKeys.value.length === 0 && branchCheckKeys.value.length === 0) {
|
||||
onlyMessage('请选择至少一条数据', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
const list = props.type === 'other' ? _selectedRowKeys.value.map((item: any) => {
|
||||
return {
|
||||
alarmId: props.id,
|
||||
ruleId: item,
|
||||
};
|
||||
});
|
||||
}) : branchCheckKeys.value
|
||||
|
||||
const res = await bindScene([...list]);
|
||||
if (res.status === 200) {
|
||||
onlyMessage('操作成功');
|
||||
emit('saveScene');
|
||||
}
|
||||
} else {
|
||||
onlyMessage('请选择至少一条数据', 'error');
|
||||
}
|
||||
};
|
||||
const closeModal = () => {
|
||||
emit('closeSave');
|
||||
|
@ -265,4 +365,16 @@ const closeModal = () => {
|
|||
font-size: 14px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.condition-name {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.branch-terms-items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding-top: 12px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,241 @@
|
|||
import {send} from "vite";
|
||||
import {isArray, isBoolean, isObject} from "lodash-es";
|
||||
import {randomString} from "@/utils/utils";
|
||||
|
||||
const TypeMap = {
|
||||
'and': '并且',
|
||||
'or': '或者'
|
||||
}
|
||||
|
||||
const DoubleFilter = ['nbtw', 'btw', 'in', 'nin'];
|
||||
|
||||
const TermsTypeMap = {
|
||||
eq: '等于_value',
|
||||
neq: '不等于_value',
|
||||
gt: '大于_value',
|
||||
gte: '大于等于_value',
|
||||
lt: '小于_value',
|
||||
lte: '小于等于_value',
|
||||
btw: '在_value和_value2之间',
|
||||
nbtw: '不在_value和_value2之间',
|
||||
time_gt_now: '距离当前时间大于_value秒',
|
||||
time_lt_now: '距离当前时间小于_value秒',
|
||||
in: '在_value,_value2之中',
|
||||
nin: '不在_value,_value2之中',
|
||||
like: '包含_value',
|
||||
nlike: '不包含_value',
|
||||
notnull: '不为空',
|
||||
isnull: '为空'
|
||||
};
|
||||
|
||||
const handleValueString = (t: string, value: any) => {
|
||||
if (DoubleFilter.includes(t)) {
|
||||
const _v = value.length === 2 ? value : [value[0], value[0]]
|
||||
return TermsTypeMap[t].replace('_value', _v[0]).replace('_value2', _v[1])
|
||||
} else if(['notnull', 'isnull'].includes(t)) {
|
||||
return TermsTypeMap[t]
|
||||
} else if (TermsTypeMap[t]){
|
||||
return TermsTypeMap[t].replace('_value', value[0]);
|
||||
} else {
|
||||
return `${t}${value[0]}`
|
||||
}
|
||||
}
|
||||
|
||||
const handleNotifyType = (data: any, options: any) => {
|
||||
if (data.notifyType === 'dingTalk') {
|
||||
const { sendTo, orgName, templateName } = options
|
||||
if (options.provider === 'dingTalkRobotWebHook') {
|
||||
return `通过群机器人消息发送 ${templateName || data?.notify?.templateId}`
|
||||
}
|
||||
const move = sendTo || orgName ? '向' : ''
|
||||
return `通过钉钉${move} ${sendTo || ''} ${orgName || ''} 发送 ${templateName || data?.notify?.templateId}`
|
||||
}
|
||||
|
||||
if (data.notifyType === 'weixin') {
|
||||
const { sendTo, orgName, tagName, templateName } = options
|
||||
const move = sendTo || orgName || tagName ? '向' : ''
|
||||
|
||||
return `通过微信${move}${sendTo || ''}${orgName || ''}${tagName || ''}发送${templateName || data?.notify?.templateId}`
|
||||
}
|
||||
|
||||
if (data.notifyType === 'email') {
|
||||
const { sendTo, templateName } = options
|
||||
const move = sendTo ? '向' : ''
|
||||
return `通过邮件${move}${sendTo || ''}发送${templateName || data?.notify?.templateId}`
|
||||
}
|
||||
|
||||
if (data.notifyType === 'voice') {
|
||||
const { sendTo, templateName } = options
|
||||
const move = sendTo ? '向' : ''
|
||||
return `通过语音${move}${sendTo || ''}发送${templateName || data?.notify?.templateId}`
|
||||
}
|
||||
|
||||
if (data.notifyType === 'sms') {
|
||||
const { sendTo, templateName } = options
|
||||
const move = sendTo ? '向' : ''
|
||||
return `通过短信${move}${sendTo || ''}发送${templateName || data?.notify?.templateId}`
|
||||
}
|
||||
|
||||
if (data.notifyType === 'sms') {
|
||||
const { templateName } = options
|
||||
return `通过WebHook发送${templateName || data?.notify?.templateId}`
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
const handleDevice = (device: any, options: any) => {
|
||||
let str = ''
|
||||
const {type, name, propertiesName, propertiesValue, tagName, productName, triggerName, relationName} = options
|
||||
if (['fixed', 'context'].includes(device?.selector)) {
|
||||
str += `${type} ${name} ${propertiesName}`
|
||||
let isValueBoolean = isBoolean(propertiesValue)
|
||||
if (propertiesValue && isValueBoolean) {
|
||||
str += '为'
|
||||
}
|
||||
str += isValueBoolean || propertiesValue ? propertiesValue : ''
|
||||
} else if (device?.selector === 'tag') {
|
||||
str = `${type} ${tagName} ${productName} ${propertiesName}`
|
||||
} else if (device?.selector === 'relation') {
|
||||
str = `${type}与${triggerName}具有相同${relationName}的${productName}设备的${propertiesName}`
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
const handleActions = (then: any): any[] => {
|
||||
let actionsArr:any[] = []
|
||||
const arr = then?.[0].actions.length ? then?.[0].actions : then?.[1].actions
|
||||
|
||||
arr?.forEach((item: any) => {
|
||||
console.log(item, item.options)
|
||||
if (item.executor === 'alarm') {
|
||||
actionsArr.push(
|
||||
item.alarm.mode === 'trigger' ?
|
||||
'满足条件后将触发关联此条件的告警' :
|
||||
'满足条件后将解除关联此条件的告警'
|
||||
)
|
||||
}
|
||||
|
||||
if (item.executor === 'notify') {
|
||||
actionsArr.push(handleNotifyType(item.notify, item.options))
|
||||
}
|
||||
|
||||
if (item.executor === 'delay') {
|
||||
actionsArr.push(item.options?.name)
|
||||
}
|
||||
|
||||
if (item.executor === 'device') {
|
||||
actionsArr.push(handleDevice(item.device, item.options))
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return actionsArr
|
||||
}
|
||||
|
||||
const handleConditions = (when: any, whenData: any[]) => {
|
||||
let termsArr: string = ''
|
||||
|
||||
if (when) {
|
||||
when?.terms.forEach((item, itemIndex) => {
|
||||
if (item.terms?.length) {
|
||||
if (itemIndex != 0) {
|
||||
termsArr += item.termType
|
||||
}
|
||||
termsArr += '【'
|
||||
item.terms.forEach((b, index) => {
|
||||
const [ name, termType, value, type ] = b
|
||||
if (index !== 0) {
|
||||
termsArr += ` ${TypeMap[type] || type} `
|
||||
}
|
||||
termsArr += `${name} ${handleValueString(termType, value)}`
|
||||
})
|
||||
termsArr += '】'
|
||||
}
|
||||
})
|
||||
} else {
|
||||
whenData.forEach((item, itemIndex) => {
|
||||
if (item.terms.length) {
|
||||
if (itemIndex !== 0) {
|
||||
termsArr += TypeMap[item.type]
|
||||
}
|
||||
termsArr += '【'
|
||||
item.terms.forEach((b, index) => {
|
||||
console.log(b)
|
||||
const { column, termType, value, type } = b
|
||||
let _val: any = { 0: value }
|
||||
|
||||
if (isObject(value)) {
|
||||
_val = { 0: value.value }
|
||||
} else if (isArray(value)) {
|
||||
_val = value
|
||||
}
|
||||
|
||||
if (index !== 0) {
|
||||
termsArr += ` ${TypeMap[type] || type} `
|
||||
}
|
||||
termsArr += `${column} ${handleValueString(termType, _val)}`
|
||||
})
|
||||
termsArr += '】'
|
||||
}
|
||||
})
|
||||
}
|
||||
return termsArr
|
||||
}
|
||||
|
||||
const handleBranches = (branches: any[], when: any, parentId: string) => {
|
||||
const msg: any[] = []
|
||||
|
||||
branches.forEach((item: any, index) => {
|
||||
const _id = `condition_${index}`
|
||||
|
||||
const obj = {
|
||||
title: `条件 ${index + 1}`,
|
||||
id: _id,
|
||||
parentId,
|
||||
children: [{
|
||||
title: handleConditions(when[index], item.when),
|
||||
id: randomString(),
|
||||
branchId: item.branchId || -1,
|
||||
parentId: _id,
|
||||
sceneId: parentId
|
||||
}]
|
||||
}
|
||||
if (index === 0) {
|
||||
msg[0] = obj
|
||||
} else {
|
||||
const lastIndex = msg.length - 1
|
||||
if (item.executeAnyway) {
|
||||
msg[lastIndex + 1] = obj
|
||||
} else {
|
||||
msg[lastIndex].children.push({
|
||||
title: handleConditions(when[index], item.when),
|
||||
id: randomString(),
|
||||
branchId: item.branchId || -1,
|
||||
parentId: _id,
|
||||
sceneId: parentId
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
return msg
|
||||
}
|
||||
export const handleSceneBranches = (data: any): any[] => {
|
||||
const group: any[] = []
|
||||
|
||||
data?.forEach((item: any) => {
|
||||
let obj: any = {
|
||||
title: item.name,
|
||||
id: item.id,
|
||||
children: []
|
||||
}
|
||||
if (item.branches?.length) {
|
||||
obj.trigger = item.options.trigger
|
||||
obj.children = handleBranches(item.branches, item.options.when, item.id)
|
||||
}
|
||||
|
||||
group.push(obj)
|
||||
})
|
||||
|
||||
return group
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
<FullPage>
|
||||
<JProTable
|
||||
model="CARD"
|
||||
:request="query"
|
||||
:request="queryTable"
|
||||
:defaultParams="{
|
||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||
terms,
|
||||
|
@ -47,11 +47,15 @@
|
|||
<img :src="typeMap.get(slotProps.triggerType)?.img" />
|
||||
</template>
|
||||
<template #content>
|
||||
<div style="height: 102px;">
|
||||
<Ellipsis style="width: calc(100% - 100px)">
|
||||
<span style="font-size: 16px; font-weight: 600">
|
||||
{{ slotProps.name }}
|
||||
</span>
|
||||
</Ellipsis>
|
||||
<div v-if="slotProps.branchName">
|
||||
{{ slotProps.branchName }}
|
||||
</div>
|
||||
<Ellipsis :lineClamp="2">
|
||||
<div class="subTitle">
|
||||
说明:{{
|
||||
|
@ -60,6 +64,7 @@
|
|||
}}
|
||||
</div>
|
||||
</Ellipsis>
|
||||
</div>
|
||||
</template>
|
||||
<template #actions="item">
|
||||
<PermissionButton
|
||||
|
@ -95,7 +100,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { query } from '@/api/rule-engine/scene';
|
||||
import { queryBranch} from '@/api/rule-engine/scene';
|
||||
import { unbindScene } from '@/api/rule-engine/configuration';
|
||||
import { useRoute } from 'vue-router';
|
||||
import type { ActionsType } from '@/components/Table';
|
||||
|
@ -154,7 +159,7 @@ const getActions = (
|
|||
popConfirm: {
|
||||
title: '确定解绑?',
|
||||
onConfirm: async () => {
|
||||
const res = await unbindScene(id, [data.id]);
|
||||
const res = await unbindScene(id, [data.id], data.branchIndex);
|
||||
if (res.status === 200) {
|
||||
onlyMessage('操作成功');
|
||||
actionRef.value.reload();
|
||||
|
@ -165,6 +170,11 @@ const getActions = (
|
|||
];
|
||||
return actions;
|
||||
};
|
||||
|
||||
const queryTable = (_terms: any) => {
|
||||
return queryBranch(_terms, id)
|
||||
}
|
||||
|
||||
const visible = ref(false);
|
||||
const log = () => {
|
||||
console.log();
|
||||
|
|
|
@ -7,7 +7,7 @@ import { storeToRefs } from 'pinia';
|
|||
import { useSceneStore } from '@/store/scene'
|
||||
import { Form } from 'jetlinks-ui-components'
|
||||
import { queryProductList } from '@/api/device/product'
|
||||
import { query as deviceQuery } from '@/api/device/instance'
|
||||
import {query as deviceQuery, detail as deviceDetailQuery} from '@/api/device/instance'
|
||||
import { getTreeData_api } from '@/api/system/department'
|
||||
|
||||
const sceneStore = useSceneStore()
|
||||
|
@ -42,7 +42,8 @@ const check = async (): Promise<boolean> => {
|
|||
}
|
||||
|
||||
if (selectorValues!.length === 1) {
|
||||
const deviceDetail = deviceResp?.result?.data?.[0]
|
||||
const deviceDetailResp = await deviceDetailQuery(selectorValues![0])
|
||||
const deviceDetail = deviceDetailResp?.result
|
||||
metadata = JSON.parse(deviceDetail?.metadata || '{}') // 只选中一个设备,以设备物模型为准
|
||||
}
|
||||
} else if (deviceTrigger.selector === 'org') { // 组织
|
||||
|
@ -60,7 +61,7 @@ const check = async (): Promise<boolean> => {
|
|||
// 判断物模型
|
||||
if (['readProperty', 'writeProperty'].includes(deviceTrigger.operation?.operator!)) {
|
||||
let hasProperties = false
|
||||
if (metadata.properties.length) {
|
||||
if (metadata.properties?.length) {
|
||||
if (deviceTrigger.operation?.readProperties && deviceTrigger.operation?.readProperties.length) {
|
||||
// hasProperties = metadata.properties.every((item: any) => deviceTrigger.operation!.readProperties!.includes(item.id))
|
||||
hasProperties = deviceTrigger.operation!.readProperties.every(_id => metadata.properties.some((item: any) => item.id === _id))
|
||||
|
|
|
@ -316,6 +316,7 @@ const checkNoticeDelete = async () => {
|
|||
}
|
||||
|
||||
const check = () => {
|
||||
console.log(_data.value.branches)
|
||||
const _executor = _data.value.branches![props.branchesName].then[props.thenName].actions?.[props.name]?.executor
|
||||
if (_executor === 'device' && _data.value.branches![props.branchesName].then[props.thenName].actions[props.name]?.device) { // 设备输出,并且有值
|
||||
checkDeviceDelete()
|
||||
|
|
|
@ -195,7 +195,7 @@ const handOptionByColumn = (option: any) => {
|
|||
} else if(option.type === 'enum') {
|
||||
valueOptions.value = _options?.elements?.map((item: any) => ({ ...item, label: item.text, value: item.value})) || []
|
||||
} else{
|
||||
valueOptions.value = _options?.map((item: any) => ({ ...item, label: item.name, value: item.id})) || []
|
||||
valueOptions.value = (isObject(_options) ? [] : _options)?.map((item: any) => ({ ...item, label: item.name, value: item.id})) || []
|
||||
}
|
||||
valueColumnOptions.value = treeFilter(cloneDeep(columnOptions.value), option.type, 'type')
|
||||
} else {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
style="padding: 0"
|
||||
type="link"
|
||||
@click.stop="triggerVisible = true"
|
||||
>关联此场景的告警</j-button
|
||||
>关联此条件的告警</j-button
|
||||
>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
@ -36,7 +36,7 @@
|
|||
style="padding: 0"
|
||||
type="link"
|
||||
@click.stop="triggerVisible = true"
|
||||
>关联此场景的告警</j-button
|
||||
>关联此条件的告警</j-button
|
||||
>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -386,6 +386,7 @@
|
|||
</template>
|
||||
<TriggerAlarm
|
||||
:id="_data.id"
|
||||
:branchId="_data.branches[branchesName].branchId"
|
||||
v-if="triggerVisible"
|
||||
@close="triggerVisible = false"
|
||||
/>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
@cancel="emit('close')"
|
||||
@ok="emit('close')"
|
||||
visible
|
||||
title="关联此场景的告警"
|
||||
title="关联此条件的告警"
|
||||
>
|
||||
<div style="margin-bottom: 24px">关联告警数量:{{ count }}</div>
|
||||
<JProTable
|
||||
|
@ -18,9 +18,8 @@
|
|||
{
|
||||
terms: [
|
||||
{
|
||||
column: 'id',
|
||||
value: id,
|
||||
termType: 'rule-bind-alarm',
|
||||
column: 'id$rule-bind-alarm',
|
||||
value: branchId ? `${id}:${branchId}` : id,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -59,6 +58,10 @@ const props = defineProps({
|
|||
type: String,
|
||||
default: '',
|
||||
},
|
||||
branchId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
|
@ -108,7 +111,8 @@ watch(
|
|||
terms: [
|
||||
{
|
||||
column: 'id$rule-bind-alarm',
|
||||
value: newId,
|
||||
// value: newId,
|
||||
value: props.branchId ? `${newId}:${props.branchId}` : newId,
|
||||
},
|
||||
],
|
||||
}).then((resp) => {
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
<template>
|
||||
<div :class='WarpClass'>
|
||||
<j-popconfirm
|
||||
title='确认删除?'
|
||||
v-if="showGroupDelete && isFirst"
|
||||
placement="topRight"
|
||||
:overlayStyle='{minWidth: "180px"}'
|
||||
@confirm='deleteGroup'
|
||||
>
|
||||
<div v-if="showGroupDelete && isFirst" class="group-delete">
|
||||
删除条件
|
||||
</div>
|
||||
</j-popconfirm>
|
||||
<div class='actions-terms-title'>
|
||||
{{ isFirst ? '当' : '否则' }}
|
||||
</div>
|
||||
|
@ -40,6 +51,7 @@
|
|||
:isFirst='index === 0'
|
||||
:isLast='index === whenData.length -1'
|
||||
:branchName='name'
|
||||
:branches_Index='branches_Index'
|
||||
:data='item'
|
||||
/>
|
||||
|
||||
|
@ -102,9 +114,27 @@ const props = defineProps({
|
|||
name: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
branches_Index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
groupLen: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
groupIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
showGroupDelete: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['deleteGroup'])
|
||||
|
||||
const showDelete = ref(false)
|
||||
const error = ref(false)
|
||||
|
||||
|
@ -169,8 +199,8 @@ const addWhen = () => {
|
|||
key: `terms_${randomString()}`
|
||||
}
|
||||
FormModel.value.branches?.[props.name].when?.push(terms)
|
||||
FormModel.value.branches?.push(null as any)
|
||||
FormModel.value.options!.when[props.name]?.terms.push({ termType: '并且', terms: [['','eq','','and']]})
|
||||
FormModel.value.branches?.splice(props.groupLen, 0, null)
|
||||
FormModel.value.options!.when[props.branches_Index]?.terms.push({ termType: '并且', terms: [['','eq','','and']]})
|
||||
}
|
||||
|
||||
const optionsClass = computed(() => {
|
||||
|
@ -193,6 +223,10 @@ const rules = [{
|
|||
}
|
||||
}]
|
||||
|
||||
const deleteGroup = () => {
|
||||
emit('deleteGroup')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang='less'>
|
||||
|
|
|
@ -1,79 +1,73 @@
|
|||
<template>
|
||||
<div class="terms-params-item">
|
||||
<div v-if="!isFirst" class="term-type-warp">
|
||||
<div class='terms-params-item'>
|
||||
<div v-if='!isFirst' class='term-type-warp'>
|
||||
<DropdownButton
|
||||
:options="[
|
||||
{ label: '并且', value: 'and' },
|
||||
{ label: '或者', value: 'or' },
|
||||
]"
|
||||
type="type"
|
||||
v-model:value="paramsValue.type"
|
||||
@select="typeSelect"
|
||||
:options='[
|
||||
{ label: "并且", value: "and" },
|
||||
{ label: "或者", value: "or" },
|
||||
]'
|
||||
type='type'
|
||||
v-model:value='paramsValue.type'
|
||||
@select='typeSelect'
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="params-item_button"
|
||||
@mouseover="mouseover"
|
||||
@mouseout="mouseout"
|
||||
class='params-item_button'
|
||||
@mouseover='mouseover'
|
||||
@mouseout='mouseout'
|
||||
>
|
||||
<DropdownButton
|
||||
:options="columnOptions"
|
||||
icon="icon-zhihangdongzuoxie-1"
|
||||
type="column"
|
||||
value-name="column"
|
||||
label-name="fullName"
|
||||
placeholder="请选择参数"
|
||||
v-model:value="paramsValue.column"
|
||||
component="treeSelect"
|
||||
@select="columnSelect"
|
||||
:options='columnOptions'
|
||||
icon='icon-zhihangdongzuoxie-1'
|
||||
type='column'
|
||||
value-name='column'
|
||||
label-name='fullName'
|
||||
placeholder='请选择参数'
|
||||
v-model:value='paramsValue.column'
|
||||
component='treeSelect'
|
||||
@select='columnSelect'
|
||||
/>
|
||||
<DropdownButton
|
||||
:options="termTypeOptions"
|
||||
:options='termTypeOptions'
|
||||
type="termType"
|
||||
value-name="id"
|
||||
label-name="name"
|
||||
value-name='id'
|
||||
label-name='name'
|
||||
placeholder="操作符"
|
||||
v-model:value="paramsValue.termType"
|
||||
@select="termsTypeSelect"
|
||||
v-model:value='paramsValue.termType'
|
||||
@select='termsTypeSelect'
|
||||
/>
|
||||
<div v-if="!['notnull','isnull'].includes(paramsValue.termType)">
|
||||
<DoubleParamsDropdown
|
||||
v-if="showDouble"
|
||||
icon="icon-canshu"
|
||||
placeholder="参数值"
|
||||
:options="valueOptions"
|
||||
:metricOptions="metricOption"
|
||||
:tabsOptions="tabsOptions"
|
||||
v-model:value="paramsValue.value.value"
|
||||
v-model:source="paramsValue.value.source"
|
||||
@select="valueSelect"
|
||||
v-if='showDouble'
|
||||
icon='icon-canshu'
|
||||
placeholder='参数值'
|
||||
:options='valueOptions'
|
||||
:metricOptions='metricOption'
|
||||
:tabsOptions='tabsOptions'
|
||||
v-model:value='paramsValue.value.value'
|
||||
v-model:source='paramsValue.value.source'
|
||||
@select='valueSelect'
|
||||
/>
|
||||
<ParamsDropdown
|
||||
v-else
|
||||
icon="icon-canshu"
|
||||
placeholder="参数值"
|
||||
:options="valueOptions"
|
||||
:metricOptions="metricOption"
|
||||
:tabsOptions="tabsOptions"
|
||||
:metric="paramsValue.value?.metric"
|
||||
v-model:value="paramsValue.value.value"
|
||||
v-model:source="paramsValue.value.source"
|
||||
@select="valueSelect"
|
||||
icon='icon-canshu'
|
||||
placeholder='参数值'
|
||||
:options='valueOptions'
|
||||
:metricOptions='metricOption'
|
||||
:tabsOptions='tabsOptions'
|
||||
:metric='paramsValue.value?.metric'
|
||||
v-model:value='paramsValue.value.value'
|
||||
v-model:source='paramsValue.value.source'
|
||||
@select='valueSelect'
|
||||
/>
|
||||
</div>
|
||||
<j-popconfirm
|
||||
title="确认删除?"
|
||||
@confirm="onDelete"
|
||||
:overlayStyle="{ minWidth: '180px' }"
|
||||
>
|
||||
<div v-show="showDelete" class="button-delete">
|
||||
<AIcon type="CloseOutlined" />
|
||||
</div>
|
||||
<j-popconfirm title='确认删除?' @confirm='onDelete' :overlayStyle='{minWidth: "180px"}'>
|
||||
<div v-show='showDelete' class='button-delete'> <AIcon type='CloseOutlined' /></div>
|
||||
</j-popconfirm>
|
||||
</div>
|
||||
<div class="term-add" @click.stop="termAdd" v-if="isLast">
|
||||
<div class="terms-content">
|
||||
<AIcon type="PlusOutlined" style="font-size: 12px" />
|
||||
<div class='term-add' @click.stop='termAdd' v-if='isLast'>
|
||||
<div class='terms-content'>
|
||||
<AIcon type='PlusOutlined' style='font-size: 12px' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -116,31 +110,35 @@ type TabsOption = {
|
|||
const props = defineProps({
|
||||
isFirst: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: true
|
||||
},
|
||||
isLast: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: true
|
||||
},
|
||||
showDeleteBtn: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: true
|
||||
},
|
||||
name: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
default: 0
|
||||
},
|
||||
termsName: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
default: 0
|
||||
},
|
||||
branchName: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
default: 0
|
||||
},
|
||||
branches_Index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
whenName: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
default: 0
|
||||
},
|
||||
value: {
|
||||
type: Object as PropType<TermsType>,
|
||||
|
@ -150,11 +148,11 @@ const props = defineProps({
|
|||
termType: 'eq',
|
||||
value: {
|
||||
source: 'manual',
|
||||
value: undefined,
|
||||
},
|
||||
}),
|
||||
},
|
||||
});
|
||||
value: undefined
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emit>();
|
||||
|
||||
|
@ -321,33 +319,20 @@ const columnSelect = (option: any) => {
|
|||
// 如果参数类型未发生变化,则不修改操作符以及值
|
||||
const termTypes = option.termTypes;
|
||||
|
||||
if (
|
||||
!termTypes.some(
|
||||
(item: { id: string }) => paramsValue.termType === item.id,
|
||||
)
|
||||
) {
|
||||
// 修改操作符
|
||||
termTypeChange = true;
|
||||
paramsValue.termType = termTypes?.length ? termTypes[0].id : 'eq';
|
||||
if (!termTypes.some((item: {id: string}) => paramsValue.termType === item.id)) { // 修改操作符
|
||||
termTypeChange = true
|
||||
paramsValue.termType = termTypes?.length ? termTypes[0].id : 'eq'
|
||||
}
|
||||
console.log('hasTypeChange', paramsValue.value.source, tabsOptions.value);
|
||||
if (
|
||||
hasTypeChange ||
|
||||
!tabsOptions.value.every((a) => a.key === paramsValue.value.source)
|
||||
) {
|
||||
// 类型发生变化
|
||||
paramsValue.termType = termTypes?.length ? termTypes[0].id : 'eq';
|
||||
|
||||
if (hasTypeChange || !tabsOptions.value.every(a => a.key === paramsValue.value.source )) { // 类型发生变化
|
||||
paramsValue.termType = termTypes?.length ? termTypes[0].id : 'eq'
|
||||
paramsValue.value = {
|
||||
source: tabsOptions.value[0].key,
|
||||
value: undefined,
|
||||
};
|
||||
value: undefined
|
||||
}
|
||||
} else if (termTypeChange) {
|
||||
const oldValue = isArray(paramsValue.value!.value)
|
||||
? paramsValue.value!.value[0]
|
||||
: paramsValue.value!.value;
|
||||
const value = arrayParamsKey.includes(paramsValue.termType as string)
|
||||
? [oldValue, undefined]
|
||||
: oldValue;
|
||||
const oldValue = isArray(paramsValue.value!.value) ? paramsValue.value!.value[0] : paramsValue.value!.value
|
||||
const value = arrayParamsKey.includes(paramsValue.termType as string) ? [ oldValue, undefined ] : oldValue
|
||||
|
||||
const _source = paramsValue.value?.source || tabsOptions.value[0].key;
|
||||
const newValue: any = {
|
||||
|
@ -359,21 +344,22 @@ const columnSelect = (option: any) => {
|
|||
newValue.metric = paramsValue.value?.metric;
|
||||
}
|
||||
|
||||
paramsValue.value = newValue;
|
||||
paramsValue.value = newValue
|
||||
}
|
||||
console.log(paramsValue, hasTypeChange);
|
||||
handOptionByColumn(option);
|
||||
emit('update:value', { ...paramsValue });
|
||||
|
||||
handOptionByColumn(option)
|
||||
emit('update:value', { ...paramsValue })
|
||||
nextTick(() => {
|
||||
formItemContext.onFieldChange();
|
||||
});
|
||||
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
|
||||
props.termsName
|
||||
][0] = option.name;
|
||||
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
|
||||
props.termsName
|
||||
][1] = paramsValue.termType;
|
||||
};
|
||||
formItemContext.onFieldChange()
|
||||
})
|
||||
|
||||
if (!formModel.value.options!.when[props.branches_Index]) {
|
||||
formModel.value.options!.when[props.branches_Index] = {terms:[{terms: [['', '', '', '并且']]}]}
|
||||
}
|
||||
console.log([props.branchName, props.whenName, props.termsName])
|
||||
formModel.value.options!.when[props.branches_Index].terms[props.whenName].terms[props.termsName][0] = option.name
|
||||
formModel.value.options!.when[props.branches_Index].terms[props.whenName].terms[props.termsName][1] = paramsValue.termType
|
||||
}
|
||||
|
||||
const termsTypeSelect = (e: { key: string; name: string }) => {
|
||||
const oldValue = isArray(paramsValue.value!.value)
|
||||
|
@ -405,28 +391,25 @@ const termsTypeSelect = (e: { key: string; name: string }) => {
|
|||
};
|
||||
|
||||
if (_source === 'metric') {
|
||||
newValue.metric = paramsValue.value?.metric;
|
||||
const isArray = isString(paramsValue.value!.value)
|
||||
? paramsValue.value!.value?.includes?.(',')
|
||||
: false;
|
||||
if (arrayParamsKey.includes(e.key) !== isArray) {
|
||||
// 有变化
|
||||
newValue.value = undefined;
|
||||
newValue.metric = paramsValue.value?.metric
|
||||
const isArray = isString(paramsValue.value!.value) ? paramsValue.value!.value?.includes?.(',') : false
|
||||
if (arrayParamsKey.includes(e.key) !== isArray) { // 有变化
|
||||
newValue.value = undefined
|
||||
}
|
||||
}
|
||||
|
||||
if(
|
||||
['isnull','notull'].includes(e.key)
|
||||
['isnull','notnull'].includes(e.key)
|
||||
){
|
||||
newValue.value = 1
|
||||
}
|
||||
paramsValue.value = newValue;
|
||||
paramsValue.value = newValue
|
||||
|
||||
emit('update:value', { ...paramsValue });
|
||||
formItemContext.onFieldChange();
|
||||
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
|
||||
props.termsName
|
||||
][1] = e.name;
|
||||
};
|
||||
emit('update:value', { ...paramsValue })
|
||||
formItemContext.onFieldChange()
|
||||
formModel.value.options!.when[props.branches_Index].terms[props.whenName].terms[props.termsName][1] = e.key
|
||||
|
||||
}
|
||||
|
||||
const valueSelect = (
|
||||
v: any,
|
||||
|
@ -441,49 +424,44 @@ const valueSelect = (
|
|||
const newValues = { ...paramsValue };
|
||||
|
||||
if (paramsValue.value?.source !== 'metric') {
|
||||
delete newValues.value.metric;
|
||||
delete newValues.value.metric
|
||||
}
|
||||
emit('update:value', { ...newValues })
|
||||
formItemContext.onFieldChange()
|
||||
|
||||
if (!formModel.value.options!.when[props.branches_Index]) {
|
||||
formModel.value.options!.when[props.branches_Index] = {terms:[{terms: [['', '', '', '并且']]}]}
|
||||
}
|
||||
formModel.value.options!.when[props.branches_Index].terms[props.whenName].terms[props.termsName][2] = labelObj
|
||||
}
|
||||
emit('update:value', { ...newValues });
|
||||
formItemContext.onFieldChange();
|
||||
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
|
||||
props.termsName
|
||||
][2] = labelObj;
|
||||
};
|
||||
|
||||
const typeSelect = (e: any) => {
|
||||
emit('update:value', { ...paramsValue });
|
||||
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
|
||||
props.termsName
|
||||
][3] = e.label;
|
||||
};
|
||||
emit('update:value', { ...paramsValue })
|
||||
formModel.value.options!.when[props.branches_Index].terms[props.whenName].terms[props.termsName][3] = e.label
|
||||
}
|
||||
|
||||
const termAdd = () => {
|
||||
const terms = {
|
||||
column: undefined,
|
||||
value: {
|
||||
source: 'manual',
|
||||
value: undefined,
|
||||
value: undefined
|
||||
},
|
||||
termType: undefined,
|
||||
type: 'and',
|
||||
key: `params_${new Date().getTime()}`,
|
||||
};
|
||||
formModel.value.branches?.[props.branchName]?.when?.[
|
||||
props.whenName
|
||||
]?.terms?.push(terms);
|
||||
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
|
||||
props.termsName
|
||||
].push(['', '', '', '并且']);
|
||||
};
|
||||
key: `params_${new Date().getTime()}`
|
||||
}
|
||||
if (!formModel.value.options!.when[props.branches_Index]) {
|
||||
formModel.value.options!.when[props.branches_Index] = {terms:[{terms: [['', '', '', '并且']]}]}
|
||||
}
|
||||
formModel.value.branches?.[props.branches_Index]?.when?.[props.whenName]?.terms?.push(terms)
|
||||
formModel.value.options!.when[props.branches_Index].terms[props.whenName].terms.push(['', '', '', '并且'])
|
||||
}
|
||||
|
||||
const onDelete = () => {
|
||||
formModel.value.branches?.[props.branchName]?.when?.[
|
||||
props.whenName
|
||||
]?.terms?.splice(props.termsName, 1);
|
||||
formModel.value.options!.when[props.branchName].terms[
|
||||
props.whenName
|
||||
].terms.splice(props.termsName, 1);
|
||||
};
|
||||
formModel.value.branches?.[props.branches_Index]?.when?.[props.whenName]?.terms?.splice(props.termsName, 1)
|
||||
formModel.value.options!.when[props.branches_Index].terms[props.whenName].terms.splice(props.termsName, 1)
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
Object.assign(
|
||||
|
@ -499,7 +477,9 @@ nextTick(() => {
|
|||
'key',
|
||||
]),
|
||||
);
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
|
@ -12,26 +12,45 @@
|
|||
</template>
|
||||
</TitleComponent>
|
||||
<template v-if='open'>
|
||||
<div>
|
||||
<j-tabs type="editable-card" v-model:activeKey="activeKey" @edit="addGroup">
|
||||
<j-tab-pane
|
||||
v-for="(b, i) in group"
|
||||
:key="b.id"
|
||||
:tab="`条件${i + 1}`"
|
||||
:closable="false"
|
||||
>
|
||||
<template v-for='(item, index) in data.branches'>
|
||||
<template v-if="index >= b.start && index < (b.start + b.len)">
|
||||
<Branches
|
||||
v-if='!!item'
|
||||
:data='item'
|
||||
:isFirst='index === 0'
|
||||
:isFirst='index === b.start'
|
||||
:name='index'
|
||||
:branches_Index='item.branches_Index'
|
||||
:groupLen="b.start + b.len"
|
||||
:groupIndex="i"
|
||||
:key='item.key'
|
||||
:showGroupDelete="group.length !== 1"
|
||||
@delete='branchesDelete'
|
||||
@deleteAll='branchesDeleteAll'
|
||||
@deleteGroup="() => groupDelete(b, i)"
|
||||
/>
|
||||
<div v-else class='actions-terms-warp' :style='{ marginTop: data.branches.length === 2 ? 0 : 24 }'>
|
||||
<div class='actions-terms-title' style='padding: 0;margin-bottom: 24px;'>
|
||||
否则
|
||||
</div>
|
||||
<div class='actions-terms-options no-when'>
|
||||
<AIcon type='PlusOutlined' class='when-add-button' @click='addBranches' />
|
||||
<AIcon type='PlusOutlined' class='when-add-button' @click='() => addBranches(b.start + b.len)' />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</j-tab-pane>
|
||||
</j-tabs>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<div v-else class='actions-branches-item'>
|
||||
<j-form-item
|
||||
:name='["branches", 0, "then"]'
|
||||
|
@ -49,7 +68,7 @@
|
|||
|
||||
<script setup lang='ts' name='Terms'>
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useSceneStore } from 'store/scene'
|
||||
import { useSceneStore } from '@/store/scene'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { provide } from 'vue'
|
||||
import { ContextKey, handleParamsData, thenRules } from './util'
|
||||
|
@ -57,15 +76,20 @@ import { getParseTerm } from '@/api/rule-engine/scene'
|
|||
import type { FormModelType } from '@/views/rule-engine/Scene/typings'
|
||||
import Branches from './Branches.vue'
|
||||
import Action from '../../action/index.vue'
|
||||
import {randomString} from "@/utils/utils";
|
||||
|
||||
const sceneStore = useSceneStore()
|
||||
const { data } = storeToRefs(sceneStore)
|
||||
const open = ref<boolean>(false)
|
||||
const columnOptions = ref<any>([])
|
||||
const group = ref<Array<{ id: string, len: number}>>([])
|
||||
const activeKey = ref('')
|
||||
|
||||
provide(ContextKey, columnOptions)
|
||||
|
||||
const change = (e: boolean) => {
|
||||
group.value = []
|
||||
activeKey.value = ''
|
||||
if (!e) {
|
||||
data.value.branches!.length = 1
|
||||
data.value.branches![0].when = []
|
||||
|
@ -81,12 +105,12 @@ const change = (e: boolean) => {
|
|||
value: undefined
|
||||
},
|
||||
termType: undefined,
|
||||
key: 'params_1',
|
||||
key: `params_${randomString()}`,
|
||||
type: 'and',
|
||||
},
|
||||
],
|
||||
type: 'and',
|
||||
key: 'terms_1',
|
||||
key: `terms_${randomString()}`,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -100,7 +124,7 @@ const queryColumn = (dataModel: FormModelType) => {
|
|||
})
|
||||
}
|
||||
|
||||
const addBranches = () => {
|
||||
const addBranches = (len: number) => {
|
||||
const branchesItem = {
|
||||
when: [],
|
||||
key: `branches_${new Date().getTime()}`,
|
||||
|
@ -111,10 +135,14 @@ const addBranches = () => {
|
|||
alarmFirst: false,
|
||||
},
|
||||
then: [],
|
||||
branchId: Math.floor(Math.random() * 100000000)
|
||||
}
|
||||
const lastIndex = data.value.branches!.length - 1 || 0
|
||||
data.value.branches?.splice(lastIndex, 1, branchesItem)
|
||||
data.value.options!.when = []
|
||||
// const lastIndex = data.value.branches!.length - 1 || 0
|
||||
data.value.branches?.splice(len - 1, 1, branchesItem)
|
||||
data.value.options!.when.splice(len - 1, 1, {
|
||||
terms: []
|
||||
})
|
||||
// data.value.options!.when = []
|
||||
}
|
||||
|
||||
const branchesDelete = (index: number) => {
|
||||
|
@ -126,10 +154,62 @@ const branchesDelete = (index: number) => {
|
|||
data.value.options?.when?.splice(index, 1)
|
||||
}
|
||||
|
||||
const addGroup = () => {
|
||||
const branchesItem: any = {
|
||||
when: [
|
||||
{
|
||||
terms: [
|
||||
{
|
||||
column: undefined,
|
||||
value: {
|
||||
source: 'fixed',
|
||||
value: undefined
|
||||
},
|
||||
termType: undefined,
|
||||
key: `params_${randomString()}`,
|
||||
type: 'and',
|
||||
},
|
||||
],
|
||||
type: 'and',
|
||||
key: `terms_${randomString()}`,
|
||||
},
|
||||
],
|
||||
key: `branches_${randomString()}`,
|
||||
shakeLimit: {
|
||||
enabled: false,
|
||||
time: 1,
|
||||
threshold: 1,
|
||||
alarmFirst: false,
|
||||
},
|
||||
then: [],
|
||||
executeAnyway: true,
|
||||
branchId: Math.floor(Math.random() * 100000000)
|
||||
}
|
||||
data.value.branches?.push(branchesItem)
|
||||
data.value.branches?.push(null as any)
|
||||
activeKey.value = `group_${branchesItem.key}`
|
||||
data.value.options!.when.push({
|
||||
terms: [{
|
||||
terms: [['','eq','','and']],
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
const branchesDeleteAll = () => {
|
||||
|
||||
}
|
||||
|
||||
const groupDelete = (g: any, index: number) => {
|
||||
let _index = index - 1
|
||||
if (_index < 0) { // 左移
|
||||
_index = 0
|
||||
}
|
||||
group.value.splice(index, 1)
|
||||
data.value.branches.splice(g.start, g.len)
|
||||
data.value.options!.when.splice(g.start, g.len)
|
||||
activeKey.value = group.value[_index].id
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
if (data.value.trigger?.device) {
|
||||
queryColumn({ trigger: data.value.trigger })
|
||||
|
@ -137,15 +217,48 @@ watchEffect(() => {
|
|||
})
|
||||
|
||||
watchEffect(() => {
|
||||
const branches = data.value.branches
|
||||
|
||||
if (data.value.branches?.filter(item => item).length) {
|
||||
open.value = !!data.value.branches[0].when.length
|
||||
} else {
|
||||
open.value = true
|
||||
}
|
||||
|
||||
let _group = []
|
||||
if (branches) {
|
||||
branches.forEach((item, index) => {
|
||||
// if (index === 0) {
|
||||
// _group.push({
|
||||
// id: `group_${item.key}`,
|
||||
// len: 0,
|
||||
// start: 0,
|
||||
// })
|
||||
// }
|
||||
|
||||
const lastIndex = _group.length - 1
|
||||
|
||||
if (index === 0 || item?.executeAnyway) {
|
||||
_group[lastIndex + 1] = {
|
||||
id: `group_${item.key}`,
|
||||
len: 1,
|
||||
start: index
|
||||
}
|
||||
} else {
|
||||
_group[lastIndex].len += 1
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
console.log('terms-onMounted')
|
||||
branches.filter(item => item).forEach((item, index) => {
|
||||
item.branches_Index = index
|
||||
})
|
||||
|
||||
group.value = _group
|
||||
if (!activeKey.value) {
|
||||
activeKey.value = _group[0].id
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
:termsName='name'
|
||||
:whenName='whenName'
|
||||
:branchName='branchName'
|
||||
:branches_Index='branches_Index'
|
||||
/>
|
||||
</j-form-item>
|
||||
</template>
|
||||
|
@ -60,6 +61,10 @@ const props = defineProps({
|
|||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
branches_Index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
whenName: {
|
||||
type: Number,
|
||||
default: 0
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
v-for='(item, index) in termsData'
|
||||
:key='item.key'
|
||||
:branchName='branchName'
|
||||
:branches_Index='branches_Index'
|
||||
:whenName='props.name'
|
||||
:name='index'
|
||||
:showDeleteBtn='termsData.length > 1'
|
||||
|
@ -89,6 +90,10 @@ const props = defineProps({
|
|||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
branches_Index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
isLast: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
|
@ -119,7 +124,7 @@ const typeChange = (e: any) => {
|
|||
|
||||
const onDelete = () => {
|
||||
formModel.value.branches?.[props.branchName]?.when?.splice(props.name, 1)
|
||||
formModel.value.options!.when[props.branchName].terms.splice(props.name, 1)
|
||||
formModel.value.options!.when[props.branches_Index].terms.splice(props.name, 1)
|
||||
}
|
||||
|
||||
const addWhen = () => {
|
||||
|
@ -140,7 +145,10 @@ const addWhen = () => {
|
|||
key: `terms_${randomString()}`
|
||||
}
|
||||
formModel.value.branches?.[props.branchName]?.when?.push(terms)
|
||||
formModel.value.options?.when?.[props.branchName]?.terms.push({ termType: '并且', terms: [['','eq','','and']]})
|
||||
if (!formModel.value.options!.when[props.branches_Index]) {
|
||||
formModel.value.options!.when[props.branches_Index] = {terms:[{terms: [['', '', '', '并且']]}]}
|
||||
}
|
||||
formModel.value.options?.when?.[props.branches_Index]?.terms.push({ termType: '并且', terms: [['','eq','','and']]})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -50,6 +50,16 @@
|
|||
.actions-terms-warp {
|
||||
display: flex;
|
||||
margin-bottom: 24px;
|
||||
position: relative;
|
||||
|
||||
.group-delete {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -14px;
|
||||
z-index: 2;
|
||||
cursor: pointer;
|
||||
color: #e50012;
|
||||
}
|
||||
|
||||
&.first-children,
|
||||
&:last-child {
|
||||
|
|
|
@ -24,3 +24,4 @@ export const thenRules = [{
|
|||
return Promise.resolve();
|
||||
}
|
||||
}]
|
||||
|
||||
|
|
|
@ -14,25 +14,25 @@
|
|||
<template v-if='!options.onlyName'>
|
||||
<div v-if='options.productName' class='center-item'>
|
||||
<AIcon type='icon-chanpin1' class='icon-padding-right' />
|
||||
<span className='trigger-options-type'>{{ options.productName }}</span>
|
||||
<span class='trigger-options-type'>{{ options.productName }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if='options.when'>
|
||||
<span className='trigger-options-when'>{{ options.when }}</span>
|
||||
<span class='trigger-options-when'>{{ options.when }}</span>
|
||||
</div>
|
||||
<div v-if='options.time'>
|
||||
<span className='trigger-options-time'>{{ options.time }}</span>
|
||||
<span class='trigger-options-time'>{{ options.time }}</span>
|
||||
</div>
|
||||
<div v-if='options.extraTime'>
|
||||
<span className='trigger-options-extraTime'>{{ options.extraTime }}</span>
|
||||
<span class='trigger-options-extraTime'>{{ options.extraTime }}</span>
|
||||
</div>
|
||||
<div v-if='options.action' class='center-item'>
|
||||
<AIcon :type='options.typeIcon' class='icon-padding-right' />
|
||||
<span className='trigger-options-action'>{{ options.action }}</span>
|
||||
<span class='trigger-options-action'>{{ options.action }}</span>
|
||||
</div>
|
||||
<div v-if='options.type' class='center-item'>
|
||||
<AIcon :type='options.typeIcon' class='icon-padding-right' />
|
||||
<span className='trigger-options-type'>{{ options.type }}</span>
|
||||
<span class='trigger-options-type'>{{ options.type }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import { useSceneStore } from '@/store/scene'
|
||||
import {storeToRefs} from "pinia";
|
||||
import type {BranchesGroup} from "@/views/rule-engine/Scene/typings";
|
||||
export const useTrigger = () => {
|
||||
const sceneStore = useSceneStore()
|
||||
const { data } = storeToRefs(sceneStore)
|
||||
const open = ref(false)
|
||||
|
||||
|
||||
watchEffect(() => {
|
||||
const group = data.value.branches as BranchesGroup
|
||||
console.log(group)
|
||||
open.value = !!group?.filter(item => item.filter(b => b)?.length).length
|
||||
})
|
||||
|
||||
return {
|
||||
open
|
||||
}
|
||||
}
|
|
@ -328,7 +328,10 @@ const getActions = (
|
|||
{
|
||||
column: 'id',
|
||||
termType: 'rule-bind-alarm',
|
||||
value: data.id,
|
||||
value: {
|
||||
ruleId: [data.id],
|
||||
branchId: [-1]
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
|
@ -280,6 +280,8 @@ export interface ActionBranchesProps {
|
|||
shakeLimit: ShakeLimitType;
|
||||
then: BranchesThen[];
|
||||
key?: string;
|
||||
|
||||
executeAnyway?: boolean
|
||||
}
|
||||
|
||||
export interface ActionsType {
|
||||
|
@ -301,6 +303,8 @@ export interface ActionsType {
|
|||
options?: Record<string, any>;
|
||||
}
|
||||
|
||||
export type BranchesGroup = Array<ActionBranchesProps[]>
|
||||
|
||||
export interface FormModelType {
|
||||
id?: string;
|
||||
name?: string;
|
||||
|
@ -319,7 +323,7 @@ export interface FormModelType {
|
|||
/**
|
||||
* 动作分支
|
||||
*/
|
||||
branches?: ActionBranchesProps[];
|
||||
branches?: ActionBranchesProps[] | Array<ActionBranchesProps[]>;
|
||||
/**
|
||||
* 拓展信息,用于前端存储一些渲染数据
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import type {ActionBranchesProps} from "./typings";
|
||||
import {isArray} from "lodash-es";
|
||||
|
||||
export const handleGroup = (branches: ActionBranchesProps[]) => {
|
||||
let group: Array<Array<ActionBranchesProps | null>> = []
|
||||
|
||||
branches.forEach((item) => {
|
||||
const lastIndex = group.length - 1
|
||||
if (item?.executeAnyway) {
|
||||
group[lastIndex] = [item]
|
||||
} else {
|
||||
if (isArray(group[lastIndex])) {
|
||||
group[lastIndex].push(item)
|
||||
} else {
|
||||
group[lastIndex] = [item]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 判断每组末尾是否有数据并且when有值
|
||||
if (group.length) {
|
||||
group = group.map(item => {
|
||||
if (item.length && item[item.length -1]?.when?.length) {
|
||||
item.push(null)
|
||||
}
|
||||
return item
|
||||
})
|
||||
} else {
|
||||
group[0] = [null]
|
||||
}
|
||||
|
||||
return group
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const groupToArray = (branchesGroup: Array<ActionBranchesProps[]>) => {
|
||||
const arr:ActionBranchesProps[] = []
|
||||
|
||||
branchesGroup.forEach(item => {
|
||||
|
||||
})
|
||||
}
|
|
@ -44,7 +44,7 @@
|
|||
import PermissionButton from '@/components/PermissionButton/index.vue';
|
||||
import AddDialog from './components/AddDialog.vue';
|
||||
import { getRoleList_api, delRole_api } from '@/api/system/role';
|
||||
import type { ActionsType } from './typings';
|
||||
import type { ActionsType } from '@/components/Table';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
const props = defineProps({
|
||||
|
|
|
@ -94,11 +94,11 @@ export default defineConfig(({ mode}) => {
|
|||
[env.VITE_APP_BASE_API]: {
|
||||
// target: 'http://192.168.32.226:8844',
|
||||
// target: 'http://192.168.32.244:8881',
|
||||
// target: 'http://192.168.32.163:8844', //张季本地
|
||||
// target: 'http://192.168.32.163:8844', //张本地
|
||||
// target: 'http://120.77.179.54:8844', // 120测试
|
||||
target: 'http://192.168.33.46:8844', // 本地开发环境
|
||||
// target: 'http://192.168.33.1:8845', // 社区版开发环境
|
||||
// target: 'http://192.168.32.5:8848', // 刘本地
|
||||
// target: 'http://192.168.32.200:8844', // 刘本地
|
||||
// target: 'http://192.168.32.187:8844', // 谭本地
|
||||
ws: 'ws://192.168.33.46:8844',
|
||||
changeOrigin: true,
|
||||
|
|
Loading…
Reference in New Issue