Commit 1d9b7b7472c60f573bd98f185bc2b363625493a5

Authored by sqy
1 parent 18eaea55

'首页开发'

... ... @@ -15,7 +15,7 @@ enum API {
15 15
16 16 // 获取
17 17 export const getAlarmContact = (params: ContactPageParams) => {
18   - return getPageData<ContactModal>(params, Api.alarmContact);
  18 + return getPageData<ContactModal>(params, API.alarmContact);
19 19 };
20 20
21 21 // 新增
... ... @@ -48,6 +48,7 @@ export const saveOrEditAlarmContact = (params: ContactInfo, isUpdate: boolean) =
48 48 addAlarmContact(params);
49 49 };
50 50
  51 +// 查询设备分页数据
51 52 export const devicePage = (params: DeviceQueryParam) => {
52 53 return defHttp.get<DeviceModel>({
53 54 url: API.devicePage,
... ...
... ... @@ -33,6 +33,7 @@
33 33 'https://api.map.baidu.com/getscript?v=3.0&ak=7uOPPyAHn2Y2ZryeQqHtcRqtIY374vKa';
34 34 const wrapRef = ref<HTMLDivElement | null>(null);
35 35 const { toPromise } = useScript({ src: BAI_DU_MAP_URL });
  36 +
36 37 async function initMap() {
37 38 await toPromise();
38 39 await nextTick();
... ...
1 1 <template>
2 2 <div class="md:flex">
3 3 <template v-for="(item, index) in growCardList" :key="item.title">
4   - <Card
5   - size="small"
6   - :loading="$attrs.loading"
7   - :title="item.title"
8   - class="md:w-1/4 w-full !md:mt-0 !mt-4"
9   - :class="[index + 1 < 4 && '!md:mr-4']"
10   - :canExpan="false"
  4 + <div
  5 + class="growCardItem md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4"
  6 + :class="[index + 1 < growCardList.length && '!md:mr-4']"
11 7 >
12   - <template #extra>
13   - <Tag :color="item.color">{{ item.action }}</Tag>
14   - </template>
15   -
16   - <div class="py-4 px-4 flex justify-between">
17   - <CountTo prefix="$" :startVal="1" :endVal="item.value" class="text-2xl" />
18   - <Icon :icon="item.icon" :size="40" />
  8 + <div class="growCardItem-top">
  9 + <img :src="item.imgUrl" style="width: 90px; height: 90px" />
  10 + <div class="growCardItem-right">
  11 + <div class="flex justify-between ml-3">
  12 + <div style="font-size: 26px; color: #333">{{ item.value }}</div>
  13 + <img src="../../../../assets/images/tip.png" style="width: 20px; height: 20px" />
  14 + </div>
  15 + <div class="ml-3">{{ item.title }}</div>
  16 + <div class="ml-3 mt-3 flex" v-if="item.offLine">
  17 + <div class="count">
  18 + <img src="../../../../assets/images/online.png" style="width: 10px; height: 10px" />
  19 + 在线 {{ item.onLine }}
  20 + </div>
  21 + <div class="count">
  22 + <img src="../../../../assets/images/offline.png" alt="" />
  23 + 离线 {{ item.offLine }}
  24 + </div>
  25 + <div class="count">
  26 + <img src="../../../../assets/images/inactive.png" alt="" />
  27 + 未激活 {{ item.inactive }}
  28 + </div>
  29 + </div>
  30 + </div>
19 31 </div>
20 32
21   - <div class="p-2 px-4 flex justify-between">
22   - <span>总{{ item.title }}</span>
23   - <CountTo prefix="$" :startVal="1" :endVal="item.total" />
24   - </div>
25   - </Card>
  33 + <div class="growCardItem-bottom"> 今日新增 {{ item.newDay }}</div>
  34 + </div>
26 35 </template>
27 36 </div>
28 37 </template>
29 38 <script lang="ts" setup>
30   - import { CountTo } from '/@/components/CountTo/index';
31   - import { Icon } from '/@/components/Icon';
32   - import { Tag, Card } from 'ant-design-vue';
33 39 import { growCardList } from '../data';
34 40 </script>
  41 +
  42 +<style scoped lang="less">
  43 + .growCardItem {
  44 + height: 179px;
  45 + background-color: #fff;
  46 + color: 666;
  47 + .growCardItem-top {
  48 + display: flex;
  49 + margin: 20px;
  50 + border-bottom: 1px solid #f2f2f5;
  51 + padding-bottom: 10px;
  52 + .growCardItem-right {
  53 + width: 300px;
  54 + .count {
  55 + display: flex;
  56 + font-size: 12px;
  57 + align-items: center;
  58 + margin-left: 8px;
  59 + }
  60 + }
  61 + }
  62 + .growCardItem-bottom {
  63 + margin-left: 20px;
  64 + }
  65 + }
  66 +</style>
... ...
  1 +<template>
  2 + <Card title="帮助文档">
  3 + <div>
  4 + <template v-for="item in helpDoc" :key="item.title">
  5 + <AnchorLink v-bind="item" />
  6 + </template>
  7 + </div>
  8 + <Card
  9 + :tab-list="tabListTitle"
  10 + v-bind="$attrs"
  11 + :active-tab-key="activeKey"
  12 + :bordered="false"
  13 + @tabChange="onTabChange"
  14 + :bodyStyle="{ padding: 0 }"
  15 + >
  16 + <div v-if="activeKey === 'tab1'">
  17 + <List item-layout="horizontal" :data-source="data">
  18 + <template #renderItem="{ item }">
  19 + <ListItem>
  20 + <ListItemMeta description="有新的告警数据需要处理,现在就去查看吧">
  21 + <template #title>
  22 + <a href="https://www.antdv.com/">{{ item.title }}</a>
  23 + </template>
  24 + <template #avatar>
  25 + <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
  26 + </template>
  27 + </ListItemMeta>
  28 + <template #extra> 7小时前 </template>
  29 + </ListItem>
  30 + </template>
  31 + </List>
  32 + </div>
  33 + <div v-else>222</div>
  34 + </Card>
  35 + <Card hoverable title="联系我们" :bordered="false">
  36 + <template #cover>
  37 + <QrCode :value="qrCodeUrl" />
  38 + </template>
  39 + <CardMeta>
  40 + <template #description>
  41 + <p>联系人: 张三</p>
  42 + <p>联系电话: 15912341234</p>
  43 + <p>联系地址: 四川省成都市剑南大道北段中1533号 </p>
  44 + </template>
  45 + </CardMeta>
  46 + </Card>
  47 + </Card>
  48 +</template>
  49 +
  50 +<script lang="ts">
  51 + import { defineComponent, ref, unref } from 'vue';
  52 + import { Card, AnchorLink, List, ListItem, ListItemMeta, Avatar, CardMeta } from 'ant-design-vue';
  53 + import { QrCode, QrCodeActionType } from '/@/components/Qrcode/index';
  54 + export default defineComponent({
  55 + components: {
  56 + Card,
  57 + AnchorLink,
  58 + List,
  59 + ListItem,
  60 + ListItemMeta,
  61 + Avatar,
  62 + CardMeta,
  63 + QrCode,
  64 + },
  65 + setup() {
  66 + const helpDoc = ref([
  67 + {
  68 + title: '如何接入设备?',
  69 + href: '',
  70 + },
  71 + {
  72 + title: '什么是设备配置?',
  73 + href: '',
  74 + },
  75 + {
  76 + title: '云组态模板如何使用?',
  77 + href: '',
  78 + },
  79 + {
  80 + title: '查看全部>>',
  81 + href: '',
  82 + },
  83 + ]);
  84 +
  85 + const activeKey = ref('tab1');
  86 + const tabListTitle = [
  87 + {
  88 + key: 'tab1',
  89 + tab: '通知公告',
  90 + },
  91 + {
  92 + key: 'tab2',
  93 + tab: '系统公告',
  94 + },
  95 + ];
  96 + const onTabChange = (key) => {
  97 + activeKey.value = key;
  98 + };
  99 +
  100 + // 列表
  101 + interface DataItem {
  102 + title: string;
  103 + }
  104 + const data: DataItem[] = [
  105 + {
  106 + title: '企业管理员',
  107 + },
  108 + {
  109 + title: '企业管理员',
  110 + },
  111 + {
  112 + title: '管理员',
  113 + },
  114 + {
  115 + title: '管理员',
  116 + },
  117 + {
  118 + title: '管理员',
  119 + },
  120 + ];
  121 +
  122 + const qrRef = ref<Nullable<QrCodeActionType>>(null);
  123 + const qrCodeUrl = 'https://www.vvbin.cn';
  124 + const download = () => {
  125 + const qrEl = unref(qrRef);
  126 + if (!qrEl) return;
  127 + qrEl.download('文件名');
  128 + };
  129 +
  130 + return {
  131 + activeKey,
  132 + tabListTitle,
  133 + onTabChange,
  134 + data,
  135 + helpDoc,
  136 + qrCodeUrl,
  137 + download,
  138 + };
  139 + },
  140 + });
  141 +</script>
  142 +
  143 +<style lang="less" scoped></style>
... ...
... ... @@ -5,12 +5,8 @@
5 5 :active-tab-key="activeKey"
6 6 @tabChange="onTabChange"
7 7 >
8   - <p v-if="activeKey === 'tab1'">
9   - <VisitAnalysis />
10   - </p>
11   - <p v-if="activeKey === 'tab2'">
12   - <VisitAnalysisBar />
13   - </p>
  8 + <VisitAnalysis v-if="activeKey === 'tab1'" />
  9 + <VisitAnalysisBar v-else />
14 10 </Card>
15 11 </template>
16 12 <script lang="ts" setup>
... ... @@ -24,11 +20,11 @@
24 20 const tabListTitle = [
25 21 {
26 22 key: 'tab1',
27   - tab: '流量趋势',
  23 + tab: '告警数统计',
28 24 },
29 25 {
30 26 key: 'tab2',
31   - tab: '访问量',
  27 + tab: '消息量统计',
32 28 },
33 29 ];
34 30
... ...
1 1 export interface GrowCardItem {
2   - icon: string;
  2 + imgUrl: string;
3 3 title: string;
4   - value: number;
5   - total: number;
6   - color: string;
7   - action: string;
  4 + value: string;
  5 + onLine?: number;
  6 + offLine?: number;
  7 + inactive?: number;
  8 + newDay: string;
8 9 }
9 10
10 11 export const growCardList: GrowCardItem[] = [
11 12 {
12   - title: '访问数',
13   - icon: 'visit-count|svg',
14   - value: 2000,
15   - total: 120000,
16   - color: 'green',
17   - action: '月',
  13 + imgUrl: '/src/assets/images/device-count.png',
  14 + title: '设备数(个)',
  15 + value: '10,0000',
  16 + onLine: 2000,
  17 + offLine: 3000,
  18 + inactive: 4000,
  19 + newDay: '123,45',
18 20 },
19 21 {
20   - title: '成交额',
21   - icon: 'total-sales|svg',
22   - value: 20000,
23   - total: 500000,
24   - color: 'blue',
25   - action: '月',
  22 + imgUrl: '/src/assets/images/alarm-count.png',
  23 + title: '11月告警数(条)',
  24 + value: '11,000',
  25 + newDay: '167,45',
26 26 },
27 27 {
28   - title: '下载数',
29   - icon: 'download-count|svg',
30   - value: 8000,
31   - total: 120000,
32   - color: 'orange',
33   - action: '周',
34   - },
35   - {
36   - title: '成交数',
37   - icon: 'transaction|svg',
38   - value: 5000,
39   - total: 50000,
40   - color: 'purple',
41   - action: '年',
  28 + imgUrl: '/src/assets/images/msg-count.png',
  29 + title: '11月消息量(条)',
  30 + value: '12,000',
  31 + newDay: '198,45',
42 32 },
43 33 ];
... ...
1 1 <template>
2   - <div class="p-4">
3   - <GrowCard :loading="loading" class="enter-y" />
4   - <SiteAnalysis class="!my-4 enter-y" :loading="loading" />
5   - <div class="md:flex enter-y">
6   - <VisitRadar class="md:w-1/3 w-full" :loading="loading" />
7   - <VisitSource class="md:w-1/3 !md:mx-4 !md:my-0 !my-4 w-full" :loading="loading" />
8   - <SalesProductPie class="md:w-1/3 w-full" :loading="loading" />
  2 + <div class="p-4 md:flex">
  3 + <div class="md:w-7/10 w-full !mr-4 enter-y">
  4 + <GrowCard :loading="loading" class="enter-y" />
  5 + <SiteAnalysis class="!my-4 enter-y" :loading="loading" />
  6 + <div class="md:flex enter-y">
  7 + <Card title="核心流程指南" style="width: 100%">
  8 + <img alt="核心流程指南" src="../../../assets/images/flow.png" />
  9 + </Card>
  10 + </div>
  11 + </div>
  12 + <div class="md:w-3/10 w-full enter-y">
  13 + <HelpDoc />
9 14 </div>
10 15 </div>
11 16 </template>
... ... @@ -13,12 +18,9 @@
13 18 import { ref } from 'vue';
14 19 import GrowCard from './components/GrowCard.vue';
15 20 import SiteAnalysis from './components/SiteAnalysis.vue';
16   - import VisitSource from './components/VisitSource.vue';
17   - import VisitRadar from './components/VisitRadar.vue';
18   - import SalesProductPie from './components/SalesProductPie.vue';
19   -
  21 + import { Card } from 'ant-design-vue';
  22 + import HelpDoc from './components/HelpDoc.vue';
20 23 const loading = ref(true);
21   -
22 24 setTimeout(() => {
23 25 loading.value = false;
24 26 }, 1500);
... ...
1 1 <template>
2 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">
  3 + <template v-for="(item, index) in alarmList" :key="item.id">
  4 + <CollapseContainer class="border mb-8">
9 5 <template #action>
10   - <div @click="handleDeleteAlarm(index)" class="cursor-pointer">
  6 + <div @click="deleteAlarmRule(index)" class="cursor-pointer">
11 7 <DeleteOutlined style="font-size: 20px" class="mr-2" />
12 8 </div>
13 9 </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   -
  10 + <BasicForm @register="registerForm" />
20 11 <CollapseContainer>
21 12 <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>
  13 + <BasicForm @register="registerFormHighSetting">
  14 + <template #checkBox="{ model, field }">
  15 + <Checkbox v-model:checked="model[field]">传递报警</Checkbox>
  16 + </template>
  17 + </BasicForm>
31 18 </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%">
  19 + <p>创建报警规则</p>
  20 + <template v-for="(createItem, createIndex) in item.createRule" :key="createItem.id">
  21 + <div class="aic mb-4" style="border: 1px solid #bfbfbf">
  22 + <div class="w-3/4">
  23 + <BasicForm @register="registerFormCreateAlarm" />
  24 + <div>
41 25 <p style="color: #f5594e" class="mt-4 ml-4"
42 26 >请添加报警规则条件
43 27 <PlusOutlined class="cursor-pointer ml-4" style="font-size: 20px"
... ... @@ -47,68 +31,29 @@
47 31 <EditOutlined class="cursor-pointer ml-4" style="font-size: 20px"
48 32 /></p>
49 33 <p class="mt-4 ml-4"
50   - >详情:1
51   - <EditOutlined
52   - @click="editCreateDetail(index, index1)"
53   - class="cursor-pointer ml-4"
54   - style="font-size: 20px"
  34 + >详情:<EditOutlined class="cursor-pointer ml-4" style="font-size: 20px"
55 35 /></p>
56   - <p class="mt-4 ml-4">dashboard: <a-select style="width: 180px" /></p>
  36 + <p class="mt-4 ml-4">dashboard:</p>
57 37 </div>
58 38 </div>
59   - <div style="width: 10%" class="alarm-remove">
60   - <a-tooltip title="移除">
  39 + <div class="w-1/4 flex justify-center">
  40 + <Tooltip title="移除">
61 41 <MinusCircleOutlined
62   - style="font-size: 25px color:#305680"
  42 + style="font-size: 25px; color: #305680"
63 43 class="cursor-pointer"
64   - @click="handleDeleteCondition(index, index1)"
  44 + @click="deleteCondition(index, createIndex)"
65 45 />
66   - </a-tooltip>
  46 + </Tooltip>
67 47 </div>
68 48 </div>
69 49 </template>
70 50 <a-button class="mt-5" @click="addCreateRole(index)"
71 51 ><PlusCircleOutlined />添加创建条件</a-button
72 52 >
73   - <!-- 创建报警规则的弹框 -->
74   - <a-modal v-model:visible="visible" title="详情" centered>
75   - <a-textarea placeholder="报警详细信息" :rows="4" />
76   - </a-modal>
77   -
78   - <p style="color: #3c3c3c">清除报警规则</p>
79   - <template v-for="(item2, index2) in item.removeRule" :key="item2">
80   - <div class="alarm-rule mb-4">
81   - <div style="width: 90%; border: 2px solid #8c8c8c; border-radius: 5px" class="flex">
82   - <div style="width: 70%; height: 100%">
83   - <p style="color: #f5594e" class="mt-4 ml-4"
84   - >请添加报警规则条件
85   - <PlusOutlined class="cursor-pointer ml-4" style="font-size: 20px"
86   - /></p>
87   - <p class="mt-4 ml-4"
88   - >启用规则:始终启用
89   - <EditOutlined class="cursor-pointer ml-4" style="font-size: 20px"
90   - /></p>
91   - <p class="mt-4 ml-4"
92   - >详情:1 <EditOutlined class="cursor-pointer ml-4" style="font-size: 20px" />
93   - </p>
94   -
95   - <p class="mt-4 ml-4">Mobile dashboard: <a-select style="width: 150px" /></p>
96   - </div>
97   - </div>
98   - <div style="width: 10%" class="alarm-remove">
99   - <a-tooltip title="移除">
100   - <MinusCircleOutlined
101   - style="font-size: 25px color:#305680"
102   - class="cursor-pointer"
103   - @click="handleDeleteRemoveCondition(index, index2)"
104   - />
105   - </a-tooltip>
106   - </div>
107   - </div>
108   - </template>
109   - <a-button class="mt-5" @click="addRemoveRule(index)"
110   - ><PlusCircleOutlined />添加清除条件</a-button
111   - >
  53 + <p>清除报警规则</p>
  54 + <BasicForm @register="registerFormClearAlarm">
  55 + <template #formHeader> </template>
  56 + </BasicForm>
112 57 </CollapseContainer>
113 58 </template>
114 59 <div class="flex justify-start">
... ... @@ -117,163 +62,156 @@
117 62 </div>
118 63 </div>
119 64 </template>
  65 +
120 66 <script lang="ts">
121   - import { defineComponent, ref } from 'vue';
122   - import {
123   - Alert,
124   - Divider,
125   - Descriptions,
126   - Input,
127   - Form,
128   - Button,
129   - Select,
130   - Tooltip,
131   - Modal,
132   - Textarea,
133   - } from 'ant-design-vue';
  67 + import { defineComponent, ref, unref } from 'vue';
  68 + import type { alarmListItem } from '../types/index';
  69 + import { CollapseContainer } from '/@/components/Container/index';
  70 + import { BasicForm, useForm } from '/@/components/Form';
  71 + import { step3Schemas, step3HighSetting, step3CreateAlarm, step3ClearAlarm } from './data';
134 72 import {
135 73 DeleteOutlined,
136 74 MinusCircleOutlined,
137 75 PlusCircleOutlined,
138 76 PlusOutlined,
139 77 EditOutlined,
  78 + CloseOutlined,
140 79 } from '@ant-design/icons-vue';
141   -
142   - import { CollapseContainer } from '/@/components/Container/index';
143   - interface alarmListItem {
144   - alarmType: string;
145   - isPass: boolean;
146   - alarmRule: [];
147   - removeRule: [];
148   - }
  80 + import { Tooltip, Checkbox } from 'ant-design-vue';
149 81 export default defineComponent({
150 82 components: {
  83 + BasicForm,
  84 + CollapseContainer,
151 85 DeleteOutlined,
152 86 MinusCircleOutlined,
153 87 PlusCircleOutlined,
154   - CollapseContainer,
155   - EditOutlined,
156 88 PlusOutlined,
157   - [Modal.name]: Modal,
158   - [Textarea.name]: Textarea,
159   - [Tooltip.name]: Tooltip,
160   - [Button.name]: Button,
161   - [Input.name]: Input,
162   - [Select.name]: Select,
163   - [Form.name]: Form,
164   - [Form.Item.name]: Form.Item,
165   - [Alert.name]: Alert,
166   - [Divider.name]: Divider,
167   - [Descriptions.name]: Descriptions,
168   - [Descriptions.Item.name]: Descriptions.Item,
  89 + EditOutlined,
  90 + CloseOutlined,
  91 + Checkbox,
  92 + Tooltip,
169 93 },
170 94 emits: ['prev'],
171 95 setup(_, { emit }) {
172   - const alarmList = ref<alarmListItem[]>([]);
173   - const visible = ref(false);
174   - const options = ref([
175   - {
176   - value: '1',
177   - label: '危险',
178   - },
179   -
180   - {
181   - value: '2',
182   - label: '重要',
183   - },
184   - {
185   - value: '3',
186   - label: '次要',
187   - },
188   - {
189   - value: '4',
190   - label: '警告',
191   - },
192   - {
193   - value: '5',
194   - label: '不确定',
195   - },
196   - ]);
197   - const rules = {
198   - alarmType: [
199   - {
200   - required: true,
201   - message: '报警类型必填',
202   - trigger: 'blur',
203   - },
204   - ],
  96 + //告警列表
  97 + let alarmList = ref<alarmListItem[]>([]);
  98 + // 添加和删除告警配置
  99 + const deleteAlarmRule = (index: number) => {
  100 + unref(alarmList).splice(index, 1);
205 101 };
206   -
  102 + // 上一步
207 103 const prevStep = () => {
208 104 emit('prev');
209 105 };
210   - // 添加报警规则
211 106 const addAlarmRule = () => {
212   - alarmList.value.push({
  107 + unref(alarmList).push({
  108 + id: Date.now(),
213 109 alarmType: '',
214 110 isPass: false,
215   - alarmRule: [],
216   - removeRule: [],
  111 + createRule: [
  112 + {
  113 + id: Date.now() + Math.random(),
  114 + alarmVisible: false,
  115 + addKeyFilterVisible: false,
  116 + detailVisible: false,
  117 + detail: '',
  118 + filterList: [],
  119 + },
  120 + ],
  121 + clearRule: [],
217 122 });
218 123 };
219   - const handleDeleteAlarm = (index) => {
220   - alarmList.value.splice(index, 1);
221   - };
222   - // 添加创建条件
223   - const addCreateRole = (index) => {
224   - alarmList.value[index].alarmRule.push({
  124 +
  125 + // 表单部分 报警类型
  126 + const [registerForm] = useForm({
  127 + labelWidth: 120,
  128 + schemas: step3Schemas,
  129 + showResetButton: false,
  130 + showSubmitButton: false,
  131 + });
  132 +
  133 + // 高级设置
  134 + const [registerFormHighSetting] = useForm({
  135 + labelWidth: 120,
  136 + schemas: step3HighSetting,
  137 + showResetButton: false,
  138 + showSubmitButton: false,
  139 + actionColOptions: {
  140 + span: 24,
  141 + },
  142 + });
  143 +
  144 + // 添加创建条件表单
  145 + const [registerFormCreateAlarm] = useForm({
  146 + labelWidth: 120,
  147 + schemas: step3CreateAlarm,
  148 + showResetButton: false,
  149 + showSubmitButton: false,
  150 + actionColOptions: {
  151 + span: 24,
  152 + },
  153 + });
  154 +
  155 + // 清除条件表单
  156 + const [registerFormClearAlarm] = useForm({
  157 + labelWidth: 120,
  158 + schemas: step3ClearAlarm,
  159 + showResetButton: false,
  160 + showSubmitButton: false,
  161 + actionColOptions: {
  162 + span: 24,
  163 + },
  164 + });
  165 +
  166 + // 添加‘创建条件’
  167 + const addCreateRole = (index: number) => {
  168 + unref(alarmList)[index].createRule.push({
  169 + id: Date.now() + Math.random(),
  170 + alarmVisible: false,
  171 + addKeyFilterVisible: false,
  172 + detailVisible: false,
225 173 detail: '',
  174 + filterList: [],
226 175 });
227 176 };
228   - const handleDeleteCondition = (index, index1) => {
229   - alarmList.value[index].alarmRule.splice(index1, 1);
230   - };
231   -
232   - // 清除报警规则
233   - const addRemoveRule = (index) => {
234   - alarmList.value[index].removeRule.push('1');
235   - };
236   - const handleDeleteRemoveCondition = (index, index1) => {
237   - alarmList.value[index].removeRule.splice(index1, 1);
  177 + // 删除‘创建条件’
  178 + const deleteCondition = (index: number, createIndex: number) => {
  179 + alarmList.value[index].createRule.splice(createIndex, 1);
238 180 };
239   -
240   - // 编辑创建规则的详情
241   - const editCreateDetail = (index, index1) => {
242   - visible.value = true;
243   - console.log(alarmList.value[index].alarmRule[index1].detail);
244   - };
245   -
246 181 return {
247   - rules,
248 182 alarmList,
249   - options,
250   - visible,
  183 + deleteAlarmRule,
251 184 prevStep,
252 185 addAlarmRule,
  186 +
  187 + registerForm,
  188 +
  189 + registerFormHighSetting,
  190 +
  191 + registerFormCreateAlarm,
253 192 addCreateRole,
254   - handleDeleteAlarm,
255   - handleDeleteCondition,
256   - addRemoveRule,
257   - handleDeleteRemoveCondition,
258   - editCreateDetail,
259   - labelCol: { style: { width: '150px' } },
260   - wrapperCol: { span: 18 },
  193 + deleteCondition,
  194 +
  195 + registerFormClearAlarm,
261 196 };
262 197 },
263 198 });
264 199 </script>
  200 +
265 201 <style lang="less" scoped>
266 202 .step3 {
267   - width: 500px;
268   - margin: 0 auto;
  203 + width: 100%;
269 204 }
270   - .alarm-rule {
271   - height: 200px;
  205 + .border {
  206 + border: 1px solid #bfbfbf;
  207 + }
  208 +
  209 + .aic {
272 210 display: flex;
273   - .alarm-remove {
274   - display: flex;
275   - justify-content: center;
276   - align-items: center;
277   - }
  211 + align-items: center;
  212 + }
  213 +
  214 + :deep(.vben-collapse-container__header) {
  215 + border: none;
278 216 }
279 217 </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>
... ...
... ... @@ -46,11 +46,73 @@ export const step2Schemas: FormSchema[] = [
46 46 export const step3Schemas: FormSchema[] = [
47 47 {
48 48 field: 'transportType',
  49 + component: 'Input',
  50 + label: '报警类型',
  51 + required: true,
  52 + componentProps: {
  53 + placeholder: '请输入报警类型',
  54 + },
  55 + },
  56 +];
  57 +
  58 +export const step3HighSetting: FormSchema[] = [
  59 + {
  60 + field: 'isPass',
  61 + component: 'Checkbox',
  62 + label: '',
  63 + slot: 'checkBox',
  64 + },
  65 + {
  66 + field: 'associationType',
  67 + component: 'Input',
  68 + label: '关联类型',
  69 + componentProps: {
  70 + placeholder: '要传递的关联类型',
  71 + },
  72 + ifShow: ({ values }) => !!values.isPass,
  73 + },
  74 +];
  75 +
  76 +export const step3CreateAlarm: FormSchema[] = [
  77 + {
  78 + field: 'severity',
49 79 component: 'Select',
50   - label: '报警规则',
51   - defaultValue: 'DEFAULT',
  80 + label: '严重程度',
52 81 componentProps: {
53   - options: [{ label: '默认', value: 'DEFAULT' }],
  82 + placeholder: '请选择严重程度',
  83 + options: [
  84 + {
  85 + value: '1',
  86 + label: '危险',
  87 + },
  88 + {
  89 + value: '2',
  90 + label: '重要',
  91 + },
  92 + {
  93 + value: '3',
  94 + label: '次要',
  95 + },
  96 + {
  97 + value: '4',
  98 + label: '警告',
  99 + },
  100 + {
  101 + value: '5',
  102 + label: '不确定',
  103 + },
  104 + ],
54 105 },
55 106 },
56 107 ];
  108 +
  109 +export const step3ClearAlarm: FormSchema[] = [
  110 + // {
  111 + // field: 'associationType',
  112 + // component: 'Input',
  113 + // label: '关联类型',
  114 + // componentProps: {
  115 + // placeholder: '要传递的关联类型',
  116 + // },
  117 + // },
  118 +];
... ...
  1 +interface alarmRuleFilter {
  2 + operator: string;
  3 + value: string;
  4 +}
  5 +interface createRule {
  6 + id: number;
  7 + alarmVisible: boolean;
  8 + addKeyFilterVisible: boolean;
  9 + detailVisible: boolean;
  10 + detail: string;
  11 + filterList?: alarmRuleFilter[];
  12 +}
  13 +interface clearRule {
  14 + detail: string;
  15 +}
  16 +export interface alarmListItem {
  17 + id: number;
  18 + alarmType: string;
  19 + isPass: boolean;
  20 + createRule: createRule[];
  21 + clearRule: clearRule[];
  22 +}
... ...