Commit c64231b090575f5df3eb63005cdc7720b635d358

Authored by loveumiko
2 parents 95403b74 9fd33ee3

Merge branch 'main_dev' of http://git.yunteng.com/yunteng/thingskit-front into f…

…ix/board-style-issues
@@ -47,7 +47,7 @@ @@ -47,7 +47,7 @@
47 transformFile?: (file: File) => string | Blob | Promise<string | Blob | File>; 47 transformFile?: (file: File) => string | Blob | Promise<string | Blob | File>;
48 api: (file: string | Blob | Promise<string | Blob | File>) => Promise<FileItem>; 48 api: (file: string | Blob | Promise<string | Blob | File>) => Promise<FileItem>;
49 overFileLimitHiddenUploadEntry?: boolean; 49 overFileLimitHiddenUploadEntry?: boolean;
50 - beforeUpload: (file: File, fileList: File[]) => boolean; 50 + beforeUpload?: (file: File, fileList: File[]) => boolean;
51 }>(), 51 }>(),
52 { 52 {
53 fileList: () => [], 53 fileList: () => [],
@@ -146,7 +146,7 @@ @@ -146,7 +146,7 @@
146 :remove="handleRemove" 146 :remove="handleRemove"
147 > 147 >
148 <Spin 148 <Spin
149 - v-if="!(fileList.length >= getMaxFileLimit) || overFileLimitHiddenUploadEntry" 149 + v-if="!(fileList.length >= getMaxFileLimit && overFileLimitHiddenUploadEntry)"
150 :spinning="loading" 150 :spinning="loading"
151 > 151 >
152 <div class="w-full h-full flex flex-col justify-center content-center"> 152 <div class="w-full h-full flex flex-col justify-center content-center">
@@ -113,6 +113,10 @@ export const alarmColumns: BasicColumn[] = [ @@ -113,6 +113,10 @@ export const alarmColumns: BasicColumn[] = [
113 title: '告警设备', 113 title: '告警设备',
114 dataIndex: 'deviceName', 114 dataIndex: 'deviceName',
115 width: 100, 115 width: 100,
  116 + customRender: ({ record }) => {
  117 + const { deviceAlias, deviceName } = record || {};
  118 + return deviceAlias || deviceName;
  119 + },
116 }, 120 },
117 { 121 {
118 title: '告警场景', 122 title: '告警场景',
@@ -46,14 +46,16 @@ @@ -46,14 +46,16 @@
46 const alarmStatus = ref(''); 46 const alarmStatus = ref('');
47 const [registerDrawer, { closeDrawer }] = useDrawerInner(async (data) => { 47 const [registerDrawer, { closeDrawer }] = useDrawerInner(async (data) => {
48 await resetFields(); 48 await resetFields();
  49 + const { deviceAlias, deviceName, severity, status, details, id } = data || {};
49 await setFieldsValue({ 50 await setFieldsValue({
50 ...data, 51 ...data,
51 - severity: alarmLevel(data.severity),  
52 - status: statusType(data.status),  
53 - details: JSON.stringify(data.details), 52 + deviceName: deviceAlias || deviceName,
  53 + severity: alarmLevel(severity),
  54 + status: statusType(status),
  55 + details: JSON.stringify(details),
54 }); 56 });
55 - alarmStatus.value = data.status;  
56 - alarmId.value = data.id; 57 + alarmStatus.value = status;
  58 + alarmId.value = id;
57 }); 59 });
58 // 处理报警 60 // 处理报警
59 const handleAlarm = async () => { 61 const handleAlarm = async () => {
@@ -19,14 +19,14 @@ @@ -19,14 +19,14 @@
19 </a-button> 19 </a-button>
20 </template> 20 </template>
21 <template #toolbar> 21 <template #toolbar>
22 - <Button @click="handleBatchAck" type="primary">批量处理</Button> 22 + <Button @click="handleBatchAck" type="primary" :disabled="getCanBatchAck">批量处理</Button>
23 </template> 23 </template>
24 </BasicTable> 24 </BasicTable>
25 <AlarmDetailDrawer @register="registerDetailDrawer" @success="handleSuccess" /> 25 <AlarmDetailDrawer @register="registerDetailDrawer" @success="handleSuccess" />
26 </div> 26 </div>
27 </template> 27 </template>
28 <script lang="ts"> 28 <script lang="ts">
29 - import { defineComponent, nextTick, h } from 'vue'; 29 + import { defineComponent, nextTick, h, computed } from 'vue';
30 import { BasicTable, useTable, TableAction } from '/@/components/Table'; 30 import { BasicTable, useTable, TableAction } from '/@/components/Table';
31 import { alarmColumns, alarmSearchSchemas } from './config/detail.config'; 31 import { alarmColumns, alarmSearchSchemas } from './config/detail.config';
32 import { doBatchAckAlarm, getDeviceAlarm } from '/@/api/device/deviceManager'; 32 import { doBatchAckAlarm, getDeviceAlarm } from '/@/api/device/deviceManager';
@@ -55,34 +55,36 @@ @@ -55,34 +55,36 @@
55 }, 55 },
56 56
57 setup() { 57 setup() {
58 - const [registerTable, { reload, getSelectRows, clearSelectedRowKeys }] = useTable({  
59 - title: '告警记录列表',  
60 - api: getDeviceAlarm,  
61 - columns: alarmColumns,  
62 - useSearchForm: true,  
63 - formConfig: {  
64 - labelWidth: 120,  
65 - schemas: alarmSearchSchemas,  
66 - fieldMapToTime: [['alarmTime', ['startTime', 'endTime'], 'x']],  
67 - },  
68 - bordered: true,  
69 - showIndexColumn: false,  
70 - showTableSetting: true,  
71 - rowSelection: {  
72 - type: 'checkbox',  
73 - getCheckboxProps: (record: AlarmLogItem) => {  
74 - return {  
75 - disabled: record.status === AlarmStatus.CLEARED_ACK,  
76 - }; 58 + const [registerTable, { reload, getSelectRows, clearSelectedRowKeys, getRowSelection }] =
  59 + useTable({
  60 + title: '告警记录列表',
  61 + api: getDeviceAlarm,
  62 + columns: alarmColumns,
  63 + useSearchForm: true,
  64 + formConfig: {
  65 + labelWidth: 120,
  66 + schemas: alarmSearchSchemas,
  67 + fieldMapToTime: [['alarmTime', ['startTime', 'endTime'], 'x']],
77 }, 68 },
78 - },  
79 - actionColumn: {  
80 - width: 200,  
81 - title: '操作',  
82 - slots: { customRender: 'action' },  
83 - fixed: 'right',  
84 - },  
85 - }); 69 + bordered: true,
  70 + showIndexColumn: false,
  71 + showTableSetting: true,
  72 + clickToRowSelect: false,
  73 + rowSelection: {
  74 + type: 'checkbox',
  75 + getCheckboxProps: (record: AlarmLogItem) => {
  76 + return {
  77 + disabled: record.status === AlarmStatus.CLEARED_ACK,
  78 + };
  79 + },
  80 + },
  81 + actionColumn: {
  82 + width: 200,
  83 + title: '操作',
  84 + slots: { customRender: 'action' },
  85 + fixed: 'right',
  86 + },
  87 + });
86 const [registerDetailDrawer, { openDrawer }] = useDrawer(); 88 const [registerDetailDrawer, { openDrawer }] = useDrawer();
87 const handleDetail = (record: Recordable) => { 89 const handleDetail = (record: Recordable) => {
88 openDrawer(true, record); 90 openDrawer(true, record);
@@ -113,7 +115,9 @@ @@ -113,7 +115,9 @@
113 const value = { 115 const value = {
114 ['触发属性']: findName, 116 ['触发属性']: findName,
115 ['触发条件']: `${findLogin}${curr.value.logicValue}`, 117 ['触发条件']: `${findLogin}${curr.value.logicValue}`,
116 - ['触发值']: `${curr.value.realValue}${findAttribute.detail?.dataType?.specs?.unit?.key}`, 118 + ['触发值']: `${curr.value.realValue}${
  119 + findAttribute.detail?.dataType?.specs?.unit?.key ?? ''
  120 + }`,
117 }; 121 };
118 const data = { 122 const data = {
119 [item.name]: value, 123 [item.name]: value,
@@ -151,23 +155,28 @@ @@ -151,23 +155,28 @@
151 return temp; 155 return temp;
152 }; 156 };
153 const handleDataFormat = (deviceDetail: any, attributes: any) => { 157 const handleDataFormat = (deviceDetail: any, attributes: any) => {
154 - const { name, tbDeviceId } = deviceDetail; 158 + const { name, tbDeviceId, alias } = deviceDetail;
155 const attribute = attributes.map((item) => ({ 159 const attribute = attributes.map((item) => ({
156 identifier: item.identifier, 160 identifier: item.identifier,
157 name: item.name, 161 name: item.name,
158 detail: item.detail, 162 detail: item.detail,
159 })); 163 }));
160 return { 164 return {
161 - name, 165 + name: alias || name,
162 tbDeviceId, 166 tbDeviceId,
163 attribute, 167 attribute,
164 }; 168 };
165 }; 169 };
166 170
  171 + const getCanBatchAck = computed(() => {
  172 + const rowSelection = getRowSelection();
  173 + return !rowSelection.selectedRowKeys?.length;
  174 + });
  175 +
167 const { createMessage } = useMessage(); 176 const { createMessage } = useMessage();
168 const handleBatchAck = async () => { 177 const handleBatchAck = async () => {
169 const ids = getSelectRows<AlarmLogItem>().map((item) => item.id); 178 const ids = getSelectRows<AlarmLogItem>().map((item) => item.id);
170 - 179 + if (!ids.length) return;
171 await doBatchAckAlarm(ids); 180 await doBatchAckAlarm(ids);
172 createMessage.success('操作成功'); 181 createMessage.success('操作成功');
173 clearSelectedRowKeys(); 182 clearSelectedRowKeys();
@@ -181,6 +190,7 @@ @@ -181,6 +190,7 @@
181 handleSuccess, 190 handleSuccess,
182 handleViewAlarmDetails, 191 handleViewAlarmDetails,
183 handleBatchAck, 192 handleBatchAck,
  193 + getCanBatchAck,
184 }; 194 };
185 }, 195 },
186 }); 196 });
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 <template #iconSelect> 11 <template #iconSelect>
12 <Upload 12 <Upload
13 name="avatar" 13 name="avatar"
  14 + accept=".png,.jpg,.jpeg,.gif"
14 list-type="picture-card" 15 list-type="picture-card"
15 class="avatar-uploader" 16 class="avatar-uploader"
16 :show-upload-list="false" 17 :show-upload-list="false"
@@ -93,6 +93,7 @@ export const formSchema: FormSchema[] = [ @@ -93,6 +93,7 @@ export const formSchema: FormSchema[] = [
93 return { 93 return {
94 listType: 'picture-card', 94 listType: 'picture-card',
95 maxFileLimit: 1, 95 maxFileLimit: 1,
  96 + accept: '.png,.jpg,.jpeg,.gif',
96 api: async (file: File) => { 97 api: async (file: File) => {
97 try { 98 try {
98 const formData = new FormData(); 99 const formData = new FormData();
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 import { ConfigurationCenterItemsModal } from '/@/api/configuration/center/model/configurationCenterModal'; 11 import { ConfigurationCenterItemsModal } from '/@/api/configuration/center/model/configurationCenterModal';
12 import { PageWrapper } from '/@/components/Page'; 12 import { PageWrapper } from '/@/components/Page';
13 import { BasicForm, useForm } from '/@/components/Form'; 13 import { BasicForm, useForm } from '/@/components/Form';
14 - import { ConfigurationPermission, searchFormSchema } from './center.data'; 14 + import { ConfigurationPermission, Platform, searchFormSchema } from './center.data';
15 import { useMessage } from '/@/hooks/web/useMessage'; 15 import { useMessage } from '/@/hooks/web/useMessage';
16 import { Authority } from '/@/components/Authority'; 16 import { Authority } from '/@/components/Authority';
17 import { isDevMode } from '/@/utils/env'; 17 import { isDevMode } from '/@/utils/env';
@@ -30,6 +30,7 @@ @@ -30,6 +30,7 @@
30 import { ViewType } from '../../visual/board/config/panelDetail'; 30 import { ViewType } from '../../visual/board/config/panelDetail';
31 import { useRole } from '/@/hooks/business/useRole'; 31 import { useRole } from '/@/hooks/business/useRole';
32 import { useClipboard } from '@vueuse/core'; 32 import { useClipboard } from '@vueuse/core';
  33 + import { Icon } from '/@/components/Icon';
33 34
34 const listColumn = ref(5); 35 const listColumn = ref(5);
35 36
@@ -187,7 +188,7 @@ @@ -187,7 +188,7 @@
187 188
188 onMounted(() => { 189 onMounted(() => {
189 const clientHeight = document.documentElement.clientHeight; 190 const clientHeight = document.documentElement.clientHeight;
190 - const rect = getBoundingClientRect(unref(listEl)!.$el!) as DOMRect; 191 + const rect = getBoundingClientRect(unref(listEl)!.$el! as HTMLElement) as DOMRect;
191 // margin-top 24 height 24 192 // margin-top 24 height 24
192 const paginationHeight = 24 + 24 + 8; 193 const paginationHeight = 24 + 24 + 8;
193 // list pading top 8 maring-top 8 extra slot 56 194 // list pading top 8 maring-top 8 extra slot 56
@@ -322,7 +323,16 @@ @@ -322,7 +323,16 @@
322 </template> 323 </template>
323 <template #description> 324 <template #description>
324 <div class="truncate h-11"> 325 <div class="truncate h-11">
325 - <div class="truncate">{{ item.organizationDTO.name }}</div> 326 + <div class="truncate flex justify-between items-center">
  327 + <div>{{ item.organizationDTO.name }}</div>
  328 + <Icon
  329 + :icon="
  330 + item.platform === Platform.PC
  331 + ? 'ri:computer-line'
  332 + : 'clarity:mobile-phone-solid'
  333 + "
  334 + />
  335 + </div>
326 <div class="truncate">{{ item.remark || '' }} </div> 336 <div class="truncate">{{ item.remark || '' }} </div>
327 </div> 337 </div>
328 </template> 338 </template>
@@ -59,6 +59,7 @@ export const formSchema: FormSchema[] = [ @@ -59,6 +59,7 @@ export const formSchema: FormSchema[] = [
59 return { 59 return {
60 listType: 'picture-card', 60 listType: 'picture-card',
61 maxFileLimit: 1, 61 maxFileLimit: 1,
  62 + accept: '.png,.jpg,.jpeg,.gif',
62 api: async (file: File) => { 63 api: async (file: File) => {
63 try { 64 try {
64 const formData = new FormData(); 65 const formData = new FormData();
@@ -175,6 +175,10 @@ export const alarmColumns: BasicColumn[] = [ @@ -175,6 +175,10 @@ export const alarmColumns: BasicColumn[] = [
175 title: '告警设备', 175 title: '告警设备',
176 dataIndex: 'deviceName', 176 dataIndex: 'deviceName',
177 width: 120, 177 width: 120,
  178 + customRender: ({ record }) => {
  179 + const { deviceAlias, deviceName } = record || {};
  180 + return deviceAlias || deviceName;
  181 + },
178 }, 182 },
179 { 183 {
180 title: '告警场景', 184 title: '告警场景',
@@ -52,13 +52,15 @@ @@ -52,13 +52,15 @@
52 const alarmStatus = ref(''); 52 const alarmStatus = ref('');
53 const [registerModal, { closeModal }] = useModalInner(async (data) => { 53 const [registerModal, { closeModal }] = useModalInner(async (data) => {
54 await resetFields(); 54 await resetFields();
  55 + const { deviceAlias, deviceName, severity, status, id } = data || {};
55 await setFieldsValue({ 56 await setFieldsValue({
56 ...data, 57 ...data,
57 - severity: alarmLevel(data.severity),  
58 - status: statusType(data.status), 58 + deviceName: deviceAlias || deviceName,
  59 + severity: alarmLevel(severity),
  60 + status: statusType(status),
59 }); 61 });
60 - alarmId.value = data.id;  
61 - alarmStatus.value = data.status; 62 + alarmId.value = id;
  63 + alarmStatus.value = status;
62 }); 64 });
63 // 处理报警 65 // 处理报警
64 const handleAlarm = async () => { 66 const handleAlarm = async () => {
@@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@
25 <template #iconSelect> 25 <template #iconSelect>
26 <Upload 26 <Upload
27 name="avatar" 27 name="avatar"
  28 + accept=".png,.jpg,.jpeg,.gif"
28 :show-upload-list="false" 29 :show-upload-list="false"
29 list-type="picture-card" 30 list-type="picture-card"
30 class="avatar-uploader" 31 class="avatar-uploader"
@@ -143,14 +143,14 @@ @@ -143,14 +143,14 @@
143 return temp; 143 return temp;
144 }; 144 };
145 const handleDataFormat = (deviceDetail: any, attributes: any) => { 145 const handleDataFormat = (deviceDetail: any, attributes: any) => {
146 - const { name, tbDeviceId } = deviceDetail; 146 + const { name, alias, tbDeviceId } = deviceDetail;
147 const attribute = attributes.map((item) => ({ 147 const attribute = attributes.map((item) => ({
148 identifier: item.identifier, 148 identifier: item.identifier,
149 name: item.name, 149 name: item.name,
150 detail: item.detail, 150 detail: item.detail,
151 })); 151 }));
152 return { 152 return {
153 - name, 153 + name: alias || name,
154 tbDeviceId, 154 tbDeviceId,
155 attribute, 155 attribute,
156 }; 156 };
@@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
5 <Upload 5 <Upload
6 style="width: 20vw" 6 style="width: 20vw"
7 name="avatar" 7 name="avatar"
  8 + accept=".png,.jpg,.jpeg,.gif"
8 list-type="picture-card" 9 list-type="picture-card"
9 class="avatar-uploader" 10 class="avatar-uploader"
10 :show-upload-list="false" 11 :show-upload-list="false"
@@ -67,6 +67,9 @@ @@ -67,6 +67,9 @@
67 for (let i in credentials) Reflect.set(credentialsFile, i, credentials[i]); 67 for (let i in credentials) Reflect.set(credentialsFile, i, credentials[i]);
68 } 68 }
69 setFieldsValue(value); 69 setFieldsValue(value);
  70 + setFieldsValue({
  71 + type: credentials.type,
  72 + });
70 }; 73 };
71 74
72 const resetValue = () => resetFields(); 75 const resetValue = () => resetFields();
@@ -268,6 +268,7 @@ @@ -268,6 +268,7 @@
268 //ft-add-2022-11-22 268 //ft-add-2022-11-22
269 const type = validate?.outTarget; 269 const type = validate?.outTarget;
270 if (type === 'DEVICE_OUT') { 270 if (type === 'DEVICE_OUT') {
  271 + if (!validate.deviceType) return createMessage.error('请选择类型');
271 if (!validate.deviceProfileId) return createMessage.error('请选择产品'); 272 if (!validate.deviceProfileId) return createMessage.error('请选择产品');
272 if (validate.device == 'PART' && validate.deviceId == undefined) 273 if (validate.device == 'PART' && validate.deviceId == undefined)
273 return createMessage.error('请选择设备'); 274 return createMessage.error('请选择设备');
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 <template #iconSelect> 11 <template #iconSelect>
12 <Upload 12 <Upload
13 name="avatar" 13 name="avatar"
  14 + accept=".png,.jpg,.jpeg,.gif"
14 list-type="picture-card" 15 list-type="picture-card"
15 class="avatar-uploader" 16 class="avatar-uploader"
16 :show-upload-list="false" 17 :show-upload-list="false"