Commit 7f7e88aeafb46611c2c07ad652801e5c6265836c

Authored by xp.Huang
2 parents 437eb431 56ea2b87

Merge branch 'ft' into 'main_dev'

perf: 优化登录页手机登录和账号登录更换为图标形式

See merge request yunteng/thingskit-front!853
... ... @@ -126,6 +126,12 @@ export const alarmColumns: BasicColumn[] = [
126 126 format: (text) => alarmLevel(text),
127 127 },
128 128 {
  129 + title: '告警详情',
  130 + dataIndex: 'details',
  131 + slots: { customRender: 'details' },
  132 + width: 160,
  133 + },
  134 + {
129 135 title: '状态',
130 136 dataIndex: 'status',
131 137 format: (text) => statusType(text),
... ...
... ... @@ -13,17 +13,31 @@
13 13 ]"
14 14 />
15 15 </template>
  16 + <template #details="{ record }">
  17 + <a-button type="link" class="ml-2" @click="handleViewAlarmDetails(record)">
  18 + 查看告警详情
  19 + </a-button>
  20 + </template>
16 21 </BasicTable>
17 22 <AlarmDetailDrawer @register="registerDetailDrawer" @success="handleSuccess" />
18 23 </div>
19 24 </template>
20 25 <script lang="ts">
21   - import { defineComponent } from 'vue';
  26 + import { defineComponent, nextTick, h } from 'vue';
22 27 import { BasicTable, useTable, TableAction } from '/@/components/Table';
23 28 import { alarmColumns, alarmSearchSchemas } from './config/detail.config';
24 29 import { getDeviceAlarm } from '/@/api/device/deviceManager';
25 30 import { useDrawer } from '/@/components/Drawer';
26 31 import AlarmDetailDrawer from './cpns/AlarmDetailDrawer.vue';
  32 + import { Modal } from 'ant-design-vue';
  33 + import { JsonPreview } from '/@/components/CodeEditor';
  34 + import { getDeviceDetail } from '/@/api/device/deviceManager';
  35 + import { getAttribute } from '/@/api/ruleengine/ruleengineApi';
  36 + import {
  37 + operationNumber_OR_TIME,
  38 + operationString,
  39 + operationBoolean,
  40 + } from '/@/views/rule/linkedge/config/formatData';
27 41
28 42 export default defineComponent({
29 43 name: 'AlarmCenter',
... ... @@ -61,11 +75,85 @@
61 75 const handleSuccess = () => {
62 76 reload();
63 77 };
  78 + const handleViewAlarmDetails = async (record: Recordable) => {
  79 + await nextTick();
  80 + const { details } = record;
  81 + const deviceIdKeys = Object.keys(details);
  82 + const detailObject = deviceIdKeys.map((key) => ({ label: key, value: details[key] }));
  83 + const dataFormat = await handleAlarmDetailFormat(deviceIdKeys);
  84 + const dataFormats = detailObject.reduce((acc: any, curr: any) => {
  85 + dataFormat.forEach((item) => {
  86 + if (item.tbDeviceId === curr.label) {
  87 + const findName = item.attribute.find(
  88 + (item) => item.identifier === curr.value.key
  89 + )?.name;
  90 + const findLogin = [
  91 + ...operationNumber_OR_TIME,
  92 + ...operationString,
  93 + ...operationBoolean,
  94 + ].find((item) => item.value === curr.value.logic)?.symbol;
  95 + const findAttribute = item.attribute.find(
  96 + (findItem) => findItem.identifier === curr.value.key
  97 + );
  98 + const value = {
  99 + ['触发属性']: findName,
  100 + ['触发条件']: `${findLogin}${curr.value.logicValue}`,
  101 + ['触发值']: `${curr.value.realValue}${findAttribute.detail?.dataType?.specs?.unit?.key}`,
  102 + };
  103 + const data = {
  104 + [item.name]: value,
  105 + };
  106 + acc.push(data);
  107 + }
  108 + });
  109 + return [...acc];
  110 + }, []);
  111 + const objectFormat = dataFormats.reduce((acc: any, curr: any) => {
  112 + return {
  113 + ...acc,
  114 + ...curr,
  115 + };
  116 + }, {});
  117 + Modal.info({
  118 + title: '告警详情',
  119 + width: 600,
  120 + centered: true,
  121 + maskClosable: true,
  122 + content: h(JsonPreview, { data: JSON.parse(JSON.stringify(objectFormat)) }),
  123 + });
  124 + };
  125 + const handleAlarmDetailFormat = async (keys: string[]) => {
  126 + const temp: any = [];
  127 + for (let item of keys) {
  128 + if (item === 'key' || item === 'data') return []; //旧数据则终止
  129 + const deviceDetailRes = await getDeviceDetail(item);
  130 + const { deviceProfileId } = deviceDetailRes;
  131 + if (!deviceProfileId) return [];
  132 + const attributeRes = await getAttribute(deviceProfileId);
  133 + const dataFormat: any = handleDataFormat(deviceDetailRes, attributeRes);
  134 + temp.push(dataFormat);
  135 + }
  136 + return temp;
  137 + };
  138 + const handleDataFormat = (deviceDetail: any, attributes: any) => {
  139 + const { name, tbDeviceId } = deviceDetail;
  140 + const attribute = attributes.map((item) => ({
  141 + identifier: item.identifier,
  142 + name: item.name,
  143 + detail: item.detail,
  144 + }));
  145 + return {
  146 + name,
  147 + tbDeviceId,
  148 + attribute,
  149 + };
  150 + };
64 151 return {
65 152 registerTable,
66 153 registerDetailDrawer,
67 154 handleDetail,
68 155 handleSuccess,
  156 + handleViewAlarmDetails,
69 157 };
70 158 },
71 159 });
... ...
... ... @@ -86,7 +86,6 @@
86 86 const deviceIdKeys = Object.keys(details);
87 87 const detailObject = deviceIdKeys.map((key) => ({ label: key, value: details[key] }));
88 88 const dataFormat = await handleAlarmDetailFormat(deviceIdKeys);
89   - console.log(detailObject, dataFormat, 'dataFormat');
90 89 const dataFormats = detailObject.reduce((acc: any, curr: any) => {
91 90 dataFormat.forEach((item) => {
92 91 if (item.tbDeviceId === curr.label) {
... ...
... ... @@ -283,6 +283,7 @@
283 283 popconfirm: {
284 284 title: '是否确认删除操作?',
285 285 onConfirm: handleDelete.bind(null, [item.id]),
  286 + disabled: item.default,
286 287 },
287 288 disabled: item.default,
288 289 },
... ...
... ... @@ -47,32 +47,44 @@
47 47 {{ t('sys.login.loginButton') }}
48 48 </Button>
49 49 </FormItem>
50   - <ARow class="enter-x flex justify-center">
51   - <!-- <ACol :md="11" :xs="24">
  50 + <!-- <ARow class="enter-x flex justify-center"> -->
  51 + <!-- <ACol :md="11" :xs="24">
52 52 <Button block @click="setLoginState(LoginStateEnum.LOGIN)">
53 53 {{ t('sys.login.userNameInFormTitle') }}
54 54 </Button>
55 55 </ACol> -->
56   - <ACol :md="11" :xs="24">
57   - <Button block @click="setLoginState(LoginStateEnum.MOBILE)">
  56 + <!-- <ACol :md="11" :xs="24"> -->
  57 + <!-- <Button block @click="setLoginState(LoginStateEnum.MOBILE)">
58 58 {{ t('sys.login.mobileSignInFormTitle') }}
59   - </Button>
60   - </ACol>
61   - </ARow>
  59 + </Button> -->
  60 + <!-- <div class="flex justify-center cursor-pointer">
  61 + <div
  62 + @click="setLoginState(LoginStateEnum.MOBILE)"
  63 + class="flex justify-center icon-button"
  64 + >
  65 + <phone-filled :style="{ fontSize: '18px' }" />
  66 + </div>
  67 + </div> -->
  68 + <!-- </ACol> -->
  69 + <!-- </ARow> -->
  70 + <Divider class="enter-x">
  71 + <div @click="setLoginState(LoginStateEnum.MOBILE)" class="flex justify-center icon-button">
  72 + <mobile-filled :style="{ fontSize: '18px' }" />
  73 + </div>
  74 + </Divider>
62 75 </Form>
63 76 </template>
64 77 <script lang="ts" setup>
65 78 import { reactive, ref, unref, computed } from 'vue';
66   - import { Checkbox, Form, Input, Row, Col, Button } from 'ant-design-vue';
  79 + import { Checkbox, Form, Input, Row, Col, Button, Divider } from 'ant-design-vue';
67 80 import LoginFormTitle from './LoginFormTitle.vue';
68   -
69 81 import { useI18n } from '/@/hooks/web/useI18n';
70 82 import { useMessage } from '/@/hooks/web/useMessage';
71   -
72 83 import { useUserStore } from '/@/store/modules/user';
73 84 import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
74 85 import { getPlatForm } from '/@/api/oem';
75 86 import { createLocalStorage, createSessionStorage } from '/@/utils/cache';
  87 + import { MobileFilled } from '@ant-design/icons-vue';
76 88
77 89 const ACol = Col;
78 90 const ARow = Row;
... ... @@ -147,3 +159,13 @@
147 159 loading.value = false;
148 160 }
149 161 </script>
  162 +
  163 +<style lang="less" scoped>
  164 + .icon-button {
  165 + align-items: center;
  166 + border-radius: 50%;
  167 + background-color: #f7f7f7;
  168 + width: 2.8rem;
  169 + height: 2.8rem;
  170 + }
  171 +</style>
... ...
... ... @@ -24,16 +24,23 @@
24 24 <Button type="primary" size="large" block @click="handleLogin" :loading="loading">
25 25 {{ t('sys.login.loginButton') }}
26 26 </Button>
27   - <Button size="large" block class="mt-4" @click="handleBackLogin">
  27 + <!-- <Button size="large" block class="mt-4" @click="handleBackLogin">
28 28 {{ t('sys.login.backSignIn') }}
29   - </Button>
  29 + </Button> -->
30 30 </FormItem>
  31 + <Divider class="enter-x">
  32 + <div class="flex justify-center cursor-pointer">
  33 + <div @click="handleBackLogin" class="flex justify-center icon-button">
  34 + <contacts-filled :style="{ fontSize: '18px' }" />
  35 + </div>
  36 + </div>
  37 + </Divider>
31 38 </Form>
32 39 </template>
33 40 </template>
34 41 <script lang="ts" setup>
35 42 import { reactive, ref, computed, unref, toRaw } from 'vue';
36   - import { Form, Input, Button, message } from 'ant-design-vue';
  43 + import { Form, Input, Button, message, Divider } from 'ant-design-vue';
37 44 import { CountdownInput } from '/@/components/CountDown';
38 45 import LoginFormTitle from './LoginFormTitle.vue';
39 46 import { useI18n } from '/@/hooks/web/useI18n';
... ... @@ -41,6 +48,7 @@
41 48 import { SendLoginSmsCode } from '/@/api/sys/user';
42 49 import { useUserStore } from '/@/store/modules/user';
43 50 import { useMessage } from '/@/hooks/web/useMessage';
  51 + import { ContactsFilled } from '@ant-design/icons-vue';
44 52 const { notification } = useMessage();
45 53
46 54 const FormItem = Form.Item;
... ... @@ -95,3 +103,12 @@
95 103 }
96 104 }
97 105 </script>
  106 +<style lang="less" scoped>
  107 + .icon-button {
  108 + align-items: center;
  109 + border-radius: 50%;
  110 + background-color: #f7f7f7;
  111 + width: 2.8rem;
  112 + height: 2.8rem;
  113 + }
  114 +</style>
... ...