Commit 9904d26ff0909c3278cda9865fc0e7c504fad4e1
Merge branch 'sqy_dev' into 'main'
'feat:设备详情页面' See merge request huang/yun-teng-iot-front!24
Showing
16 changed files
with
464 additions
and
218 deletions
... | ... | @@ -6,7 +6,7 @@ VITE_PUBLIC_PATH = / |
6 | 6 | |
7 | 7 | # Cross-domain proxy, you can configure multiple |
8 | 8 | # Please note that no line breaks |
9 | -VITE_PROXY = [["/api","http://192.168.10.117:8082/api"],["/upload","http://192.168.10.116:3300/upload"]] | |
9 | +VITE_PROXY = [["/api","http://192.168.10.123:8082/api"],["/upload","http://192.168.10.116:3300/upload"]] | |
10 | 10 | # VITE_PROXY=[["/api","https://vvbin.cn/test"]] |
11 | 11 | |
12 | 12 | # Delete console | ... | ... |
src/views/device/config.data.ts
deleted
100644 → 0
1 | -import { BasicColumn } from '/@/components/Table'; | |
2 | -import { FormSchema } from '/@/components/Table'; | |
3 | -import { findDictItemByCode } from '/@/api/system/dict'; | |
4 | -import { MessageEnum } from '/@/enums/messageEnum'; | |
5 | -import { DeviceTypeEnum, DeviceState } from '/@/api/device/model/deviceModel'; | |
6 | -// 表格列数据 | |
7 | -export const columns: BasicColumn[] = [ | |
8 | - { | |
9 | - title: '默认', | |
10 | - }, | |
11 | - { | |
12 | - title: '设备名称', | |
13 | - dataIndex: 'name', | |
14 | - width: 200, | |
15 | - }, | |
16 | - { | |
17 | - title: '设备类型', | |
18 | - dataIndex: 'deviceType', | |
19 | - width: 200, | |
20 | - slots: { customRender: 'deviceType' }, | |
21 | - }, | |
22 | - { | |
23 | - title: '设备配置', | |
24 | - dataIndex: 'deviceProfile.name', | |
25 | - width: 180, | |
26 | - slots: { customRender: 'deviceProfile' }, | |
27 | - }, | |
28 | - { | |
29 | - title: '标签', | |
30 | - dataIndex: 'label', | |
31 | - width: 180, | |
32 | - }, | |
33 | - { | |
34 | - title: '配置信息', | |
35 | - dataIndex: 'deviceInfo', | |
36 | - width: 180, | |
37 | - slots: { customRender: 'config' }, | |
38 | - }, | |
39 | - { | |
40 | - title: '状态', | |
41 | - dataIndex: 'deviceState', | |
42 | - width: 120, | |
43 | - slots: { customRender: 'deviceState' }, | |
44 | - }, | |
45 | - { | |
46 | - title: '最后连接时间', | |
47 | - dataIndex: 'lastConnectTime', | |
48 | - width: 180, | |
49 | - }, | |
50 | - { | |
51 | - title: '创建时间', | |
52 | - dataIndex: 'createTime', | |
53 | - width: 180, | |
54 | - }, | |
55 | -]; | |
56 | - | |
57 | -// 查询字段 | |
58 | -export const searchFormSchema: FormSchema[] = [ | |
59 | - { | |
60 | - field: 'deviceType', | |
61 | - label: '设备类型', | |
62 | - component: 'Select', | |
63 | - componentProps: { | |
64 | - options: [ | |
65 | - { label: '网关设备', value: DeviceTypeEnum.GATEWAY }, | |
66 | - { label: '直连设备', value: DeviceTypeEnum.DIRECT_CONNECTION }, | |
67 | - { label: '网关子设备', value: DeviceTypeEnum.SENSOR }, | |
68 | - ], | |
69 | - }, | |
70 | - colProps: { span: 4 }, | |
71 | - }, | |
72 | - { | |
73 | - field: 'deviceState', | |
74 | - label: '设备状态', | |
75 | - component: 'Select', | |
76 | - componentProps: { | |
77 | - options: [ | |
78 | - { label: '待激活', value: DeviceState.INACTIVE }, | |
79 | - { label: '在线', value: DeviceState.ONLINE }, | |
80 | - { label: '离线', value: DeviceState.OFFLINE }, | |
81 | - ], | |
82 | - }, | |
83 | - colProps: { span: 4 }, | |
84 | - }, | |
85 | - { | |
86 | - field: 'name', | |
87 | - label: '设备名称', | |
88 | - component: 'Input', | |
89 | - colProps: { span: 8 }, | |
90 | - }, | |
91 | -]; | |
92 | - | |
93 | -// 弹框配置项 | |
94 | -export const formSchema: FormSchema[] = [ | |
95 | - { | |
96 | - field: 'configName', | |
97 | - label: '配置名称', | |
98 | - required: true, | |
99 | - component: 'Input', | |
100 | - }, | |
101 | - { | |
102 | - field: 'messageType', | |
103 | - label: '消息类型', | |
104 | - required: true, | |
105 | - component: 'ApiSelect', | |
106 | - componentProps: { | |
107 | - api: findDictItemByCode, | |
108 | - params: { | |
109 | - dictCode: 'message_type', | |
110 | - }, | |
111 | - labelField: 'itemText', | |
112 | - valueField: 'itemValue', | |
113 | - }, | |
114 | - }, | |
115 | - { | |
116 | - field: 'platformType', | |
117 | - label: '平台类型', | |
118 | - required: true, | |
119 | - component: 'ApiSelect', | |
120 | - componentProps: { | |
121 | - api: findDictItemByCode, | |
122 | - params: { | |
123 | - dictCode: 'platform_type', | |
124 | - }, | |
125 | - labelField: 'itemText', | |
126 | - valueField: 'itemValue', | |
127 | - }, | |
128 | - ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), | |
129 | - }, | |
130 | - { | |
131 | - field: 'accessKeyId', | |
132 | - label: 'accessKeyId', | |
133 | - required: true, | |
134 | - component: 'Input', | |
135 | - ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), | |
136 | - }, | |
137 | - { | |
138 | - field: 'accessKeySecret', | |
139 | - label: 'accessKeySecret', | |
140 | - required: true, | |
141 | - component: 'Input', | |
142 | - ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), | |
143 | - }, | |
144 | - { | |
145 | - field: 'host', | |
146 | - label: '服务器地址', | |
147 | - defaultValue: 'smtp.163.com', | |
148 | - required: true, | |
149 | - component: 'Input', | |
150 | - ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), | |
151 | - }, | |
152 | - { | |
153 | - field: 'port', | |
154 | - label: '端口', | |
155 | - defaultValue: 25, | |
156 | - required: true, | |
157 | - component: 'InputNumber', | |
158 | - ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), | |
159 | - }, | |
160 | - { | |
161 | - field: 'username', | |
162 | - label: '用户名', | |
163 | - required: true, | |
164 | - component: 'Input', | |
165 | - ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), | |
166 | - }, | |
167 | - { | |
168 | - field: 'password', | |
169 | - label: '密码', | |
170 | - required: true, | |
171 | - component: 'InputPassword', | |
172 | - ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), | |
173 | - }, | |
174 | - { | |
175 | - field: 'config', | |
176 | - label: '消息配置', | |
177 | - component: 'Input', | |
178 | - show: false, | |
179 | - }, | |
180 | - { | |
181 | - field: 'id', | |
182 | - label: '主键', | |
183 | - component: 'Input', | |
184 | - show: false, | |
185 | - }, | |
186 | - { | |
187 | - field: 'status', | |
188 | - label: '状态', | |
189 | - component: 'RadioButtonGroup', | |
190 | - defaultValue: 0, | |
191 | - componentProps: { | |
192 | - options: [ | |
193 | - { label: '启用', value: 1 }, | |
194 | - { label: '停用', value: 0 }, | |
195 | - ], | |
196 | - }, | |
197 | - }, | |
198 | - { | |
199 | - label: '备注', | |
200 | - field: 'remark', | |
201 | - component: 'InputTextArea', | |
202 | - }, | |
203 | -]; | |
204 | - | |
205 | -export const isMessage = (type: string) => { | |
206 | - return type === MessageEnum.IS_SMS; | |
207 | -}; | |
208 | -export const isEmail = (type: string) => { | |
209 | - return type === MessageEnum.IS_EMAIL; | |
210 | -}; |
src/views/device/manage/config/data.ts
renamed from
src/views/device/step/data.ts
1 | +import { FormSchema } from '/@/components/Form'; | |
2 | +import { BasicColumn } from '/@/components/Table'; | |
3 | +export const columns: BasicColumn[] = [ | |
4 | + { | |
5 | + title: '设备名称', | |
6 | + dataIndex: 'name', | |
7 | + width: 120, | |
8 | + key: 'name', | |
9 | + }, | |
10 | + { | |
11 | + title: '设备标签', | |
12 | + dataIndex: 'label', | |
13 | + width: 100, | |
14 | + key: 'label', | |
15 | + }, | |
16 | + { | |
17 | + title: '设备配置', | |
18 | + dataIndex: 'deviceProfile.name', | |
19 | + width: 160, | |
20 | + key: 'deviceProfile.name', | |
21 | + }, | |
22 | + | |
23 | + { | |
24 | + title: '设备类型', | |
25 | + dataIndex: 'deviceType', | |
26 | + key: 'deviceType', | |
27 | + }, | |
28 | + { | |
29 | + title: '描述', | |
30 | + dataIndex: 'label', | |
31 | + width: 180, | |
32 | + key: 'label', | |
33 | + }, | |
34 | +]; | |
35 | + | |
36 | +// 实时数据 | |
37 | +export const realTimeDataSearchSchemas: FormSchema[] = [ | |
38 | + { | |
39 | + field: 'key', | |
40 | + label: '键 / 值', | |
41 | + component: 'Input', | |
42 | + colProps: { span: 12 }, | |
43 | + }, | |
44 | +]; | |
45 | +export const realTimeDataColumns: BasicColumn[] = [ | |
46 | + { | |
47 | + title: '最后更新时间', | |
48 | + dataIndex: 'update', | |
49 | + width: 120, | |
50 | + }, | |
51 | + { | |
52 | + title: '键', | |
53 | + dataIndex: 'label', | |
54 | + width: 100, | |
55 | + }, | |
56 | + { | |
57 | + title: '值', | |
58 | + dataIndex: 'name', | |
59 | + width: 160, | |
60 | + }, | |
61 | +]; | |
62 | + | |
63 | +// 告警 | |
64 | +export const alarmSearchSchemas: FormSchema[] = [ | |
65 | + { | |
66 | + field: 'icon', | |
67 | + label: '告警状态', | |
68 | + component: 'Select', | |
69 | + colProps: { span: 8 }, | |
70 | + }, | |
71 | + { | |
72 | + field: 'icon', | |
73 | + label: ' ', | |
74 | + component: 'DatePicker', | |
75 | + colProps: { span: 8 }, | |
76 | + }, | |
77 | + { | |
78 | + field: 'icon', | |
79 | + label: '告警类型', | |
80 | + component: 'Input', | |
81 | + colProps: { span: 8 }, | |
82 | + }, | |
83 | +]; | |
84 | +export const alarmColumns: BasicColumn[] = [ | |
85 | + { | |
86 | + title: '告警时间', | |
87 | + dataIndex: 'aaa', | |
88 | + width: 120, | |
89 | + }, | |
90 | + { | |
91 | + title: '告警设备', | |
92 | + dataIndex: 'label', | |
93 | + width: 100, | |
94 | + }, | |
95 | + { | |
96 | + title: '类型', | |
97 | + dataIndex: 'ccc', | |
98 | + width: 160, | |
99 | + }, | |
100 | + { | |
101 | + title: '告警级别', | |
102 | + dataIndex: 'ddd', | |
103 | + width: 160, | |
104 | + }, | |
105 | + { | |
106 | + title: '状态', | |
107 | + dataIndex: 'eee', | |
108 | + width: 160, | |
109 | + }, | |
110 | + { | |
111 | + title: '操作', | |
112 | + dataIndex: 'name', | |
113 | + width: 160, | |
114 | + }, | |
115 | +]; | |
116 | + | |
117 | +// 子设备 | |
118 | +export const childDeviceSchemas: FormSchema[] = [ | |
119 | + { | |
120 | + field: 'icon', | |
121 | + label: '设备配置', | |
122 | + component: 'Select', | |
123 | + colProps: { span: 12 }, | |
124 | + }, | |
125 | + { | |
126 | + field: 'icon', | |
127 | + label: '设备名称', | |
128 | + component: 'Input', | |
129 | + colProps: { span: 12 }, | |
130 | + }, | |
131 | +]; | |
132 | +export const childDeviceColumns: BasicColumn[] = [ | |
133 | + { | |
134 | + title: '名称', | |
135 | + dataIndex: 'name', | |
136 | + width: 120, | |
137 | + }, | |
138 | + { | |
139 | + title: '设备配置', | |
140 | + dataIndex: 'label', | |
141 | + width: 100, | |
142 | + }, | |
143 | + { | |
144 | + title: '标签', | |
145 | + dataIndex: 'aaa', | |
146 | + width: 160, | |
147 | + }, | |
148 | + { | |
149 | + title: '状态', | |
150 | + dataIndex: 'bbb', | |
151 | + width: 160, | |
152 | + }, | |
153 | + { | |
154 | + title: '最后连接时间', | |
155 | + dataIndex: 'ccc', | |
156 | + width: 160, | |
157 | + }, | |
158 | + { | |
159 | + title: '创建时间', | |
160 | + dataIndex: 'ddd', | |
161 | + width: 160, | |
162 | + }, | |
163 | +]; | ... | ... |
src/views/device/manage/config/device.data.ts
renamed from
src/views/device/device.data.ts
1 | +<template> | |
2 | + <!-- <BasicModal v-bind="$attrs" width="55rem" @register="register" centered /> --> | |
3 | + <BasicDrawer | |
4 | + v-bind="$attrs" | |
5 | + isDetail | |
6 | + :title="deviceInfo?.name" | |
7 | + @register="register" | |
8 | + :destroyOnClose="true" | |
9 | + @close="closeDrawer" | |
10 | + > | |
11 | + <Tabs v-model:activeKey="activeKey" :size="size" type="card"> | |
12 | + <TabPane key="1" tab="详情" | |
13 | + ><Detail :deviceDetail="deviceInfo" ref="deviceDetailRef" | |
14 | + /></TabPane> | |
15 | + <TabPane key="2" tab="实时数据"><RealTimeData /></TabPane> | |
16 | + <TabPane key="3" tab="告警"><Alarm /></TabPane> | |
17 | + <TabPane key="4" tab="子设备"><ChildDevice /></TabPane> | |
18 | + </Tabs> | |
19 | + </BasicDrawer> | |
20 | +</template> | |
21 | +<script lang="ts"> | |
22 | + import { defineComponent, ref } from 'vue'; | |
23 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | |
24 | + | |
25 | + import { Tabs, TabPane } from 'ant-design-vue'; | |
26 | + import Detail from '../tabs/Detail.vue'; | |
27 | + import RealTimeData from '../tabs/RealTimeData.vue'; | |
28 | + import Alarm from '../tabs/Alarm.vue'; | |
29 | + import ChildDevice from '../tabs/ChildDevice.vue'; | |
30 | + export default defineComponent({ | |
31 | + name: 'DeviceModal', | |
32 | + components: { | |
33 | + BasicDrawer, | |
34 | + Tabs, | |
35 | + TabPane, | |
36 | + Detail, | |
37 | + RealTimeData, | |
38 | + Alarm, | |
39 | + ChildDevice, | |
40 | + }, | |
41 | + emits: ['reload', 'register'], | |
42 | + setup() { | |
43 | + const activeKey = ref('1'); | |
44 | + const size = ref('small'); | |
45 | + const deviceInfo = ref({}); | |
46 | + const deviceDetailRef = ref(); | |
47 | + // 详情回显 | |
48 | + const [register] = useDrawerInner((data) => { | |
49 | + deviceInfo.value = data.record; | |
50 | + const { latitude, longitude, address } = data.record.deviceInfo; | |
51 | + deviceDetailRef.value.initMap(longitude, latitude, address); | |
52 | + }); | |
53 | + | |
54 | + const closeDrawer = () => { | |
55 | + activeKey.value = '1'; | |
56 | + }; | |
57 | + | |
58 | + return { | |
59 | + size, | |
60 | + activeKey, | |
61 | + deviceInfo, | |
62 | + register, | |
63 | + closeDrawer, | |
64 | + deviceDetailRef, | |
65 | + }; | |
66 | + }, | |
67 | + }); | |
68 | +</script> | ... | ... |
src/views/device/manage/cpns/modal/DeviceModal.vue
renamed from
src/views/device/DeviceModal.vue
... | ... | @@ -34,8 +34,8 @@ |
34 | 34 | import { defineComponent, ref, computed, unref } from 'vue'; |
35 | 35 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
36 | 36 | import { createOrEditDevice, getDeviceToken } from '/@/api/device/deviceManager'; |
37 | - import DeviceStep1 from '/@/views/device/step/DeviceStep1.vue'; | |
38 | - import DeviceStep2 from '/@/views/device/step/DeviceStep2.vue'; | |
37 | + import DeviceStep1 from '../step/DeviceStep1.vue'; | |
38 | + import DeviceStep2 from '../step/DeviceStep2.vue'; | |
39 | 39 | import { Steps } from 'ant-design-vue'; |
40 | 40 | import { useMessage } from '/@/hooks/web/useMessage'; |
41 | 41 | ... | ... |
src/views/device/manage/cpns/step/DeviceStep1.vue
renamed from
src/views/device/step/DeviceStep1.vue
... | ... | @@ -59,7 +59,7 @@ |
59 | 59 | <script lang="ts"> |
60 | 60 | import { defineComponent, ref, nextTick, unref, reactive, watch } from 'vue'; |
61 | 61 | import { BasicForm, useForm } from '/@/components/Form'; |
62 | - import { step1Schemas } from './data'; | |
62 | + import { step1Schemas } from '../../config/data'; | |
63 | 63 | import { useScript } from '/@/hooks/web/useScript'; |
64 | 64 | import { Input, Divider, Upload, message, Modal, Form, Row, Col } from 'ant-design-vue'; |
65 | 65 | import { EnvironmentTwoTone, PlusOutlined } from '@ant-design/icons-vue'; | ... | ... |
src/views/device/manage/cpns/step/DeviceStep2.vue
renamed from
src/views/device/step/DeviceStep2.vue
src/views/device/manage/cpns/tabs/Alarm.vue
0 → 100644
1 | +<template> | |
2 | + <BasicTable @register="registerTable" /> | |
3 | +</template> | |
4 | +<script lang="ts"> | |
5 | + import { defineComponent } from 'vue'; | |
6 | + import { BasicTable, useTable } from '/@/components/Table'; | |
7 | + import { alarmColumns, alarmSearchSchemas } from '../../config/detail.config'; | |
8 | + export default defineComponent({ | |
9 | + name: 'DeviceManagement', | |
10 | + components: { | |
11 | + BasicTable, | |
12 | + }, | |
13 | + setup(_) { | |
14 | + const [registerTable] = useTable({ | |
15 | + columns: alarmColumns, | |
16 | + formConfig: { | |
17 | + labelWidth: 120, | |
18 | + schemas: alarmSearchSchemas, | |
19 | + }, | |
20 | + useSearchForm: true, | |
21 | + showTableSetting: true, | |
22 | + bordered: true, | |
23 | + showIndexColumn: false, | |
24 | + }); | |
25 | + | |
26 | + return { | |
27 | + registerTable, | |
28 | + }; | |
29 | + }, | |
30 | + }); | |
31 | +</script> | ... | ... |
1 | +<template> | |
2 | + <BasicTable @register="registerTable" /> | |
3 | +</template> | |
4 | +<script lang="ts"> | |
5 | + import { defineComponent } from 'vue'; | |
6 | + import { BasicTable, useTable } from '/@/components/Table'; | |
7 | + import { childDeviceColumns, childDeviceSchemas } from '../../config/detail.config'; | |
8 | + | |
9 | + export default defineComponent({ | |
10 | + name: 'DeviceManagement', | |
11 | + components: { | |
12 | + BasicTable, | |
13 | + }, | |
14 | + setup(_) { | |
15 | + const [registerTable] = useTable({ | |
16 | + columns: childDeviceColumns, | |
17 | + formConfig: { | |
18 | + labelWidth: 120, | |
19 | + schemas: childDeviceSchemas, | |
20 | + }, | |
21 | + useSearchForm: true, | |
22 | + showTableSetting: true, | |
23 | + bordered: true, | |
24 | + showIndexColumn: false, | |
25 | + }); | |
26 | + | |
27 | + return { | |
28 | + registerTable, | |
29 | + }; | |
30 | + }, | |
31 | + }); | |
32 | +</script> | ... | ... |
src/views/device/manage/cpns/tabs/Detail.vue
0 → 100644
1 | +<template> | |
2 | + <div class="tabs-detail"> | |
3 | + <div v-if="deviceDetail?.deviceInfo?.avatar"> | |
4 | + <p>设备图片</p> | |
5 | + <Image :src="deviceDetail.deviceInfo.avatar" :width="100" /> | |
6 | + </div> | |
7 | + <div> | |
8 | + <p>设备信息</p> | |
9 | + <Table | |
10 | + bordered | |
11 | + :columns="columns" | |
12 | + :data-source="[{ ...deviceDetail, key: 'name' }]" | |
13 | + :pagination="false" | |
14 | + /> | |
15 | + </div> | |
16 | + <div v-if="deviceDetail?.deviceInfo?.address"> | |
17 | + <p>设备位置</p> | |
18 | + <div ref="wrapRef" style="height: 400px; width: 90%" class="ml-6"></div> | |
19 | + </div> | |
20 | + <div class="mt-4"> | |
21 | + <a-button type="primary" class="mr-4">复制设备ID</a-button> | |
22 | + <a-button type="primary">复制访问令牌</a-button> | |
23 | + </div> | |
24 | + </div> | |
25 | +</template> | |
26 | +<script lang="ts"> | |
27 | + import { defineComponent, ref, unref, nextTick } from 'vue'; | |
28 | + import { Image, Table } from 'ant-design-vue'; | |
29 | + import { columns } from '../../config/detail.config'; | |
30 | + import { useScript } from '/@/hooks/web/useScript'; | |
31 | + export default defineComponent({ | |
32 | + components: { | |
33 | + Image, | |
34 | + Table, | |
35 | + }, | |
36 | + props: { | |
37 | + deviceDetail: { | |
38 | + type: Object, | |
39 | + required: true, | |
40 | + }, | |
41 | + }, | |
42 | + setup() { | |
43 | + const BAI_DU_MAP_URL = | |
44 | + 'https://api.map.baidu.com/getscript?v=3.0&ak=7uOPPyAHn2Y2ZryeQqHtcRqtIY374vKa'; | |
45 | + const wrapRef = ref<HTMLDivElement | null>(null); | |
46 | + const { toPromise } = useScript({ src: BAI_DU_MAP_URL }); | |
47 | + | |
48 | + async function initMap(longitude, latitude, address) { | |
49 | + await toPromise(); | |
50 | + await nextTick(); | |
51 | + const wrapEl = unref(wrapRef); | |
52 | + const BMap = (window as any).BMap; | |
53 | + if (!wrapEl) return; | |
54 | + const map = new BMap.Map(wrapEl); | |
55 | + let myIcon = new BMap.Icon( | |
56 | + 'http://api.map.baidu.com/img/markers.png', | |
57 | + new BMap.Size(40, 25), | |
58 | + { | |
59 | + offset: new BMap.Size(0, 0), // 指定定位位置 | |
60 | + imageOffset: new BMap.Size(20, -260), // 设置图片偏移 | |
61 | + } | |
62 | + ); | |
63 | + const point = new BMap.Point(Number(longitude), Number(latitude)); | |
64 | + var content = `我在 ${address}`; | |
65 | + var label = new BMap.Label(content, { | |
66 | + // 创建文本标注 | |
67 | + position: point, | |
68 | + offset: new BMap.Size(15, -35), | |
69 | + }); | |
70 | + map.addOverlay(label); // 将标注添加到地图中 | |
71 | + label.setStyle({ | |
72 | + // 设置label的样式 | |
73 | + color: '#000', | |
74 | + fontSize: '10px', | |
75 | + border: '1px solid #1E90FF', | |
76 | + }); | |
77 | + let marker = new BMap.Marker(point, { icon: myIcon }); | |
78 | + map.centerAndZoom(point, 15); | |
79 | + map.enableScrollWheelZoom(true); | |
80 | + map.addOverlay(marker); | |
81 | + } | |
82 | + | |
83 | + return { | |
84 | + columns, | |
85 | + wrapRef, | |
86 | + initMap, | |
87 | + }; | |
88 | + }, | |
89 | + }); | |
90 | +</script> | |
91 | +<style lang="less" scoped></style> | ... | ... |
1 | +<template> | |
2 | + <BasicTable @register="registerTable" /> | |
3 | +</template> | |
4 | +<script lang="ts"> | |
5 | + import { defineComponent } from 'vue'; | |
6 | + import { BasicTable, useTable } from '/@/components/Table'; | |
7 | + import { realTimeDataColumns, realTimeDataSearchSchemas } from '../../config/detail.config'; | |
8 | + export default defineComponent({ | |
9 | + name: 'DeviceManagement', | |
10 | + components: { | |
11 | + BasicTable, | |
12 | + }, | |
13 | + setup(_) { | |
14 | + const [registerTable] = useTable({ | |
15 | + columns: realTimeDataColumns, | |
16 | + formConfig: { | |
17 | + labelWidth: 120, | |
18 | + schemas: realTimeDataSearchSchemas, | |
19 | + }, | |
20 | + useSearchForm: true, | |
21 | + showTableSetting: true, | |
22 | + bordered: true, | |
23 | + showIndexColumn: false, | |
24 | + }); | |
25 | + | |
26 | + return { | |
27 | + registerTable, | |
28 | + }; | |
29 | + }, | |
30 | + }); | |
31 | +</script> | ... | ... |
src/views/device/manage/index.vue
renamed from
src/views/device/index.vue
... | ... | @@ -48,6 +48,11 @@ |
48 | 48 | <TableAction |
49 | 49 | :actions="[ |
50 | 50 | { |
51 | + label: '详情', | |
52 | + icon: 'ant-design:eye-outlined', | |
53 | + onClick: handleDetail.bind(null, record), | |
54 | + }, | |
55 | + { | |
51 | 56 | label: '编辑', |
52 | 57 | icon: 'clarity:note-edit-line', |
53 | 58 | onClick: handleEdit.bind(null, record), |
... | ... | @@ -65,6 +70,7 @@ |
65 | 70 | /> |
66 | 71 | </template> |
67 | 72 | </BasicTable> |
73 | + <DeviceDetailDrawer @register="registerDetailDrawer" /> | |
68 | 74 | <DeviceModal @register="registerModal" @success="handleSuccess" @reload="handleReload" /> |
69 | 75 | </PageWrapper> |
70 | 76 | </template> |
... | ... | @@ -72,16 +78,18 @@ |
72 | 78 | import { defineComponent, reactive } from 'vue'; |
73 | 79 | import { DeviceState, DeviceTypeEnum } from '/@/api/device/model/deviceModel'; |
74 | 80 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
75 | - import { columns, searchFormSchema } from './device.data'; | |
81 | + import { columns, searchFormSchema } from './config/device.data'; | |
76 | 82 | import { Tag } from 'ant-design-vue'; |
77 | 83 | import { useMessage } from '/@/hooks/web/useMessage'; |
78 | 84 | import { deleteDevice, devicePage } from '/@/api/device/deviceManager'; |
79 | 85 | import { PageEnum } from '/@/enums/pageEnum'; |
80 | 86 | import { useGo } from '/@/hooks/web/usePage'; |
81 | 87 | import { PageWrapper } from '/@/components/Page'; |
82 | - import OrganizationIdTree from '/@/views/common/OrganizationIdTree.vue'; | |
83 | 88 | import { useModal } from '/@/components/Modal'; |
84 | - import DeviceModal from '/@/views/device/DeviceModal.vue'; | |
89 | + import OrganizationIdTree from '/@/views/common/OrganizationIdTree.vue'; | |
90 | + import DeviceModal from './cpns/modal/DeviceModal.vue'; | |
91 | + import { useDrawer } from '/@/components/Drawer'; | |
92 | + import DeviceDetailDrawer from './cpns/modal/DeviceDetailDrawer.vue'; | |
85 | 93 | |
86 | 94 | export default defineComponent({ |
87 | 95 | name: 'DeviceManagement', |
... | ... | @@ -92,6 +100,7 @@ |
92 | 100 | OrganizationIdTree, |
93 | 101 | Tag, |
94 | 102 | DeviceModal, |
103 | + DeviceDetailDrawer, | |
95 | 104 | }, |
96 | 105 | setup(_) { |
97 | 106 | const { createMessage } = useMessage(); |
... | ... | @@ -99,6 +108,7 @@ |
99 | 108 | |
100 | 109 | const searchInfo = reactive<Recordable>({}); |
101 | 110 | const [registerModal, { openModal }] = useModal(); |
111 | + const [registerDetailDrawer, { openDrawer }] = useDrawer(); | |
102 | 112 | const [registerTable, { reload }] = useTable({ |
103 | 113 | title: '设备列表', |
104 | 114 | api: devicePage, |
... | ... | @@ -113,7 +123,7 @@ |
113 | 123 | showIndexColumn: false, |
114 | 124 | searchInfo: searchInfo, |
115 | 125 | actionColumn: { |
116 | - width: 180, | |
126 | + width: 200, | |
117 | 127 | title: '操作', |
118 | 128 | dataIndex: 'action', |
119 | 129 | slots: { customRender: 'action' }, |
... | ... | @@ -130,6 +140,12 @@ |
130 | 140 | }); |
131 | 141 | } |
132 | 142 | |
143 | + function handleDetail(record: Recordable) { | |
144 | + openDrawer(true, { | |
145 | + record, | |
146 | + }); | |
147 | + } | |
148 | + | |
133 | 149 | function handleEdit(record: Recordable) { |
134 | 150 | openModal(true, { |
135 | 151 | isUpdate: true, |
... | ... | @@ -155,9 +171,11 @@ |
155 | 171 | function goDeviceProfile() { |
156 | 172 | go(PageEnum.DEVICE_PROFILE); |
157 | 173 | } |
174 | + | |
158 | 175 | return { |
159 | 176 | registerTable, |
160 | 177 | handleCreate, |
178 | + handleDetail, | |
161 | 179 | handleEdit, |
162 | 180 | handleDelete, |
163 | 181 | handleSuccess, |
... | ... | @@ -165,6 +183,7 @@ |
165 | 183 | handleSelect, |
166 | 184 | registerModal, |
167 | 185 | handleReload, |
186 | + registerDetailDrawer, | |
168 | 187 | DeviceTypeEnum, |
169 | 188 | DeviceState, |
170 | 189 | searchInfo, | ... | ... |
src/views/device/manage/types/index.ts
0 → 100644
1 | +export interface DeviceType { | |
2 | + alarmStatus: number; | |
3 | + createTime: string; | |
4 | + creator: string; | |
5 | + deviceInfo: Object; | |
6 | + deviceProfile: Object; | |
7 | + deviceState: string; | |
8 | + deviceToken: string; | |
9 | + deviceType: string; | |
10 | + enabled: boolean; | |
11 | + id: string; | |
12 | + key: string; | |
13 | + label: string; | |
14 | + name: string; | |
15 | + organizationDTO: Object; | |
16 | + organizationId: string; | |
17 | + profileId: string; | |
18 | + tenantCode: string; | |
19 | + updateTime: string; | |
20 | +} | ... | ... |