Commit 0109c9c52e6535cca35112013e83da468790635c

Authored by xp.Huang
2 parents c62eeb71 edc2a8ba

Merge branch 'perf/device-list' into 'main_dev'

perf: 设备列表新增告警状态提示 && 变更收藏样式

See merge request yunteng/thingskit-front!1160
... ... @@ -187,6 +187,7 @@ export interface DeviceRecord {
187 187 brand?: string;
188 188 deviceProfileId: string;
189 189 organizationId: string;
  190 + alarmStatus: number;
190 191 deviceProfile: {
191 192 default: boolean;
192 193 name: string;
... ...
... ... @@ -4,12 +4,12 @@
4 4 <Tooltip v-if="action.tooltip" v-bind="getTooltip(action.tooltip)">
5 5 <PopConfirmButton v-bind="action">
6 6 <Icon :icon="action.icon" :class="{ 'mr-1': !!action.label }" v-if="action.icon" />
7   - <template v-if="action.label">{{ action.label }}</template>
  7 + <template v-if="action.label"><Label :label="action.label" /></template>
8 8 </PopConfirmButton>
9 9 </Tooltip>
10 10 <PopConfirmButton v-else v-bind="action">
11 11 <Icon :icon="action.icon" :class="{ 'mr-1': !!action.label }" v-if="action.icon" />
12   - <template v-if="action.label">{{ action.label }}</template>
  12 + <template v-if="action.label"><Label :label="action.label" /> </template>
13 13 </PopConfirmButton>
14 14 <Divider
15 15 type="vertical"
... ... @@ -36,7 +36,7 @@
36 36 </div>
37 37 </template>
38 38 <script lang="ts">
39   - import { defineComponent, PropType, computed, toRaw, unref } from 'vue';
  39 + import { defineComponent, PropType, computed, toRaw, unref, VNode } from 'vue';
40 40 // import { MoreOutlined } from '@ant-design/icons-vue';
41 41 import { Divider, Tooltip, TooltipProps } from 'ant-design-vue';
42 42 import Icon from '/@/components/Icon/index';
... ... @@ -52,7 +52,14 @@
52 52
53 53 export default defineComponent({
54 54 name: 'TableAction',
55   - components: { Icon, PopConfirmButton, Divider, Dropdown, Tooltip },
  55 + components: {
  56 + Icon,
  57 + PopConfirmButton,
  58 + Divider,
  59 + Dropdown,
  60 + Tooltip,
  61 + Label: (props: { label: VNode | string }) => props.label,
  62 + },
56 63 props: {
57 64 actions: {
58 65 type: Array as PropType<ActionItem[]>,
... ...
1 1 import { ButtonProps } from 'ant-design-vue/es/button/buttonTypes';
2 2 import { TooltipProps } from 'ant-design-vue/es/tooltip/Tooltip';
3 3 import { RoleEnum } from '/@/enums/roleEnum';
  4 +import { VNode } from 'vue';
4 5 export interface ActionItem extends ButtonProps {
5 6 onClick?: Fn;
6   - label?: string;
  7 + label?: string | VNode;
7 8 color?: 'success' | 'error' | 'warning';
8 9 icon?: string;
9 10 popConfirm?: PopConfirm;
... ...
... ... @@ -70,6 +70,7 @@ export const columns: BasicColumn[] = [
70 70 title: '状态',
71 71 dataIndex: 'deviceState',
72 72 width: 110,
  73 + className: 'device-status',
73 74 slots: { customRender: 'deviceState' },
74 75 },
75 76 {
... ...
... ... @@ -19,7 +19,20 @@
19 19 <Tabs.TabPane key="modelOfMatter" tab="物模型数据">
20 20 <ModelOfMatter :deviceDetail="deviceDetail" />
21 21 </Tabs.TabPane>
22   - <Tabs.TabPane key="3" tab="告警">
  22 + <Tabs.TabPane key="3">
  23 + <template #tab>
  24 + <Badge :offset="[2, -5]" style="color: inherit">
  25 + <span>告警</span>
  26 + <template #count>
  27 + <div
  28 + :style="{ visibility: deviceDetail.alarmStatus ? 'visible' : 'hidden' }"
  29 + class="w-3.5 h-3.5 !flex justify-center items-center rounded-1 border-red-400 border"
  30 + >
  31 + <Icon icon="mdi:bell-warning" color="#f46161" :size="12" class="!mr-0" />
  32 + </div>
  33 + </template>
  34 + </Badge>
  35 + </template>
23 36 <AlarmLog :device-id="deviceDetail.id" class="bg-gray-100" />
24 37 </Tabs.TabPane>
25 38 <Tabs.TabPane key="4" tab="子设备" v-if="deviceDetail?.deviceType === 'GATEWAY'">
... ... @@ -51,7 +64,7 @@
51 64 <script lang="ts" setup>
52 65 import { ref, computed } from 'vue';
53 66 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
54   - import { Tabs } from 'ant-design-vue';
  67 + import { Tabs, Badge } from 'ant-design-vue';
55 68 import Detail from '../tabs/Detail.vue';
56 69 import ChildDevice from '../tabs/ChildDevice.vue';
57 70 import TBoxDetail from '../tabs/TBoxDetail.vue';
... ... @@ -62,6 +75,7 @@
62 75 import { DeviceRecord } from '/@/api/device/model/deviceModel';
63 76 import Task from '../tabs/Task.vue';
64 77 import AlarmLog from '/@/views/alarm/log/index.vue';
  78 + import { Icon } from '/@/components/Icon';
65 79
66 80 const emit = defineEmits(['reload', 'register', 'openTbDeviceDetail', 'openGatewayDeviceDetail']);
67 81
... ...
... ... @@ -106,13 +106,17 @@
106 106 </Tag>
107 107 </template>
108 108 <template #deviceState="{ record }">
109   - <!-- <HeartOutlined v-if="!record.isCollect" class="mr-1" style="color: red" /> -->
110   - <Tooltip>
111   - <template #title> 我的收藏</template>
112   - <HeartTwoTone v-if="record.isCollect" class="mr-1" twoToneColor="#3B82F6" />
113   - </Tooltip>
  109 + <div v-if="record.isCollect">
  110 + <div class="absolute top-0 left-0 device-collect"> </div>
  111 + <Icon
  112 + icon="ph:star-fill"
  113 + class="fill-light-50 absolute top-0.5 left-0.5"
  114 + color="#fff"
  115 + :size="12"
  116 + />
  117 + </div>
  118 +
114 119 <Tag
115   - :style="{ marginLeft: !record.isCollect ? '17px' : '' }"
116 120 :color="
117 121 record.deviceState == DeviceState.INACTIVE
118 122 ? 'warning'
... ... @@ -135,7 +139,7 @@
135 139 <TableAction
136 140 :actions="[
137 141 {
138   - label: '详情',
  142 + label: AlarmDetailActionButton({ hasAlarm: !!record.alarmStatus }),
139 143 icon: 'ant-design:eye-outlined',
140 144 auth: DeviceListAuthEnum.DETAIL,
141 145 onClick: handleDetail.bind(null, record),
... ... @@ -232,7 +236,7 @@
232 236 </div>
233 237 </template>
234 238 <script lang="ts" setup>
235   - import { reactive, onMounted, ref } from 'vue';
  239 + import { reactive, onMounted, ref, h, CSSProperties } from 'vue';
236 240 import {
237 241 DeviceModel,
238 242 DeviceRecord,
... ... @@ -241,8 +245,7 @@
241 245 } from '/@/api/device/model/deviceModel';
242 246 import { BasicTable, useTable, TableAction, TableImg } from '/@/components/Table';
243 247 import { columns, DeviceListAuthEnum, searchFormSchema } from './config/device.data';
244   - import { Tag, Popover, Button, Tooltip } from 'ant-design-vue';
245   - import { HeartTwoTone } from '@ant-design/icons-vue';
  248 + import { Tag, Popover, Button, Badge } from 'ant-design-vue';
246 249 import {
247 250 deleteDevice,
248 251 devicePage,
... ... @@ -278,6 +281,7 @@
278 281 } from './cpns/modal/BatchUpdateProductModal';
279 282 import { DataActionModeEnum } from '/@/enums/toolEnum';
280 283 import { AuthDropDown } from '/@/components/Widget';
  284 + import Icon from '/@/components/Icon';
281 285
282 286 const { isCustomer } = useAuthDeviceDetail();
283 287 const { createMessage } = useMessage();
... ... @@ -294,6 +298,32 @@
294 298 const [registerImportModal, { openModal: openImportModal }] = useModal();
295 299 const [registerBatchUpdateProductModal, { openModal: openBatchUpdateProductModal }] = useModal();
296 300
  301 + const AlarmDetailActionButton = ({ hasAlarm }: { hasAlarm?: boolean }) =>
  302 + h(
  303 + Badge,
  304 + { offset: [0, -5] },
  305 + {
  306 + default: () => h('span', { style: { color: '#377dff' } }, '详情'),
  307 + count: () =>
  308 + h(
  309 + 'div',
  310 + {
  311 + style: {
  312 + visibility: hasAlarm ? 'visible' : 'hidden',
  313 + width: '14px',
  314 + height: '14px',
  315 + display: 'flex',
  316 + justifyContent: 'center',
  317 + alignItems: 'center',
  318 + border: '1px solid #f46161',
  319 + borderRadius: '50%',
  320 + } as CSSProperties,
  321 + },
  322 + h(Icon, { icon: 'mdi:bell-warning', color: '#f46161', size: 12 })
  323 + ),
  324 + }
  325 + );
  326 +
297 327 const batchUpdateProductFlag = ref(true);
298 328
299 329 const [
... ... @@ -336,6 +366,7 @@
336 366 rowKey: 'id',
337 367 searchInfo: searchInfo,
338 368 clickToRowSelect: false,
  369 + rowClassName: (record) => ((record as DeviceRecord).alarmStatus ? 'device-alarm-badge' : ''),
339 370 actionColumn: {
340 371 width: 200,
341 372 title: '操作',
... ... @@ -566,3 +597,16 @@
566 597 }
567 598 }
568 599 </style>
  600 +
  601 +<style lang="less">
  602 + .device-status {
  603 + position: relative;
  604 +
  605 + .device-collect {
  606 + width: 0;
  607 + height: 0;
  608 + border-top: 30px solid #377dff;
  609 + border-right: 30px solid transparent;
  610 + }
  611 + }
  612 +</style>
... ...