Commit f4a6af58d1b1ec94d9c8fd8f24d9e3e73e1aedaf

Authored by fengistao
1 parent d2d7b6ed

feat:新增设备配置,调通新增和分页和详情,待调通删除

  1 +import { defHttp } from '/@/utils/http/axios';
  2 +import {
  3 + TDeviceConfigParams,
  4 + IDeviceConfigAddOrEditModel,
  5 +} from '/@/api/device/model/deviceConfigModel';
  6 +
  7 +enum EDeviceConfigApi {
  8 + /**
  9 + * 设备配置URL
  10 + */
  11 + DEVICE_CONFIG_GET_PAGE = '/deviceProfile',
  12 + DEVICE_CONFIG_POST_ADD_OR_EDIT = '/deviceProfile',
  13 + DEVICE_CONFIG_GET_DETAIL = '/deviceProfile/',
  14 + DEVICE_CONFIG_DELETE = '/deviceProfile',
  15 + DEVICE_CONFIG_GET_RULECHAIN = '/rulechain/me/list',
  16 + ALARM_CONTACT_GET_PAGE = '/alarmContact',
  17 + DEVICE_CONFIG_EXPORT = '/deviceProfile/export',
  18 + DEVICE_CONFIG_IMPORT = '/deviceProfile/import',
  19 +}
  20 +
  21 +/**
  22 + * 设备配置详情
  23 + */
  24 +export const deviceConfigGetDetail = (id: string) => {
  25 + return defHttp.get({
  26 + url: `${EDeviceConfigApi.DEVICE_CONFIG_GET_DETAIL}${id}`,
  27 + });
  28 +};
  29 +
  30 +/**
  31 + * 获取规则链
  32 + */
  33 +export const deviceConfigGetRuleChain = (params: {}) => {
  34 + return defHttp.get({
  35 + url: EDeviceConfigApi.DEVICE_CONFIG_GET_RULECHAIN,
  36 + params,
  37 + });
  38 +};
  39 +
  40 +/**
  41 + * 获取告警联系人
  42 + */
  43 +export const alarmContactGetPage = () => {
  44 + return defHttp.get({
  45 + url: `${EDeviceConfigApi.ALARM_CONTACT_GET_PAGE}?page=1&pageSize=10`,
  46 + });
  47 +};
  48 +
  49 +/**
  50 + * 分页查询设备配置页面
  51 + */
  52 +export const deviceConfigGetQuery = (params?: TDeviceConfigParams) => {
  53 + return defHttp.get({
  54 + url: EDeviceConfigApi.DEVICE_CONFIG_GET_PAGE,
  55 + params,
  56 + });
  57 +};
  58 +
  59 +/**
  60 + * 新增或者编辑设备配置
  61 +
  62 + */
  63 +export const deviceConfigAddOrEdit = (params: IDeviceConfigAddOrEditModel) => {
  64 + return defHttp.post<IDeviceConfigAddOrEditModel>({
  65 + url: EDeviceConfigApi.DEVICE_CONFIG_POST_ADD_OR_EDIT,
  66 + params,
  67 + });
  68 +};
  69 +
  70 +/**
  71 + * 删除设备配置
  72 + */
  73 +export const deviceConfigDelete = (ids: string[]) => {
  74 + return defHttp.delete({
  75 + url: EDeviceConfigApi.DEVICE_CONFIG_DELETE,
  76 + data: {
  77 + ids: ids,
  78 + },
  79 + });
  80 +};
  81 +
  82 +/**
  83 + * 导出设备配置
  84 + */
  85 +export const deviceConfigExport = (params: IDeviceConfigAddOrEditModel) => {
  86 + return defHttp.post<IDeviceConfigAddOrEditModel>({
  87 + url: EDeviceConfigApi.DEVICE_CONFIG_EXPORT,
  88 + params,
  89 + });
  90 +};
  91 +
  92 +/**
  93 + * 导入设备配置
  94 + */
  95 +export const deviceConfigImport = (params: IDeviceConfigAddOrEditModel) => {
  96 + return defHttp.post<IDeviceConfigAddOrEditModel>({
  97 + url: EDeviceConfigApi.DEVICE_CONFIG_IMPORT,
  98 + params,
  99 + });
  100 +};
... ...
  1 +import { BasicPageParams } from '/@/api/model/baseModel';
  2 +
  3 +export type TDeviceConfigPageQueryParam = BasicPageParams & TDeviceConfigParams;
  4 +
  5 +export type TDeviceConfigParams = {
  6 + name?: string;
  7 + transportType?: string;
  8 + orderFiled?: string;
  9 + orderType?: string;
  10 +};
  11 +
  12 +export interface IDeviceConfigAddOrEditModel {
  13 + alarmProfile?: {
  14 + alarmContactId: string;
  15 + createTime: '2021-12-15T02:17:26.644Z';
  16 + creator: string;
  17 + defaultConfig: string;
  18 + description: string;
  19 + deviceProfileId: string;
  20 + enabled: true;
  21 + icon: string;
  22 + id: string;
  23 + messageMode: string;
  24 + name: string;
  25 + roleIds: [string];
  26 + tenantExpireTime: '2021-12-15T02:17:26.644Z';
  27 + tenantId: string;
  28 + tenantStatus: 'DISABLED';
  29 + updateTime: '2021-12-15T02:17:26.644Z';
  30 + updater: string;
  31 + };
  32 + convertJs?: string;
  33 + createTime?: '2021-12-15T02:17:26.644Z';
  34 + creator?: string;
  35 + defaultConfig?: string;
  36 + defaultRuleChainId?: string;
  37 + description?: string;
  38 + enabled?: true;
  39 + icon?: string;
  40 + id?: string;
  41 + name?: string;
  42 + profileData?: {
  43 + configuration: {};
  44 + transportConfiguration: {};
  45 + provisionConfiguration: {
  46 + provisionDeviceSecret: string;
  47 + };
  48 + alarms: [
  49 + {
  50 + id: 'highTemperatureAlarmID';
  51 + alarmType: 'High Temperature Alarm';
  52 + createRules: {
  53 + additionalProp1: {
  54 + condition: {
  55 + condition: [
  56 + {
  57 + key: {
  58 + type: 'TIME_SERIES';
  59 + key: 'temp';
  60 + };
  61 + valueType: 'NUMERIC';
  62 + value: {};
  63 + predicate: {};
  64 + }
  65 + ];
  66 + spec: {};
  67 + };
  68 + schedule: {
  69 + type: 'ANY_TIME';
  70 + };
  71 + alarmDetails: string;
  72 + dashboardId: {
  73 + id: '784f394c-42b6-435a-983c-b7beff2784f9';
  74 + entityType: 'DASHBOARD';
  75 + };
  76 + };
  77 + additionalProp2: {
  78 + condition: {
  79 + condition: [
  80 + {
  81 + key: {
  82 + type: 'TIME_SERIES';
  83 + key: 'temp';
  84 + };
  85 + valueType: 'NUMERIC';
  86 + value: {};
  87 + predicate: {};
  88 + }
  89 + ];
  90 + spec: {};
  91 + };
  92 + schedule: {
  93 + type: 'ANY_TIME';
  94 + };
  95 + alarmDetails: string;
  96 + dashboardId: {
  97 + id: '784f394c-42b6-435a-983c-b7beff2784f9';
  98 + entityType: 'DASHBOARD';
  99 + };
  100 + };
  101 + additionalProp3: {
  102 + condition: {
  103 + condition: [
  104 + {
  105 + key: {
  106 + type: 'TIME_SERIES';
  107 + key: 'temp';
  108 + };
  109 + valueType: 'NUMERIC';
  110 + value: {};
  111 + predicate: {};
  112 + }
  113 + ];
  114 + spec: {};
  115 + };
  116 + schedule: {
  117 + type: 'ANY_TIME';
  118 + };
  119 + alarmDetails: string;
  120 + dashboardId: {
  121 + id: '784f394c-42b6-435a-983c-b7beff2784f9';
  122 + entityType: 'DASHBOARD';
  123 + };
  124 + };
  125 + };
  126 + clearRule: {
  127 + condition: {
  128 + condition: [
  129 + {
  130 + key: {
  131 + type: 'TIME_SERIES';
  132 + key: 'temp';
  133 + };
  134 + valueType: 'NUMERIC';
  135 + value: {};
  136 + predicate: {};
  137 + }
  138 + ];
  139 + spec: {};
  140 + };
  141 + schedule: {
  142 + type: 'ANY_TIME';
  143 + };
  144 + alarmDetails: string;
  145 + dashboardId: {
  146 + id: '784f394c-42b6-435a-983c-b7beff2784f9';
  147 + entityType: 'DASHBOARD';
  148 + };
  149 + };
  150 + propagate: true;
  151 + propagateRelationTypes: [string];
  152 + }
  153 + ];
  154 + };
  155 + roleIds?: [string];
  156 + tbProfileId?: string;
  157 + tenantExpireTime?: '2021-12-15T02:17:26.645Z';
  158 + tenantId?: string;
  159 + tenantStatus?: 'DISABLED';
  160 + transportType?: 'COAP';
  161 + updateTime?: '2021-12-15T02:17:26.645Z';
  162 + updater?: string;
  163 +}
... ...
... ... @@ -70,7 +70,8 @@ export const notifyAddLeaseApi = (params: NotifyAddreLeaseModel) => {
70 70 */
71 71 export const notifyDeleteApi = (ids: string[]) => {
72 72 return defHttp.delete({
73   - url: `${NotifyManagerApi.NOTICE_DELETE_URL}?ids=${ids}`,
  73 + url: NotifyManagerApi.NOTICE_DELETE_URL,
  74 + data: ids,
74 75 });
75 76 };
76 77
... ...
... ... @@ -96,7 +96,7 @@ export const useMultipleTabStore = defineStore({
96 96 const len = this.tabList.length;
97 97 const { path } = unref(router.currentRoute);
98 98
99   - let toPath: PageEnum | string = BASE_HOME;
  99 + let toPath: PageEnum | string = PageEnum.BASE_HOME;
100 100
101 101 if (len > 0) {
102 102 const page = this.tabList[len - 1];
... ...
... ... @@ -180,11 +180,12 @@ export const usePermissionStore = defineStore({
180 180 this.changePermissionCode();
181 181 routeList = (await getMenuList()) as AppRouteRecordRaw[];
182 182 //这里判断是否含有首页
  183 + // console.log(routeList);
183 184 const getHomePage = routeList.find((f) => {
184 185 return f.path == '/dashboard';
185 186 });
186 187 if (getHomePage?.path == '/dashboard') {
187   - router.push('/dashboard');
  188 + router.push('/dashboard/workbench');
188 189 } else {
189 190 const route = routeList[0].path + '';
190 191 router.push(route);
... ... @@ -206,7 +207,6 @@ export const usePermissionStore = defineStore({
206 207 routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
207 208 break;
208 209 }
209   - console.log('错误页');
210 210 routes.push(ERROR_LOG_ROUTE);
211 211 patchHomeAffix(routes);
212 212 return routes;
... ...
... ... @@ -12,22 +12,44 @@
12 12 <a-step title="设备配置" />
13 13 <a-step title="传输配置" />
14 14 <a-step title="告警配置" />
  15 + <a-step title="告警通知" />
15 16 </a-steps>
16 17 </div>
17 18 <div class="mt-5">
18   - <DeviceProfileStep1 @next="handleStep1Next" v-if="current === 0" />
19   - <DeviceProfileStep2 @prev="handleStepPrev" @next="handleStep2Next" v-if="current === 1" />
20   - <DeviceProfileStep3 @prev="handleStepPrev" @redo="handleRedo" v-if="current === 2" />
  19 + <DeviceProfileStep1 :echoStep1="editEchoData" @next="handleStepNext1" v-if="current === 0" />
  20 + <DeviceProfileStep2
  21 + :echoStep2="editEchoData"
  22 + @prev="handleStepPrev"
  23 + @next="handleStep2Next"
  24 + v-if="current === 1"
  25 + />
  26 + <DeviceProfileStep3
  27 + :echoStep3="editEchoData"
  28 + @prev="handleStepPrev"
  29 + @next="handleStep3Next"
  30 + @redo="handleRedo"
  31 + v-if="current === 2"
  32 + />
  33 + <DeviceProfileStep4
  34 + :echoStep4="editEchoData"
  35 + ref="getStepData"
  36 + @prev="handleStepPrev"
  37 + v-if="current === 3"
  38 + />
21 39 </div>
22 40 </BasicModal>
23 41 </template>
24 42 <script lang="ts">
25   - import { defineComponent, ref, computed, unref } from 'vue';
  43 + import { defineComponent, ref, computed, unref, getCurrentInstance } from 'vue';
26 44 import { BasicModal, useModalInner } from '/@/components/Modal';
27 45 import DeviceProfileStep1 from '/@/views/device/profile/step/DeviceProfileStep1.vue';
28 46 import DeviceProfileStep2 from '/@/views/device/profile/step/DeviceProfileStep2.vue';
29 47 import DeviceProfileStep3 from '/@/views/device/profile/step/DeviceProfileStep3.vue';
  48 + import DeviceProfileStep4 from '/@/views/device/profile/step/DeviceProfileStep4.vue';
30 49 import { Steps } from 'ant-design-vue';
  50 + import { deviceConfigAddOrEdit } from '/@/api/device/deviceConfigApi';
  51 + import { useMessage } from '/@/hooks/web/useMessage';
  52 +
31 53 export default defineComponent({
32 54 name: 'DeviceModal',
33 55 components: {
... ... @@ -35,48 +57,84 @@
35 57 DeviceProfileStep1,
36 58 DeviceProfileStep2,
37 59 DeviceProfileStep3,
  60 + DeviceProfileStep4,
38 61 [Steps.name]: Steps,
39 62 [Steps.Step.name]: Steps.Step,
40 63 },
41 64 props: {
42 65 userData: { type: Object },
43 66 },
44   - setup(_) {
  67 + emits: ['success'],
  68 + setup(_, { emit }) {
  69 + const { createMessage } = useMessage();
  70 + const getStepData = ref(null);
  71 + const { proxy } = getCurrentInstance();
  72 + const postDeviceConfogData: any = ref({});
  73 + const getStepOneData: any = ref({});
  74 + const getStepTwoData: any = ref({});
  75 + const editEchoData: any = ref({});
45 76 const current = ref(0);
46 77 const isUpdate = ref(true);
47 78 const getTitle = computed(() => (!unref(isUpdate) ? '新增设备配置' : '编辑设备配置'));
48   - const [register] = useModalInner((data) => {
  79 + const [register, { closeModal }] = useModalInner((data) => {
49 80 isUpdate.value = !!data?.isUpdate;
50 81 if (!unref(isUpdate)) {
51 82 current.value = 0;
52 83 }
  84 + if (unref(isUpdate)) {
  85 + editEchoData.value = data.record;
  86 + console.log(editEchoData.value);
  87 + }
53 88 });
54 89 function handleStepPrev() {
55 90 current.value--;
56 91 }
57   - function handleStep1Next() {
  92 + function handleStepNext1(v) {
  93 + current.value++;
  94 + console.log('第一步的数据', v);
  95 + getStepOneData.value = v;
  96 + }
  97 + function handleStep2Next(v) {
58 98 current.value++;
  99 + console.log('第二步的数据', v);
  100 + getStepTwoData.value = v;
59 101 }
60   - function handleStep2Next() {
  102 + function handleStep3Next(v) {
61 103 current.value++;
  104 + console.log('第三步的数据', v);
62 105 }
63 106 function handleRedo() {
64 107 current.value = 0;
65 108 }
66   - const handleSubmit = () => {
67   - console.log();
  109 + const handleSubmit = async () => {
  110 + let getStep4Data = proxy.$refs.getStepData.getAllFields();
  111 + console.log('第四步的数据', getStep4Data);
  112 + Object.assign(
  113 + postDeviceConfogData.value,
  114 + getStepOneData.value,
  115 + getStepTwoData.value,
  116 + getStep4Data
  117 + );
  118 + console.log('搜集的所有数据', postDeviceConfogData.value);
  119 + await deviceConfigAddOrEdit(postDeviceConfogData.value);
  120 + createMessage.success('新增设备配置成功');
  121 + closeModal();
  122 + emit('success');
68 123 };
69   - const handleCancel = () => {
70   - console.log();
  124 + const handleCancel = async () => {
  125 + console.log(2);
71 126 };
72 127 return {
  128 + editEchoData,
  129 + getStepData,
  130 + handleStep3Next,
73 131 handleSubmit,
74 132 handleCancel,
75 133 register,
76 134 getTitle,
77 135 current,
78 136 handleStepPrev,
79   - handleStep1Next,
  137 + handleStepNext1,
80 138 handleStep2Next,
81 139 handleRedo,
82 140 };
... ...
1 1 import { FormSchema } from '/@/components/Form';
2 2 import { findDictItemByCode } from '/@/api/system/dict';
  3 +import { alarmContactGetPage } from '/@/api/device/deviceConfigApi';
3 4
4 5 export const alertContactsSchemas: FormSchema[] = [
5 6 {
6   - field: 'alertType',
  7 + field: 'name',
  8 + label: '告警通知联系人',
  9 + component: 'ApiSelect',
  10 + componentProps: {
  11 + api: alarmContactGetPage,
  12 + labelField: 'username',
  13 + valueField: 'id',
  14 + },
  15 + },
  16 + {
  17 + field: 'messageMode',
7 18 label: '告警通知方式',
8 19 required: true,
9 20 component: 'ApiSelect',
... ...
  1 +<template>
  2 + <BasicModal v-bind="$attrs" width="55rem" @register="register" :title="getTitle">
  3 + <PageWrapper title="设备配置详情">
  4 + <Description @register="register1" class="mt-4" />
  5 + </PageWrapper>
  6 + </BasicModal>
  7 +</template>
  8 +<script lang="ts">
  9 + import { defineComponent, ref, computed, unref } from 'vue';
  10 + import { BasicModal, useModalInner } from '/@/components/Modal';
  11 + import { Description, DescItem, useDescription } from '/@/components/Description/index';
  12 + import { PageWrapper } from '/@/components/Page';
  13 + import { deviceConfigGetDetail } from '/@/api/device/deviceConfigApi';
  14 +
  15 + const schema: DescItem[] = [
  16 + {
  17 + field: 'description',
  18 + label: '描述',
  19 + },
  20 + {
  21 + field: 'enabled',
  22 + label: '禁用',
  23 + },
  24 + {
  25 + field: 'name',
  26 + label: '设备配置名称',
  27 + },
  28 + {
  29 + field: 'transportType',
  30 + label: '传输类型',
  31 + },
  32 + ];
  33 + export default defineComponent({
  34 + name: 'ConfigDrawer',
  35 + components: { BasicModal, Description, PageWrapper },
  36 + emits: ['success', 'register'],
  37 + setup() {
  38 + let descInfo = ref(null);
  39 + const isUpdate = ref(true);
  40 + const [register] = useModalInner(async (data) => {
  41 + isUpdate.value = !!data?.isUpdate;
  42 + let getDescInfo = await deviceConfigGetDetail(data.record.id);
  43 + descInfo.value = getDescInfo;
  44 + });
  45 + const getTitle = computed(() => (!unref(isUpdate) ? '查看设备配置' : '查看设备配置'));
  46 + const [register1] = useDescription({
  47 + title: '详情',
  48 + bordered: false,
  49 + data: descInfo,
  50 + schema: schema,
  51 + });
  52 + return {
  53 + register,
  54 + register1,
  55 + getTitle,
  56 + };
  57 + },
  58 + });
  59 +</script>
... ...
1 1 <template>
2 2 <div>
3   - <BasicTable @register="registerTable">
  3 + <BasicTable
  4 + @selection-change="useSelectionChange"
  5 + @register="registerTable"
  6 + :rowSelection="{ type: 'checkbox' }"
  7 + >
4 8 <template #toolbar>
5 9 <a-button type="primary" @click="handleCreate"> 新增设备配置 </a-button>
  10 + <ImpExcel @success="loadDataSuccess" dateFormat="YYYY-MM-DD">
  11 + <a-button type="info" @click="handleImport"> 导入设备配置 </a-button>
  12 + </ImpExcel>
  13 + <a-button type="danger" @click="handleTableDel"> 删除 </a-button>
6 14 </template>
7 15 <template #action="{ record }">
8 16 <TableAction
9 17 :actions="[
10 18 {
  19 + label: '详情',
  20 + icon: 'clarity:note-edit-line',
  21 + onClick: handleDetailView.bind(null, record),
  22 + },
  23 + {
11 24 label: '编辑',
12 25 icon: 'clarity:note-edit-line',
13 26 onClick: handleEdit.bind(null, record),
14 27 },
15 28 {
  29 + label: '导出',
  30 + icon: 'clarity:note-edit-line',
  31 + onClick: handleExport.bind(null, record),
  32 + },
  33 + {
16 34 label: '删除',
17 35 icon: 'ant-design:delete-outlined',
18 36 color: 'error',
... ... @@ -25,26 +43,34 @@
25 43 />
26 44 </template>
27 45 </BasicTable>
28   - <DeviceProfileModal @register="registerModal" @success="handleSuccess" />
  46 + <DeviceProfileModal v-if="isJudgeStatus" @register="registerModal" @success="handleSuccess" />
  47 + <DeviceConfigDetail v-if="!isJudgeStatus" @register="registerModal" @success="handleSuccess" />
29 48 </div>
30 49 </template>
31 50 <script lang="ts">
32   - import { defineComponent } from 'vue';
  51 + import { defineComponent, ref, reactive } from 'vue';
33 52 import { BasicTable, useTable, TableAction } from '/@/components/Table';
34 53 import { columns, searchFormSchema } from './device.profile.data';
35 54 import { useMessage } from '/@/hooks/web/useMessage';
36   - import { deviceProfilePage, deleteDeviceProfile } from '/@/api/device/deviceManager';
  55 + import { deviceConfigGetQuery, deviceConfigDelete } from '/@/api/device/deviceConfigApi';
37 56 import { useModal } from '/@/components/Modal';
38 57 import DeviceProfileModal from '/@/views/device/profile/DeviceProfileModal.vue';
  58 + import DeviceConfigDetail from '/@/views/device/profile/deviceConfigDetail.vue';
  59 + // import { aoaToSheetXlsx } from '/@/components/Excel';
  60 + import { ImpExcel, ExcelData } from '/@/components/Excel';
  61 +
39 62 export default defineComponent({
40 63 name: 'DeviceProfileManagement',
41   - components: { BasicTable, DeviceProfileModal, TableAction },
  64 + components: { BasicTable, DeviceProfileModal, TableAction, ImpExcel, DeviceConfigDetail },
42 65 setup() {
  66 + let selectedRowKeys: string[] = reactive([]);
  67 + let isJudgeStatus = ref(true);
43 68 const { createMessage } = useMessage();
44 69 const [registerModal, { openModal }] = useModal();
45   - const [registerTable, { reload }] = useTable({
  70 + const [registerTable, { reload, getSelectRowKeys }] = useTable({
46 71 title: '设备配置列表',
47   - api: deviceProfilePage,
  72 + clickToRowSelect: false,
  73 + api: deviceConfigGetQuery,
48 74 columns,
49 75 formConfig: {
50 76 labelWidth: 120,
... ... @@ -62,10 +88,36 @@
62 88 },
63 89 });
64 90
  91 + const tableListRef = ref<
  92 + {
  93 + title: string;
  94 + columns?: any[];
  95 + dataSource?: any[];
  96 + }[]
  97 + >([]);
  98 +
  99 + function loadDataSuccess(excelDataList: ExcelData[]) {
  100 + tableListRef.value = [];
  101 + console.log(excelDataList);
  102 + for (const excelData of excelDataList) {
  103 + const {
  104 + header,
  105 + results,
  106 + meta: { sheetName },
  107 + } = excelData;
  108 + const columns: BasicColumn[] = [];
  109 + for (const title of header) {
  110 + columns.push({ title, dataIndex: title });
  111 + }
  112 + tableListRef.value.push({ title: sheetName, dataSource: results, columns });
  113 + }
  114 + }
  115 +
65 116 function handleCreate() {
66 117 openModal(true, {
67 118 isUpdate: false,
68 119 });
  120 + isJudgeStatus.value = true;
69 121 }
70 122
71 123 function handleEdit(record: Recordable) {
... ... @@ -73,20 +125,56 @@
73 125 record,
74 126 isUpdate: true,
75 127 });
  128 + isJudgeStatus.value = true;
  129 + }
  130 + const useSelectionChange = () => {
  131 + selectedRowKeys = getSelectRowKeys();
  132 + };
  133 + async function handleTableDel() {
  134 + await deviceConfigDelete(selectedRowKeys);
  135 + createMessage.success('删除成功');
  136 + // reload();
  137 + handleSuccess();
76 138 }
77 139
78 140 function handleDelete(record: Recordable) {
79 141 let ids = [record.id];
80   - deleteDeviceProfile(ids).then(() => {
  142 + deviceConfigDelete(ids).then(() => {
81 143 createMessage.success('删除设备配置成功');
82 144 handleSuccess();
83 145 });
84 146 }
85 147
  148 + async function handleDetailView(record: Recordable) {
  149 + openModal(true, {
  150 + record,
  151 + isUpdate: false,
  152 + });
  153 + isJudgeStatus.value = false;
  154 + }
  155 + function handleExport(record: Recordable) {
  156 + console.log(record);
  157 + // aoaToSheetXlsx({
  158 + // // data: record,
  159 + // // header: arrHeader,
  160 + // filename: '二维数组方式导出excel.xlsx',
  161 + // });
  162 + }
  163 + function handleImport() {
  164 + console.log('record');
  165 + }
86 166 function handleSuccess() {
87 167 reload();
88 168 }
89 169 return {
  170 + useSelectionChange,
  171 + handleTableDel,
  172 + isJudgeStatus,
  173 + tableListRef,
  174 + loadDataSuccess,
  175 + handleImport,
  176 + handleExport,
  177 + handleDetailView,
90 178 registerTable,
91 179 handleCreate,
92 180 handleEdit,
... ...
... ... @@ -34,18 +34,15 @@
34 34 resetFunc: customResetFunc,
35 35 submitFunc: customSubmitFunc,
36 36 });
37   -
38 37 async function customResetFunc() {
39 38 emit('prev');
40 39 }
41   -
42 40 async function customSubmitFunc() {
43 41 try {
44 42 const values = await validate();
45 43 emit('next', values);
46 44 } catch (error) {}
47 45 }
48   -
49 46 return { register };
50 47 },
51 48 });
... ...
... ... @@ -58,30 +58,11 @@
58 58 </template>
59 59 <div class="flex justify-start">
60 60 <a-button class="mr-5" @click="prevStep">上一步</a-button>
61   - <a-button type="primary" @click="addAlarmRule">添加报警规则</a-button>
62   - <a-button style="margin-left: 14px" @click="handleClickAddAlertContacts">下一步</a-button>
  61 + <a-button @click="handleFormStep3toStep4Next">下一步</a-button>
  62 + <a-button style="margin-left: 20px" type="primary" @click="addAlarmRule"
  63 + >添加报警规则</a-button
  64 + >
63 65 </div>
64   - <BasicModal
65   - v-if="statusModel"
66   - @register="registerAlert"
67   - v-bind="$attrs"
68   - :showCancelBtn="true"
69   - :showOkBtn="true"
70   - :canFullscreen="false"
71   - :closable="false"
72   - :height="900"
73   - :width="500"
74   - :maskClosable="false"
75   - title="告警通知"
76   - :helpMessage="['告警通知']"
77   - @ok="handleModal"
78   - >
79   - <div>
80   - <span>请选择告警通知联系人:</span>
81   - <Tag v-for="(item, index) in 10" closable @close="log" :key="index"> 冯涛+{{ item }}</Tag>
82   - </div>
83   - <AlertContacts ref="getAlertContactRef" />
84   - </BasicModal>
85 66 </div>
86 67 </template>
87 68
... ... @@ -98,9 +79,7 @@
98 79 PlusOutlined,
99 80 EditOutlined,
100 81 } from '@ant-design/icons-vue';
101   - import { Tooltip, Checkbox, Tag } from 'ant-design-vue';
102   - import AlertContacts from '../cpns/index.vue';
103   - import { BasicModal, useModal } from '/@/components/Modal';
  82 + import { Tooltip, Checkbox } from 'ant-design-vue';
104 83
105 84 export default defineComponent({
106 85 components: {
... ... @@ -113,12 +92,10 @@
113 92 EditOutlined,
114 93 Checkbox,
115 94 Tooltip,
116   - BasicModal,
117   - AlertContacts,
118   - Tag,
119 95 },
120   - emits: ['prev'],
  96 + emits: ['prev', 'next'],
121 97 setup(_, { emit }) {
  98 + const getAllFormData: any = ref({});
122 99 //告警列表
123 100 let alarmList = ref<alarmListItem[]>([]);
124 101 const log = (e) => {
... ... @@ -135,8 +112,8 @@
135 112 const addAlarmRule = () => {
136 113 unref(alarmList).push({
137 114 id: Date.now(),
138   - alarmType: '',
139   - isPass: false,
  115 + messageMode: '',
  116 + enabled: false,
140 117 createRule: [
141 118 {
142 119 id: Date.now() + Math.random(),
... ... @@ -152,7 +129,7 @@
152 129 };
153 130
154 131 // 表单部分 报警类型
155   - const [registerForm] = useForm({
  132 + const [registerForm, { validate: validateRegisterForm }] = useForm({
156 133 labelWidth: 120,
157 134 schemas: step3Schemas,
158 135 showResetButton: false,
... ... @@ -160,7 +137,7 @@
160 137 });
161 138
162 139 // 高级设置
163   - const [registerFormHighSetting] = useForm({
  140 + const [registerFormHighSetting, { validate: validateRegisterFormHighSetting }] = useForm({
164 141 labelWidth: 120,
165 142 schemas: step3HighSetting,
166 143 showResetButton: false,
... ... @@ -171,7 +148,7 @@
171 148 });
172 149
173 150 // 添加创建条件表单
174   - const [registerFormCreateAlarm] = useForm({
  151 + const [registerFormCreateAlarm, { validate: validateRegisterFormCreateAlarm }] = useForm({
175 152 labelWidth: 120,
176 153 schemas: step3CreateAlarm,
177 154 showResetButton: false,
... ... @@ -182,7 +159,7 @@
182 159 });
183 160
184 161 // 清除条件表单
185   - const [registerFormClearAlarm] = useForm({
  162 + const [registerFormClearAlarm, { validate: validateRegisterFormClearAlarm }] = useForm({
186 163 labelWidth: 120,
187 164 schemas: step3ClearAlarm,
188 165 showResetButton: false,
... ... @@ -208,22 +185,27 @@
208 185 alarmList.value[index].createRule.splice(createIndex, 1);
209 186 };
210 187
211   - const statusModel = ref(false);
212   - const [registerAlert, { openModal }] = useModal();
213   - const handleClickAddAlertContacts = () => {
214   - statusModel.value = true;
215   - openModal(statusModel.value);
216   - };
217   - const handleModal = () => {
218   - console.log(1);
  188 + const handleFormStep3toStep4Next = async () => {
  189 + try {
  190 + // const values = 1;
  191 + const valueRegisterForm = await validateRegisterForm();
  192 + const valueRegisterFormHighSetting = await validateRegisterFormHighSetting();
  193 + const valueRegisterFormCreateAlarm = await validateRegisterFormCreateAlarm();
  194 + const valueRegisterFormClearAlarm = await validateRegisterFormClearAlarm();
  195 + Object.assign(
  196 + getAllFormData.value,
  197 + valueRegisterForm,
  198 + valueRegisterFormHighSetting,
  199 + valueRegisterFormCreateAlarm,
  200 + valueRegisterFormClearAlarm
  201 + );
  202 + emit('next', getAllFormData.value);
  203 + } catch (error) {}
219 204 };
220 205
221 206 return {
222   - handleModal,
  207 + handleFormStep3toStep4Next,
223 208 log,
224   - statusModel,
225   - registerAlert,
226   - handleClickAddAlertContacts,
227 209 alarmList,
228 210 deleteAlarmRule,
229 211 prevStep,
... ...
1 1 <template>
2   - <div class="step3">
3   - <h1 v-if="alarmList.length === 0" style="font-size: 24px" class="text-center"
4   - >未配置报警规则</h1
5   - >
6   -
7   - <template v-else v-for="(item, index) in alarmList" :key="item">
8   - <CollapseContainer :title="item.alarmType" style="border: 1px solid #bfbfbf" class="mb-6">
9   - <template #action>
10   - <div @click="handleDeleteAlarm(index)" class="cursor-pointer">
11   - <DeleteOutlined style="font-size: 20px" class="mr-2" />
12   - </div>
13   - </template>
14   - <a-form :wrapper-col="wrapperCol" labelAlign="left" :model="item" :rules="rules">
15   - <a-form-item label="报警类型" :labelCol="{ style: { width: '80px' } }" name="alarmType">
16   - <a-input v-model:value="item.alarmType" />
17   - </a-form-item>
18   - </a-form>
19   -
20   - <CollapseContainer>
21   - <template #action> 高级设置 </template>
22   - <div class="flex" style="align-items: center">
23   - <input type="checkbox" v-model="item.isPass" /> <div class="ml-2">传递警报</div>
24   - </div>
25   -
26   - <a-form :wrapper-col="wrapperCol" labelAlign="left" v-if="item.isPass">
27   - <a-form-item label="传递的关联类型" :labelCol="{ style: { width: '120px' } }">
28   - <a-input />
29   - </a-form-item>
30   - </a-form>
31   - </CollapseContainer>
32   - <p style="color: #3c3c3c">创建报警规则</p>
33   - <template v-for="(item1, index1) in item.alarmRule" :key="item1">
34   - <div class="alarm-rule mb-4">
35   - <div style="width: 90%; border: 2px solid #8c8c8c; border-radius: 5px" class="flex">
36   - <div style="width: 30%; height: 100%; border-right: 1px solid #e0e0e0">
37   - <span style="color: #305680; margin-left: 10px">严重程度</span>
38   - <a-select :options="options" style="width: 100px; margin-left: 10px" />
39   - </div>
40   - <div style="width: 70%; height: 100%">
41   - <p style="color: #f5594e" class="mt-4 ml-4"
42   - >请添加报警规则条件
43   - <PlusOutlined
44   - class="cursor-pointer ml-4"
45   - style="font-size: 20px"
46   - @click="editAlarmCondition(index, index1)"
47   - /></p>
48   - <p class="mt-4 ml-4"
49   - >启用规则:始终启用
50   - <EditOutlined class="cursor-pointer ml-4" style="font-size: 20px"
51   - /></p>
52   - <p class="mt-4 ml-4"
53   - >详情:{{ item1.detail }}
54   - <EditOutlined
55   - @click="item1.detailVisible = true"
56   - class="cursor-pointer ml-4"
57   - style="font-size: 20px"
58   - /></p>
59   - <p class="mt-4 ml-4">dashboard: <a-select style="width: 180px" /></p>
60   - </div>
61   - </div>
62   - <div style="width: 10%" class="alarm-remove">
63   - <a-tooltip title="移除">
64   - <MinusCircleOutlined
65   - style="font-size: 25px color:#305680"
66   - class="cursor-pointer"
67   - @click="handleDeleteCondition(index, index1)"
68   - />
69   - </a-tooltip>
70   - </div>
71   - </div>
72   - <!-- 编辑报警规则条件 -->
73   - <a-modal
74   - v-model:visible="item1.alarmVisible"
75   - title="编辑报警规则条件"
76   - centered
77   - width="800px"
78   - @cancel="handleAlarmCancel(index, index1)"
79   - @ok="item1.alarmVisible = false"
80   - >
81   - <CollapseContainer title="键名筛选器" style="border: 1px solid #bfbfbf" class="mb-6">
82   - <a-modal
83   - v-model:visible="item1.addKeyFilterVisible"
84   - title="添加键名筛选器"
85   - centered
86   - width="600px"
87   - @ok="item1.addKeyFilterVisible = false"
88   - >
89   - <a-form
90   - :wrapper-col="wrapperCol"
91   - :labelCol="{ style: { width: '80px' } }"
92   - labelAlign="right"
93   - >
94   - <a-form-item label="键类型">
95   - <a-select :options="keyTypeOptions" default-value="Timeseries" />
96   - </a-form-item>
97   - <a-form-item label="键名">
98   - <a-input />
99   - </a-form-item>
100   - <a-form-item label="值类型">
101   - <a-select :options="valueTypeOptions" />
102   - </a-form-item>
103   - </a-form>
104   - <collapseContainer title="筛选器">
105   - <template v-for="filterItem in item1.filterList" :key="filterItem">
106   - <div class="flex justify-between mb-4" style="align-items: center">
107   - <a-select
108   - style="width: 150px"
109   - :options="operatorOptions"
110   - default-value="="
111   - /><a-input style="width: 350px" />
112   - <a-tooltip title="删除筛选器">
113   - <CloseOutlined @click="deleteFilter(index, index1)" />
114   - </a-tooltip>
115   - </div>
116   - </template>
117   - <div class="flex">
118   - <a-button type="primary" class="mr-4" @click="addFilter(index, index1)"
119   - >添加</a-button
120   - >
121   - <a-button type="primary">添加复合</a-button>
122   - </div>
123   - </collapseContainer>
124   - </a-modal>
125   - <div class="flex justify-start">
126   - <a-button type="primary" @click="item1.addKeyFilterVisible = true"
127   - >添加键名筛选器</a-button
128   - >
129   - </div>
130   - </CollapseContainer>
131   - <CollapseContainer title="筛选器预览" style="border: 1px solid #bfbfbf" class="mb-6" />
132   - </a-modal>
133   - <!-- 启用规则-->
134   - <!-- <a-modal
135   - v-model:visible="visible"
136   - title="编辑报警规则条件"
137   - centered
138   - @cancel="handleCancel(index, index1)"
139   - @ok="visible = false"
140   - >
141   - 编辑报警规则条件123
142   - </a-modal> -->
143   -
144   - <!-- 创建报警规则详情的弹框 -->
145   - <a-modal
146   - v-model:visible="item1.detailVisible"
147   - title="详情"
148   - centered
149   - @cancel="handleCancel(index, index1)"
150   - @ok="item1.detailVisible = false"
151   - >
152   - <a-textarea v-model:value="item1.detail" placeholder="报警详细信息" :rows="4" />
153   - </a-modal>
154   - </template>
155   - <a-button class="mt-5" @click="addCreateRole(index)"
156   - ><PlusCircleOutlined />添加创建条件</a-button
157   - >
158   - <p style="color: #3c3c3c">清除报警规则</p>
159   - <template v-for="(item2, index2) in item.removeRule" :key="item2">
160   - <div class="alarm-rule mb-4">
161   - <div style="width: 90%; border: 2px solid #8c8c8c; border-radius: 5px" class="flex">
162   - <div style="width: 70%; height: 100%">
163   - <p style="color: #f5594e" class="mt-4 ml-4"
164   - >请添加报警规则条件
165   - <PlusOutlined class="cursor-pointer ml-4" style="font-size: 20px"
166   - /></p>
167   - <p class="mt-4 ml-4"
168   - >启用规则:始终启用
169   - <EditOutlined class="cursor-pointer ml-4" style="font-size: 20px"
170   - /></p>
171   - <p class="mt-4 ml-4"
172   - >详情:{{ item2.detail }}
173   - <EditOutlined
174   - class="cursor-pointer ml-4"
175   - style="font-size: 20px"
176   - @click="editRemoveVisible = true"
177   - />
178   - </p>
179   -
180   - <p class="mt-4 ml-4">Mobile dashboard: <a-select style="width: 150px" /></p>
181   - </div>
182   - </div>
183   - <div style="width: 10%" class="alarm-remove">
184   - <a-tooltip title="移除">
185   - <MinusCircleOutlined
186   - style="font-size: 25px color:#305680"
187   - class="cursor-pointer"
188   - @click="handleDeleteRemoveCondition(index, index2)"
189   - />
190   - </a-tooltip>
191   - </div>
192   - </div>
193   - <a-modal
194   - v-model:visible="editRemoveVisible"
195   - title="详情"
196   - centered
197   - @cancel="handleCancel1(index, index2)"
198   - @ok="editRemoveVisible = false"
199   - >
200   - <a-textarea v-model:value="item2.detail" placeholder="报警详细信息" :rows="4" />
201   - </a-modal>
202   - </template>
203   - <a-button class="mt-5" @click="addRemoveRule(index)"
204   - ><PlusCircleOutlined />添加清除条件</a-button
205   - >
206   - </CollapseContainer>
207   - </template>
208   - <div class="flex justify-start">
209   - <a-button class="mr-5" @click="prevStep">上一步</a-button>
210   - <a-button type="primary" @click="addAlarmRule">添加报警规则</a-button>
211   - </div>
  2 + <div>
  3 + <span>请选择告警通知联系人:</span>
  4 + <Tag v-for="(item, index) in 15" closable :key="index"> 冯涛+{{ item }}</Tag>
  5 + <BasicForm :showSubmitButton="false" @register="register" />
212 6 </div>
213 7 </template>
214 8 <script lang="ts">
215 9 import { defineComponent, ref } from 'vue';
216   - import {
217   - Alert,
218   - Divider,
219   - Descriptions,
220   - Input,
221   - Form,
222   - FormItem,
223   - Button,
224   - Select,
225   - Tooltip,
226   - Textarea,
227   - Modal,
228   - } from 'ant-design-vue';
229   - import {
230   - DeleteOutlined,
231   - MinusCircleOutlined,
232   - PlusCircleOutlined,
233   - PlusOutlined,
234   - EditOutlined,
235   - CloseOutlined,
236   - } from '@ant-design/icons-vue';
237   - import { CollapseContainer } from '/@/components/Container/index';
238   - import { alarmListItem } from '../types/index';
  10 + import { Tag } from 'ant-design-vue';
  11 + import { BasicForm, useForm } from '/@/components/Form/index';
  12 + import { alertContactsSchemas } from '../cpns/config';
  13 +
239 14 export default defineComponent({
240 15 components: {
241   - DeleteOutlined,
242   - MinusCircleOutlined,
243   - PlusCircleOutlined,
244   - CollapseContainer,
245   - EditOutlined,
246   - PlusOutlined,
247   - CloseOutlined,
248   - [Form.name]: Form,
249   - [FormItem.name]: FormItem,
250   - [Modal.name]: Modal,
251   - [Textarea.name]: Textarea,
252   - [Tooltip.name]: Tooltip,
253   - [Button.name]: Button,
254   - [Input.name]: Input,
255   - [Select.name]: Select,
256   - [Form.name]: Form,
257   - [Form.Item.name]: Form.Item,
258   - [Alert.name]: Alert,
259   - [Divider.name]: Divider,
260   - [Descriptions.name]: Descriptions,
261   - [Descriptions.Item.name]: Descriptions.Item,
  16 + Tag,
  17 + BasicForm,
262 18 },
263 19 emits: ['prev'],
264 20 setup(_, { emit }) {
265   - const alarmList = ref<alarmListItem[]>([]);
266   -
267   - const options = ref([
268   - {
269   - value: '1',
270   - label: '危险',
271   - },
272   -
273   - {
274   - value: '2',
275   - label: '重要',
276   - },
277   - {
278   - value: '3',
279   - label: '次要',
280   - },
281   - {
282   - value: '4',
283   - label: '警告',
284   - },
285   - {
286   - value: '5',
287   - label: '不确定',
288   - },
289   - ]);
290   - const keyTypeOptions = ref([
291   - {
292   - value: 'properties',
293   - label: '属性',
294   - },
295   -
296   - {
297   - value: 'Timeseries',
298   - label: 'Timeseries',
299   - },
300   - {
301   - value: 'constant',
302   - label: '常量',
303   - },
304   - ]);
305   - const valueTypeOptions = ref([
306   - {
307   - value: 'string',
308   - label: '字符串',
309   - },
310   - {
311   - value: 'number',
312   - label: '数字',
313   - },
314   - {
315   - value: 'boolean',
316   - label: '布尔值',
317   - },
318   - {
319   - value: 'dateTime',
320   - label: '日期时间',
321   - },
322   - ]);
323   - const operatorOptions = ref([
324   - {
325   - value: '=',
326   - label: '等于',
327   - },
328   - {
329   - value: '!=',
330   - label: '不等于',
331   - },
332   - {
333   - value: '>',
334   - label: '大于',
335   - },
336   - {
337   - value: '<',
338   - label: '小于',
339   - },
340   - {
341   - value: '>=',
342   - label: '大于或等于',
343   - },
344   - {
345   - value: '<=',
346   - label: '小于或等于',
347   - },
348   - ]);
349   - const rules = {
350   - alarmType: [
351   - {
352   - required: true,
353   - message: '报警类型必填',
354   - trigger: 'blur',
355   - },
356   - ],
357   - };
358   -
359   - const prevStep = () => {
  21 + const getValueData: any = ref({});
  22 + const [register, { setProps, validate }] = useForm({
  23 + schemas: alertContactsSchemas,
  24 + actionColOptions: {
  25 + span: 24,
  26 + },
  27 + resetButtonOptions: {
  28 + text: '上一步',
  29 + },
  30 + resetFunc: customResetFunc,
  31 + });
  32 + async function customResetFunc() {
360 33 emit('prev');
361   - };
362   - // 添加报警规则
363   - const addAlarmRule = () => {
364   - alarmList.value.push({
365   - alarmType: '',
366   - isPass: false,
367   - createRule: [],
368   - clearRule: [],
369   - });
370   - };
371   - const handleDeleteAlarm = (index: number) => {
372   - alarmList.value.splice(index, 1);
373   - };
374   - // 添加‘创建条件’
375   - const addCreateRole = (index: number) => {
376   - alarmList.value[index].createRule.push({
377   - alarmVisible: false,
378   - addKeyFilterVisible: false,
379   - detailVisible: false,
380   - detail: '',
381   - filterList: [],
382   - });
383   - };
384   - const handleDeleteCondition = (index: number, index1: number) => {
385   - alarmList.value[index].createRule.splice(index1, 1);
386   - };
387   -
388   - // 添加‘清除报警规则’
389   - const addRemoveRule = (index: number) => {
390   - alarmList.value[index].clearRule.push({
391   - detail: '',
392   - });
393   - };
394   - const handleDeleteRemoveCondition = (index: number, index1: number) => {
395   - alarmList.value[index].clearRule.splice(index1, 1);
396   - };
397   -
398   - // 弹框取消事件 --2个
399   - const visible = ref(false);
400   - const editRemoveVisible = ref(false);
401   - const handleCancel = (index: number, index1: number) => {
402   - alarmList.value[index].createRule[index1].detail = '';
403   - alarmList.value[index].createRule[index1].detailVisible = false;
404   - };
405   -
406   - const handleCancel1 = (index: number, index2: number) => {
407   - alarmList.value[index].clearRule[index2].detail = '';
408   - editRemoveVisible.value = false;
409   - };
410   -
411   - const handleAlarmCancel = (index, index1) => {
412   - alarmList.value[index].createRule[index1].alarmVisible = false;
413   - console.log('object---');
414   - };
415   - const editAlarmCondition = (index, index1) => {
416   - alarmList.value[index].createRule[index1].alarmVisible = true;
417   - console.log('object');
418   - };
419   - // 添加键名筛选器
420   - const addFilter = (index, index1) => {
421   - console.log(index, index1);
422   - alarmList.value[index].createRule[index1].filterList?.push({
423   - operator: '=',
424   - value: '',
425   - });
426   - };
427   - const deleteFilter = (index: number, index1: number) => {
428   - alarmList.value[index].createRule[index1].filterList?.splice(index1, 1);
429   - };
  34 + }
  35 + async function getAllFields(getV) {
  36 + const values = await validate();
  37 + getValueData.value = values;
  38 + getV = getValueData.value;
  39 + return getV;
  40 + }
430 41 return {
431   - rules,
432   - alarmList,
433   - options,
434   - visible,
435   - editRemoveVisible,
436   - prevStep,
437   - addAlarmRule,
438   - addCreateRole,
439   - handleDeleteAlarm,
440   - handleDeleteCondition,
441   - addRemoveRule,
442   - handleDeleteRemoveCondition,
443   - handleCancel,
444   - handleCancel1,
445   - handleAlarmCancel,
446   - editAlarmCondition,
447   - keyTypeOptions,
448   - valueTypeOptions,
449   - operatorOptions,
450   - deleteFilter,
451   - addFilter,
452   - labelCol: { style: { width: '150px' } },
453   - wrapperCol: { span: 18 },
  42 + customResetFunc,
  43 + getAllFields,
  44 + register,
  45 + setProps,
454 46 };
455 47 },
456 48 });
457 49 </script>
458   -<style lang="less" scoped>
459   - .step3 {
460   - width: 500px;
461   - margin: 0 auto;
462   - }
463   - .alarm-rule {
464   - height: 200px;
465   - display: flex;
466   - .alarm-remove {
467   - display: flex;
468   - justify-content: center;
469   - align-items: center;
470   - }
471   - }
472   -</style>
... ...
  1 +<template>
  2 + <div class="step3">
  3 + <h1 v-if="alarmList.length === 0" style="font-size: 24px" class="text-center"
  4 + >未配置报警规则</h1
  5 + >
  6 +
  7 + <template v-else v-for="(item, index) in alarmList" :key="item">
  8 + <CollapseContainer :title="item.alarmType" style="border: 1px solid #bfbfbf" class="mb-6">
  9 + <template #action>
  10 + <div @click="handleDeleteAlarm(index)" class="cursor-pointer">
  11 + <DeleteOutlined style="font-size: 20px" class="mr-2" />
  12 + </div>
  13 + </template>
  14 + <a-form :wrapper-col="wrapperCol" labelAlign="left" :model="item" :rules="rules">
  15 + <a-form-item label="报警类型" :labelCol="{ style: { width: '80px' } }" name="alarmType">
  16 + <a-input v-model:value="item.alarmType" />
  17 + </a-form-item>
  18 + </a-form>
  19 +
  20 + <CollapseContainer>
  21 + <template #action> 高级设置 </template>
  22 + <div class="flex" style="align-items: center">
  23 + <input type="checkbox" v-model="item.isPass" /> <div class="ml-2">传递警报</div>
  24 + </div>
  25 +
  26 + <a-form :wrapper-col="wrapperCol" labelAlign="left" v-if="item.isPass">
  27 + <a-form-item label="传递的关联类型" :labelCol="{ style: { width: '120px' } }">
  28 + <a-input />
  29 + </a-form-item>
  30 + </a-form>
  31 + </CollapseContainer>
  32 + <p style="color: #3c3c3c">创建报警规则</p>
  33 + <template v-for="(item1, index1) in item.alarmRule" :key="item1">
  34 + <div class="alarm-rule mb-4">
  35 + <div style="width: 90%; border: 2px solid #8c8c8c; border-radius: 5px" class="flex">
  36 + <div style="width: 30%; height: 100%; border-right: 1px solid #e0e0e0">
  37 + <span style="color: #305680; margin-left: 10px">严重程度</span>
  38 + <a-select :options="options" style="width: 100px; margin-left: 10px" />
  39 + </div>
  40 + <div style="width: 70%; height: 100%">
  41 + <p style="color: #f5594e" class="mt-4 ml-4"
  42 + >请添加报警规则条件
  43 + <PlusOutlined
  44 + class="cursor-pointer ml-4"
  45 + style="font-size: 20px"
  46 + @click="editAlarmCondition(index, index1)"
  47 + /></p>
  48 + <p class="mt-4 ml-4"
  49 + >启用规则:始终启用
  50 + <EditOutlined class="cursor-pointer ml-4" style="font-size: 20px"
  51 + /></p>
  52 + <p class="mt-4 ml-4"
  53 + >详情:{{ item1.detail }}
  54 + <EditOutlined
  55 + @click="item1.detailVisible = true"
  56 + class="cursor-pointer ml-4"
  57 + style="font-size: 20px"
  58 + /></p>
  59 + <p class="mt-4 ml-4">dashboard: <a-select style="width: 180px" /></p>
  60 + </div>
  61 + </div>
  62 + <div style="width: 10%" class="alarm-remove">
  63 + <a-tooltip title="移除">
  64 + <MinusCircleOutlined
  65 + style="font-size: 25px color:#305680"
  66 + class="cursor-pointer"
  67 + @click="handleDeleteCondition(index, index1)"
  68 + />
  69 + </a-tooltip>
  70 + </div>
  71 + </div>
  72 + <!-- 编辑报警规则条件 -->
  73 + <a-modal
  74 + v-model:visible="item1.alarmVisible"
  75 + title="编辑报警规则条件"
  76 + centered
  77 + width="800px"
  78 + @cancel="handleAlarmCancel(index, index1)"
  79 + @ok="item1.alarmVisible = false"
  80 + >
  81 + <CollapseContainer title="键名筛选器" style="border: 1px solid #bfbfbf" class="mb-6">
  82 + <a-modal
  83 + v-model:visible="item1.addKeyFilterVisible"
  84 + title="添加键名筛选器"
  85 + centered
  86 + width="600px"
  87 + @ok="item1.addKeyFilterVisible = false"
  88 + >
  89 + <a-form
  90 + :wrapper-col="wrapperCol"
  91 + :labelCol="{ style: { width: '80px' } }"
  92 + labelAlign="right"
  93 + >
  94 + <a-form-item label="键类型">
  95 + <a-select :options="keyTypeOptions" default-value="Timeseries" />
  96 + </a-form-item>
  97 + <a-form-item label="键名">
  98 + <a-input />
  99 + </a-form-item>
  100 + <a-form-item label="值类型">
  101 + <a-select :options="valueTypeOptions" />
  102 + </a-form-item>
  103 + </a-form>
  104 + <collapseContainer title="筛选器">
  105 + <template v-for="filterItem in item1.filterList" :key="filterItem">
  106 + <div class="flex justify-between mb-4" style="align-items: center">
  107 + <a-select
  108 + style="width: 150px"
  109 + :options="operatorOptions"
  110 + default-value="="
  111 + /><a-input style="width: 350px" />
  112 + <a-tooltip title="删除筛选器">
  113 + <CloseOutlined @click="deleteFilter(index, index1)" />
  114 + </a-tooltip>
  115 + </div>
  116 + </template>
  117 + <div class="flex">
  118 + <a-button type="primary" class="mr-4" @click="addFilter(index, index1)"
  119 + >添加</a-button
  120 + >
  121 + <a-button type="primary">添加复合</a-button>
  122 + </div>
  123 + </collapseContainer>
  124 + </a-modal>
  125 + <div class="flex justify-start">
  126 + <a-button type="primary" @click="item1.addKeyFilterVisible = true"
  127 + >添加键名筛选器</a-button
  128 + >
  129 + </div>
  130 + </CollapseContainer>
  131 + <CollapseContainer title="筛选器预览" style="border: 1px solid #bfbfbf" class="mb-6" />
  132 + </a-modal>
  133 + <!-- 启用规则-->
  134 + <!-- <a-modal
  135 + v-model:visible="visible"
  136 + title="编辑报警规则条件"
  137 + centered
  138 + @cancel="handleCancel(index, index1)"
  139 + @ok="visible = false"
  140 + >
  141 + 编辑报警规则条件123
  142 + </a-modal> -->
  143 +
  144 + <!-- 创建报警规则详情的弹框 -->
  145 + <a-modal
  146 + v-model:visible="item1.detailVisible"
  147 + title="详情"
  148 + centered
  149 + @cancel="handleCancel(index, index1)"
  150 + @ok="item1.detailVisible = false"
  151 + >
  152 + <a-textarea v-model:value="item1.detail" placeholder="报警详细信息" :rows="4" />
  153 + </a-modal>
  154 + </template>
  155 + <a-button class="mt-5" @click="addCreateRole(index)"
  156 + ><PlusCircleOutlined />添加创建条件</a-button
  157 + >
  158 + <p style="color: #3c3c3c">清除报警规则</p>
  159 + <template v-for="(item2, index2) in item.removeRule" :key="item2">
  160 + <div class="alarm-rule mb-4">
  161 + <div style="width: 90%; border: 2px solid #8c8c8c; border-radius: 5px" class="flex">
  162 + <div style="width: 70%; height: 100%">
  163 + <p style="color: #f5594e" class="mt-4 ml-4"
  164 + >请添加报警规则条件
  165 + <PlusOutlined class="cursor-pointer ml-4" style="font-size: 20px"
  166 + /></p>
  167 + <p class="mt-4 ml-4"
  168 + >启用规则:始终启用
  169 + <EditOutlined class="cursor-pointer ml-4" style="font-size: 20px"
  170 + /></p>
  171 + <p class="mt-4 ml-4"
  172 + >详情:{{ item2.detail }}
  173 + <EditOutlined
  174 + class="cursor-pointer ml-4"
  175 + style="font-size: 20px"
  176 + @click="editRemoveVisible = true"
  177 + />
  178 + </p>
  179 +
  180 + <p class="mt-4 ml-4">Mobile dashboard: <a-select style="width: 150px" /></p>
  181 + </div>
  182 + </div>
  183 + <div style="width: 10%" class="alarm-remove">
  184 + <a-tooltip title="移除">
  185 + <MinusCircleOutlined
  186 + style="font-size: 25px color:#305680"
  187 + class="cursor-pointer"
  188 + @click="handleDeleteRemoveCondition(index, index2)"
  189 + />
  190 + </a-tooltip>
  191 + </div>
  192 + </div>
  193 + <a-modal
  194 + v-model:visible="editRemoveVisible"
  195 + title="详情"
  196 + centered
  197 + @cancel="handleCancel1(index, index2)"
  198 + @ok="editRemoveVisible = false"
  199 + >
  200 + <a-textarea v-model:value="item2.detail" placeholder="报警详细信息" :rows="4" />
  201 + </a-modal>
  202 + </template>
  203 + <a-button class="mt-5" @click="addRemoveRule(index)"
  204 + ><PlusCircleOutlined />添加清除条件</a-button
  205 + >
  206 + </CollapseContainer>
  207 + </template>
  208 + <div class="flex justify-start">
  209 + <a-button class="mr-5" @click="prevStep">上一步</a-button>
  210 + <a-button type="primary" @click="addAlarmRule">添加报警规则</a-button>
  211 + </div>
  212 + </div>
  213 +</template>
  214 +<script lang="ts">
  215 + import { defineComponent, ref } from 'vue';
  216 + import {
  217 + Alert,
  218 + Divider,
  219 + Descriptions,
  220 + Input,
  221 + Form,
  222 + FormItem,
  223 + Button,
  224 + Select,
  225 + Tooltip,
  226 + Textarea,
  227 + Modal,
  228 + } from 'ant-design-vue';
  229 + import {
  230 + DeleteOutlined,
  231 + MinusCircleOutlined,
  232 + PlusCircleOutlined,
  233 + PlusOutlined,
  234 + EditOutlined,
  235 + CloseOutlined,
  236 + } from '@ant-design/icons-vue';
  237 + import { CollapseContainer } from '/@/components/Container/index';
  238 + import { alarmListItem } from '../types/index';
  239 + export default defineComponent({
  240 + components: {
  241 + DeleteOutlined,
  242 + MinusCircleOutlined,
  243 + PlusCircleOutlined,
  244 + CollapseContainer,
  245 + EditOutlined,
  246 + PlusOutlined,
  247 + CloseOutlined,
  248 + [Form.name]: Form,
  249 + [FormItem.name]: FormItem,
  250 + [Modal.name]: Modal,
  251 + [Textarea.name]: Textarea,
  252 + [Tooltip.name]: Tooltip,
  253 + [Button.name]: Button,
  254 + [Input.name]: Input,
  255 + [Select.name]: Select,
  256 + [Form.name]: Form,
  257 + [Form.Item.name]: Form.Item,
  258 + [Alert.name]: Alert,
  259 + [Divider.name]: Divider,
  260 + [Descriptions.name]: Descriptions,
  261 + [Descriptions.Item.name]: Descriptions.Item,
  262 + },
  263 + emits: ['prev'],
  264 + setup(_, { emit }) {
  265 + const alarmList = ref<alarmListItem[]>([]);
  266 +
  267 + const options = ref([
  268 + {
  269 + value: '1',
  270 + label: '危险',
  271 + },
  272 +
  273 + {
  274 + value: '2',
  275 + label: '重要',
  276 + },
  277 + {
  278 + value: '3',
  279 + label: '次要',
  280 + },
  281 + {
  282 + value: '4',
  283 + label: '警告',
  284 + },
  285 + {
  286 + value: '5',
  287 + label: '不确定',
  288 + },
  289 + ]);
  290 + const keyTypeOptions = ref([
  291 + {
  292 + value: 'properties',
  293 + label: '属性',
  294 + },
  295 +
  296 + {
  297 + value: 'Timeseries',
  298 + label: 'Timeseries',
  299 + },
  300 + {
  301 + value: 'constant',
  302 + label: '常量',
  303 + },
  304 + ]);
  305 + const valueTypeOptions = ref([
  306 + {
  307 + value: 'string',
  308 + label: '字符串',
  309 + },
  310 + {
  311 + value: 'number',
  312 + label: '数字',
  313 + },
  314 + {
  315 + value: 'boolean',
  316 + label: '布尔值',
  317 + },
  318 + {
  319 + value: 'dateTime',
  320 + label: '日期时间',
  321 + },
  322 + ]);
  323 + const operatorOptions = ref([
  324 + {
  325 + value: '=',
  326 + label: '等于',
  327 + },
  328 + {
  329 + value: '!=',
  330 + label: '不等于',
  331 + },
  332 + {
  333 + value: '>',
  334 + label: '大于',
  335 + },
  336 + {
  337 + value: '<',
  338 + label: '小于',
  339 + },
  340 + {
  341 + value: '>=',
  342 + label: '大于或等于',
  343 + },
  344 + {
  345 + value: '<=',
  346 + label: '小于或等于',
  347 + },
  348 + ]);
  349 + const rules = {
  350 + alarmType: [
  351 + {
  352 + required: true,
  353 + message: '报警类型必填',
  354 + trigger: 'blur',
  355 + },
  356 + ],
  357 + };
  358 +
  359 + const prevStep = () => {
  360 + emit('prev');
  361 + };
  362 + // 添加报警规则
  363 + const addAlarmRule = () => {
  364 + alarmList.value.push({
  365 + alarmType: '',
  366 + isPass: false,
  367 + createRule: [],
  368 + clearRule: [],
  369 + });
  370 + };
  371 + const handleDeleteAlarm = (index: number) => {
  372 + alarmList.value.splice(index, 1);
  373 + };
  374 + // 添加‘创建条件’
  375 + const addCreateRole = (index: number) => {
  376 + alarmList.value[index].createRule.push({
  377 + alarmVisible: false,
  378 + addKeyFilterVisible: false,
  379 + detailVisible: false,
  380 + detail: '',
  381 + filterList: [],
  382 + });
  383 + };
  384 + const handleDeleteCondition = (index: number, index1: number) => {
  385 + alarmList.value[index].createRule.splice(index1, 1);
  386 + };
  387 +
  388 + // 添加‘清除报警规则’
  389 + const addRemoveRule = (index: number) => {
  390 + alarmList.value[index].clearRule.push({
  391 + detail: '',
  392 + });
  393 + };
  394 + const handleDeleteRemoveCondition = (index: number, index1: number) => {
  395 + alarmList.value[index].clearRule.splice(index1, 1);
  396 + };
  397 +
  398 + // 弹框取消事件 --2个
  399 + const visible = ref(false);
  400 + const editRemoveVisible = ref(false);
  401 + const handleCancel = (index: number, index1: number) => {
  402 + alarmList.value[index].createRule[index1].detail = '';
  403 + alarmList.value[index].createRule[index1].detailVisible = false;
  404 + };
  405 +
  406 + const handleCancel1 = (index: number, index2: number) => {
  407 + alarmList.value[index].clearRule[index2].detail = '';
  408 + editRemoveVisible.value = false;
  409 + };
  410 +
  411 + const handleAlarmCancel = (index, index1) => {
  412 + alarmList.value[index].createRule[index1].alarmVisible = false;
  413 + console.log('object---');
  414 + };
  415 + const editAlarmCondition = (index, index1) => {
  416 + alarmList.value[index].createRule[index1].alarmVisible = true;
  417 + console.log('object');
  418 + };
  419 + // 添加键名筛选器
  420 + const addFilter = (index, index1) => {
  421 + console.log(index, index1);
  422 + alarmList.value[index].createRule[index1].filterList?.push({
  423 + operator: '=',
  424 + value: '',
  425 + });
  426 + };
  427 + const deleteFilter = (index: number, index1: number) => {
  428 + alarmList.value[index].createRule[index1].filterList?.splice(index1, 1);
  429 + };
  430 + return {
  431 + rules,
  432 + alarmList,
  433 + options,
  434 + visible,
  435 + editRemoveVisible,
  436 + prevStep,
  437 + addAlarmRule,
  438 + addCreateRole,
  439 + handleDeleteAlarm,
  440 + handleDeleteCondition,
  441 + addRemoveRule,
  442 + handleDeleteRemoveCondition,
  443 + handleCancel,
  444 + handleCancel1,
  445 + handleAlarmCancel,
  446 + editAlarmCondition,
  447 + keyTypeOptions,
  448 + valueTypeOptions,
  449 + operatorOptions,
  450 + deleteFilter,
  451 + addFilter,
  452 + labelCol: { style: { width: '150px' } },
  453 + wrapperCol: { span: 18 },
  454 + };
  455 + },
  456 + });
  457 +</script>
  458 +<style lang="less" scoped>
  459 + .step3 {
  460 + width: 500px;
  461 + margin: 0 auto;
  462 + }
  463 + .alarm-rule {
  464 + height: 200px;
  465 + display: flex;
  466 + .alarm-remove {
  467 + display: flex;
  468 + justify-content: center;
  469 + align-items: center;
  470 + }
  471 + }
  472 +</style>
... ...
1 1 import { FormSchema } from '/@/components/Form';
2 2 import { findDictItemByCode } from '/@/api/system/dict';
  3 +import { getOrganizationList } from '/@/api/system/system';
  4 +import { copyTransFun } from '/@/utils/fnUtils';
  5 +import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi';
3 6
4 7 export const step1Schemas: FormSchema[] = [
5 8 {
... ... @@ -12,7 +15,30 @@ export const step1Schemas: FormSchema[] = [
12 15 },
13 16 },
14 17 {
15   - field: 'deviceType',
  18 + required: true,
  19 + field: 'organizationId',
  20 + label: '请选择组织',
  21 + component: 'ApiTreeSelect',
  22 + componentProps: {
  23 + api: async () => {
  24 + const data = await getOrganizationList();
  25 + copyTransFun(data as any as any[]);
  26 + return data;
  27 + },
  28 + },
  29 + },
  30 + {
  31 + field: 'defaultRuleChainId',
  32 + label: '请选择规则链',
  33 + component: 'ApiSelect',
  34 + componentProps: {
  35 + api: deviceConfigGetRuleChain,
  36 + labelField: 'name',
  37 + valueField: 'type',
  38 + },
  39 + },
  40 + {
  41 + field: 'defaultConfig',
16 42 label: '队列优先级',
17 43 component: 'ApiSelect',
18 44 componentProps: {
... ... @@ -25,8 +51,8 @@ export const step1Schemas: FormSchema[] = [
25 51 },
26 52 },
27 53 {
28   - label: '备注',
29   - field: 'remark',
  54 + label: '描述',
  55 + field: 'description',
30 56 component: 'InputTextArea',
31 57 },
32 58 ];
... ... @@ -36,16 +62,39 @@ export const step2Schemas: FormSchema[] = [
36 62 field: 'transportType',
37 63 component: 'Select',
38 64 label: '传输方式',
39   - defaultValue: 'DEFAULT',
  65 + defaultValue: 'COAP',
  66 + componentProps: {
  67 + options: [
  68 + { label: 'MQTT', value: 'MQTT' },
  69 + { label: 'TCP', value: 'TCP' },
  70 + { label: 'COAP', value: 'COAP' },
  71 + ],
  72 + },
  73 + },
  74 + {
  75 + field: 'Topic',
  76 + component: 'Input',
  77 + label: 'Topic',
40 78 componentProps: {
41   - options: [{ label: '默认', value: 'DEFAULT' }],
  79 + placeholder: '请输入',
  80 + },
  81 + },
  82 + {
  83 + field: 'Payload',
  84 + component: 'Select',
  85 + label: 'Payload',
  86 + componentProps: {
  87 + options: [
  88 + { label: 'JSON', value: 'DEFAULT' },
  89 + { label: 'Protobuf', value: 'DEFAULT' },
  90 + ],
42 91 },
43 92 },
44 93 ];
45 94
46 95 export const step3Schemas: FormSchema[] = [
47 96 {
48   - field: 'transportType',
  97 + field: 'description',
49 98 component: 'Input',
50 99 label: '报警类型',
51 100 required: true,
... ... @@ -57,19 +106,19 @@ export const step3Schemas: FormSchema[] = [
57 106
58 107 export const step3HighSetting: FormSchema[] = [
59 108 {
60   - field: 'isPass',
  109 + field: 'enabled',
61 110 component: 'Checkbox',
62 111 label: '',
63 112 slot: 'checkBox',
64 113 },
65 114 {
66   - field: 'associationType',
  115 + field: 'messageMode',
67 116 component: 'Input',
68 117 label: '关联类型',
69 118 componentProps: {
70 119 placeholder: '要传递的关联类型',
71 120 },
72   - ifShow: ({ values }) => !!values.isPass,
  121 + ifShow: ({ values }) => !!values.enabled,
73 122 },
74 123 ];
75 124
... ...
... ... @@ -15,8 +15,8 @@ interface clearRule {
15 15 }
16 16 export interface alarmListItem {
17 17 id: number;
18   - alarmType: string;
19   - isPass: boolean;
  18 + messageMode: string;
  19 + enabled: boolean;
20 20 createRule: createRule[];
21 21 clearRule: clearRule[];
22 22 }
... ...
... ... @@ -73,14 +73,16 @@ export const searchFormSchema: FormSchema[] = [
73 73 {
74 74 field: 'messageType',
75 75 label: '消息类型',
76   - component: 'Select',
  76 + required: true,
  77 + component: 'ApiSelect',
77 78 componentProps: {
78   - options: [
79   - { label: '短信', value: 'PHONE_MESSAGE' },
80   - { label: '邮件', value: 'EMAIL_MESSAGE' },
81   - ],
  79 + api: findDictItemByCode,
  80 + params: {
  81 + dictCode: 'message_type',
  82 + },
  83 + labelField: 'itemText',
  84 + valueField: 'itemValue',
82 85 },
83   - colProps: { span: 8 },
84 86 },
85 87 {
86 88 field: 'status',
... ...
... ... @@ -101,7 +101,6 @@
101 101
102 102 const useSelectionChange = () => {
103 103 selectedRowKeys = getSelectRowKeys();
104   - selectedRowKeys.join(',');
105 104 };
106 105
107 106 async function handleToolbarDel() {
... ... @@ -124,7 +123,7 @@
124 123 isJudgeStatus.value = true;
125 124 }
126 125 async function handleDelete(record: Recordable) {
127   - let ids = record.id;
  126 + let ids = [record.id];
128 127 await notifyDeleteApi(ids);
129 128 createMessage.success('删除成功');
130 129 reload();
... ...