Commit 542fc359c1c247ad0c34b9e949872baf317138be

Authored by fengtao
1 parent 222a16b9

feat:联调上下线记录接口

... ... @@ -7,6 +7,7 @@ import {
7 7 DeviceQueryParam,
8 8 DeviceRecord,
9 9 DeviceTypeEnum,
  10 + DeviceStateLogModel,
10 11 } from '/@/api/device/model/deviceModel';
11 12 import { ChildDeviceParams } from './model/deviceModel';
12 13 import { PaginationResult } from '/#/axios';
... ... @@ -26,11 +27,14 @@ enum DeviceManagerApi {
26 27 DEVICE_ALARM_URL = '/alarm',
27 28
28 29 DEVICE_CREDENTIALS = '/device/credentials',
  30 +
29 31 COMMAND_ISSUANCE = '/rpc',
30 32
31 33 DEVICE_ATTR = '/device/attributes',
32 34
33 35 GATEWAY_DEVICE = '/device/gateway/list',
  36 +
  37 + DEVICE_STATE_LOG_URL = '/device/state/log',
34 38 }
35 39
36 40 export const devicePage = (params: DeviceQueryParam) => {
... ... @@ -258,3 +262,40 @@ export const getDeviceAttrs = (params: { deviceProfileId: string; dataType?: str
258 262 params: { dataType },
259 263 });
260 264 };
  265 +
  266 +/**
  267 + * 设备上下线记录相关api
  268 + */
  269 +export const deviceStateLogPage = (params: DeviceQueryParam) => {
  270 + return defHttp.get<DeviceStateLogModel>({
  271 + url: DeviceManagerApi.DEVICE_STATE_LOG_URL,
  272 + params,
  273 + });
  274 +};
  275 +
  276 +export const deleteStateLogDevice = (ids: string[]) => {
  277 + return defHttp.delete({
  278 + url: DeviceManagerApi.DEVICE_STATE_LOG_URL,
  279 + data: {
  280 + ids: ids,
  281 + },
  282 + });
  283 +};
  284 +
  285 +export const deviceStateLogDetail = (id) => {
  286 + return defHttp.get<DeviceStateLogModel>({
  287 + url: DeviceManagerApi.DEVICE_STATE_LOG_URL + '/' + id,
  288 + });
  289 +};
  290 +
  291 +export const deviceStateLogPost = (data) => {
  292 + return defHttp.post(
  293 + {
  294 + url: DeviceManagerApi.DEVICE_STATE_LOG_URL,
  295 + data,
  296 + }
  297 + // {
  298 + // joinPrefix: false,
  299 + // }
  300 + );
  301 +};
... ...
... ... @@ -170,3 +170,33 @@ export interface DeviceModelOfMatterAttrs {
170 170 identifier: string;
171 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 +}
... ...
  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 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 4 </BasicDrawer>
5 5 </template>
6 6 <script lang="ts" setup>
7   - import { BasicForm, useForm } from '/@/components/Form';
8 7 import { formSchema } from './config.data';
9 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 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 21 const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
19   - await resetFields();
20 22 setDrawerProps({ confirmLoading: false });
21   - await setFieldsValue(data.record);
  23 + const res = await deviceStateLogDetail(data.record.id);
  24 + setDescProps({ data: res });
22 25 });
23 26 </script>
... ...
... ... @@ -2,6 +2,7 @@ import { BasicColumn, FormSchema } from '/@/components/Table';
2 2 import moment from 'moment';
3 3 import { h } from 'vue';
4 4 import { Tag } from 'ant-design-vue';
  5 +import { DescItem } from '/@/components/Description';
5 6
6 7 // 表格数据
7 8 export const columns: BasicColumn[] = [
... ... @@ -12,17 +13,24 @@ export const columns: BasicColumn[] = [
12 13 },
13 14 {
14 15 title: '设备配置',
15   - dataIndex: 'deviceConfig',
  16 + dataIndex: 'deviceProfileName',
16 17 width: 120,
17 18 },
18 19 {
19 20 title: '设备类型',
20   - dataIndex: 'entityType',
  21 + dataIndex: 'deviceType',
21 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 32 title: '所属组织',
25   - dataIndex: 'orgName',
  33 + dataIndex: 'organizationName',
26 34 width: 120,
27 35 },
28 36 {
... ... @@ -31,9 +39,9 @@ export const columns: BasicColumn[] = [
31 39 width: 180,
32 40 customRender: ({ record }) => {
33 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 45 return h(Tag, { color }, () => text);
38 46 },
39 47 },
... ... @@ -79,12 +87,12 @@ export const searchFormSchema: FormSchema[] = [
79 87 placeholder: '请选择状态',
80 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 110 },
103 111 ];
104 112
105   -// 详情配置
106   -export const formSchema: FormSchema[] = [
  113 +export const formSchema: DescItem[] = [
107 114 {
108 115 field: 'deviceName',
109 116 label: '设备名称',
110   - component: 'Input',
111   - componentProps: {
112   - disabled: true,
113   - },
114 117 },
115 118 {
116   - field: 'deviceConfig',
  119 + field: 'deviceProfileName',
117 120 label: '设备配置',
118   - component: 'Input',
119   - componentProps: {
120   - disabled: true,
121   - },
122 121 },
123 122 {
124   - field: 'entityType',
  123 + field: 'deviceType',
125 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 135 label: '所属组织',
134   - component: 'Input',
135   - componentProps: {
136   - disabled: true,
137   - },
138 136 },
139 137 {
140 138 field: 'status',
141 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 145 field: 'createTime',
149 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 2 <div>
3 3 <BasicTable :clickToRowSelect="false" @register="registerTable">
4 4 <template #toolbar>
5   - <Authority value="api:yt:onlinerecord:delete">
  5 + <Authority value="api:yt:device:state:log::delete">
6 6 <Popconfirm
7 7 title="您确定要批量删除数据"
8 8 ok-text="确定"
... ... @@ -17,14 +17,20 @@
17 17 <TableAction
18 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 26 label: '详情',
21   - auth: 'api:yt:onlinerecord:get',
  27 + auth: 'api:yt:device:state:log::detail',
22 28 icon: 'clarity:note-edit-line',
23 29 onClick: handleViewDetail.bind(null, record),
24 30 },
25 31 {
26 32 label: '删除',
27   - auth: 'api:yt:onlinerecord:delete',
  33 + auth: 'api:yt:device:state:log::delete',
28 34 icon: 'ant-design:delete-outlined',
29 35 color: 'error',
30 36 popConfirm: {
... ... @@ -37,6 +43,7 @@
37 43 </template>
38 44 </BasicTable>
39 45 <OnlineRecordDrawer @register="registerDrawer" @success="handleSuccess" />
  46 + <OnlineHandleDrawer @register="registerHandleDrawer" @success="handleHandleSuccess" />
40 47 </div>
41 48 </template>
42 49
... ... @@ -45,17 +52,16 @@
45 52 import { BasicTable, useTable, TableAction } from '/@/components/Table';
46 53 import { useDrawer } from '/@/components/Drawer';
47 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 58 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
51   - import { deleteConvertApi } from '/@/api/datamanager/dataManagerApi';
52 59 import { Popconfirm } from 'ant-design-vue';
53 60 import { Authority } from '/@/components/Authority';
54 61
55 62 const [registerTable, { setProps, reload }] = useTable({
56 63 title: '上下线记录',
57   - dataSource: mockList,
58   - // api: getExceptionPage,
  64 + api: deviceStateLogPage,
59 65 columns,
60 66 showIndexColumn: false,
61 67 clickToRowSelect: false,
... ... @@ -76,12 +82,19 @@
76 82 fixed: 'right',
77 83 },
78 84 });
  85 +
79 86 const handleSuccess = () => {
80 87 reload();
81 88 resetSelectedRowKeys();
82 89 };
  90 +
  91 + const handleHandleSuccess = () => {
  92 + reload();
  93 + resetSelectedRowKeys();
  94 + };
  95 +
83 96 const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } =
84   - useBatchDelete(deleteConvertApi, handleSuccess, setProps);
  97 + useBatchDelete(deleteStateLogDevice, handleSuccess, setProps);
85 98
86 99 nextTick(() => {
87 100 setProps(selectionOptions);
... ... @@ -90,10 +103,18 @@
90 103 // 弹框
91 104 const [registerDrawer, { openDrawer }] = useDrawer();
92 105
  106 + const [registerHandleDrawer, { openDrawer: openHandleDrawer }] = useDrawer();
  107 +
93 108 const handleViewDetail = (record) => {
94 109 openDrawer(true, {
95 110 isUpdate: true,
96 111 record,
97 112 });
98 113 };
  114 + const handleView = (record) => {
  115 + openHandleDrawer(true, {
  116 + isUpdate: true,
  117 + record,
  118 + });
  119 + };
99 120 </script>
... ...