Commit 988e262dfea1c4cd31ab275d2537cb793bcf8e00
Merge branch 'local_dev_ft' into 'main'
feat:联调上下线记录接口 See merge request huang/yun-teng-iot-front!457
Showing
10 changed files
with
297 additions
and
172 deletions
| @@ -7,6 +7,7 @@ import { | @@ -7,6 +7,7 @@ import { | ||
| 7 | DeviceQueryParam, | 7 | DeviceQueryParam, |
| 8 | DeviceRecord, | 8 | DeviceRecord, |
| 9 | DeviceTypeEnum, | 9 | DeviceTypeEnum, |
| 10 | + DeviceStateLogModel, | ||
| 10 | } from '/@/api/device/model/deviceModel'; | 11 | } from '/@/api/device/model/deviceModel'; |
| 11 | import { ChildDeviceParams } from './model/deviceModel'; | 12 | import { ChildDeviceParams } from './model/deviceModel'; |
| 12 | import { PaginationResult } from '/#/axios'; | 13 | import { PaginationResult } from '/#/axios'; |
| @@ -26,11 +27,14 @@ enum DeviceManagerApi { | @@ -26,11 +27,14 @@ enum DeviceManagerApi { | ||
| 26 | DEVICE_ALARM_URL = '/alarm', | 27 | DEVICE_ALARM_URL = '/alarm', |
| 27 | 28 | ||
| 28 | DEVICE_CREDENTIALS = '/device/credentials', | 29 | DEVICE_CREDENTIALS = '/device/credentials', |
| 30 | + | ||
| 29 | COMMAND_ISSUANCE = '/rpc', | 31 | COMMAND_ISSUANCE = '/rpc', |
| 30 | 32 | ||
| 31 | DEVICE_ATTR = '/device/attributes', | 33 | DEVICE_ATTR = '/device/attributes', |
| 32 | 34 | ||
| 33 | GATEWAY_DEVICE = '/device/gateway/list', | 35 | GATEWAY_DEVICE = '/device/gateway/list', |
| 36 | + | ||
| 37 | + DEVICE_STATE_LOG_URL = '/device/state/log', | ||
| 34 | } | 38 | } |
| 35 | 39 | ||
| 36 | export const devicePage = (params: DeviceQueryParam) => { | 40 | export const devicePage = (params: DeviceQueryParam) => { |
| @@ -257,3 +261,40 @@ export const getDeviceAttrs = (params: { deviceProfileId: string; dataType?: str | @@ -257,3 +261,40 @@ export const getDeviceAttrs = (params: { deviceProfileId: string; dataType?: str | ||
| 257 | params: { dataType }, | 261 | params: { dataType }, |
| 258 | }); | 262 | }); |
| 259 | }; | 263 | }; |
| 264 | + | ||
| 265 | +/** | ||
| 266 | + * 设备上下线记录相关api | ||
| 267 | + */ | ||
| 268 | +export const deviceStateLogPage = (params: DeviceQueryParam) => { | ||
| 269 | + return defHttp.get<DeviceStateLogModel>({ | ||
| 270 | + url: DeviceManagerApi.DEVICE_STATE_LOG_URL, | ||
| 271 | + params, | ||
| 272 | + }); | ||
| 273 | +}; | ||
| 274 | + | ||
| 275 | +export const deleteStateLogDevice = (ids: string[]) => { | ||
| 276 | + return defHttp.delete({ | ||
| 277 | + url: DeviceManagerApi.DEVICE_STATE_LOG_URL, | ||
| 278 | + data: { | ||
| 279 | + ids: ids, | ||
| 280 | + }, | ||
| 281 | + }); | ||
| 282 | +}; | ||
| 283 | + | ||
| 284 | +export const deviceStateLogDetail = (id) => { | ||
| 285 | + return defHttp.get<DeviceStateLogModel>({ | ||
| 286 | + url: DeviceManagerApi.DEVICE_STATE_LOG_URL + '/' + id, | ||
| 287 | + }); | ||
| 288 | +}; | ||
| 289 | + | ||
| 290 | +export const deviceStateLogPost = (data) => { | ||
| 291 | + return defHttp.post( | ||
| 292 | + { | ||
| 293 | + url: DeviceManagerApi.DEVICE_STATE_LOG_URL, | ||
| 294 | + data, | ||
| 295 | + } | ||
| 296 | + // { | ||
| 297 | + // joinPrefix: false, | ||
| 298 | + // } | ||
| 299 | + ); | ||
| 300 | +}; |
| @@ -170,3 +170,33 @@ export interface DeviceModelOfMatterAttrs { | @@ -170,3 +170,33 @@ export interface DeviceModelOfMatterAttrs { | ||
| 170 | identifier: string; | 170 | identifier: string; |
| 171 | detail: StructJSON; | 171 | detail: StructJSON; |
| 172 | } | 172 | } |
| 173 | + | ||
| 174 | +export interface DeviceStateLogModel { | ||
| 175 | + items: [ | ||
| 176 | + { | ||
| 177 | + createTime: string; | ||
| 178 | + creator: string; | ||
| 179 | + defaultConfig: string; | ||
| 180 | + description: string; | ||
| 181 | + deviceName: string; | ||
| 182 | + deviceProfileName: string; | ||
| 183 | + deviceType: string; | ||
| 184 | + enabled: true; | ||
| 185 | + icon: string; | ||
| 186 | + id: string; | ||
| 187 | + name: string; | ||
| 188 | + organizationName: string; | ||
| 189 | + remark: string; | ||
| 190 | + roleIds: [string]; | ||
| 191 | + status: 0; | ||
| 192 | + tbDeviceId: string; | ||
| 193 | + tenantExpireTime: string; | ||
| 194 | + tenantId: string; | ||
| 195 | + tenantProfileId: string; | ||
| 196 | + tenantStatus: string; | ||
| 197 | + updateTime: string; | ||
| 198 | + updater: string; | ||
| 199 | + } | ||
| 200 | + ]; | ||
| 201 | + total: 0; | ||
| 202 | +} |
| @@ -277,7 +277,6 @@ | @@ -277,7 +277,6 @@ | ||
| 277 | const deviceProfileId = ref(''); | 277 | const deviceProfileId = ref(''); |
| 278 | count.value = Number(getParams('count')); | 278 | count.value = Number(getParams('count')); |
| 279 | deviceProfileId.value = getParams('deviceProfileId') || ''; | 279 | deviceProfileId.value = getParams('deviceProfileId') || ''; |
| 280 | - | ||
| 281 | const setRowClassName = async () => { | 280 | const setRowClassName = async () => { |
| 282 | if (deviceProfileId.value !== undefined) { | 281 | if (deviceProfileId.value !== undefined) { |
| 283 | const { items, total } = await devicePage({ | 282 | const { items, total } = await devicePage({ |
| @@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
| 15 | 15 | ||
| 16 | const loading = ref(false); | 16 | const loading = ref(false); |
| 17 | 17 | ||
| 18 | - const props = defineProps<{ | 18 | + defineProps<{ |
| 19 | record: DeviceRecord; | 19 | record: DeviceRecord; |
| 20 | }>(); | 20 | }>(); |
| 21 | const go = useGo(); | 21 | const go = useGo(); |
| @@ -35,10 +35,9 @@ | @@ -35,10 +35,9 @@ | ||
| 35 | }, | 35 | }, |
| 36 | }, | 36 | }, |
| 37 | { | 37 | { |
| 38 | - field: 'deviceType', | 38 | + field: 'deviceTypeName', |
| 39 | label: '设备类型', | 39 | label: '设备类型', |
| 40 | render: (_, data) => { | 40 | render: (_, data) => { |
| 41 | - console.log(data); | ||
| 42 | return h( | 41 | return h( |
| 43 | Button, | 42 | Button, |
| 44 | { | 43 | { |
| @@ -55,7 +54,7 @@ | @@ -55,7 +54,7 @@ | ||
| 55 | ); | 54 | ); |
| 56 | }, | 55 | }, |
| 57 | }, | 56 | }, |
| 58 | - () => `${data.deviceType}(${data.deviceCount})` | 57 | + () => `${data.deviceTypeName}(${data.deviceCount})` |
| 59 | ); | 58 | ); |
| 60 | }, | 59 | }, |
| 61 | }, | 60 | }, |
| @@ -87,7 +86,7 @@ | @@ -87,7 +86,7 @@ | ||
| 87 | ); | 86 | ); |
| 88 | if (!error) { | 87 | if (!error) { |
| 89 | const record = data.find((item) => item.itemValue === deviceType); | 88 | const record = data.find((item) => item.itemValue === deviceType); |
| 90 | - return { deviceType: record?.itemText }; | 89 | + return { deviceTypeName: record?.itemText }; |
| 91 | } | 90 | } |
| 92 | return {}; | 91 | return {}; |
| 93 | }; | 92 | }; |
| @@ -112,30 +111,22 @@ | @@ -112,30 +111,22 @@ | ||
| 112 | return {}; | 111 | return {}; |
| 113 | }; | 112 | }; |
| 114 | 113 | ||
| 115 | - async function getValues() { | ||
| 116 | - const { defaultRuleChainId, deviceType, defaultQueueName } = props.record; | ||
| 117 | - return await Promise.all([ | ||
| 118 | - findDeviceType(deviceType), | ||
| 119 | - findHandleQueue(defaultQueueName), | ||
| 120 | - findRuleChain(defaultRuleChainId), | ||
| 121 | - ]); | ||
| 122 | - } | ||
| 123 | - | ||
| 124 | - const renderProductInfo = async () => { | 114 | + const renderProductInfo = async (record: DeviceRecord) => { |
| 125 | try { | 115 | try { |
| 126 | data.value = {} as unknown as DeviceRecord; | 116 | data.value = {} as unknown as DeviceRecord; |
| 127 | loading.value = true; | 117 | loading.value = true; |
| 128 | - const values = await getValues(); | ||
| 129 | - // const { defaultRuleChainId, deviceType, defaultQueueName } = props.record; | ||
| 130 | - // data.value = props.record; | ||
| 131 | - // const values = await Promise.all([ | ||
| 132 | - // findDeviceType(deviceType), | ||
| 133 | - // findHandleQueue(defaultQueueName), | ||
| 134 | - // findRuleChain(defaultRuleChainId), | ||
| 135 | - // ]); | 118 | + const { defaultRuleChainId, deviceType, defaultQueueName } = record; |
| 119 | + if (![defaultRuleChainId, deviceType, defaultQueueName].some(Boolean)) { | ||
| 120 | + return; | ||
| 121 | + } | ||
| 122 | + data.value = record; | ||
| 123 | + const values = await Promise.all([ | ||
| 124 | + findDeviceType(deviceType), | ||
| 125 | + findHandleQueue(defaultQueueName), | ||
| 126 | + findRuleChain(defaultRuleChainId), | ||
| 127 | + ]); | ||
| 136 | const value = values.reduce((prev, next) => ({ ...prev, ...next }), {}); | 128 | const value = values.reduce((prev, next) => ({ ...prev, ...next }), {}); |
| 137 | - data.value = Object.assign(unref(data), props.record, value); | ||
| 138 | - console.log(data.value); | 129 | + data.value = Object.assign(unref(data), value); |
| 139 | setDescProps({ data: unref(data) }); | 130 | setDescProps({ data: unref(data) }); |
| 140 | } catch (error) { | 131 | } catch (error) { |
| 141 | throw error; | 132 | throw error; |
| 1 | +<template> | ||
| 2 | + <BasicDrawer v-bind="$attrs" @register="registerDrawer" title="处理上下线记录" width="30%"> | ||
| 3 | + <Description :column="3" size="middle" @register="registeDesc" /> | ||
| 4 | + <div style="height: 30px"></div> | ||
| 5 | + <BasicForm @register="registerForm" /> | ||
| 6 | + <div class="flex flex-end" style="float: right"> | ||
| 7 | + <a-button type="primary" @click="handleDeviceState">处理</a-button> | ||
| 8 | + </div> | ||
| 9 | + </BasicDrawer> | ||
| 10 | +</template> | ||
| 11 | +<script lang="ts" setup> | ||
| 12 | + import { reactive } from 'vue'; | ||
| 13 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
| 14 | + import { formHandleSchema, formDetailSchema } from './config.data'; | ||
| 15 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
| 16 | + import { deviceStateLogPost } from '/@/api/device/deviceManager'; | ||
| 17 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
| 18 | + import { useDescription } from '/@/components/Description'; | ||
| 19 | + import { Description } from '/@/components/Description/index'; | ||
| 20 | + | ||
| 21 | + const emits = defineEmits(['success', 'register']); | ||
| 22 | + | ||
| 23 | + const { createMessage } = useMessage(); | ||
| 24 | + | ||
| 25 | + const record = reactive({ | ||
| 26 | + obj: {}, | ||
| 27 | + }); | ||
| 28 | + | ||
| 29 | + const [registerForm, { resetFields, getFieldsValue }] = useForm({ | ||
| 30 | + schemas: formHandleSchema, | ||
| 31 | + showActionButtonGroup: false, | ||
| 32 | + }); | ||
| 33 | + | ||
| 34 | + const [registeDesc, { setDescProps }] = useDescription({ | ||
| 35 | + schema: formDetailSchema, | ||
| 36 | + column: 2, | ||
| 37 | + layout: 'vertical', | ||
| 38 | + }); | ||
| 39 | + | ||
| 40 | + const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => { | ||
| 41 | + await resetFields(); | ||
| 42 | + setDrawerProps({ confirmLoading: false }); | ||
| 43 | + record.obj = data.record; | ||
| 44 | + setDescProps({ data: data.record }); | ||
| 45 | + }); | ||
| 46 | + | ||
| 47 | + const handleDeviceState = async () => { | ||
| 48 | + const values = getFieldsValue(); | ||
| 49 | + await deviceStateLogPost({ | ||
| 50 | + ...record.obj, | ||
| 51 | + ...values, | ||
| 52 | + }); | ||
| 53 | + emits('success'); | ||
| 54 | + closeDrawer(); | ||
| 55 | + createMessage.success('处理成功'); | ||
| 56 | + }; | ||
| 57 | +</script> |
| 1 | <template> | 1 | <template> |
| 2 | - <BasicDrawer v-bind="$attrs" @register="registerDrawer" title="上下线记录详情" width="40%"> | ||
| 3 | - <BasicForm @register="registerForm" /> | 2 | + <BasicDrawer v-bind="$attrs" @register="registerDrawer" title="上下线记录详情" width="25%"> |
| 3 | + <Description :column="3" size="middle" @register="registeDesc" /> | ||
| 4 | </BasicDrawer> | 4 | </BasicDrawer> |
| 5 | </template> | 5 | </template> |
| 6 | <script lang="ts" setup> | 6 | <script lang="ts" setup> |
| 7 | - import { BasicForm, useForm } from '/@/components/Form'; | ||
| 8 | import { formSchema } from './config.data'; | 7 | import { formSchema } from './config.data'; |
| 9 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | 8 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; |
| 9 | + import { deviceStateLogDetail } from '/@/api/device/deviceManager'; | ||
| 10 | + import { Description } from '/@/components/Description/index'; | ||
| 11 | + import { useDescription } from '/@/components/Description'; | ||
| 10 | 12 | ||
| 11 | defineEmits(['success', 'register']); | 13 | defineEmits(['success', 'register']); |
| 12 | - const [registerForm, { setFieldsValue, resetFields }] = useForm({ | ||
| 13 | - labelWidth: 120, | ||
| 14 | - schemas: formSchema, | ||
| 15 | - showActionButtonGroup: false, | 14 | + |
| 15 | + const [registeDesc, { setDescProps }] = useDescription({ | ||
| 16 | + schema: formSchema, | ||
| 17 | + column: 2, | ||
| 18 | + layout: 'vertical', | ||
| 16 | }); | 19 | }); |
| 17 | 20 | ||
| 18 | const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (data) => { | 21 | const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (data) => { |
| 19 | - await resetFields(); | ||
| 20 | setDrawerProps({ confirmLoading: false }); | 22 | setDrawerProps({ confirmLoading: false }); |
| 21 | - await setFieldsValue(data.record); | 23 | + const res = await deviceStateLogDetail(data.record.id); |
| 24 | + setDescProps({ data: res }); | ||
| 22 | }); | 25 | }); |
| 23 | </script> | 26 | </script> |
| @@ -2,6 +2,7 @@ import { BasicColumn, FormSchema } from '/@/components/Table'; | @@ -2,6 +2,7 @@ import { BasicColumn, FormSchema } from '/@/components/Table'; | ||
| 2 | import moment from 'moment'; | 2 | import moment from 'moment'; |
| 3 | import { h } from 'vue'; | 3 | import { h } from 'vue'; |
| 4 | import { Tag } from 'ant-design-vue'; | 4 | import { Tag } from 'ant-design-vue'; |
| 5 | +import { DescItem } from '/@/components/Description'; | ||
| 5 | 6 | ||
| 6 | // 表格数据 | 7 | // 表格数据 |
| 7 | export const columns: BasicColumn[] = [ | 8 | export const columns: BasicColumn[] = [ |
| @@ -12,17 +13,24 @@ export const columns: BasicColumn[] = [ | @@ -12,17 +13,24 @@ export const columns: BasicColumn[] = [ | ||
| 12 | }, | 13 | }, |
| 13 | { | 14 | { |
| 14 | title: '设备配置', | 15 | title: '设备配置', |
| 15 | - dataIndex: 'deviceConfig', | 16 | + dataIndex: 'deviceProfileName', |
| 16 | width: 120, | 17 | width: 120, |
| 17 | }, | 18 | }, |
| 18 | { | 19 | { |
| 19 | title: '设备类型', | 20 | title: '设备类型', |
| 20 | - dataIndex: 'entityType', | 21 | + dataIndex: 'deviceType', |
| 21 | width: 180, | 22 | width: 180, |
| 23 | + format: (_text: string, record: Recordable) => { | ||
| 24 | + return record.deviceType == 'DIRECT_CONNECTION' | ||
| 25 | + ? '直连设备' | ||
| 26 | + : record.deviceType == 'GATEWAY' | ||
| 27 | + ? '网关设备' | ||
| 28 | + : '网关子设备'; | ||
| 29 | + }, | ||
| 22 | }, | 30 | }, |
| 23 | { | 31 | { |
| 24 | title: '所属组织', | 32 | title: '所属组织', |
| 25 | - dataIndex: 'orgName', | 33 | + dataIndex: 'organizationName', |
| 26 | width: 120, | 34 | width: 120, |
| 27 | }, | 35 | }, |
| 28 | { | 36 | { |
| @@ -31,9 +39,9 @@ export const columns: BasicColumn[] = [ | @@ -31,9 +39,9 @@ export const columns: BasicColumn[] = [ | ||
| 31 | width: 180, | 39 | width: 180, |
| 32 | customRender: ({ record }) => { | 40 | customRender: ({ record }) => { |
| 33 | const status = record.status; | 41 | const status = record.status; |
| 34 | - const enable = status === 'SUCCESS' ? '启用' : '禁用'; | ||
| 35 | - const color = enable === '启用' ? 'green' : 'red'; | ||
| 36 | - const text = enable === '启用' ? '启用' : '禁用'; | 42 | + const enable = status === 1 ? '在线' : '离线'; |
| 43 | + const color = enable === '在线' ? 'green' : 'red'; | ||
| 44 | + const text = enable === '在线' ? '在线' : '离线'; | ||
| 37 | return h(Tag, { color }, () => text); | 45 | return h(Tag, { color }, () => text); |
| 38 | }, | 46 | }, |
| 39 | }, | 47 | }, |
| @@ -79,12 +87,12 @@ export const searchFormSchema: FormSchema[] = [ | @@ -79,12 +87,12 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 79 | placeholder: '请选择状态', | 87 | placeholder: '请选择状态', |
| 80 | options: [ | 88 | options: [ |
| 81 | { | 89 | { |
| 82 | - label: '启用', | ||
| 83 | - value: 'NOTICE', | 90 | + label: '在线', |
| 91 | + value: 1, | ||
| 84 | }, | 92 | }, |
| 85 | { | 93 | { |
| 86 | - label: '禁用', | ||
| 87 | - value: 'MEETING', | 94 | + label: '离线', |
| 95 | + value: 0, | ||
| 88 | }, | 96 | }, |
| 89 | ], | 97 | ], |
| 90 | }, | 98 | }, |
| @@ -102,112 +110,93 @@ export const searchFormSchema: FormSchema[] = [ | @@ -102,112 +110,93 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 102 | }, | 110 | }, |
| 103 | ]; | 111 | ]; |
| 104 | 112 | ||
| 105 | -// 详情配置 | ||
| 106 | -export const formSchema: FormSchema[] = [ | 113 | +export const formSchema: DescItem[] = [ |
| 107 | { | 114 | { |
| 108 | field: 'deviceName', | 115 | field: 'deviceName', |
| 109 | label: '设备名称', | 116 | label: '设备名称', |
| 110 | - component: 'Input', | ||
| 111 | - componentProps: { | ||
| 112 | - disabled: true, | ||
| 113 | - }, | ||
| 114 | }, | 117 | }, |
| 115 | { | 118 | { |
| 116 | - field: 'deviceConfig', | 119 | + field: 'deviceProfileName', |
| 117 | label: '设备配置', | 120 | label: '设备配置', |
| 118 | - component: 'Input', | ||
| 119 | - componentProps: { | ||
| 120 | - disabled: true, | ||
| 121 | - }, | ||
| 122 | }, | 121 | }, |
| 123 | { | 122 | { |
| 124 | - field: 'entityType', | 123 | + field: 'deviceType', |
| 125 | label: '设备类型', | 124 | label: '设备类型', |
| 126 | - component: 'Input', | ||
| 127 | - componentProps: { | ||
| 128 | - disabled: true, | 125 | + render: (_, data) => { |
| 126 | + return data.deviceType == 'DIRECT_CONNECTION' | ||
| 127 | + ? '直连设备' | ||
| 128 | + : data.deviceType == 'GATEWAY' | ||
| 129 | + ? '网关设备' | ||
| 130 | + : '网关子设备'; | ||
| 129 | }, | 131 | }, |
| 130 | }, | 132 | }, |
| 131 | { | 133 | { |
| 132 | - field: 'orgName', | 134 | + field: 'organizationName', |
| 133 | label: '所属组织', | 135 | label: '所属组织', |
| 134 | - component: 'Input', | ||
| 135 | - componentProps: { | ||
| 136 | - disabled: true, | ||
| 137 | - }, | ||
| 138 | }, | 136 | }, |
| 139 | { | 137 | { |
| 140 | field: 'status', | 138 | field: 'status', |
| 141 | label: '状态', | 139 | label: '状态', |
| 142 | - component: 'Input', | ||
| 143 | - componentProps: { | ||
| 144 | - disabled: true, | 140 | + render: (_, data) => { |
| 141 | + return data.status == 1 ? '在线' : '离线'; | ||
| 145 | }, | 142 | }, |
| 146 | }, | 143 | }, |
| 147 | { | 144 | { |
| 148 | field: 'createTime', | 145 | field: 'createTime', |
| 149 | label: '时间', | 146 | label: '时间', |
| 150 | - colProps: { span: 24 }, | ||
| 151 | - component: 'Input', | ||
| 152 | - componentProps: { | ||
| 153 | - disabled: true, | 147 | + }, |
| 148 | +]; | ||
| 149 | + | ||
| 150 | +export const formDetailSchema: DescItem[] = [ | ||
| 151 | + { | ||
| 152 | + field: 'deviceName', | ||
| 153 | + label: '设备名称', | ||
| 154 | + }, | ||
| 155 | + { | ||
| 156 | + field: 'status', | ||
| 157 | + label: '状态', | ||
| 158 | + render: (_, data) => { | ||
| 159 | + return data.status == 1 ? '在线' : '离线'; | ||
| 154 | }, | 160 | }, |
| 155 | }, | 161 | }, |
| 162 | + { | ||
| 163 | + field: 'createTime', | ||
| 164 | + label: '时间', | ||
| 165 | + }, | ||
| 156 | ]; | 166 | ]; |
| 157 | 167 | ||
| 158 | -export const mockList = [ | ||
| 159 | - { | ||
| 160 | - deviceName: '网关/直连设备', | ||
| 161 | - id: '2d2321s122131', | ||
| 162 | - deviceConfig: '车车网关设备配置', | ||
| 163 | - entityType: '网关', | ||
| 164 | - orgName: 'cheche', | ||
| 165 | - status: 'SUCCESS', | ||
| 166 | - createTime: '2022-12-22 16:25:36', | ||
| 167 | - }, | ||
| 168 | - { | ||
| 169 | - deviceName: '网关/直连设备', | ||
| 170 | - id: '2d22321s12131', | ||
| 171 | - deviceConfig: '车车网关设备配置', | ||
| 172 | - entityType: '网关', | ||
| 173 | - orgName: 'cheche', | ||
| 174 | - status: 'SUCCESS', | ||
| 175 | - createTime: '2022-12-22 16:25:36', | ||
| 176 | - }, | ||
| 177 | - { | ||
| 178 | - deviceName: '网关/直连设备', | ||
| 179 | - id: '2d232d1s12131', | ||
| 180 | - deviceConfig: '车车网关设备配置', | ||
| 181 | - entityType: '网关', | ||
| 182 | - orgName: 'cheche', | ||
| 183 | - status: 'SUCCESS', | ||
| 184 | - createTime: '2022-12-22 16:25:36', | ||
| 185 | - }, | ||
| 186 | - { | ||
| 187 | - deviceName: '网关/直连设备', | ||
| 188 | - id: '2d2321fs12131', | ||
| 189 | - deviceConfig: '车车网关设备配置', | ||
| 190 | - entityType: '网关', | ||
| 191 | - orgName: 'cheche', | ||
| 192 | - status: 'SUCCESS', | ||
| 193 | - createTime: '2022-12-22 16:25:36', | ||
| 194 | - }, | ||
| 195 | - { | ||
| 196 | - deviceName: '网关/直连设备', | ||
| 197 | - id: '2d2321ggs12131', | ||
| 198 | - deviceConfig: '车车网关设备配置', | ||
| 199 | - entityType: '网关', | ||
| 200 | - orgName: 'cheche', | ||
| 201 | - status: 'SUCCESS', | ||
| 202 | - createTime: '2022-12-22 16:25:36', | ||
| 203 | - }, | ||
| 204 | - { | ||
| 205 | - deviceName: '网关/直连设备', | ||
| 206 | - id: '2d2321hhs12131', | ||
| 207 | - deviceConfig: '车车网关设备配置', | ||
| 208 | - entityType: '网关', | ||
| 209 | - orgName: 'cheche', | ||
| 210 | - status: 'FATURE', | ||
| 211 | - createTime: '2022-12-22 16:25:36', | 168 | +//处理表单 |
| 169 | +export const formHandleSchema: FormSchema[] = [ | ||
| 170 | + // { | ||
| 171 | + // field: 'deviceName', | ||
| 172 | + // label: '设备名称', | ||
| 173 | + // component: 'Input', | ||
| 174 | + // componentProps: { | ||
| 175 | + // disabled: true, | ||
| 176 | + // }, | ||
| 177 | + // }, | ||
| 178 | + // { | ||
| 179 | + // field: 'status', | ||
| 180 | + // label: '状态', | ||
| 181 | + // component: 'Input', | ||
| 182 | + // componentProps: { | ||
| 183 | + // disabled: true, | ||
| 184 | + // }, | ||
| 185 | + // }, | ||
| 186 | + // { | ||
| 187 | + // field: 'createTime', | ||
| 188 | + // label: '时间', | ||
| 189 | + // colProps: { span: 24 }, | ||
| 190 | + // component: 'Input', | ||
| 191 | + // componentProps: { | ||
| 192 | + // disabled: true, | ||
| 193 | + // }, | ||
| 194 | + // }, | ||
| 195 | + { | ||
| 196 | + field: 'description', | ||
| 197 | + label: '备注', | ||
| 198 | + colProps: { span: 24 }, | ||
| 199 | + component: 'InputTextArea', | ||
| 200 | + componentProps: {}, | ||
| 212 | }, | 201 | }, |
| 213 | ]; | 202 | ]; |
| @@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
| 2 | <div> | 2 | <div> |
| 3 | <BasicTable :clickToRowSelect="false" @register="registerTable"> | 3 | <BasicTable :clickToRowSelect="false" @register="registerTable"> |
| 4 | <template #toolbar> | 4 | <template #toolbar> |
| 5 | - <Authority value="api:yt:onlinerecord:delete"> | 5 | + <Authority value="api:yt:device:state:log::delete"> |
| 6 | <Popconfirm | 6 | <Popconfirm |
| 7 | title="您确定要批量删除数据" | 7 | title="您确定要批量删除数据" |
| 8 | ok-text="确定" | 8 | ok-text="确定" |
| @@ -17,14 +17,20 @@ | @@ -17,14 +17,20 @@ | ||
| 17 | <TableAction | 17 | <TableAction |
| 18 | :actions="[ | 18 | :actions="[ |
| 19 | { | 19 | { |
| 20 | + label: '处理', | ||
| 21 | + auth: 'api:yt:device:state:log::post', | ||
| 22 | + icon: 'clarity:note-edit-line', | ||
| 23 | + onClick: handleView.bind(null, record), | ||
| 24 | + }, | ||
| 25 | + { | ||
| 20 | label: '详情', | 26 | label: '详情', |
| 21 | - auth: 'api:yt:onlinerecord:get', | 27 | + auth: 'api:yt:device:state:log::detail', |
| 22 | icon: 'clarity:note-edit-line', | 28 | icon: 'clarity:note-edit-line', |
| 23 | onClick: handleViewDetail.bind(null, record), | 29 | onClick: handleViewDetail.bind(null, record), |
| 24 | }, | 30 | }, |
| 25 | { | 31 | { |
| 26 | label: '删除', | 32 | label: '删除', |
| 27 | - auth: 'api:yt:onlinerecord:delete', | 33 | + auth: 'api:yt:device:state:log::delete', |
| 28 | icon: 'ant-design:delete-outlined', | 34 | icon: 'ant-design:delete-outlined', |
| 29 | color: 'error', | 35 | color: 'error', |
| 30 | popConfirm: { | 36 | popConfirm: { |
| @@ -37,6 +43,7 @@ | @@ -37,6 +43,7 @@ | ||
| 37 | </template> | 43 | </template> |
| 38 | </BasicTable> | 44 | </BasicTable> |
| 39 | <OnlineRecordDrawer @register="registerDrawer" @success="handleSuccess" /> | 45 | <OnlineRecordDrawer @register="registerDrawer" @success="handleSuccess" /> |
| 46 | + <OnlineHandleDrawer @register="registerHandleDrawer" @success="handleHandleSuccess" /> | ||
| 40 | </div> | 47 | </div> |
| 41 | </template> | 48 | </template> |
| 42 | 49 | ||
| @@ -45,17 +52,16 @@ | @@ -45,17 +52,16 @@ | ||
| 45 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 52 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
| 46 | import { useDrawer } from '/@/components/Drawer'; | 53 | import { useDrawer } from '/@/components/Drawer'; |
| 47 | import OnlineRecordDrawer from './OnlineRecordDrawer.vue'; | 54 | import OnlineRecordDrawer from './OnlineRecordDrawer.vue'; |
| 48 | - // import { getExceptionPage } from '/@/api/log/logManager'; | ||
| 49 | - import { searchFormSchema, columns, mockList } from './config.data'; | 55 | + import OnlineHandleDrawer from './OnlineHandleDrawer.vue'; |
| 56 | + import { deviceStateLogPage, deleteStateLogDevice } from '/@/api/device/deviceManager'; | ||
| 57 | + import { searchFormSchema, columns } from './config.data'; | ||
| 50 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | 58 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; |
| 51 | - import { deleteConvertApi } from '/@/api/datamanager/dataManagerApi'; | ||
| 52 | import { Popconfirm } from 'ant-design-vue'; | 59 | import { Popconfirm } from 'ant-design-vue'; |
| 53 | import { Authority } from '/@/components/Authority'; | 60 | import { Authority } from '/@/components/Authority'; |
| 54 | 61 | ||
| 55 | const [registerTable, { setProps, reload }] = useTable({ | 62 | const [registerTable, { setProps, reload }] = useTable({ |
| 56 | title: '上下线记录', | 63 | title: '上下线记录', |
| 57 | - dataSource: mockList, | ||
| 58 | - // api: getExceptionPage, | 64 | + api: deviceStateLogPage, |
| 59 | columns, | 65 | columns, |
| 60 | showIndexColumn: false, | 66 | showIndexColumn: false, |
| 61 | clickToRowSelect: false, | 67 | clickToRowSelect: false, |
| @@ -76,12 +82,19 @@ | @@ -76,12 +82,19 @@ | ||
| 76 | fixed: 'right', | 82 | fixed: 'right', |
| 77 | }, | 83 | }, |
| 78 | }); | 84 | }); |
| 85 | + | ||
| 79 | const handleSuccess = () => { | 86 | const handleSuccess = () => { |
| 80 | reload(); | 87 | reload(); |
| 81 | resetSelectedRowKeys(); | 88 | resetSelectedRowKeys(); |
| 82 | }; | 89 | }; |
| 90 | + | ||
| 91 | + const handleHandleSuccess = () => { | ||
| 92 | + reload(); | ||
| 93 | + resetSelectedRowKeys(); | ||
| 94 | + }; | ||
| 95 | + | ||
| 83 | const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } = | 96 | const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } = |
| 84 | - useBatchDelete(deleteConvertApi, handleSuccess, setProps); | 97 | + useBatchDelete(deleteStateLogDevice, handleSuccess, setProps); |
| 85 | 98 | ||
| 86 | nextTick(() => { | 99 | nextTick(() => { |
| 87 | setProps(selectionOptions); | 100 | setProps(selectionOptions); |
| @@ -90,10 +103,18 @@ | @@ -90,10 +103,18 @@ | ||
| 90 | // 弹框 | 103 | // 弹框 |
| 91 | const [registerDrawer, { openDrawer }] = useDrawer(); | 104 | const [registerDrawer, { openDrawer }] = useDrawer(); |
| 92 | 105 | ||
| 106 | + const [registerHandleDrawer, { openDrawer: openHandleDrawer }] = useDrawer(); | ||
| 107 | + | ||
| 93 | const handleViewDetail = (record) => { | 108 | const handleViewDetail = (record) => { |
| 94 | openDrawer(true, { | 109 | openDrawer(true, { |
| 95 | isUpdate: true, | 110 | isUpdate: true, |
| 96 | record, | 111 | record, |
| 97 | }); | 112 | }); |
| 98 | }; | 113 | }; |
| 114 | + const handleView = (record) => { | ||
| 115 | + openHandleDrawer(true, { | ||
| 116 | + isUpdate: true, | ||
| 117 | + record, | ||
| 118 | + }); | ||
| 119 | + }; | ||
| 99 | </script> | 120 | </script> |
| @@ -31,16 +31,6 @@ | @@ -31,16 +31,6 @@ | ||
| 31 | ]" | 31 | ]" |
| 32 | /> | 32 | /> |
| 33 | </template> | 33 | </template> |
| 34 | - <template #status="{ record }"> | ||
| 35 | - <Switch | ||
| 36 | - :disabled="disabled" | ||
| 37 | - :checked="record.status === 1" | ||
| 38 | - :loading="record.pendingStatus" | ||
| 39 | - checkedChildren="启用" | ||
| 40 | - unCheckedChildren="禁用" | ||
| 41 | - @change="(checked:boolean)=>statusChange(checked,record)" | ||
| 42 | - /> | ||
| 43 | - </template> | ||
| 44 | </BasicTable> | 34 | </BasicTable> |
| 45 | <ItemDrawer @register="registerDrawer" @success="handleSuccess" /> | 35 | <ItemDrawer @register="registerDrawer" @success="handleSuccess" /> |
| 46 | </div> | 36 | </div> |
| @@ -51,17 +41,15 @@ | @@ -51,17 +41,15 @@ | ||
| 51 | import { defineComponent, ref } from 'vue'; | 41 | import { defineComponent, ref } from 'vue'; |
| 52 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 42 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
| 53 | import { sysDictItemPage, deleteDictItem } from '/@/api/system/dict'; | 43 | import { sysDictItemPage, deleteDictItem } from '/@/api/system/dict'; |
| 54 | - import { Switch } from 'ant-design-vue'; | ||
| 55 | import { BasicDrawer, useDrawer, useDrawerInner } from '/@/components/Drawer'; | 44 | import { BasicDrawer, useDrawer, useDrawerInner } from '/@/components/Drawer'; |
| 56 | import ItemDrawer from '/@/views/system/dict/item/ItemDrawer.vue'; | 45 | import ItemDrawer from '/@/views/system/dict/item/ItemDrawer.vue'; |
| 57 | import { columns, searchFormSchema } from './dict.item.data'; | 46 | import { columns, searchFormSchema } from './dict.item.data'; |
| 58 | import { useMessage } from '/@/hooks/web/useMessage'; | 47 | import { useMessage } from '/@/hooks/web/useMessage'; |
| 59 | import Authority from '/@/components/Authority/src/Authority.vue'; | 48 | import Authority from '/@/components/Authority/src/Authority.vue'; |
| 60 | - import { setDictItemStatus } from '/@/api/system/dict'; | ||
| 61 | 49 | ||
| 62 | export default defineComponent({ | 50 | export default defineComponent({ |
| 63 | name: 'ItemIndex', | 51 | name: 'ItemIndex', |
| 64 | - components: { BasicDrawer, BasicTable, ItemDrawer, TableAction, Authority, Switch }, | 52 | + components: { BasicDrawer, BasicTable, ItemDrawer, TableAction, Authority }, |
| 65 | setup() { | 53 | setup() { |
| 66 | let dictId; | 54 | let dictId; |
| 67 | const disabled = ref(false); | 55 | const disabled = ref(false); |
| @@ -81,7 +69,7 @@ | @@ -81,7 +69,7 @@ | ||
| 81 | 69 | ||
| 82 | reload(); | 70 | reload(); |
| 83 | }); | 71 | }); |
| 84 | - const [registerTable, { reload, setSelectedRowKeys, setProps }] = useTable({ | 72 | + const [registerTable, { reload }] = useTable({ |
| 85 | title: '字典值列表', | 73 | title: '字典值列表', |
| 86 | api: sysDictItemPage, | 74 | api: sysDictItemPage, |
| 87 | columns, | 75 | columns, |
| @@ -137,27 +125,6 @@ | @@ -137,27 +125,6 @@ | ||
| 137 | function handleSuccess() { | 125 | function handleSuccess() { |
| 138 | reload(); | 126 | reload(); |
| 139 | } | 127 | } |
| 140 | - const statusChange = async (checked, record) => { | ||
| 141 | - setProps({ | ||
| 142 | - loading: true, | ||
| 143 | - }); | ||
| 144 | - setSelectedRowKeys([]); | ||
| 145 | - const newStatus = checked ? 1 : 0; | ||
| 146 | - const { createMessage } = useMessage(); | ||
| 147 | - try { | ||
| 148 | - await setDictItemStatus(record.id, newStatus); | ||
| 149 | - if (newStatus) { | ||
| 150 | - createMessage.success(`启用成功`); | ||
| 151 | - } else { | ||
| 152 | - createMessage.success('禁用成功'); | ||
| 153 | - } | ||
| 154 | - } finally { | ||
| 155 | - setProps({ | ||
| 156 | - loading: false, | ||
| 157 | - }); | ||
| 158 | - reload(); | ||
| 159 | - } | ||
| 160 | - }; | ||
| 161 | return { | 128 | return { |
| 162 | register, | 129 | register, |
| 163 | registerTable, | 130 | registerTable, |
| @@ -166,7 +133,6 @@ | @@ -166,7 +133,6 @@ | ||
| 166 | handleEdit, | 133 | handleEdit, |
| 167 | handleDelete, | 134 | handleDelete, |
| 168 | handleSuccess, | 135 | handleSuccess, |
| 169 | - statusChange, | ||
| 170 | disabled, | 136 | disabled, |
| 171 | }; | 137 | }; |
| 172 | }, | 138 | }, |
| 1 | +import { Switch } from 'ant-design-vue'; | ||
| 1 | import { BasicColumn } from '/@/components/Table'; | 2 | import { BasicColumn } from '/@/components/Table'; |
| 2 | import { FormSchema } from '/@/components/Table'; | 3 | import { FormSchema } from '/@/components/Table'; |
| 4 | +import { useMessage } from '/@/hooks/web/useMessage'; | ||
| 5 | +import { setDictItemStatus } from '/@/api/system/dict'; | ||
| 6 | +import { h } from 'vue'; | ||
| 3 | 7 | ||
| 4 | export const columns: BasicColumn[] = [ | 8 | export const columns: BasicColumn[] = [ |
| 5 | { | 9 | { |
| @@ -21,8 +25,32 @@ export const columns: BasicColumn[] = [ | @@ -21,8 +25,32 @@ export const columns: BasicColumn[] = [ | ||
| 21 | title: '状态', | 25 | title: '状态', |
| 22 | dataIndex: 'status', | 26 | dataIndex: 'status', |
| 23 | width: 100, | 27 | width: 100, |
| 24 | - slots: { customRender: 'status' }, | 28 | + customRender: ({ record }) => { |
| 29 | + if (!Reflect.has(record, 'pendingStatus')) { | ||
| 30 | + record.pendingStatus = false; | ||
| 31 | + } | ||
| 32 | + return h(Switch, { | ||
| 33 | + checked: record.status === 1, | ||
| 34 | + checkedChildren: '已启用', | ||
| 35 | + unCheckedChildren: '已禁用', | ||
| 36 | + loading: record.pendingStatus, | ||
| 37 | + onChange(checked: boolean) { | ||
| 38 | + record.pendingStatus = true; | ||
| 39 | + const newStatus = checked ? 1 : 0; | ||
| 40 | + const { createMessage } = useMessage(); | ||
| 41 | + setDictItemStatus(record.id, newStatus) | ||
| 42 | + .then(() => { | ||
| 43 | + record.status = newStatus; | ||
| 44 | + createMessage.success(`修改成功`); | ||
| 45 | + }) | ||
| 46 | + .finally(() => { | ||
| 47 | + record.pendingStatus = false; | ||
| 48 | + }); | ||
| 49 | + }, | ||
| 50 | + }); | ||
| 51 | + }, | ||
| 25 | }, | 52 | }, |
| 53 | + | ||
| 26 | { | 54 | { |
| 27 | title: '排序', | 55 | title: '排序', |
| 28 | dataIndex: 'sort', | 56 | dataIndex: 'sort', |