Commit bbef30c5a6fc7dba485dee556a93b112196793e8

Authored by fengtao
2 parents 99fa6d2b 3ef67b0f

fix

@@ -2,7 +2,6 @@ import { defHttp } from '/@/utils/http/axios'; @@ -2,7 +2,6 @@ import { defHttp } from '/@/utils/http/axios';
2 import { 2 import {
3 // ScreenParamModel, 3 // ScreenParamModel,
4 ScreenAddModel, 4 ScreenAddModel,
5 - ScreenUpdateModel,  
6 ScreenLinkPageQueryParam, 5 ScreenLinkPageQueryParam,
7 ScreenByDeptIdParams, 6 ScreenByDeptIdParams,
8 IChangeStatus, 7 IChangeStatus,
@@ -19,7 +18,8 @@ enum ScreenManagerApi { @@ -19,7 +18,8 @@ enum ScreenManagerApi {
19 SCREEN_ORGANIZATION_URL = '/organization/me/list', 18 SCREEN_ORGANIZATION_URL = '/organization/me/list',
20 SCREEN_CHANGE_STATUS = '/convert/update/scene', 19 SCREEN_CHANGE_STATUS = '/convert/update/scene',
21 SCREEN_GET_BY_DEPTID = '/sceneLinkage/device/', 20 SCREEN_GET_BY_DEPTID = '/sceneLinkage/device/',
22 - SCREEN_BYDEVICEID_GET_ATTRBUTELIST = '/plugins/telemetry/', 21 + GET_ATTRBUTELIST = '/deviceProfile/devices/keys/timeseries',
  22 + ALARM_PROFILE = '/alarm/profile/',
23 } 23 }
24 24
25 /** 25 /**
@@ -78,7 +78,7 @@ export const screenLinkPagePutApi = (params: IChangeStatus) => @@ -78,7 +78,7 @@ export const screenLinkPagePutApi = (params: IChangeStatus) =>
78 }); 78 });
79 79
80 /** 80 /**
81 - * 根据部门id获取设备列表 81 + * 根据组织获取设备列表
82 */ 82 */
83 export const screenLinkPageByDeptIdGetDevice = (params: ScreenByDeptIdParams) => { 83 export const screenLinkPageByDeptIdGetDevice = (params: ScreenByDeptIdParams) => {
84 return defHttp.get({ 84 return defHttp.get({
@@ -88,20 +88,21 @@ export const screenLinkPageByDeptIdGetDevice = (params: ScreenByDeptIdParams) => @@ -88,20 +88,21 @@ export const screenLinkPageByDeptIdGetDevice = (params: ScreenByDeptIdParams) =>
88 }; 88 };
89 89
90 /** 90 /**
91 - * 根据设备id获取属性列表 91 + * 获取住址下的告警配置
92 */ 92 */
93 -export const screenLinkPageByDeviceIdGetAttribut = (entityType, entityId) => { 93 +export const getOrganizationAlarmConfig = (params: { organizationId }) => {
  94 + return defHttp.get({
  95 + url: ScreenManagerApi.ALARM_PROFILE + params.organizationId,
  96 + });
  97 +};
  98 +
  99 +/**
  100 + * 获取设备属性列表
  101 + */
  102 +export const getAttribute = () => {
94 return defHttp.get( 103 return defHttp.get(
95 { 104 {
96 - url:  
97 - ScreenManagerApi.SCREEN_BYDEVICEID_GET_ATTRBUTELIST +  
98 - `${entityType}` +  
99 - '/' +  
100 - `${entityId}` +  
101 - '/' +  
102 - 'keys' +  
103 - '/' +  
104 - 'timeseries', 105 + url: ScreenManagerApi.GET_ATTRBUTELIST,
105 }, 106 },
106 { 107 {
107 joinPrefix: false, 108 joinPrefix: false,
@@ -58,6 +58,7 @@ @@ -58,6 +58,7 @@
58 */ 58 */
59 lazyTime: { type: Number, default: 0 }, 59 lazyTime: { type: Number, default: 0 },
60 }); 60 });
  61 + const emit = defineEmits(['expand']);
61 62
62 const show = ref(true); 63 const show = ref(true);
63 64
@@ -72,7 +73,12 @@ @@ -72,7 +73,12 @@
72 // 200 milliseconds here is because the expansion has animation, 73 // 200 milliseconds here is because the expansion has animation,
73 useTimeoutFn(triggerWindowResize, 200); 74 useTimeoutFn(triggerWindowResize, 200);
74 } 75 }
  76 + emit('expand', show.value);
75 } 77 }
  78 + defineExpose({
  79 + handleExpand,
  80 + show,
  81 + });
76 </script> 82 </script>
77 <style lang="less"> 83 <style lang="less">
78 @prefix-cls: ~'@{namespace}-collapse-container'; 84 @prefix-cls: ~'@{namespace}-collapse-container';
  1 +/**
  2 + * 运算符枚举值
  3 + */
  4 +
  5 +// 数字运算符或者时间运算符
  6 +export enum Number_Operation {
  7 + EQUAL = 'EQUAL',
  8 + NOT_EQUAL = 'NOT_EQUAL',
  9 + LESS = 'LESS',
  10 + LESS_OR_EQUAL = 'LESS_OR_EQUAL',
  11 + GREATER = 'GREATER',
  12 + GREATER_OR_EQUAL = 'GREATER_OR_EQUAL',
  13 +}
  14 +
  15 +export enum String_Operation {
  16 + EQUAL = 'EQUAL',
  17 + NOT_EQUAL = 'NOT_EQUAL',
  18 + BEGAN_IN = 'BEGAN_IN',
  19 + END_IN = 'END_IN',
  20 + INCLUDE = 'INCLUDE',
  21 + NOT_INCLUDE = 'NOT_INCLUDE',
  22 +}
  23 +
  24 +export enum Boolean_Operation {
  25 + EQUAL = 'EQUAL',
  26 + NOT_EQUAL = 'NOT_EQUAL',
  27 +}
@@ -31,6 +31,7 @@ interface UserState { @@ -31,6 +31,7 @@ interface UserState {
31 lastUpdateTime: number; 31 lastUpdateTime: number;
32 jwtToken?: string; 32 jwtToken?: string;
33 refreshToken?: string; 33 refreshToken?: string;
  34 + outTarget?: string;
34 } 35 }
35 36
36 const storage = createLocalStorage(); 37 const storage = createLocalStorage();
@@ -40,6 +41,7 @@ export const useUserStore = defineStore({ @@ -40,6 +41,7 @@ export const useUserStore = defineStore({
40 //平台信息 41 //平台信息
41 platInfo: storage.get('platformInfo') || null, 42 platInfo: storage.get('platformInfo') || null,
42 enterPriseInfo: storage.get('enterPriseInfo') || null, 43 enterPriseInfo: storage.get('enterPriseInfo') || null,
  44 + outTarget: 'DEVICE_OUT',
43 // user info 45 // user info
44 userInfo: null, 46 userInfo: null,
45 userUpdateInfo: null, 47 userUpdateInfo: null,
@@ -62,6 +64,9 @@ export const useUserStore = defineStore({ @@ -62,6 +64,9 @@ export const useUserStore = defineStore({
62 getUserInfo(): UserInfo { 64 getUserInfo(): UserInfo {
63 return this.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {}; 65 return this.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {};
64 }, 66 },
  67 + getOutTarget(): any {
  68 + return this.outTarget;
  69 + },
65 getUserUpdateInfo(): UserUpdateInfo { 70 getUserUpdateInfo(): UserUpdateInfo {
66 return this.userUpdateInfo || {}; 71 return this.userUpdateInfo || {};
67 }, 72 },
@@ -88,6 +93,9 @@ export const useUserStore = defineStore({ @@ -88,6 +93,9 @@ export const useUserStore = defineStore({
88 setEnterPriseInfo(enterPriseInfo: any) { 93 setEnterPriseInfo(enterPriseInfo: any) {
89 this.enterPriseInfo = enterPriseInfo; 94 this.enterPriseInfo = enterPriseInfo;
90 }, 95 },
  96 + setOutTarget(outTarget) {
  97 + this.outTarget = outTarget;
  98 + },
91 storeToken(jwtToken: string, refreshToken: string) { 99 storeToken(jwtToken: string, refreshToken: string) {
92 this.jwtToken = jwtToken; 100 this.jwtToken = jwtToken;
93 this.refreshToken = refreshToken; 101 this.refreshToken = refreshToken;
@@ -39,7 +39,6 @@ @@ -39,7 +39,6 @@
39 import { Button } from '/@/components/Button'; 39 import { Button } from '/@/components/Button';
40 import MqttCpns from '../step/cpns/mqtt/Mqtt.vue'; 40 import MqttCpns from '../step/cpns/mqtt/Mqtt.vue';
41 import CoapCpns from '../step/cpns/coap/Coap.vue'; 41 import CoapCpns from '../step/cpns/coap/Coap.vue';
42 - import Lwm2mCpns from '../step/cpns/lwm2m/index.vue';  
43 42
44 export default defineComponent({ 43 export default defineComponent({
45 components: { 44 components: {
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 v-bind="$attrs" 4 v-bind="$attrs"
5 @register="registerDrawer" 5 @register="registerDrawer"
6 @ok="handleSubmit" 6 @ok="handleSubmit"
7 - width="50vw" 7 + width="100%"
8 showFooter 8 showFooter
9 @close="handleClose" 9 @close="handleClose"
10 :title="title" 10 :title="title"
@@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
14 <BasicForm @register="registerForm" /> 14 <BasicForm @register="registerForm" />
15 <!-- 基础表单 --> 15 <!-- 基础表单 -->
16 <!-- 触发器-begin --> 16 <!-- 触发器-begin -->
  17 + <Divider orientation="left">触发器</Divider>
17 <div> 18 <div>
18 <template v-for="(item, index) in triggerData" :key="item"> 19 <template v-for="(item, index) in triggerData" :key="item">
19 <Trigger 20 <Trigger
@@ -25,13 +26,15 @@ @@ -25,13 +26,15 @@
25 </template> 26 </template>
26 <!-- 按钮 --> 27 <!-- 按钮 -->
27 <a-button type="primary" class="mt-4" @click="addTrigger" v-if="isView"> 28 <a-button type="primary" class="mt-4" @click="addTrigger" v-if="isView">
28 - 添加触发器</a-button 29 + <PlusOutlined />
  30 + 新增触发器</a-button
29 > 31 >
30 <!-- 按钮 --> 32 <!-- 按钮 -->
31 </div> 33 </div>
32 <!-- 触发器-end --> 34 <!-- 触发器-end -->
33 35
34 <!-- 执行条件-begin --> 36 <!-- 执行条件-begin -->
  37 + <Divider orientation="left">执行条件</Divider>
35 <div> 38 <div>
36 <template v-for="(item, index) in conditionData" :key="item"> 39 <template v-for="(item, index) in conditionData" :key="item">
37 <Condition 40 <Condition
@@ -43,13 +46,15 @@ @@ -43,13 +46,15 @@
43 </template> 46 </template>
44 <!-- 按钮 --> 47 <!-- 按钮 -->
45 <a-button type="primary" class="mt-4" @click="addCondition" v-if="isView"> 48 <a-button type="primary" class="mt-4" @click="addCondition" v-if="isView">
46 - 添加执行条件</a-button 49 + <PlusOutlined />
  50 + 新增执行条件</a-button
47 > 51 >
48 <!-- 按钮 --> 52 <!-- 按钮 -->
49 </div> 53 </div>
50 <!-- 执行条件-end --> 54 <!-- 执行条件-end -->
51 55
52 <!-- 执行动作-begin --> 56 <!-- 执行动作-begin -->
  57 + <Divider orientation="left">执行动作</Divider>
53 <div> 58 <div>
54 <template v-for="(item, index) in actionData" :key="item"> 59 <template v-for="(item, index) in actionData" :key="item">
55 <Action 60 <Action
@@ -60,10 +65,10 @@ @@ -60,10 +65,10 @@
60 @deleteAction="deleteAction" 65 @deleteAction="deleteAction"
61 /> 66 />
62 </template> 67 </template>
63 -  
64 <!-- 按钮 --> 68 <!-- 按钮 -->
65 <a-button type="primary" class="mt-4" @click="addAction" v-if="isView"> 69 <a-button type="primary" class="mt-4" @click="addAction" v-if="isView">
66 - 添加执行动作</a-button 70 + <PlusOutlined />
  71 + 新增执行动作</a-button
67 > 72 >
68 <!-- 按钮 --> 73 <!-- 按钮 -->
69 </div> 74 </div>
@@ -72,287 +77,274 @@ @@ -72,287 +77,274 @@
72 </BasicDrawer> 77 </BasicDrawer>
73 </div> 78 </div>
74 </template> 79 </template>
75 -<script lang="ts">  
76 - import { defineComponent, ref, watch, unref, computed, nextTick } from 'vue'; 80 +<script lang="ts" setup>
  81 + import { ref, watch, unref, computed, nextTick } from 'vue';
77 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; 82 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
78 import { formSchema, organizationId } from './config'; 83 import { formSchema, organizationId } from './config';
79 import { BasicForm, useForm } from '/@/components/Form'; 84 import { BasicForm, useForm } from '/@/components/Form';
80 - import { formatTriggerData, formatConditionData } from './cpns/format-data'; 85 + import { genTriggerData, genConditionData, genActionData } from './cpns/format-data';
  86 + import { Divider } from 'ant-design-vue';
  87 + import { PlusOutlined } from '@ant-design/icons-vue';
81 import { useMessage } from '/@/hooks/web/useMessage'; 88 import { useMessage } from '/@/hooks/web/useMessage';
82 import { 89 import {
83 screenLinkPageAddApi, 90 screenLinkPageAddApi,
84 screenLinkPageByDeptIdGetDevice, 91 screenLinkPageByDeptIdGetDevice,
  92 + getOrganizationAlarmConfig,
85 } from '/@/api/ruleengine/ruleengineApi'; 93 } from '/@/api/ruleengine/ruleengineApi';
86 import Trigger from './cpns/Trigger.vue'; 94 import Trigger from './cpns/Trigger.vue';
87 import Condition from './cpns/Condition.vue'; 95 import Condition from './cpns/Condition.vue';
88 import Action from './cpns/Action.vue'; 96 import Action from './cpns/Action.vue';
89 - export default defineComponent({  
90 - name: 'SceneLinkAgeDrawer',  
91 - components: {  
92 - BasicDrawer,  
93 - BasicForm,  
94 - Trigger,  
95 - Condition,  
96 - Action,  
97 - },  
98 - emits: ['register', 'success'],  
99 - setup(_, { emit }) {  
100 - const { createMessage } = useMessage();  
101 - const triggerData = ref([]);  
102 - const conditionData = ref([]);  
103 - const actionData = ref([]);  
104 - const skipUnwrap = {  
105 - triggerItemRefs: ref([]),  
106 - conditionItemRefs: ref([]),  
107 - actionItemRefs: ref([]),  
108 - };  
109 - const title = computed(  
110 - () => `${isUpdate.value === 3 ? '查看' : isUpdate.value ? '编辑' : '新增'}场景联动`  
111 - );  
112 - let getTriggerFormValue = ref([]);  
113 - let getConditionFormValue = ref([]);  
114 - let getActionFormValue = ref([]);  
115 - const editEntryIdData = ref([]);  
116 - const isUpdate = ref(false);  
117 - const id = ref(undefined);  
118 - const tenantId = ref(undefined);  
119 - const isView = ref(true);  
120 - const [registerForm, { resetFields, validate, setFieldsValue }] = useForm({  
121 - labelWidth: 120,  
122 - schemas: formSchema,  
123 - showActionButtonGroup: false,  
124 - });  
125 - const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {  
126 - setDrawerProps({ confirmLoading: false, loading: true });  
127 - isUpdate.value = data.isUpdate; 97 + import { useUserStore } from '/@/store/modules/user';
128 98
129 - if (!unref(isUpdate)) {  
130 - resetFields();  
131 - //初始化执行动作  
132 - actionData.value = [Date.now()];  
133 - } else {  
134 - // 取值  
135 - const {  
136 - id: recordId,  
137 - tenantId: recordTenantId,  
138 - organizationId,  
139 - triggers,  
140 - doConditions,  
141 - doActions,  
142 - } = data.record;  
143 - // 赋值  
144 - await setFieldsValue(data.record);  
145 - id.value = recordId;  
146 - tenantId.value = recordTenantId;  
147 - // 获取当前组织下的设备列表  
148 - const options = await screenLinkPageByDeptIdGetDevice({  
149 - organizationId,  
150 - });  
151 - // 生成回显时对应得组件数量  
152 - triggerData.value = [...new Array(triggers.length).keys()];  
153 - conditionData.value = [...new Array(doConditions.length).keys()];  
154 - actionData.value = [...new Array(doActions.length).keys()];  
155 - // 回显设备列表  
156 - editEntryIdData.value = options.items.map((v) => {  
157 - return {  
158 - value: v.tbDeviceId,  
159 - label: v.name,  
160 - };  
161 - });  
162 - nextTick(() => {  
163 - setEditFields(skipUnwrap.triggerItemRefs, editEntryIdData);  
164 - setEditFields(skipUnwrap.conditionItemRefs, editEntryIdData);  
165 - setEditFields(skipUnwrap.actionItemRefs, editEntryIdData);  
166 - }); 99 + const emit = defineEmits(['register', 'success']);
167 100
168 - // 回显触发器数据---此处是个闭包!  
169 - triggers.forEach((trigger, index) => {  
170 - nextTick(() => {  
171 - unref(skipUnwrap.triggerItemRefs)[index].setFieldsFormValueFun({  
172 - triggerType: trigger.triggerType,  
173 - entityId: trigger.entityId,  
174 - type1: trigger.triggerCondition?.condition[0]?.key?.type,  
175 - type2: trigger.triggerCondition?.condition[0]?.key?.key,  
176 - operation: trigger.triggerCondition?.condition[0]?.predicate?.operation,  
177 - value: trigger.triggerCondition?.condition[0]?.predicate?.value?.defaultValue,  
178 - });  
179 - });  
180 - });  
181 -  
182 - doConditions.forEach((item, index) => {  
183 - nextTick(() => {  
184 - unref(skipUnwrap.conditionItemRefs)[index].setFieldsFormValueFun({  
185 - triggerType: item?.triggerType,  
186 - entityId: item?.entityId,  
187 - type: item.triggerCondition?.condition[0].key.key,  
188 - operation: item?.triggerCondition?.condition[0]?.predicate?.operation,  
189 - value: item?.triggerCondition?.condition[0]?.predicate?.value?.defaultValue,  
190 - });  
191 - });  
192 - }); 101 + const { createMessage } = useMessage();
  102 + const triggerData = ref([]);
  103 + const conditionData = ref([]);
  104 + const actionData = ref([]);
  105 + const skipUnwrap = {
  106 + triggerItemRefs: ref([]),
  107 + conditionItemRefs: ref([]),
  108 + actionItemRefs: ref([]),
  109 + };
  110 + const title = computed(
  111 + () => `${isUpdate.value === 3 ? '查看' : isUpdate.value ? '编辑' : '新增'}场景联动`
  112 + );
  113 + let getTriggerFormValue = ref([]);
  114 + let getConditionFormValue = ref([]);
  115 + let getActionFormValue = ref([]);
  116 + const editEntryIdData = ref([]);
  117 + const isUpdate = ref(false);
  118 + const id = ref(undefined);
  119 + const tenantId = ref(undefined);
  120 + const isView = ref(true);
  121 + const [registerForm, { resetFields, validate, setFieldsValue }] = useForm({
  122 + labelWidth: 120,
  123 + schemas: formSchema,
  124 + showActionButtonGroup: false,
  125 + });
  126 + const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
  127 + setDrawerProps({ confirmLoading: false, loading: true });
  128 + isUpdate.value = data.isUpdate;
  129 + if (!unref(isUpdate)) {
  130 + resetFields();
  131 + //初始化执行动作
  132 + actionData.value = [Date.now()];
  133 + } else {
  134 + // 取值
  135 + const {
  136 + id: recordId,
  137 + tenantId: recordTenantId,
  138 + organizationId,
  139 + triggers,
  140 + doConditions,
  141 + doActions,
  142 + } = data.record;
  143 + // 赋值
  144 + await setFieldsValue(data.record);
  145 + id.value = recordId;
  146 + tenantId.value = recordTenantId;
  147 + // 获取当前组织下的设备列表
  148 + const options = await screenLinkPageByDeptIdGetDevice({
  149 + organizationId,
  150 + });
  151 + // 生成回显时对应得组件数量
  152 + triggerData.value = [...new Array(triggers.length).keys()];
  153 + conditionData.value = [...new Array(doConditions.length).keys()];
  154 + actionData.value = [...new Array(doActions.length).keys()];
  155 + // 回显设备列表
  156 + editEntryIdData.value = options.items.map((v) => {
  157 + return {
  158 + value: v.tbDeviceId,
  159 + label: v.name,
  160 + };
  161 + });
  162 + nextTick(() => {
  163 + setEditFields(skipUnwrap.triggerItemRefs, editEntryIdData);
  164 + setEditFields(skipUnwrap.conditionItemRefs, editEntryIdData);
  165 + setEditFields(skipUnwrap.actionItemRefs, editEntryIdData);
  166 + });
193 167
194 - doActions.forEach((item, index) => {  
195 - nextTick(() => {  
196 - unref(skipUnwrap.actionItemRefs)[index].setFieldsFormValueFun({  
197 - outTarget: item.outTarget,  
198 - deviceId: item.deviceId,  
199 - });  
200 - unref(skipUnwrap.actionItemRefs)[index].setJsonValue(item.doContext.params);  
201 - }); 168 + // 回显触发器数据---此处是个闭包!
  169 + triggers.forEach((trigger, index) => {
  170 + nextTick(() => {
  171 + unref(skipUnwrap.triggerItemRefs)[index].setFieldsFormValueFun({
  172 + triggerType: trigger.triggerType,
  173 + entityId: trigger.entityId,
  174 + type1: trigger.triggerCondition?.condition[0]?.key?.type,
  175 + type2: trigger.triggerCondition?.condition[0]?.key?.key,
  176 + operation: trigger.triggerCondition?.condition[0]?.predicate?.operation,
  177 + value: trigger.triggerCondition?.condition[0]?.predicate?.value?.defaultValue,
202 }); 178 });
203 - }  
204 - if (unref(isUpdate) === 3) isView.value = false;  
205 - setDrawerProps({  
206 - showFooter: isView.value,  
207 - loading: false,  
208 }); 179 });
209 }); 180 });
210 181
211 - // 设置设备的options  
212 - const setEditFields = (linkAge, deviceList) => {  
213 - unref(linkAge).map((item) => {  
214 - item.updateFieldDeviceId(deviceList); 182 + doConditions.forEach((item, index) => {
  183 + nextTick(() => {
  184 + unref(skipUnwrap.conditionItemRefs)[index].setFieldsFormValueFun({
  185 + triggerType: item?.triggerType,
  186 + entityId: item?.entityId,
  187 + type: item.triggerCondition?.condition[0].key.key,
  188 + operation: item?.triggerCondition?.condition[0]?.predicate?.operation,
  189 + value: item?.triggerCondition?.condition[0]?.predicate?.value?.defaultValue,
  190 + });
215 }); 191 });
216 - };  
217 - // 监听组织变化更新设备列表  
218 - const deviceList = ref([]);  
219 - watch(organizationId, async (newValue: string) => {  
220 - if (!newValue) return;  
221 - const { items } = await screenLinkPageByDeptIdGetDevice({ organizationId: newValue });  
222 - deviceList.value = items.map((item) => ({ label: item.name, value: item.tbDeviceId }));  
223 - setFields(skipUnwrap.triggerItemRefs, true);  
224 - setFields(skipUnwrap.conditionItemRefs, true);  
225 - setFields(skipUnwrap.actionItemRefs, true);  
226 }); 192 });
227 193
228 - // 根据上面组织变化动态改变触发器,执行条件,执行动作的设备值  
229 - function setFields(linkAge, isOrganizationChange = false) {  
230 - unref(linkAge).map((item) => {  
231 - isOrganizationChange && item.resetFieldsValueFunc();  
232 - item.updateFieldDeviceId(deviceList);  
233 - });  
234 - }  
235 -  
236 - // 添加触发器  
237 - const addTrigger = () => {  
238 - unref(triggerData).push(Date.now());  
239 - nextTick(() => {  
240 - setFields(skipUnwrap.triggerItemRefs);  
241 - });  
242 - };  
243 - // 添加执行条件  
244 - const addCondition = () => {  
245 - unref(conditionData).push(Date.now()); 194 + doActions.forEach((item, index) => {
246 nextTick(() => { 195 nextTick(() => {
247 - setFields(skipUnwrap.conditionItemRefs);  
248 - });  
249 - };  
250 - // 添加执行动作  
251 - const addAction = () => {  
252 - unref(actionData).push(Date.now());  
253 - nextTick(() => {  
254 - setFields(skipUnwrap.actionItemRefs); 196 + unref(skipUnwrap.actionItemRefs)[index].setFieldsFormValueFun({
  197 + outTarget: item.outTarget,
  198 + deviceId: item.deviceId,
  199 + });
  200 + unref(skipUnwrap.actionItemRefs)[index].setJsonValue(item.doContext.params);
255 }); 201 });
256 - }; 202 + });
  203 + }
  204 + if (unref(isUpdate) === 3) isView.value = false;
  205 + setDrawerProps({
  206 + showFooter: isView.value,
  207 + loading: false,
  208 + });
  209 + });
257 210
258 - /**  
259 - * 获取触发器、执行条件、执行动作表单值--多个  
260 - */  
261 - const getFormValueFunc = () => {  
262 - getTriggerFormValue.value = unref(skipUnwrap.triggerItemRefs)?.map((item) => {  
263 - return formatTriggerData(item.getFieldsValueFunc());  
264 - });  
265 - getConditionFormValue.value = unref(skipUnwrap.conditionItemRefs).map((item) => {  
266 - return formatConditionData(item.getFieldsValueFunc());  
267 - });  
268 - getActionFormValue.value = unref(skipUnwrap.actionItemRefs).map((item) => {  
269 - return item.getFieldsValueFunc();  
270 - });  
271 - };  
272 - const handleSubmit = async () => {  
273 - let basicFormValue = await validate();  
274 - if (!basicFormValue) return;  
275 - for (const item of unref(skipUnwrap.actionItemRefs)) {  
276 - const valid = await item.validateForm();  
277 - if (!valid) return;  
278 - }  
279 - try {  
280 - setDrawerProps({ confirmLoading: true });  
281 - getFormValueFunc();  
282 - const postAddOrEditData = {  
283 - ...basicFormValue,  
284 - triggers: unref(getTriggerFormValue),  
285 - doConditions: unref(getConditionFormValue),  
286 - doActions: unref(getActionFormValue),  
287 - ...{  
288 - id: unref(id),  
289 - tenantId: unref(tenantId),  
290 - },  
291 - };  
292 - await screenLinkPageAddApi(postAddOrEditData, unref(isUpdate));  
293 - createMessage.success(`${unref(isUpdate) ? '编辑' : '新增'}成功`);  
294 - closeDrawer();  
295 - handleClose();  
296 - emit('success');  
297 - } finally {  
298 - setDrawerProps({ confirmLoading: false });  
299 - }  
300 - }; 211 + // 设置设备的options
  212 + const setEditFields = (linkAge, deviceList) => {
  213 + unref(linkAge).map((item) => {
  214 + item.updateFieldDeviceId(deviceList);
  215 + });
  216 + };
  217 + // 监听组织变化更新设备列表
  218 + const deviceList = ref([]);
  219 + const alarmConfigList = ref([]);
  220 + watch(organizationId, async (newValue: string) => {
  221 + if (!newValue) return;
  222 + const { items } = await screenLinkPageByDeptIdGetDevice({ organizationId: newValue });
  223 + deviceList.value = items.map((item) => ({ label: item.name, value: item.tbDeviceId }));
  224 + setFields(skipUnwrap.triggerItemRefs, true);
  225 + setFields(skipUnwrap.conditionItemRefs, true);
  226 + setFields(skipUnwrap.actionItemRefs, true);
301 227
302 - // 删除  
303 - const deleteTrigger = (triggerIndex: number) => {  
304 - unref(triggerData).splice(triggerIndex, 1);  
305 - };  
306 - const deleteCondition = (conditionIndex: number) => {  
307 - unref(conditionData).splice(conditionIndex, 1);  
308 - };  
309 - const deleteAction = (actionIndex: number) => {  
310 - unref(actionData).splice(actionIndex, 1);  
311 - };  
312 - const handleClose = () => {  
313 - id.value = undefined;  
314 - tenantId.value = undefined;  
315 - organizationId.value = undefined;  
316 - isView.value = true;  
317 - getTriggerFormValue.value = [];  
318 - getConditionFormValue.value = [];  
319 - getActionFormValue.value = [];  
320 - triggerData.value = [];  
321 - conditionData.value = [];  
322 - actionData.value = [];  
323 - unref(skipUnwrap.triggerItemRefs).map((item) => {  
324 - item.resetFieldsValueFunc();  
325 - });  
326 - unref(skipUnwrap.conditionItemRefs).map((item) => {  
327 - item.resetFieldsValueFunc();  
328 - });  
329 - unref(skipUnwrap.actionItemRefs).map((item) => {  
330 - item.resetFieldsValueFunc();  
331 - });  
332 - }; 228 + const data = await getOrganizationAlarmConfig({ organizationId: newValue });
  229 + alarmConfigList.value = data.map((item) => ({ label: item.name, value: item.id }));
  230 + setAlarmConfig(skipUnwrap.actionItemRefs, true);
  231 + });
333 232
334 - return {  
335 - title,  
336 - isUpdate,  
337 - registerDrawer,  
338 - registerForm,  
339 - // 添加 or 删除 触发器,条件,动作  
340 - triggerData,  
341 - conditionData,  
342 - actionData,  
343 - addCondition,  
344 - addTrigger,  
345 - addAction,  
346 - deleteTrigger,  
347 - deleteCondition,  
348 - deleteAction,  
349 - // Refs引用  
350 - skipUnwrap,  
351 - handleSubmit,  
352 - handleClose, 233 + // 根据上面组织变化动态改变触发器,执行条件,执行动作的设备值
  234 + function setFields(linkAge, isOrganizationChange = false) {
  235 + unref(linkAge).map((item) => {
  236 + isOrganizationChange && item.resetFieldsValueFunc();
  237 + item.updateFieldDeviceId(deviceList);
  238 + });
  239 + }
353 240
354 - isView, 241 + function setAlarmConfig(linkAge, isOrganizationChange = false) {
  242 + unref(linkAge).map((item) => {
  243 + isOrganizationChange && item.resetFieldsValueFunc();
  244 + item.updateFieldAlarmConfig(alarmConfigList);
  245 + });
  246 + }
  247 + // 添加触发器
  248 + const addTrigger = () => {
  249 + unref(triggerData).push(Date.now());
  250 + nextTick(() => {
  251 + setFields(skipUnwrap.triggerItemRefs);
  252 + });
  253 + };
  254 + // 添加执行条件
  255 + const addCondition = () => {
  256 + unref(conditionData).push(Date.now());
  257 + nextTick(() => {
  258 + setFields(skipUnwrap.conditionItemRefs);
  259 + });
  260 + };
  261 + // 添加执行动作
  262 + const addAction = () => {
  263 + unref(actionData).push(Date.now());
  264 + nextTick(() => {
  265 + setFields(skipUnwrap.actionItemRefs);
  266 + });
  267 + };
  268 +
  269 + /**
  270 + * 获取触发器、执行条件、执行动作表单值--多个
  271 + */
  272 + const getFormValueFunc = () => {
  273 + getTriggerFormValue.value = unref(skipUnwrap.triggerItemRefs)?.map((item) => {
  274 + return genTriggerData(item.getFieldsValueFunc());
  275 + });
  276 + getConditionFormValue.value = unref(skipUnwrap.conditionItemRefs).map((item) => {
  277 + return genConditionData(item.getFieldsValueFunc());
  278 + });
  279 + getActionFormValue.value = unref(skipUnwrap.actionItemRefs).map((item) => {
  280 + console.log(item.jsonInstance.get());
  281 + return genActionData(item.getFieldsValueFunc());
  282 + });
  283 + console.log(getActionFormValue.value);
  284 + };
  285 + const handleSubmit = async () => {
  286 + let basicFormValue = await validate();
  287 + if (!basicFormValue) return;
  288 + for (const item of unref(skipUnwrap.actionItemRefs)) {
  289 + const valid = await item.validateForm();
  290 + if (!valid) return;
  291 + }
  292 + try {
  293 + setDrawerProps({ confirmLoading: true });
  294 + getFormValueFunc();
  295 + const postAddOrEditData = {
  296 + ...basicFormValue,
  297 + triggers: !unref(getTriggerFormValue).length ? null : unref(getTriggerFormValue),
  298 + doConditions: !unref(getConditionFormValue).length ? null : unref(getConditionFormValue),
  299 + doActions: unref(getActionFormValue).flat(),
  300 + id: unref(id),
  301 + tenantId: unref(tenantId),
355 }; 302 };
356 - },  
357 - }); 303 + console.log(postAddOrEditData);
  304 + await screenLinkPageAddApi(postAddOrEditData, unref(isUpdate));
  305 + createMessage.success(`${unref(isUpdate) ? '编辑' : '新增'}成功`);
  306 + closeDrawer();
  307 + handleClose();
  308 + emit('success');
  309 + } finally {
  310 + setDrawerProps({ confirmLoading: false });
  311 + }
  312 + };
  313 + const userStore = useUserStore();
  314 + // 删除
  315 + const deleteTrigger = (triggerIndex: number) => {
  316 + unref(triggerData).splice(triggerIndex, 1);
  317 + };
  318 + const deleteCondition = (conditionIndex: number) => {
  319 + unref(conditionData).splice(conditionIndex, 1);
  320 + };
  321 + const deleteAction = ({ actionIndex, outTarget }) => {
  322 + // console.log(actionIndex, outTarget.value);
  323 + unref(actionData).splice(actionIndex, 1);
  324 + if (unref(outTarget) === 'MSG_NOTIFY') {
  325 + userStore.setOutTarget('DEVICE_OUT');
  326 + }
  327 + };
  328 + const handleClose = () => {
  329 + id.value = undefined;
  330 + tenantId.value = undefined;
  331 + organizationId.value = undefined;
  332 + isView.value = true;
  333 + getTriggerFormValue.value = [];
  334 + getConditionFormValue.value = [];
  335 + getActionFormValue.value = [];
  336 + triggerData.value = [];
  337 + conditionData.value = [];
  338 + actionData.value = [];
  339 + unref(skipUnwrap.triggerItemRefs).map((item) => {
  340 + item.resetFieldsValueFunc();
  341 + });
  342 + unref(skipUnwrap.conditionItemRefs).map((item) => {
  343 + item.resetFieldsValueFunc();
  344 + });
  345 + unref(skipUnwrap.actionItemRefs).map((item) => {
  346 + item.resetFieldsValueFunc();
  347 + });
  348 + userStore.setOutTarget('DEVICE_OUT');
  349 + };
358 </script> 350 </script>
@@ -21,32 +21,6 @@ export enum TriggerEnum { @@ -21,32 +21,6 @@ export enum TriggerEnum {
21 IS_DEVICE_STATUS = 'DEVICE_STATUS', 21 IS_DEVICE_STATUS = 'DEVICE_STATUS',
22 IS_TIME_ALL = 'SCHEDULE_TRIGGER', 22 IS_TIME_ALL = 'SCHEDULE_TRIGGER',
23 } 23 }
24 -  
25 -export enum AttributeActionEnum {  
26 - IS_ATTRIBUTE_ACT = 'ATTRIBUTE',  
27 - IS_UP_DOWN_ACT = 'TIME_SERIES',  
28 -}  
29 -  
30 -export enum AttrAndWenDuEnum {  
31 - IS_ALL_ATTR = 'ALL_ATTR',  
32 - IS_WENDU_ACT = 'NUMERIC',  
33 - IS_SHIDU = 'NUMERIC',  
34 - IS_CONDITION_WENDU = 'NUMERIC2',  
35 - IS_CONDITION_SHIDU = 'NUMERIC1',  
36 - IS_TYPE2 = 'type2',  
37 -}  
38 -  
39 -export const isUpAndDown = (type: string) => {  
40 - return type === AttributeActionEnum.IS_UP_DOWN_ACT;  
41 -};  
42 -export const isTimeAll = (type: string) => {  
43 - return type === TriggerEnum.IS_TIME_ACT;  
44 -};  
45 -  
46 -export const isMsg = (type: string) => {  
47 - return type === TriggerEnum.IS_MSG_NOTIFY;  
48 -};  
49 -  
50 export const isDevice = (type: string) => { 24 export const isDevice = (type: string) => {
51 return type === TriggerEnum.IS_DEVICE_ACT; 25 return type === TriggerEnum.IS_DEVICE_ACT;
52 }; 26 };
@@ -55,32 +29,6 @@ export const isTime = (type: string) => { @@ -55,32 +29,6 @@ export const isTime = (type: string) => {
55 return type === TriggerEnum.IS_TIME_ACT; 29 return type === TriggerEnum.IS_TIME_ACT;
56 }; 30 };
57 31
58 -export const isScene = (type: string) => {  
59 - return type === TriggerEnum.IS_SCENE_ACT;  
60 -};  
61 -  
62 -export const isHand = (type: string) => {  
63 - return type === TriggerEnum.IS_HAND_ACT;  
64 -};  
65 -export const isType2 = (type: string) => {  
66 - return type === AttrAndWenDuEnum.IS_TYPE2;  
67 -};  
68 -  
69 -export const isConditionShiDu = (type: string) => {  
70 - return type === AttrAndWenDuEnum.IS_CONDITION_SHIDU;  
71 -};  
72 -export const isConditionWenDu = (type: string) => {  
73 - return type === AttrAndWenDuEnum.IS_CONDITION_WENDU;  
74 -};  
75 -  
76 -export const isShiDu = (type: string) => {  
77 - return type === AttrAndWenDuEnum.IS_SHIDU;  
78 -};  
79 -  
80 -export const isWenDu = (type: string) => {  
81 - return type === AttrAndWenDuEnum.IS_WENDU_ACT;  
82 -};  
83 -  
84 export const columns: BasicColumn[] = [ 32 export const columns: BasicColumn[] = [
85 { 33 {
86 title: '场景联动名称', 34 title: '场景联动名称',
@@ -232,107 +180,87 @@ export const searchFormSchema: FormSchema[] = [ @@ -232,107 +180,87 @@ export const searchFormSchema: FormSchema[] = [
232 colProps: { span: 6 }, 180 colProps: { span: 6 },
233 }, 181 },
234 ]; 182 ];
  183 +// 持续时间
  184 +const isTimeDuration = (type) => {
  185 + return type === 'timeDuration';
  186 +};
  187 +const isReplace = (type) => {
  188 + return type === 'replace';
  189 +};
  190 +// 部分
  191 +const isPart = (type: string) => {
  192 + return type === 'PART';
  193 +};
235 194
236 -export const useTriggerDrawerSchema: FormSchema[] = [ 195 +export const trigger_condition_schema: FormSchema[] = [
237 { 196 {
238 - field: 'triggerType', 197 + field: 'triggered',
239 label: '', 198 label: '',
240 component: 'Select', 199 component: 'Select',
241 componentProps: { 200 componentProps: {
242 - placeholder: '设备触发', 201 + placeholder: '请选择触发类型',
243 options: [ 202 options: [
244 - { label: '设备触发', value: 'DEVICE_TRIGGER' },  
245 - // { label: '定时触发', value: 'SCHEDULE_TRIGGER' },  
246 - // { label: '场景触发', value: 'SCENE_TRIGGER' },  
247 - // { label: '手动触发', value: 'HAND_ACT' }, 203 + { label: '简单', value: 'SIMPLE' },
  204 + { label: '持续时长', value: 'timeDuration' },
  205 + { label: '重复次数', value: 'replace' },
248 ], 206 ],
249 }, 207 },
250 - colProps: { span: 8 }, 208 + colProps: { span: 6 },
251 }, 209 },
252 { 210 {
253 - field: 'entityId', 211 + field: 'device',
254 label: '', 212 label: '',
255 component: 'Select', 213 component: 'Select',
256 componentProps: { 214 componentProps: {
257 placeholder: '请选择设备', 215 placeholder: '请选择设备',
  216 + options: [
  217 + { label: '全部', value: 'ALL' },
  218 + { label: '部分', value: 'PART' },
  219 + ],
258 }, 220 },
259 - ifShow: ({ values }) => isDevice(values.triggerType),  
260 - colProps: {  
261 - span: 8,  
262 - }, 221 + colProps: { span: 6 },
263 }, 222 },
264 { 223 {
265 - field: 'type1', 224 + field: 'entityId',
266 label: '', 225 label: '',
267 component: 'Select', 226 component: 'Select',
268 componentProps: { 227 componentProps: {
269 - placeholder: '属性触发方式',  
270 - options: [{ label: '属性触发', value: 'TIME_SERIES' }],  
271 - },  
272 - ifShow: ({ values }) => isDevice(values.triggerType),  
273 - dynamicDisabled: ({ values }) => !values.entityId,  
274 - colProps: { span: 8 },  
275 - },  
276 - {  
277 - field: 'type2',  
278 - label: '',  
279 - component: 'AutoComplete',  
280 - componentProps: {  
281 - placeholder: '请选择属性', 228 + placeholder: '请选择设备',
  229 + mode: 'multiple',
282 }, 230 },
283 - ifShow: ({ values }) => isDevice(values.triggerType),  
284 - dynamicDisabled: ({ values }) => !values.type1,  
285 - colProps: { span: 8 }, 231 + ifShow: ({ values }) => isPart(values.device),
  232 + colProps: { span: 6 },
286 }, 233 },
287 { 234 {
288 - field: 'operation', 235 + field: 'time',
289 label: '', 236 label: '',
290 - component: 'Select', 237 + component: 'Input',
291 componentProps: { 238 componentProps: {
292 - placeholder: '请选择比较模式',  
293 - options: [  
294 - { label: '=', value: 'EQUAL' },  
295 - { label: '<', value: 'LESS' },  
296 - { label: '>', value: 'GREATER' },  
297 - { label: '<=', value: 'LESS_OR_EQUAL' },  
298 - { label: '>=', value: 'GREATER_OR_EQUAL' },  
299 - ], 239 + placeholder: '请输入持续时间',
300 }, 240 },
301 - show: ({ values }) => isDevice(values.triggerType),  
302 - dynamicDisabled: ({ values }) => !values.type2,  
303 - colProps: { span: 8 }, 241 + ifShow: ({ values }) => isTimeDuration(values.triggered),
  242 + colProps: { span: 6 },
304 }, 243 },
305 { 244 {
306 - field: 'value', 245 + field: 'timeUnit',
307 label: '', 246 label: '',
308 component: 'Input', 247 component: 'Input',
309 componentProps: { 248 componentProps: {
310 - maxLength: 16,  
311 - placeholder: '请输入比较值',  
312 - },  
313 - show: ({ values }) => isDevice(values.triggerType),  
314 - dynamicDisabled: ({ values }) => !values.operation,  
315 - colProps: {  
316 - span: 8, 249 + placeholder: '请输入持续时间单位',
317 }, 250 },
  251 + ifShow: ({ values }) => isTimeDuration(values.triggered),
  252 + colProps: { span: 6 },
318 }, 253 },
319 { 254 {
320 - field: 'entityId1', 255 + field: 'replaceValue',
321 label: '', 256 label: '',
322 component: 'Input', 257 component: 'Input',
323 componentProps: { 258 componentProps: {
324 - maxLength: 255,  
325 - placeholder: '请输入Cron表达式', 259 + placeholder: '事件计数值',
326 }, 260 },
327 - colProps: {  
328 - span: 12,  
329 - },  
330 - ifShow: ({ values }) => values.triggerType === TriggerEnum.IS_TIME_ACT, 261 + ifShow: ({ values }) => isReplace(values.triggered),
  262 + colProps: { span: 6 },
331 }, 263 },
332 -];  
333 -// !!!----------------------------------------------------^_^------------------------------------------------------------!!!  
334 -  
335 -export const useConditionDrawerSchema: FormSchema[] = [  
336 { 264 {
337 field: 'triggerType', 265 field: 'triggerType',
338 label: '', 266 label: '',
@@ -341,191 +269,367 @@ export const useConditionDrawerSchema: FormSchema[] = [ @@ -341,191 +269,367 @@ export const useConditionDrawerSchema: FormSchema[] = [
341 placeholder: '设备触发', 269 placeholder: '设备触发',
342 options: [ 270 options: [
343 { label: '设备触发', value: 'DEVICE_TRIGGER' }, 271 { label: '设备触发', value: 'DEVICE_TRIGGER' },
344 - // { label: '时间范围', value: 'SCHEDULE_TRIGGER' }, 272 + // { label: '定时触发', value: 'SCHEDULE_TRIGGER' },
  273 + // { label: '场景触发', value: 'SCENE_TRIGGER' },
  274 + // { label: '手动触发', value: 'HAND_ACT' },
345 ], 275 ],
346 }, 276 },
347 - colProps: { span: 8 }, 277 + colProps: { span: 6 },
348 }, 278 },
  279 +
349 { 280 {
350 - field: 'entityId', 281 + field: 'type1',
351 label: '', 282 label: '',
352 component: 'Select', 283 component: 'Select',
353 - componentProps() {  
354 - return {  
355 - placeholder: '请选择设备',  
356 - }; 284 + componentProps: {
  285 + placeholder: '属性触发方式',
  286 + options: [{ label: '属性触发', value: 'TIME_SERIES' }],
357 }, 287 },
358 ifShow: ({ values }) => isDevice(values.triggerType), 288 ifShow: ({ values }) => isDevice(values.triggerType),
359 - colProps: {  
360 - span: 8,  
361 - }, 289 + colProps: { span: 6 },
362 }, 290 },
363 { 291 {
364 - field: 'type', 292 + field: 'type2',
365 label: '', 293 label: '',
366 component: 'AutoComplete', 294 component: 'AutoComplete',
367 componentProps: { 295 componentProps: {
368 placeholder: '请选择属性', 296 placeholder: '请选择属性',
369 }, 297 },
370 ifShow: ({ values }) => isDevice(values.triggerType), 298 ifShow: ({ values }) => isDevice(values.triggerType),
371 - dynamicDisabled: ({ values }) => !values.entityId,  
372 - colProps: { span: 8 }, 299 + colProps: { span: 6 },
373 }, 300 },
374 { 301 {
375 - field: 'operation', 302 + field: 'operationType',
376 label: '', 303 label: '',
377 component: 'Select', 304 component: 'Select',
378 - componentProps: {  
379 - placeholder: '请选择比较模式',  
380 - options: [  
381 - { label: '=', value: 'EQUAL' },  
382 - { label: '<', value: 'LESS' },  
383 - { label: '>', value: 'GREATER' },  
384 - { label: '<=', value: 'LESS_OR_EQUAL' },  
385 - { label: '>=', value: 'GREATER_OR_EQUAL' },  
386 - ],  
387 - },  
388 - show: ({ values }) => isDevice(values.triggerType),  
389 - dynamicDisabled: ({ values }) => !values.type,  
390 - colProps: { span: 8 }, 305 + slot: 'operationType',
  306 + colProps: { span: 6 },
391 }, 307 },
392 { 308 {
393 - field: 'value', 309 + field: 'detail',
394 label: '', 310 label: '',
395 - component: 'Input', 311 + component: 'InputTextArea',
396 componentProps: { 312 componentProps: {
397 - maxLength: 16,  
398 - placeholder: '请输入比较值', 313 + placeholder: '请输入详情',
399 }, 314 },
400 - show: ({ values }) => isDevice(values.triggerType),  
401 - dynamicDisabled: ({ values }) => !values.operation,  
402 colProps: { 315 colProps: {
403 - span: 8, 316 + span: 13,
404 }, 317 },
405 }, 318 },
406 - // {  
407 - // field: 'createTime',  
408 - // component: 'DatePicker',  
409 - // label: 'createTime',  
410 - // componentProps: {  
411 - // placeholder: '请选择起始时间',  
412 - // },  
413 - // colProps: {  
414 - // span: 12,  
415 - // },  
416 - // ifShow: ({ values }) => isTimeAll(values.triggerType),  
417 - // },  
418 - // {  
419 - // field: 'updateTime',  
420 - // component: 'DatePicker',  
421 - // label: 'updateTime',  
422 - // componentProps: {  
423 - // placeholder: '请选择结束时间',  
424 - // },  
425 - // colProps: {  
426 - // span: 12,  
427 - // },  
428 - // ifShow: ({ values }) => isTimeAll(values.triggerType),  
429 - // },  
430 ]; 319 ];
  320 +// !!!----------------------------------------------------^_^------------------------------------------------------------!!!
431 enum ActionEnum { 321 enum ActionEnum {
432 DEVICE_OUT = 'DEVICE_OUT', 322 DEVICE_OUT = 'DEVICE_OUT',
  323 + ALARM_OUT = 'MSG_NOTIFY',
433 } 324 }
434 const isDeviceOut = (type: string) => type === ActionEnum.DEVICE_OUT; 325 const isDeviceOut = (type: string) => type === ActionEnum.DEVICE_OUT;
435 -export const useActionDrawerSchema: FormSchema[] = [ 326 +const isAlarmOut = (type: string) => type === ActionEnum.ALARM_OUT;
  327 +
  328 +export const actionSchema: FormSchema[] = [
436 { 329 {
437 field: 'outTarget', 330 field: 'outTarget',
438 label: '', 331 label: '',
439 component: 'Select', 332 component: 'Select',
440 required: true, 333 required: true,
441 componentProps: { 334 componentProps: {
442 - placeholder: '设备输出', 335 + placeholder: '请选择执行动作',
  336 + },
  337 + slot: 'outTarget',
  338 + colProps: { span: 6 },
  339 + },
  340 + {
  341 + field: 'device',
  342 + label: '',
  343 + component: 'Select',
  344 + componentProps: {
  345 + placeholder: '请选择设备',
443 options: [ 346 options: [
444 - { label: '设备输出', value: 'DEVICE_OUT' },  
445 - // { label: '消息通知', value: 'MSG_NOTIFY' },  
446 - // { label: '场景联动', value: 'SCENE_TRIGGER' }, 347 + { label: '全部', value: 'ALL' },
  348 + { label: '部分', value: 'PART' },
447 ], 349 ],
448 }, 350 },
449 - colProps: { span: 12 }, 351 + ifShow: ({ values }) => isDeviceOut(values.outTarget),
  352 + colProps: { span: 6 },
450 }, 353 },
451 { 354 {
452 field: 'deviceId', 355 field: 'deviceId',
453 label: '', 356 label: '',
454 - required: true,  
455 component: 'Select', 357 component: 'Select',
456 componentProps: { 358 componentProps: {
457 placeholder: '请选择设备', 359 placeholder: '请选择设备',
  360 + mode: 'multiple',
458 }, 361 },
459 - ifShow: ({ values }) => isDeviceOut(values.outTarget),  
460 - colProps: {  
461 - span: 12,  
462 - }, 362 + ifShow: ({ values }) => isPart(values.device),
  363 + colProps: { span: 6 },
463 }, 364 },
464 { 365 {
465 - field: 'doContext',  
466 - component: 'InputTextArea', 366 + field: 'alarm_config',
467 label: '', 367 label: '',
  368 + component: 'Select',
468 componentProps: { 369 componentProps: {
469 - maxLength: 255, 370 + placeholder: '请选择告警配置',
470 }, 371 },
  372 + ifShow: ({ values }) => values.outTarget === 'MSG_NOTIFY',
  373 + colProps: { span: 6 },
  374 + },
  375 + {
  376 + field: 'doContext',
  377 + component: 'Input',
  378 + label: '',
471 slot: 'doContext', 379 slot: 'doContext',
472 show: ({ values }) => isDeviceOut(values.outTarget), 380 show: ({ values }) => isDeviceOut(values.outTarget),
473 colProps: { 381 colProps: {
474 span: 24, 382 span: 24,
475 }, 383 },
476 }, 384 },
477 - // {  
478 - // field: 'wu2',  
479 - // component: 'Input',  
480 - // label: '',  
481 - // componentProps: {  
482 - // placeholder: '暂不实现',  
483 - // },  
484 - // colProps: {  
485 - // span: 12,  
486 - // },  
487 - // ifShow: ({ values }) => isMsg(Reflect.get(values, 'outTarget')),  
488 - // },  
489 - // {  
490 - // field: 'wu3',  
491 - // label: '',  
492 - // component: 'Input',  
493 - // componentProps: {  
494 - // placeholder: '无',  
495 - // style: {  
496 - // visibility: 'hidden',  
497 - // },  
498 - // },  
499 - // colProps: { span: 12 },  
500 - // ifShow: ({ values }) => isMsg(Reflect.get(values, 'outTarget')),  
501 - // },  
502 - // {  
503 - // field: 'entityId',  
504 - // label: '',  
505 - // component: 'Select',  
506 - // colProps: {  
507 - // span: 12,  
508 - // },  
509 - // componentProps: {  
510 - // placeholder: '请选择场景',  
511 - // options: [  
512 - // { label: '场景触发器1', value: '1' },  
513 - // { label: '场景触发器2', value: '2' },  
514 - // ],  
515 - // },  
516 - // ifShow: ({ values }) => isScene(Reflect.get(values, 'outTarget')),  
517 - // },  
518 - // {  
519 - // field: 'wu4',  
520 - // label: '',  
521 - // component: 'Input',  
522 - // componentProps: {  
523 - // placeholder: '无',  
524 - // style: {  
525 - // visibility: 'hidden',  
526 - // },  
527 - // },  
528 - // colProps: { span: 12 },  
529 - // ifShow: ({ values }) => isScene(Reflect.get(values, 'outTarget')),  
530 - // }, 385 + {
  386 + field: 'alarm_level',
  387 + component: 'Select',
  388 + label: '',
  389 + show: ({ values }) => isAlarmOut(values.outTarget),
  390 + componentProps: {
  391 + placeholder: '请选择告警等级',
  392 + options: [
  393 + {
  394 + label: '紧急',
  395 + value: ' CRITICAL',
  396 + },
  397 + {
  398 + label: '重要',
  399 + value: 'MAJOR',
  400 + },
  401 + {
  402 + label: '次要',
  403 + value: 'MINOR',
  404 + },
  405 + {
  406 + label: '警告',
  407 + value: 'WARNING',
  408 + },
  409 + {
  410 + label: '不确定',
  411 + value: 'INDETERMINATE',
  412 + },
  413 + ],
  414 + },
  415 + colProps: {
  416 + span: 6,
  417 + },
  418 + },
  419 + {
  420 + field: 'clear_alarm',
  421 + component: 'Checkbox',
  422 + label: '',
  423 + show: ({ values }) => isAlarmOut(values.outTarget),
  424 + colProps: {
  425 + span: 8,
  426 + },
  427 + slot: 'clearAlarm',
  428 + },
531 ]; 429 ];
  430 +import { Number_Operation, String_Operation, Boolean_Operation } from '/@/enums/operationEnum';
  431 +export function isType(operationType) {
  432 + switch (operationType) {
  433 + case 'NUMERIC':
  434 + return [
  435 + {
  436 + field: 'operation',
  437 + label: '执行操作',
  438 + component: 'Select',
  439 + required: true,
  440 + componentProps: {
  441 + options: [
  442 + { label: '等于', value: Number_Operation.EQUAL },
  443 + { label: '不等于', value: Number_Operation.NOT_EQUAL },
  444 + { label: '小于', value: Number_Operation.LESS },
  445 + { label: '小于等于', value: Number_Operation.LESS_OR_EQUAL },
  446 + { label: '大于', value: Number_Operation.GREATER },
  447 + { label: '大于等于', value: Number_Operation.GREATER_OR_EQUAL },
  448 + ],
  449 + },
  450 + colProps: {
  451 + span: 8,
  452 + },
  453 + },
  454 + {
  455 + field: 'value',
  456 + label: '操作值',
  457 + required: true,
  458 + component: 'InputNumber',
  459 + colProps: {
  460 + span: 8,
  461 + },
  462 + },
  463 + ];
  464 + case 'STRING':
  465 + return [
  466 + {
  467 + field: 'ignoreCase',
  468 + label: '忽略大小写',
  469 + component: 'Checkbox',
  470 + labelWidth: 150,
  471 + colProps: {
  472 + span: 7,
  473 + },
  474 + },
  475 + {
  476 + field: 'operation',
  477 + label: '执行操作',
  478 + component: 'Select',
  479 + required: true,
  480 + componentProps: {
  481 + options: [
  482 + { label: '等于', value: String_Operation.EQUAL },
  483 + { label: '不等于', value: String_Operation.NOT_EQUAL },
  484 + { label: '开始于', value: String_Operation.BEGAN_IN },
  485 + { label: '结束于', value: String_Operation.END_IN },
  486 + { label: '包含', value: String_Operation.INCLUDE },
  487 + { label: '不包含', value: String_Operation.NOT_INCLUDE },
  488 + ],
  489 + },
  490 + colProps: {
  491 + span: 7,
  492 + },
  493 + },
  494 + {
  495 + field: 'value',
  496 + label: '操作值',
  497 + required: true,
  498 + component: 'Input',
  499 + colProps: {
  500 + span: 7,
  501 + },
  502 + },
  503 + ];
  504 + case 'BOOLEAN':
  505 + return [
  506 + {
  507 + field: 'operation',
  508 + label: '执行操作',
  509 + component: 'Select',
  510 + required: true,
  511 + componentProps: {
  512 + options: [
  513 + { label: '等于', value: Boolean_Operation.EQUAL },
  514 + { label: '不等于', value: Boolean_Operation.NOT_EQUAL },
  515 + ],
  516 + },
  517 + colProps: {
  518 + span: 8,
  519 + },
  520 + },
  521 + {
  522 + field: 'value',
  523 + label: '操作值',
  524 + component: 'Select',
  525 + required: true,
  526 + componentProps: {
  527 + options: [
  528 + {
  529 + label: '真',
  530 + value: 'true',
  531 + },
  532 + {
  533 + label: '假',
  534 + value: 'false',
  535 + },
  536 + ],
  537 + },
  538 + colProps: {
  539 + span: 8,
  540 + },
  541 + },
  542 + ];
  543 + case 'TIME':
  544 + return [
  545 + {
  546 + field: 'operation',
  547 + label: '执行操作',
  548 + required: true,
  549 + component: 'Select',
  550 + componentProps: {
  551 + options: [
  552 + { label: '等于', value: Number_Operation.EQUAL },
  553 + { label: '不等于', value: Number_Operation.NOT_EQUAL },
  554 + { label: '小于', value: Number_Operation.LESS },
  555 + { label: '小于等于', value: Number_Operation.LESS_OR_EQUAL },
  556 + { label: '大于', value: Number_Operation.GREATER },
  557 + { label: '大于等于', value: Number_Operation.GREATER_OR_EQUAL },
  558 + ],
  559 + },
  560 + colProps: {
  561 + span: 8,
  562 + },
  563 + },
  564 + {
  565 + field: 'value',
  566 + label: '操作值',
  567 + required: true,
  568 + component: 'DatePicker',
  569 + componentProps: {
  570 + showTime: true,
  571 + },
  572 + colProps: {
  573 + span: 8,
  574 + },
  575 + },
  576 + ];
  577 + }
  578 +}
  579 +export function conditionPreView(data, operationType) {
  580 + if (operationType === 'NUMERIC' || operationType === 'TIME') {
  581 + const { EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL } = Number_Operation;
  582 + return data.map((item) => {
  583 + return {
  584 + operation:
  585 + item?.operation === EQUAL
  586 + ? '等于'
  587 + : item?.operation === NOT_EQUAL
  588 + ? '不等于'
  589 + : item?.operation === LESS
  590 + ? '小于'
  591 + : item?.operation === LESS_OR_EQUAL
  592 + ? '小于等于'
  593 + : item?.operation === GREATER
  594 + ? '大于'
  595 + : item?.operation === GREATER_OR_EQUAL
  596 + ? '大于等于'
  597 + : '',
  598 + value: item.value,
  599 + attribute: item.attribute,
  600 + };
  601 + });
  602 + } else if (operationType === 'STRING') {
  603 + const { EQUAL, NOT_EQUAL, BEGAN_IN, END_IN, INCLUDE, NOT_INCLUDE } = String_Operation;
  604 + return data.map((item) => {
  605 + return {
  606 + operation:
  607 + item?.operation === EQUAL
  608 + ? '等于'
  609 + : item?.operation === NOT_EQUAL
  610 + ? '不等于'
  611 + : item?.operation === BEGAN_IN
  612 + ? '开始于'
  613 + : item?.operation === END_IN
  614 + ? '结束于'
  615 + : item?.operation === INCLUDE
  616 + ? '包含'
  617 + : item?.operation === NOT_INCLUDE
  618 + ? '不包含'
  619 + : '',
  620 + value: item.value,
  621 + attribute: item.attribute,
  622 + };
  623 + });
  624 + } else if (operationType === 'BOOLEAN') {
  625 + const { EQUAL, NOT_EQUAL } = Boolean_Operation;
  626 + return data.map((item) => {
  627 + return {
  628 + operation:
  629 + item?.operation === EQUAL ? '等于' : item?.operation === NOT_EQUAL ? '不等于' : '',
  630 + value: item.value,
  631 + attribute: item.attribute,
  632 + };
  633 + });
  634 + }
  635 +}
  1 +<template>
  2 + <div>
  3 + <CollapseContainer style="background-color: #f2f2f2" title="清除告警" :canExpan="false">
  4 + <template #action>
  5 + <div>
  6 + <span class="mr-2">启用规则</span>
  7 + <RadioGroup v-model:value="schedule" :options="scheduleOptions" />
  8 + </div>
  9 + </template>
  10 + <BasicForm @register="registerForm">
  11 + <template #operationType="{ model, field }">
  12 + <Select
  13 + :options="options"
  14 + v-model:value="model[field]"
  15 + @change="operationType = model[field]"
  16 + placeholder="请选择比较类型"
  17 + allowClear
  18 + />
  19 + </template>
  20 + </BasicForm>
  21 + <Card size="small" :bordered="false" style="border: 2px dashed #797979" v-if="operationType">
  22 + <ConditionScreening
  23 + :childGetFieldsValue="childGetFieldsValue"
  24 + ref="conditionScreeningRef"
  25 + />
  26 + </Card>
  27 + </CollapseContainer>
  28 + </div>
  29 +</template>
  30 +<script lang="ts" setup>
  31 + import { ref, provide } from 'vue';
  32 + import { CollapseContainer } from '/@/components/Container/index';
  33 + import { BasicForm, useForm } from '/@/components/Form/index';
  34 + import { Radio, Card, Select } from 'ant-design-vue';
  35 + import { trigger_condition_schema } from '../config';
  36 + import { getAttribute } from '/@/api/ruleengine/ruleengineApi';
  37 + import ConditionScreening from './ConditionScreening.vue';
  38 +
  39 + const RadioGroup = Radio.Group;
  40 +
  41 + const [registerForm, { resetFields, getFieldsValue, updateSchema, setFieldsValue }] = useForm({
  42 + schemas: trigger_condition_schema,
  43 + showActionButtonGroup: false,
  44 + });
  45 +
  46 + const updateFieldDeviceId = (deviceList: any[]) => {
  47 + updateSchema({
  48 + field: 'entityId',
  49 + componentProps: {
  50 + options: deviceList,
  51 + onChange(e) {
  52 + if (e) {
  53 + updateFieldAttributeFunc();
  54 + }
  55 + },
  56 + },
  57 + });
  58 + };
  59 + const conditionScreeningRef = ref();
  60 + const resetFieldsValueFunc = () => resetFields();
  61 + // 回显数据函数
  62 + const setFieldsFormValueFun = (fieldsValue) => {
  63 + setFieldsValue(fieldsValue);
  64 + };
  65 + const updateFieldAttributeFunc = async () => {
  66 + const data = await getAttribute();
  67 + const options = data.map((m) => {
  68 + return {
  69 + label: m,
  70 + value: m,
  71 + };
  72 + });
  73 + updateSchema({
  74 + field: 'type2',
  75 + componentProps: {
  76 + placeholder: '请选择属性',
  77 + options,
  78 + },
  79 + });
  80 + };
  81 + const schedule = ref('ANY_TIME');
  82 + const scheduleOptions = [
  83 + { label: '始终启用', value: 'ANY_TIME' },
  84 + { label: '定时启用', value: 'SPECIFIC_TIME' },
  85 + { label: '自定义启用', value: 'SPECIFIC_TIME' },
  86 + ];
  87 + const operationType = ref<string>('');
  88 + const options = [
  89 + {
  90 + label: '数字',
  91 + value: 'NUMERIC',
  92 + },
  93 + {
  94 + label: '布尔值',
  95 + value: 'BOOLEAN',
  96 + },
  97 + {
  98 + label: '字符串',
  99 + value: 'STRING',
  100 + },
  101 + {
  102 + label: '时间',
  103 + value: 'TIME',
  104 + },
  105 + ];
  106 + const childGetFieldsValue = () => getFieldsValue();
  107 + provide('operationType', operationType);
  108 +
  109 + defineExpose({
  110 + getFieldsValue,
  111 + updateFieldDeviceId,
  112 + resetFieldsValueFunc,
  113 + setFieldsFormValueFun,
  114 + childGetFieldsValue,
  115 + conditionScreeningRef,
  116 + schedule,
  117 + });
  118 +</script>
  1 +<template>
  2 + <div>
  3 + <CollapseContainer ref="collapseContainerRef" @expand="handleExpand">
  4 + <template #title>
  5 + <div>条件筛选</div>
  6 + <RichText
  7 + :firstAttribute="firstAttribute"
  8 + :otherAttribute="otherAttribute"
  9 + @resetFilter="resetFilter"
  10 + /></template>
  11 +
  12 + <template v-for="(item, index) in conditionScreeningList" :key="item">
  13 + <ConditionScreeningForm
  14 + :conditionScreeningList="conditionScreeningList"
  15 + :ref="refItem.conditionScreeningRefs"
  16 + :index="index"
  17 + @deleteConditionForm="deleteConditionForm"
  18 + />
  19 + </template>
  20 + </CollapseContainer>
  21 +
  22 + <div class="flex justify-between">
  23 + <a-button type="primary" class="mt-4 ml-2" @click="addConditionForm">新增条件筛选</a-button>
  24 + <a-button type="primary" class="mt-4 mr-2" @click="preView" v-if="isPreview">保存</a-button>
  25 + </div>
  26 + </div>
  27 +</template>
  28 +
  29 +<script lang="ts" setup>
  30 + import { unref, ref } from 'vue';
  31 + import ConditionScreeningForm from './ConditionScreeningForm.vue';
  32 + import { conditionPreView } from '../config.ts';
  33 + import { CollapseContainer } from '/@/components/Container/index';
  34 + import RichText from './RichText.vue';
  35 + const props = defineProps({
  36 + childGetFieldsValue: {
  37 + type: Function,
  38 + required: true,
  39 + },
  40 + });
  41 + const refItem = {
  42 + conditionScreeningRefs: ref([]),
  43 + };
  44 +
  45 + const isPreview = ref(true);
  46 + const collapseContainerRef = ref();
  47 + const conditionScreeningList = ref([Date.now()]);
  48 + const addConditionForm = () => {
  49 + if (!unref(isPreview)) {
  50 + collapseContainerRef.value.handleExpand();
  51 + }
  52 + unref(conditionScreeningList).push(Date.now());
  53 + };
  54 + const handleExpand = (show) => {
  55 + isPreview.value = show;
  56 + };
  57 +
  58 + const firstAttribute = ref({});
  59 + const otherAttribute = ref([]);
  60 + // 预览条件筛选结果
  61 + const preView = async () => {
  62 + const attributes = [];
  63 + const fieldsValue = props.childGetFieldsValue();
  64 + for (let i = 0; i < unref(refItem.conditionScreeningRefs).length; i++) {
  65 + if (i === 0) {
  66 + const attr = conditionPreView(
  67 + [
  68 + {
  69 + ...unref(refItem.conditionScreeningRefs)[i].getFieldsValue(),
  70 + attribute: fieldsValue.type2,
  71 + },
  72 + ],
  73 + fieldsValue.operationType
  74 + );
  75 + firstAttribute.value = attr[0];
  76 + await unref(refItem.conditionScreeningRefs)[i].validate();
  77 + continue;
  78 + }
  79 + const valid = await unref(refItem.conditionScreeningRefs)[i].validate();
  80 + if (!valid) return;
  81 +
  82 + attributes.push({
  83 + ...unref(refItem.conditionScreeningRefs)[i].getFieldsValue(),
  84 + attribute: fieldsValue.type2,
  85 + });
  86 + }
  87 + otherAttribute.value = conditionPreView(attributes, fieldsValue.operationType);
  88 +
  89 + collapseContainerRef.value.handleExpand();
  90 + };
  91 +
  92 + const resetFilter = () => {
  93 + firstAttribute.value = {};
  94 + otherAttribute.value = [];
  95 + };
  96 + const deleteConditionForm = (index) => {
  97 + unref(conditionScreeningList).splice(index, 1);
  98 + };
  99 + defineExpose({
  100 + refItem,
  101 + });
  102 +</script>
  1 +<template>
  2 + <div class="flex" style="align-items: center">
  3 + <BasicForm @register="registerFormCondition" class="basicStyle" />
  4 + <Tooltip title="移除" class="ml-4">
  5 + <Icon
  6 + icon="fluent:delete-off-20-regular"
  7 + size="20"
  8 + class="mr-2 cursor-pointer"
  9 + @click="deleteConditionForm(index)"
  10 + />
  11 + </Tooltip>
  12 + </div>
  13 +</template>
  14 +
  15 +<script lang="ts" setup>
  16 + import { watch, ref, onMounted, inject } from 'vue';
  17 + import { BasicForm, useForm } from '/@/components/Form/index';
  18 + import { Icon } from '/@/components/Icon';
  19 + import { Tooltip } from 'ant-design-vue';
  20 + import { isType } from '../config.ts';
  21 + defineProps({
  22 + index: {
  23 + type: Number,
  24 + required: true,
  25 + },
  26 + conditionScreeningList: {
  27 + type: Array,
  28 + default: () => [],
  29 + },
  30 + });
  31 + const emit = defineEmits(['deleteConditionForm']);
  32 + const operationType = inject('operationType');
  33 + let schemas = ref([]);
  34 + onMounted(() => {
  35 + schemas.value = isType(operationType.value);
  36 + });
  37 + watch(operationType, (newValue) => {
  38 + schemas.value = isType(newValue);
  39 + resetFields();
  40 + });
  41 + const [
  42 + registerFormCondition,
  43 + {
  44 + resetFields,
  45 + appendSchemaByField,
  46 + removeSchemaByFiled,
  47 + getFieldsValue,
  48 + setFieldsValue,
  49 + validate,
  50 + },
  51 + ] = useForm({
  52 + showActionButtonGroup: false,
  53 + labelWidth: 100,
  54 + compact: true,
  55 + schemas,
  56 + });
  57 + const deleteConditionForm = (index: number) => {
  58 + emit('deleteConditionForm', index);
  59 + };
  60 + defineExpose({
  61 + appendSchemaByField,
  62 + removeSchemaByFiled,
  63 + getFieldsValue,
  64 + setFieldsValue,
  65 + validate,
  66 + });
  67 +</script>
  68 +
  69 +<style lang="less">
  70 + .basicStyle {
  71 + margin-top: 0.5rem;
  72 + width: 80%;
  73 + border: 2px dashed #797979;
  74 + padding: 1rem 0 0.5rem;
  75 + border-radius: 0.25rem;
  76 + }
  77 + .ant-input-number {
  78 + width: 200px;
  79 + }
  80 +</style>
  1 +<template>
  2 + <div class="flex ml-4" v-if="firstAttribute?.value && firstAttribute?.attribute">
  3 + <div class="text" style="color: #305680">{{ firstAttribute?.attribute }}</div>
  4 + {{ firstAttribute?.operation }}
  5 + <div class="text" style="color: #ff8c68">{{ firstAttribute?.value }}</div>
  6 + {{ firstAttribute?.compoundConditions ?? '' }}
  7 + </div>
  8 + <div
  9 + v-if="otherAttribute.length > 0 && otherAttribute[0].value && otherAttribute[0].operation"
  10 + class="flex"
  11 + >
  12 + <template v-for="item in otherAttribute" :key="item.value">
  13 + <div class="flex" v-if="item?.value && item?.attribute">
  14 + <div class="text mr-2" style="color: #305680">{{ item.attribute }}</div>
  15 + {{ item.operation }}
  16 + <div class="text ml-2" style="color: #ff8c68">{{ item.value }}</div>
  17 + {{ item.compoundConditions ?? '' }}
  18 + </div>
  19 + </template>
  20 + </div>
  21 +</template>
  22 +
  23 +<script lang="ts" setup>
  24 + import { watch, inject } from 'vue';
  25 + defineProps({
  26 + firstAttribute: {
  27 + type: Object,
  28 + default: () => {},
  29 + },
  30 + otherAttribute: {
  31 + type: Array,
  32 + default: () => [],
  33 + },
  34 + });
  35 + const emit = defineEmits(['resetFilter']);
  36 + const operationType = inject('operationType');
  37 + watch(operationType, () => {
  38 + emit('resetFilter');
  39 + });
  40 +</script>
  41 +
  42 +<style scoped>
  43 + .text {
  44 + border: 1px solid #d2d2d2;
  45 + border-radius: 5px;
  46 + padding: 0 5px;
  47 + margin: 0 5px;
  48 + }
  49 + .parentheses {
  50 + font-size: 16px;
  51 + }
  52 +</style>
1 <template> 1 <template>
2 - <CollapseContainer style="background-color: #f8f9fa" :title="`执行动作 ${actionIndex + 1}`"> 2 + <CollapseContainer style="background-color: #f2f2f2" :title="`执行动作 ${actionIndex + 1}`">
3 <template #action> 3 <template #action>
4 <Tooltip title="移除" v-if="actionData.length > 1"> 4 <Tooltip title="移除" v-if="actionData.length > 1">
5 <Icon 5 <Icon
@@ -11,6 +11,15 @@ @@ -11,6 +11,15 @@
11 </Tooltip> 11 </Tooltip>
12 </template> 12 </template>
13 <BasicForm @register="registerAction"> 13 <BasicForm @register="registerAction">
  14 + <template #outTarget="{ model, field }">
  15 + <Select
  16 + :options="options"
  17 + v-model:value="model[field]"
  18 + @change="changeOutTarget"
  19 + placeholder="请选择执行动作"
  20 + allowClear
  21 + :disabled="hasDisabled"
  22 + /></template>
14 <template #doContext> 23 <template #doContext>
15 <div class="flex"> 24 <div class="flex">
16 <div ref="jsoneditorRef" style="height: 100%; width: 100%"></div> 25 <div ref="jsoneditorRef" style="height: 100%; width: 100%"></div>
@@ -18,109 +27,159 @@ @@ -18,109 +27,159 @@
18 title='{"method":"setDOValue","params":{"devID":"492S211218028819","data":{"DO1":1}}}' 27 title='{"method":"setDOValue","params":{"devID":"492S211218028819","data":{"DO1":1}}}'
19 class="ml-2" 28 class="ml-2"
20 > 29 >
21 - <QuestionCircleOutlined style="font-size: 1rem"  
22 - /></Tooltip> 30 + <QuestionCircleOutlined style="font-size: 1rem" />
  31 + </Tooltip>
23 </div> 32 </div>
24 </template> 33 </template>
  34 + <template #clearAlarm>
  35 + <Checkbox v-model:checked="checked"> 清除告警 </Checkbox>
  36 + </template>
25 </BasicForm> 37 </BasicForm>
  38 + <Card
  39 + v-if="checked"
  40 + :bordered="false"
  41 + style="border: 2px dashed #797979"
  42 + :bodyStyle="{ padding: 0 }"
  43 + >
  44 + <ClearAlarm ref="clearAlarmRef" />
  45 + </Card>
26 </CollapseContainer> 46 </CollapseContainer>
27 </template> 47 </template>
28 -<script lang="ts">  
29 - import { defineComponent, ref, onMounted, nextTick, unref } from 'vue'; 48 +<script lang="ts" setup>
  49 + import { ref, onMounted, nextTick, unref, computed, provide } from 'vue';
30 import { CollapseContainer } from '/@/components/Container/index'; 50 import { CollapseContainer } from '/@/components/Container/index';
31 import { BasicForm, useForm } from '/@/components/Form/index'; 51 import { BasicForm, useForm } from '/@/components/Form/index';
32 - import { Tooltip } from 'ant-design-vue'; 52 + import { Tooltip, Select, Checkbox, Card } from 'ant-design-vue';
33 import { Icon } from '/@/components/Icon'; 53 import { Icon } from '/@/components/Icon';
34 - import { useActionDrawerSchema } from '../config'; 54 + import { actionSchema } from '../config';
35 import jsoneditor from 'jsoneditor'; 55 import jsoneditor from 'jsoneditor';
36 import 'jsoneditor/dist/jsoneditor.min.css'; 56 import 'jsoneditor/dist/jsoneditor.min.css';
37 - import { Tooltip } from 'ant-design-vue';  
38 import { QuestionCircleOutlined } from '@ant-design/icons-vue'; 57 import { QuestionCircleOutlined } from '@ant-design/icons-vue';
  58 + import { useUserStore } from '/@/store/modules/user';
  59 + import ClearAlarm from './ClearAlarm.vue';
  60 + defineProps({
  61 + actionIndex: {
  62 + type: Number,
  63 + required: true,
  64 + },
  65 + actionData: {
  66 + type: Array,
  67 + default: () => [],
  68 + },
  69 + });
  70 + const emit = defineEmits(['deleteAction']);
  71 + const userStore = useUserStore();
  72 + const options = computed(() => {
  73 + return [
  74 + { label: '设备输出', value: 'DEVICE_OUT' },
  75 + { label: '告警输出', value: 'MSG_NOTIFY', disabled: userStore.getOutTarget === 'MSG_NOTIFY' },
  76 + ];
  77 + });
  78 + const hasDisabled = ref(false);
  79 + const outTarget = ref('');
  80 + const changeOutTarget = (value: string) => {
  81 + outTarget.value = value;
  82 + if (value === 'MSG_NOTIFY') {
  83 + hasDisabled.value = true;
  84 + userStore.setOutTarget(value);
  85 + }
  86 + };
  87 + const [registerAction, { getFieldsValue, resetFields, updateSchema, setFieldsValue, validate }] =
  88 + useForm({
  89 + schemas: actionSchema,
  90 + showActionButtonGroup: false,
  91 + });
39 92
40 - export default defineComponent({  
41 - components: { CollapseContainer, BasicForm, Tooltip, Icon, Tooltip, QuestionCircleOutlined },  
42 - props: {  
43 - actionIndex: {  
44 - type: Number,  
45 - required: true, 93 + // 获取整个执行动作表单值
  94 + const getFieldsValueFunc = () => {
  95 + const predicate =
  96 + clearAlarmRef?.value?.conditionScreeningRef?.refItem?.conditionScreeningRefs?.value?.map(
  97 + (item) => item.getFieldsValue()
  98 + );
  99 + console.log({
  100 + ...getFieldsValue(),
  101 + ...clearAlarmRef?.value?.getFieldsValue(),
  102 + predicate,
  103 + doContext: unref(jsonInstance.value).get(),
  104 + schedule: clearAlarmRef?.value?.schedule,
  105 + });
  106 + return {
  107 + ...getFieldsValue(),
  108 + ...clearAlarmRef?.value?.getFieldsValue(),
  109 + predicate,
  110 + doContext: unref(jsonInstance.value).get(),
  111 + schedule: clearAlarmRef?.value?.schedule,
  112 + };
  113 + };
  114 + const setFieldsFormValueFun = (fieldsValue) => {
  115 + setFieldsValue(fieldsValue);
  116 + };
  117 + const resetFieldsValueFunc = () => resetFields();
  118 + const updateFieldDeviceId = (deviceList) => {
  119 + updateSchema({
  120 + field: 'deviceId',
  121 + componentProps: {
  122 + options: deviceList,
46 }, 123 },
47 - actionData: {  
48 - type: Array,  
49 - default: () => [], 124 + });
  125 + };
  126 + const updateFieldAlarmConfig = (alarmConfigList) => {
  127 + updateSchema({
  128 + field: 'alarm_config',
  129 + componentProps: {
  130 + options: alarmConfigList,
50 }, 131 },
51 - },  
52 - emits: ['deleteAction'],  
53 - setup(props, { emit }) {  
54 - const [  
55 - registerAction,  
56 - { getFieldsValue, resetFields, updateSchema, setFieldsValue, validate },  
57 - ] = useForm({  
58 - schemas: useActionDrawerSchema,  
59 - showActionButtonGroup: false,  
60 - });  
61 - const getFieldsValueFunc = () => ({  
62 - ...getFieldsValue(),  
63 - doContext: unref(jsonInstance.value).get(),  
64 - });  
65 - const setFieldsFormValueFun = (fieldsValue) => {  
66 - setFieldsValue(fieldsValue);  
67 - };  
68 - const resetFieldsValueFunc = () => resetFields();  
69 - const updateFieldDeviceId = (deviceList) => {  
70 - updateSchema({  
71 - field: 'deviceId',  
72 - componentProps: {  
73 - options: deviceList,  
74 - },  
75 - });  
76 - };  
77 - const validateForm = () => {  
78 - return validate();  
79 - };  
80 - const handleDelete = (actionIndex) => {  
81 - emit('deleteAction', actionIndex);  
82 - }; 132 + });
  133 + hasDisabled.value = false;
  134 + userStore.setOutTarget('DEVICE_OUT');
  135 + };
83 136
84 - // json 以及初始化JSON  
85 - const jsoneditorRef = ref();  
86 - const jsonValue = ref({});  
87 - const jsonInstance = ref();  
88 - onMounted(() => {  
89 - nextTick(() => {  
90 - let options = {  
91 - mode: 'code',  
92 - mainMenuBar: false,  
93 - statusBar: false,  
94 - onError(err) {  
95 - alert('EF1 ->' + err.toString());  
96 - },  
97 - };  
98 - let editor = new jsoneditor(jsoneditorRef.value, options);  
99 - editor.set(jsonValue.value);  
100 - jsonInstance.value = editor;  
101 - });  
102 - }); 137 + const checked = ref(false);
  138 + const validateForm = () => {
  139 + return validate();
  140 + };
103 141
104 - const getJsonValue = () => unref(jsonInstance).get();  
105 - const setJsonValue = (Json) => {  
106 - nextTick(() => {  
107 - unref(jsonInstance).set(Json);  
108 - });  
109 - };  
110 - return {  
111 - updateFieldDeviceId,  
112 - resetFieldsValueFunc,  
113 - getFieldsValueFunc,  
114 - validateForm,  
115 - registerAction,  
116 - handleDelete,  
117 - setFieldsFormValueFun,  
118 - jsoneditorRef,  
119 - jsonInstance,  
120 - getJsonValue,  
121 - setJsonValue, 142 + const handleDelete = (actionIndex) => {
  143 + emit('deleteAction', { actionIndex, outTarget });
  144 + };
  145 +
  146 + // json 以及初始化JSON
  147 + const jsoneditorRef = ref();
  148 + const jsonValue = ref({});
  149 + const jsonInstance = ref();
  150 + onMounted(() => {
  151 + nextTick(() => {
  152 + let options = {
  153 + mode: 'code',
  154 + mainMenuBar: false,
  155 + statusBar: false,
122 }; 156 };
123 - }, 157 + let editor = new jsoneditor(jsoneditorRef.value, options);
  158 + editor.set(jsonValue.value);
  159 + jsonInstance.value = editor;
  160 + });
  161 + });
  162 +
  163 + const getJsonValue = () => unref(jsonInstance).get();
  164 + const setJsonValue = (Json) => {
  165 + nextTick(() => {
  166 + unref(jsonInstance).set(Json);
  167 + });
  168 + };
  169 +
  170 + const operationType = ref<string>('');
  171 + const clearAlarmRef = ref();
  172 + provide('operationType', operationType);
  173 + defineExpose({
  174 + getFieldsValueFunc,
  175 + setFieldsFormValueFun,
  176 + resetFieldsValueFunc,
  177 + updateFieldDeviceId,
  178 + updateFieldAlarmConfig,
  179 + validateForm,
  180 + getJsonValue,
  181 + setJsonValue,
  182 + jsonInstance,
124 }); 183 });
125 </script> 184 </script>
126 185
1 <template> 1 <template>
2 - <CollapseContainer style="background-color: #f8f9fa" :title="`执行条件 ${conditionIndex + 1}`"> 2 + <CollapseContainer style="background-color: #f2f2f2" :title="`执行条件 ${conditionIndex + 1}`">
3 <template #action> 3 <template #action>
4 - <Tooltip title="移除">  
5 - <Icon  
6 - icon="fluent:delete-off-20-regular"  
7 - size="20"  
8 - class="mr-2 cursor-pointer"  
9 - @click="handleDelete(conditionIndex)"  
10 - />  
11 - </Tooltip> 4 + <div class="flex">
  5 + <div>
  6 + <span class="mr-2">启用规则</span>
  7 + <RadioGroup v-model:value="schedule" :options="scheduleOptions" />
  8 + </div>
  9 + <Tooltip title="移除" class="ml-4">
  10 + <Icon
  11 + icon="fluent:delete-off-20-regular"
  12 + size="20"
  13 + class="mr-2 cursor-pointer"
  14 + @click="handleDelete(conditionIndex)"
  15 + />
  16 + </Tooltip>
  17 + </div>
12 </template> 18 </template>
13 - <BasicForm @register="registerCondition" /> 19 + <BasicForm @register="registerCondition">
  20 + <template #operationType="{ model, field }">
  21 + <Select
  22 + :options="options"
  23 + v-model:value="model[field]"
  24 + @change="operationType = model[field]"
  25 + placeholder="请选择比较类型"
  26 + allowClear
  27 + />
  28 + </template>
  29 + </BasicForm>
  30 + <Card size="small" :bordered="false" style="border: 2px dashed #797979" v-if="operationType">
  31 + <ConditionScreening :childGetFieldsValue="childGetFieldsValue" ref="conditionScreeningRef" />
  32 + </Card>
14 </CollapseContainer> 33 </CollapseContainer>
15 </template> 34 </template>
16 -<script lang="ts">  
17 - import { defineComponent } from 'vue'; 35 +<script lang="ts" setup>
  36 + import { ref, provide } from 'vue';
18 import { CollapseContainer } from '/@/components/Container/index'; 37 import { CollapseContainer } from '/@/components/Container/index';
19 import { BasicForm, useForm } from '/@/components/Form/index'; 38 import { BasicForm, useForm } from '/@/components/Form/index';
20 - import { Tooltip } from 'ant-design-vue';  
21 - import { useConditionDrawerSchema } from '../config';  
22 - import { screenLinkPageByDeviceIdGetAttribut } from '/@/api/ruleengine/ruleengineApi'; 39 + import { Tooltip, Radio, Card, Select } from 'ant-design-vue';
  40 +
  41 + import { trigger_condition_schema } from '../config';
  42 + import { getAttribute } from '/@/api/ruleengine/ruleengineApi';
23 import { Icon } from '/@/components/Icon'; 43 import { Icon } from '/@/components/Icon';
  44 + import ConditionScreening from './ConditionScreening.vue';
  45 + const RadioGroup = Radio.Group;
24 46
25 - export default defineComponent({  
26 - components: { CollapseContainer, BasicForm, Tooltip, Icon },  
27 - props: {  
28 - conditionIndex: {  
29 - type: Number,  
30 - required: true,  
31 - }, 47 + defineProps({
  48 + conditionIndex: {
  49 + type: Number,
  50 + required: true,
32 }, 51 },
33 - emits: ['deleteCondition'],  
34 - setup(props, { emit }) {  
35 - const [registerCondition, { getFieldsValue, updateSchema, resetFields, setFieldsValue }] =  
36 - useForm({  
37 - schemas: useConditionDrawerSchema,  
38 - showActionButtonGroup: false,  
39 - });  
40 - const getFieldsValueFunc = () => getFieldsValue();  
41 - const resetFieldsValueFunc = () => resetFields();  
42 - const updateFieldDeviceId = (deviceList: any[]) => {  
43 - updateSchema({  
44 - field: 'entityId',  
45 - componentProps: {  
46 - options: deviceList,  
47 - onChange(e) {  
48 - if (e) {  
49 - updateFieldAttributeFunc(e);  
50 - }  
51 - },  
52 - },  
53 - });  
54 - };  
55 - const updateFieldAttributeFunc = async (e) => {  
56 - const data1 = await screenLinkPageByDeviceIdGetAttribut('DEVICE', e);  
57 - const data = data1.map((m) => {  
58 - return {  
59 - label: m,  
60 - value: m,  
61 - };  
62 - });  
63 - updateSchema({  
64 - field: 'type',  
65 - componentProps: {  
66 - placeholder: '请选择属性',  
67 - options: data,  
68 - onChange(e) {  
69 - if (e) {  
70 - updateSchema([  
71 - {  
72 - field: 'operation',  
73 - ifShow: true,  
74 - },  
75 - {  
76 - field: 'value',  
77 - ifShow: true,  
78 - },  
79 - ]);  
80 - } else {  
81 - updateSchema([  
82 - {  
83 - field: 'operation',  
84 - ifShow: false,  
85 - },  
86 - {  
87 - field: 'value',  
88 - ifShow: false,  
89 - },  
90 - ]);  
91 - }  
92 - },  
93 - },  
94 - });  
95 - };  
96 - const setFieldsFormValueFun = (fieldsValue) => {  
97 - setFieldsValue(fieldsValue);  
98 - };  
99 - const editSelectDevice = () => {  
100 - if (props.bindConditionEntryIdFather !== 1) {  
101 - setTimeout(() => {  
102 - updateSchema({  
103 - field: 'entityId',  
104 - componentProps: {  
105 - options: props.bindConditionEntryIdFather,  
106 - },  
107 - });  
108 - }, 100);  
109 - }  
110 - }; 52 + });
  53 + const emit = defineEmits(['deleteCondition']);
111 54
112 - const handleDelete = (conditionIndex) => {  
113 - emit('deleteCondition', conditionIndex);  
114 - };  
115 - return {  
116 - updateFieldDeviceId,  
117 - editSelectDevice,  
118 - getFieldsValueFunc,  
119 - registerCondition,  
120 - resetFieldsValueFunc,  
121 - handleDelete, 55 + const [registerCondition, { getFieldsValue, updateSchema, resetFields, setFieldsValue }] =
  56 + useForm({
  57 + schemas: trigger_condition_schema,
  58 + showActionButtonGroup: false,
  59 + });
  60 + const conditionScreeningRef = ref();
  61 + const getFieldsValueFunc = () => {
  62 + const predicate = conditionScreeningRef?.value?.refItem?.conditionScreeningRefs?.value?.map(
  63 + (item) => {
  64 + return item.getFieldsValue();
  65 + }
  66 + );
  67 + return { ...getFieldsValue(), predicate, schedule: schedule.value };
  68 + };
  69 + const resetFieldsValueFunc = () => resetFields();
  70 + const updateFieldDeviceId = (deviceList: any[]) => {
  71 + updateSchema({
  72 + field: 'entityId',
  73 + componentProps: {
  74 + options: deviceList,
  75 + onChange(e) {
  76 + if (e) {
  77 + updateFieldAttributeFunc();
  78 + }
  79 + },
  80 + },
  81 + });
  82 + };
  83 + const setFieldsFormValueFun = (fieldsValue) => {
  84 + setFieldsValue(fieldsValue);
  85 + };
  86 + const updateFieldAttributeFunc = async () => {
  87 + const data1 = await getAttribute();
  88 + const data = data1.map((m) => ({ label: m, value: m }));
  89 + updateSchema({
  90 + field: 'type',
  91 + componentProps: {
  92 + placeholder: '请选择属性',
  93 + options: data,
  94 + },
  95 + });
  96 + };
  97 + const handleDelete = (conditionIndex) => {
  98 + emit('deleteCondition', conditionIndex);
  99 + };
122 100
123 - setFieldsFormValueFun,  
124 - }; 101 + const schedule = ref('ANY_TIME');
  102 + const scheduleOptions = [
  103 + { label: '始终启用', value: 'ANY_TIME' },
  104 + { label: '定时启用', value: 'SPECIFIC_TIME' },
  105 + { label: '自定义启用', value: 'CUSTOM' },
  106 + ];
  107 + const operationType = ref<string>('');
  108 + const options = [
  109 + {
  110 + label: '数字',
  111 + value: 'NUMERIC',
  112 + },
  113 + {
  114 + label: '布尔值',
  115 + value: 'BOOLEAN',
  116 + },
  117 + {
  118 + label: '字符串',
  119 + value: 'STRING',
125 }, 120 },
  121 + {
  122 + label: '时间',
  123 + value: 'TIME',
  124 + },
  125 + ];
  126 + provide('operationType', operationType);
  127 +
  128 + // 子组件获取父组件的值
  129 + const childGetFieldsValue = () => getFieldsValue();
  130 +
  131 + defineExpose({
  132 + getFieldsValueFunc,
  133 + updateFieldDeviceId,
  134 + resetFieldsValueFunc,
  135 + setFieldsFormValueFun,
  136 + childGetFieldsValue,
126 }); 137 });
127 </script> 138 </script>
1 -export const formatTriggerData = (triggerData) => {  
2 - const { triggerType, entityId, type1, type2, operation, value } = triggerData;  
3 - return { 1 +export const genTriggerData = (triggerData) => {
  2 + const {
4 triggerType, 3 triggerType,
5 entityId, 4 entityId,
  5 + type1,
  6 + type2,
  7 + device,
  8 + detail,
  9 + predicate,
  10 + operationType,
  11 + triggered,
  12 + schedule,
  13 + } = triggerData;
  14 + const mapPredicate = predicate.map((item) => {
  15 + return {
  16 + key: {
  17 + type: type1,
  18 + key: type2,
  19 + },
  20 + valueType: operationType,
  21 + value: null,
  22 + predicate: {
  23 + type: operationType,
  24 + operation: item.operation,
  25 + value: {
  26 + defaultValue: item.value,
  27 + userValue: null,
  28 + dynamicValue: null,
  29 + },
  30 + },
  31 + };
  32 + });
  33 + return {
  34 + triggerType,
  35 + entityType: device,
  36 + entityId: entityId?.length ? entityId : null,
6 triggerCondition: { 37 triggerCondition: {
7 - condition: [  
8 - {  
9 - key: {  
10 - type: type1,  
11 - key: type2,  
12 - },  
13 - valueType: 'NUMERIC',  
14 - predicate: {  
15 - type: 'NUMERIC',  
16 - operation: operation,  
17 - value: {  
18 - defaultValue: Number(value),  
19 - },  
20 - }, 38 + alarmDetails: detail,
  39 + condition: {
  40 + condition: mapPredicate,
  41 + spec: {
  42 + type: triggered,
  43 + // unit: 'SECONDS',
  44 + // predicate: {
  45 + // defaultValue: 30,
  46 + // userValue: null,
  47 + // dynamicValue: null,
  48 + // },
21 }, 49 },
22 - ],  
23 - spec: {  
24 - type: 'SIMPLE', 50 + },
  51 + schedule: {
  52 + type: schedule,
  53 + // timezone: 'Asia/Shanghai',
  54 + // daysOfWeek: [2, 3],
  55 + // startsOn: 8700000,
  56 + // endsOn: 30300000,
25 }, 57 },
26 }, 58 },
27 }; 59 };
28 }; 60 };
29 61
30 -export const formatConditionData = (conditionData) => {  
31 - const { triggerType, entityId, type, operation, value } = conditionData;  
32 - return { 62 +export const genConditionData = (actionData) => {
  63 + const {
33 triggerType, 64 triggerType,
34 entityId, 65 entityId,
  66 + type1,
  67 + type2,
  68 + device,
  69 + detail,
  70 + predicate,
  71 + operationType,
  72 + triggered,
  73 + schedule,
  74 + } = actionData;
  75 + const mapPredicate = predicate.map((item) => {
  76 + return {
  77 + key: {
  78 + type: type1,
  79 + key: type2,
  80 + },
  81 + valueType: operationType,
  82 + value: null,
  83 + predicate: {
  84 + type: operationType,
  85 + operation: item.operation,
  86 + value: {
  87 + defaultValue: item.value,
  88 + userValue: null,
  89 + dynamicValue: null,
  90 + },
  91 + },
  92 + };
  93 + });
  94 + return {
  95 + triggerType,
  96 + entityType: device,
  97 + entityId: entityId?.length ? entityId : null,
35 triggerCondition: { 98 triggerCondition: {
36 - condition: [  
37 - {  
38 - key: {  
39 - key: type,  
40 - type: 'TIME_SERIES',  
41 - },  
42 - valueType: 'NUMERIC',  
43 - predicate: {  
44 - type: 'NUMERIC',  
45 - value: {  
46 - defaultValue: Number(value),  
47 - },  
48 - operation: operation,  
49 - }, 99 + alarmDetails: detail,
  100 + condition: {
  101 + condition: mapPredicate,
  102 + spec: {
  103 + type: triggered,
  104 + // unit: 'SECONDS',
  105 + // predicate: {
  106 + // defaultValue: 30,
  107 + // userValue: null,
  108 + // dynamicValue: null,
  109 + // },
50 }, 110 },
51 - ],  
52 - spec: {  
53 - type: 'SIMPLE', 111 + },
  112 + schedule: {
  113 + type: schedule,
  114 + // timezone: 'Asia/Shanghai',
  115 + // daysOfWeek: [2, 3],
  116 + // startsOn: 8700000,
  117 + // endsOn: 30300000,
54 }, 118 },
55 }, 119 },
56 }; 120 };
57 }; 121 };
  122 +
  123 +export const genActionData = (conditionData) => {
  124 + const {
  125 + alarm_config,
  126 + alarm_level,
  127 + detail,
  128 + device,
  129 + doContext,
  130 + operationType,
  131 + outTarget,
  132 + predicate,
  133 + triggerType,
  134 + triggered,
  135 + type1,
  136 + type2,
  137 + schedule,
  138 + entityId,
  139 + deviceId,
  140 + } = conditionData;
  141 +
  142 + const mapPredicate = predicate?.map((item) => {
  143 + return {
  144 + key: {
  145 + type: type1,
  146 + key: type2,
  147 + },
  148 + valueType: operationType,
  149 + value: null,
  150 + predicate: {
  151 + type: operationType,
  152 + operation: item.operation,
  153 + value: {
  154 + defaultValue: item.value,
  155 + userValue: null,
  156 + dynamicValue: null,
  157 + },
  158 + },
  159 + };
  160 + });
  161 + console.log(doContext);
  162 + return [
  163 + {
  164 + alarmProfileId: alarm_config,
  165 + outTarget,
  166 + entityType: device,
  167 + entityId: entityId?.length ? entityId : null,
  168 + deviceId,
  169 + doContext: mapPredicate?.length
  170 + ? {
  171 + alarmLevel: alarm_level,
  172 + clearRule: {
  173 + triggerType,
  174 + triggerCondition: {
  175 + alarmDetails: detail,
  176 + condition: {
  177 + condition: mapPredicate,
  178 + spec: {
  179 + type: triggered,
  180 + // unit: 'SECONDS',
  181 + // predicate: {
  182 + // defaultValue: 30,
  183 + // userValue: null,
  184 + // dynamicValue: null,
  185 + // },
  186 + },
  187 + },
  188 + schedule: {
  189 + type: schedule,
  190 + // timezone: 'Asia/Shanghai',
  191 + // daysOfWeek: [2, 3],
  192 + // startsOn: 8700000,
  193 + // endsOn: 30300000,
  194 + },
  195 + },
  196 + },
  197 + }
  198 + : doContext,
  199 + },
  200 + ];
  201 +};
1 <template> 1 <template>
2 <div> 2 <div>
3 - <CollapseContainer style="background-color: #f8f9fa" :title="`触发器 ${triggerIndex + 1}`"> 3 + <CollapseContainer style="background-color: #f2f2f2" :title="`触发器 ${triggerIndex + 1}`">
4 <template #action> 4 <template #action>
5 - <Tooltip title="移除">  
6 - <Icon  
7 - icon="fluent:delete-off-20-regular"  
8 - size="20"  
9 - class="mr-2 cursor-pointer"  
10 - @click="handleDelete(triggerIndex)"  
11 - />  
12 - </Tooltip> 5 + <div class="flex">
  6 + <div>
  7 + <span class="mr-2">启用规则</span>
  8 + <RadioGroup v-model:value="schedule" :options="scheduleOptions" />
  9 + </div>
  10 + <Tooltip title="移除" class="ml-4">
  11 + <Icon
  12 + icon="fluent:delete-off-20-regular"
  13 + size="20"
  14 + class="mr-2 cursor-pointer"
  15 + @click="handleDelete(triggerIndex)"
  16 + />
  17 + </Tooltip>
  18 + </div>
13 </template> 19 </template>
14 - <BasicForm @register="registerForm" /> 20 + <BasicForm @register="registerForm">
  21 + <template #operationType="{ model, field }">
  22 + <Select
  23 + :options="options"
  24 + v-model:value="model[field]"
  25 + @change="operationType = model[field]"
  26 + placeholder="请选择比较类型"
  27 + allowClear
  28 + />
  29 + </template>
  30 + </BasicForm>
  31 + <Card size="small" :bordered="false" style="border: 2px dashed #797979" v-if="operationType">
  32 + <ConditionScreening
  33 + :childGetFieldsValue="childGetFieldsValue"
  34 + ref="conditionScreeningRef"
  35 + />
  36 + </Card>
15 </CollapseContainer> 37 </CollapseContainer>
16 </div> 38 </div>
17 </template> 39 </template>
18 -<script lang="ts">  
19 - import { defineComponent } from 'vue'; 40 +<script lang="ts" setup>
  41 + import { ref, provide } from 'vue';
20 import { CollapseContainer } from '/@/components/Container/index'; 42 import { CollapseContainer } from '/@/components/Container/index';
21 import { BasicForm, useForm } from '/@/components/Form/index'; 43 import { BasicForm, useForm } from '/@/components/Form/index';
22 import { Icon } from '/@/components/Icon'; 44 import { Icon } from '/@/components/Icon';
23 - import { Tooltip } from 'ant-design-vue';  
24 - import { useTriggerDrawerSchema } from '../config';  
25 - import { screenLinkPageByDeviceIdGetAttribut } from '/@/api/ruleengine/ruleengineApi';  
26 - export default defineComponent({  
27 - components: { CollapseContainer, BasicForm, Icon, Tooltip },  
28 - props: {  
29 - triggerIndex: {  
30 - type: Number,  
31 - required: true,  
32 - }, 45 + import { Tooltip, Radio, Card, Select } from 'ant-design-vue';
  46 + import { trigger_condition_schema } from '../config';
  47 + import { getAttribute } from '/@/api/ruleengine/ruleengineApi';
  48 + import ConditionScreening from './ConditionScreening.vue';
  49 + const RadioGroup = Radio.Group;
  50 +
  51 + defineProps({
  52 + triggerIndex: {
  53 + type: Number,
  54 + required: true,
33 }, 55 },
34 - emits: ['deleteTrigger'],  
35 - setup(props, { emit }) {  
36 - const [registerForm, { resetFields, getFieldsValue, updateSchema, setFieldsValue }] = useForm(  
37 - {  
38 - schemas: useTriggerDrawerSchema,  
39 - showActionButtonGroup: false,  
40 - }  
41 - );  
42 - const getFieldsValueFunc = () => getFieldsValue(); 56 + });
  57 + const emit = defineEmits(['deleteTrigger']);
  58 + const conditionScreeningRef = ref();
  59 + const [registerForm, { resetFields, getFieldsValue, updateSchema, setFieldsValue }] = useForm({
  60 + schemas: trigger_condition_schema,
  61 + showActionButtonGroup: false,
  62 + });
43 63
44 - const updateFieldDeviceId = (deviceList: any[]) => {  
45 - updateSchema({  
46 - field: 'entityId',  
47 - componentProps: {  
48 - options: deviceList,  
49 - onChange(e) {  
50 - if (e) {  
51 - updateFieldAttributeFunc(e);  
52 - }  
53 - },  
54 - },  
55 - }); 64 + const getFieldsValueFunc = () => {
  65 + const predicate = conditionScreeningRef?.value?.refItem?.conditionScreeningRefs?.value?.map(
  66 + (item) => {
  67 + return item.getFieldsValue();
  68 + }
  69 + );
  70 + return { ...getFieldsValue(), predicate, schedule: schedule.value };
  71 + };
  72 + const updateFieldDeviceId = (deviceList: any[]) => {
  73 + updateSchema({
  74 + field: 'entityId',
  75 + componentProps: {
  76 + options: deviceList,
  77 + onChange(e) {
  78 + if (e) {
  79 + updateFieldAttributeFunc();
  80 + }
  81 + },
  82 + },
  83 + });
  84 + };
  85 + const resetFieldsValueFunc = () => resetFields();
  86 + // 回显数据函数
  87 + const setFieldsFormValueFun = (fieldsValue) => {
  88 + setFieldsValue(fieldsValue);
  89 + };
  90 + const updateFieldAttributeFunc = async () => {
  91 + const data1 = await getAttribute();
  92 + const options = data1.map((m) => {
  93 + return {
  94 + label: m,
  95 + value: m,
56 }; 96 };
57 - const updateFieldAttributeFunc = async (e) => {  
58 - const data1 = await screenLinkPageByDeviceIdGetAttribut('DEVICE', e);  
59 - const options = data1.map((m) => {  
60 - return {  
61 - label: m,  
62 - value: m,  
63 - };  
64 - });  
65 - updateSchema({  
66 - field: 'type2',  
67 - componentProps: {  
68 - placeholder: '请选择属性',  
69 - options,  
70 - onChange(value) {  
71 - if (value) {  
72 - updateSchema([  
73 - {  
74 - field: 'operation',  
75 - ifShow: true,  
76 - },  
77 - {  
78 - field: 'value',  
79 - ifShow: true,  
80 - },  
81 - ]);  
82 - setFieldsValue({  
83 - operation: '',  
84 - value: '',  
85 - });  
86 - return;  
87 - }  
88 - updateSchema([  
89 - {  
90 - field: 'operation',  
91 - ifShow: false,  
92 - },  
93 - {  
94 - field: 'value',  
95 - ifShow: false,  
96 - },  
97 - ]);  
98 - setFieldsValue({  
99 - operation: '',  
100 - value: '',  
101 - }); 97 + });
  98 + updateSchema({
  99 + field: 'type2',
  100 + componentProps: {
  101 + placeholder: '请选择属性',
  102 + options,
  103 + onChange(value) {
  104 + if (value) {
  105 + updateSchema([
  106 + {
  107 + field: 'operation',
  108 + ifShow: true,
  109 + },
  110 + {
  111 + field: 'value',
  112 + ifShow: true,
  113 + },
  114 + ]);
  115 + setFieldsValue({
  116 + operation: '',
  117 + value: '',
  118 + });
  119 + return;
  120 + }
  121 + updateSchema([
  122 + {
  123 + field: 'operation',
  124 + ifShow: false,
102 }, 125 },
103 - },  
104 - });  
105 - };  
106 -  
107 - const resetFieldsValueFunc = () => resetFields();  
108 - // 回显数据函数  
109 - const setFieldsFormValueFun = (fieldsValue) => {  
110 - setFieldsValue(fieldsValue);  
111 - };  
112 -  
113 - const editSelectDevice = () => {  
114 - if (props.bindTriggerEntryIdFather != 1) {  
115 - updateSchema({  
116 - field: 'entityId',  
117 - componentProps: {  
118 - options: props.bindTriggerEntryIdFather, 126 + {
  127 + field: 'value',
  128 + ifShow: false,
119 }, 129 },
  130 + ]);
  131 + setFieldsValue({
  132 + operation: '',
  133 + value: '',
120 }); 134 });
121 - }  
122 - };  
123 - // editSelectDevice(); 135 + },
  136 + },
  137 + });
  138 + };
124 139
125 - const handleDelete = (triggerIndex) => {  
126 - emit('deleteTrigger', triggerIndex);  
127 - };  
128 - return {  
129 - updateFieldAttributeFunc,  
130 - updateFieldDeviceId,  
131 - resetFieldsValueFunc,  
132 - editSelectDevice,  
133 - getFieldsValueFunc,  
134 - registerForm,  
135 - handleDelete, 140 + const handleDelete = (triggerIndex) => {
  141 + emit('deleteTrigger', triggerIndex);
  142 + };
136 143
137 - setFieldsFormValueFun,  
138 - }; 144 + const schedule = ref('ANY_TIME');
  145 + const scheduleOptions = [
  146 + { label: '始终启用', value: 'ANY_TIME' },
  147 + { label: '定时启用', value: 'SPECIFIC_TIME' },
  148 + { label: '自定义启用', value: 'CUSTOM' },
  149 + ];
  150 + const operationType = ref<string>('');
  151 + const options = [
  152 + {
  153 + label: '数字',
  154 + value: 'NUMERIC',
139 }, 155 },
  156 + {
  157 + label: '布尔值',
  158 + value: 'BOOLEAN',
  159 + },
  160 + {
  161 + label: '字符串',
  162 + value: 'STRING',
  163 + },
  164 + {
  165 + label: '时间',
  166 + value: 'TIME',
  167 + },
  168 + ];
  169 + // 子组件获取父组件的值
  170 + const childGetFieldsValue = () => getFieldsValue();
  171 +
  172 + provide('operationType', operationType);
  173 +
  174 + defineExpose({
  175 + getFieldsValueFunc,
  176 + updateFieldDeviceId,
  177 + resetFieldsValueFunc,
  178 + setFieldsFormValueFun,
  179 + childGetFieldsValue,
140 }); 180 });
141 </script> 181 </script>
142 -  
143 -<style>  
144 - .ant-slider-handle {  
145 - display: none !important;  
146 - }  
147 -</style>