Commit bdeac9846c3e3a8d010cf2b1aeb253fba2482ee0
1 parent
6000cf9a
'feat:设备分配客户,oem按钮调整,地图铆钉不显示,账号问题'
Showing
16 changed files
with
188 additions
and
28 deletions
... | ... | @@ -136,3 +136,35 @@ export const saveDeviceToken = (data) => { |
136 | 136 | } |
137 | 137 | ); |
138 | 138 | }; |
139 | + | |
140 | +// 获取当前租户下的客户列表 | |
141 | +export const getCustomerList = (params) => { | |
142 | + return defHttp.get({ | |
143 | + url: '/user/customers/' + params.organizationId, | |
144 | + }); | |
145 | +}; | |
146 | + | |
147 | +// 分配客户或 | |
148 | +export const dispatchCustomer = (data) => { | |
149 | + const { customerId, tbDeviceId } = data; | |
150 | + return defHttp.post( | |
151 | + { | |
152 | + url: `/customer/${customerId}/device/${tbDeviceId}`, | |
153 | + }, | |
154 | + { | |
155 | + joinPrefix: false, | |
156 | + } | |
157 | + ); | |
158 | +}; | |
159 | +// 取消分配客户 | |
160 | +export const cancelDispatchCustomer = (data) => { | |
161 | + const { customerId, tbDeviceId } = data; | |
162 | + return defHttp.delete( | |
163 | + { | |
164 | + url: `/customer/${customerId}/device/${tbDeviceId}`, | |
165 | + }, | |
166 | + { | |
167 | + joinPrefix: false, | |
168 | + } | |
169 | + ); | |
170 | +}; | ... | ... |
1 | 1 | import { formatToDateTime } from '/@/utils/dateUtil'; |
2 | 2 | import { FormSchema } from '/@/components/Form'; |
3 | 3 | import { BasicColumn } from '/@/components/Table'; |
4 | - | |
5 | 4 | import { DeviceTypeEnum } from '/@/api/device/model/deviceModel'; |
6 | - | |
5 | +import { getCustomerList } from '/@/api/device/deviceManager'; | |
7 | 6 | export const columns: BasicColumn[] = [ |
8 | 7 | { |
9 | 8 | title: '设备名称', |
... | ... | @@ -287,3 +286,19 @@ export const statusType = (type: string): string => { |
287 | 286 | return '激活未确认'; |
288 | 287 | } |
289 | 288 | }; |
289 | + | |
290 | +export const customerForm: FormSchema[] = [ | |
291 | + { | |
292 | + field: 'customerId', | |
293 | + label: '分配客户', | |
294 | + component: 'ApiSelect', | |
295 | + componentProps: { | |
296 | + api: getCustomerList, | |
297 | + immediate: false, | |
298 | + labelField: 'realName', | |
299 | + valueField: 'customerId', | |
300 | + }, | |
301 | + required: true, | |
302 | + colProps: { span: 12 }, | |
303 | + }, | |
304 | +]; | ... | ... |
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + @register="registerModal" | |
5 | + title="将设备分配给客户" | |
6 | + :canFullscreen="false" | |
7 | + centered | |
8 | + @ok="dispatchCustomer" | |
9 | + :minHeight="150" | |
10 | + okText="分配" | |
11 | + > | |
12 | + <BasicForm @register="registerForm" /> | |
13 | + </BasicModal> | |
14 | +</template> | |
15 | + | |
16 | +<script lang="ts"> | |
17 | + import { defineComponent } from 'vue'; | |
18 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | |
19 | + import { BasicForm, useForm } from '/@/components/Form'; | |
20 | + import { customerForm } from '../../config/detail.config'; | |
21 | + import { dispatchCustomer as dispatchCustomerApi } from '/@/api/device/deviceManager'; | |
22 | + export default defineComponent({ | |
23 | + name: 'AlarmDetailModal', | |
24 | + components: { | |
25 | + BasicModal, | |
26 | + BasicForm, | |
27 | + }, | |
28 | + emits: ['reload', 'register'], | |
29 | + setup(_, { emit }) { | |
30 | + let record = {}; | |
31 | + const [registerModal, { closeModal }] = useModalInner((data: any) => { | |
32 | + const { organizationId } = data; | |
33 | + record = data; | |
34 | + updateSchema([ | |
35 | + { | |
36 | + field: 'customerId', | |
37 | + componentProps: { | |
38 | + params: { organizationId }, | |
39 | + }, | |
40 | + }, | |
41 | + ]); | |
42 | + }); | |
43 | + const [registerForm, { validate, getFieldsValue, updateSchema, resetFields }] = useForm({ | |
44 | + labelWidth: 100, | |
45 | + showActionButtonGroup: false, | |
46 | + schemas: customerForm, | |
47 | + }); | |
48 | + // 分配客户 | |
49 | + const dispatchCustomer = async () => { | |
50 | + await validate(); | |
51 | + const { customerId } = getFieldsValue(); | |
52 | + await dispatchCustomerApi({ ...record, customerId }); | |
53 | + closeModal(); | |
54 | + resetFields(); | |
55 | + emit('reload'); | |
56 | + }; | |
57 | + | |
58 | + return { | |
59 | + registerModal, | |
60 | + registerForm, | |
61 | + dispatchCustomer, | |
62 | + }; | |
63 | + }, | |
64 | + }); | |
65 | +</script> | ... | ... |
... | ... | @@ -11,7 +11,12 @@ |
11 | 11 | :customRequest="customUpload" |
12 | 12 | :before-upload="beforeUpload" |
13 | 13 | > |
14 | - <img v-if="devicePic" :src="devicePic" alt="avatar" /> | |
14 | + <img | |
15 | + v-if="devicePic" | |
16 | + :src="devicePic" | |
17 | + alt="avatar" | |
18 | + style="width: 6.25rem; height: 6.25rem" | |
19 | + /> | |
15 | 20 | <div v-else> |
16 | 21 | <PlusOutlined /> |
17 | 22 | <div class="ant-upload-text">图片上传</div> |
... | ... | @@ -76,7 +81,6 @@ |
76 | 81 | [Divider.name]: Divider, |
77 | 82 | Upload, |
78 | 83 | EnvironmentTwoTone, |
79 | - // LoadingOutlined, | |
80 | 84 | PlusOutlined, |
81 | 85 | Modal, |
82 | 86 | [Form.name]: Form, |
... | ... | @@ -175,7 +179,8 @@ |
175 | 179 | if (!wrapEl) return; |
176 | 180 | let preMarker = null; |
177 | 181 | const map = new BMap.Map(wrapEl); |
178 | - let myIcon = new BMap.Icon('/src/assets/images/wz.png', new BMap.Size(20, 30)); | |
182 | + const icon = '/src/assets/images/wz.png'; | |
183 | + let myIcon = new BMap.Icon(icon, new BMap.Size(20, 30)); | |
179 | 184 | const point = new BMap.Point(Number(longitude), Number(latitude)); |
180 | 185 | let marker = new BMap.Marker(point, { icon: myIcon }); |
181 | 186 | if (marker) { | ... | ... |
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | /> |
9 | 9 | <BasicTable @register="registerTable" class="w-5/6 xl:w-4/5"> |
10 | 10 | <template #toolbar> |
11 | - <a-button type="primary" @click="handleCreate"> 新增设备 </a-button> | |
11 | + <a-button type="primary" @click="handleCreate" v-if="authBtn(role)"> 新增设备 </a-button> | |
12 | 12 | </template> |
13 | 13 | <template #deviceProfile="{ record }"> |
14 | 14 | <a-button type="link" class="ml-2" @click="goDeviceProfile"> |
... | ... | @@ -50,6 +50,23 @@ |
50 | 50 | <template #action="{ record }"> |
51 | 51 | <TableAction |
52 | 52 | :actions="[ |
53 | + record.customerId | |
54 | + ? { | |
55 | + tooltip: '取消分配给客户', | |
56 | + icon: 'mdi:account-arrow-left', | |
57 | + ifShow: authBtn(role), | |
58 | + popConfirm: { | |
59 | + title: '是否取消分配给客户', | |
60 | + confirm: handleCancelDispatchCustomer.bind(null, record), | |
61 | + }, | |
62 | + } | |
63 | + : { | |
64 | + icon: 'mdi:account-arrow-right', | |
65 | + tooltip: '分配给客户', | |
66 | + ifShow: authBtn(role), | |
67 | + onClick: handleDispatchCustomer.bind(null, record), | |
68 | + }, | |
69 | + | |
53 | 70 | { |
54 | 71 | label: '详情', |
55 | 72 | icon: 'ant-design:eye-outlined', |
... | ... | @@ -58,11 +75,13 @@ |
58 | 75 | { |
59 | 76 | label: '编辑', |
60 | 77 | icon: 'clarity:note-edit-line', |
78 | + ifShow: authBtn(role), | |
61 | 79 | onClick: handleEdit.bind(null, record), |
62 | 80 | }, |
63 | 81 | { |
64 | 82 | label: '删除', |
65 | 83 | icon: 'ant-design:delete-outlined', |
84 | + ifShow: authBtn(role), | |
66 | 85 | color: 'error', |
67 | 86 | popConfirm: { |
68 | 87 | title: '是否确认删除', |
... | ... | @@ -74,7 +93,8 @@ |
74 | 93 | </template> |
75 | 94 | </BasicTable> |
76 | 95 | <DeviceDetailDrawer @register="registerDetailDrawer" /> |
77 | - <DeviceModal @register="registerModal" @success="handleSuccess" @reload="handleReload" /> | |
96 | + <DeviceModal @register="registerModal" @success="handleSuccess" @reload="handleSuccess" /> | |
97 | + <CustomerModal @register="registerCustomerModal" @reload="handleSuccess" /> | |
78 | 98 | </PageWrapper> |
79 | 99 | </div> |
80 | 100 | </template> |
... | ... | @@ -85,7 +105,7 @@ |
85 | 105 | import { columns, searchFormSchema } from './config/device.data'; |
86 | 106 | import { Tag } from 'ant-design-vue'; |
87 | 107 | import { useMessage } from '/@/hooks/web/useMessage'; |
88 | - import { deleteDevice, devicePage } from '/@/api/device/deviceManager'; | |
108 | + import { deleteDevice, devicePage, cancelDispatchCustomer } from '/@/api/device/deviceManager'; | |
89 | 109 | import { PageEnum } from '/@/enums/pageEnum'; |
90 | 110 | import { useGo } from '/@/hooks/web/usePage'; |
91 | 111 | import { PageWrapper } from '/@/components/Page'; |
... | ... | @@ -95,7 +115,11 @@ |
95 | 115 | import DeviceModal from './cpns/modal/DeviceModal.vue'; |
96 | 116 | import { useDrawer } from '/@/components/Drawer'; |
97 | 117 | import DeviceDetailDrawer from './cpns/modal/DeviceDetailDrawer.vue'; |
118 | + import CustomerModal from './cpns/modal/CustomerModal.vue'; | |
98 | 119 | |
120 | + import { USER_INFO_KEY } from '/@/enums/cacheEnum'; | |
121 | + import { getAuthCache } from '/@/utils/auth'; | |
122 | + import { authBtn } from '/@/enums/roleEnum'; | |
99 | 123 | export default defineComponent({ |
100 | 124 | name: 'DeviceManagement', |
101 | 125 | components: { |
... | ... | @@ -106,6 +130,7 @@ |
106 | 130 | Tag, |
107 | 131 | DeviceModal, |
108 | 132 | DeviceDetailDrawer, |
133 | + CustomerModal, | |
109 | 134 | }, |
110 | 135 | setup(_) { |
111 | 136 | const { createMessage } = useMessage(); |
... | ... | @@ -114,6 +139,7 @@ |
114 | 139 | const searchInfo = reactive<Recordable>({}); |
115 | 140 | const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); |
116 | 141 | const [registerModal, { openModal }] = useModal(); |
142 | + const [registerCustomerModal, { openModal: openCustomerModal }] = useModal(); | |
117 | 143 | const [registerDetailDrawer, { openDrawer }] = useDrawer(); |
118 | 144 | const [registerTable, { reload }] = useTable({ |
119 | 145 | title: '设备列表', |
... | ... | @@ -130,22 +156,32 @@ |
130 | 156 | showIndexColumn: false, |
131 | 157 | searchInfo: searchInfo, |
132 | 158 | actionColumn: { |
133 | - width: 200, | |
159 | + width: 250, | |
134 | 160 | title: '操作', |
135 | 161 | dataIndex: 'action', |
136 | 162 | slots: { customRender: 'action' }, |
137 | 163 | fixed: 'right', |
138 | 164 | }, |
139 | 165 | }); |
140 | - const handleReload = () => { | |
141 | - handleSuccess(); | |
142 | - }; | |
166 | + | |
167 | + const userInfo: any = getAuthCache(USER_INFO_KEY); | |
168 | + const role: string = userInfo.roles[0]; | |
143 | 169 | |
144 | 170 | function handleCreate() { |
145 | 171 | openModal(true, { |
146 | 172 | isUpdate: false, |
147 | 173 | }); |
148 | 174 | } |
175 | + // 分配客户 | |
176 | + function handleDispatchCustomer(record: Recordable) { | |
177 | + openCustomerModal(true, record); | |
178 | + } | |
179 | + // 取消分配客户 | |
180 | + async function handleCancelDispatchCustomer(record: Recordable) { | |
181 | + console.log('record', record); | |
182 | + await cancelDispatchCustomer({ ...record, customerId: '' }); | |
183 | + handleSuccess(); | |
184 | + } | |
149 | 185 | |
150 | 186 | function handleDetail(record: Recordable) { |
151 | 187 | const { id, tbDeviceId } = record; |
... | ... | @@ -191,12 +227,16 @@ |
191 | 227 | goDeviceProfile, |
192 | 228 | handleSelect, |
193 | 229 | registerModal, |
194 | - handleReload, | |
195 | 230 | registerDetailDrawer, |
196 | 231 | DeviceTypeEnum, |
197 | 232 | DeviceState, |
198 | 233 | searchInfo, |
199 | 234 | organizationIdTreeRef, |
235 | + handleDispatchCustomer, | |
236 | + handleCancelDispatchCustomer, | |
237 | + registerCustomerModal, | |
238 | + authBtn, | |
239 | + role, | |
200 | 240 | }; |
201 | 241 | }, |
202 | 242 | }); | ... | ... |
... | ... | @@ -41,7 +41,7 @@ export const columns: BasicColumn[] = [ |
41 | 41 | customRender: ({ record }) => { |
42 | 42 | const status = record.readStatus; |
43 | 43 | const enable = status == 0 ? '未读' : status == 1 ? '已读' : '其他'; |
44 | - const color = enable == '未读' ? 'green' : enable == '已读' ? 'yellow' : 'red'; | |
44 | + const color = enable == '未读' ? 'yellow' : enable == '已读' ? 'green' : 'red'; | |
45 | 45 | const text = enable == '未读' ? '未读' : enable == '已读' ? '已读' : '其他'; |
46 | 46 | return h(Tag, { color }, () => text); |
47 | 47 | }, | ... | ... |
... | ... | @@ -90,7 +90,7 @@ |
90 | 90 | setModalProps({ confirmLoading: true }); |
91 | 91 | await SaveOrUpdateUserInfo(values, unref(isUpdate)); |
92 | 92 | closeModal(); |
93 | - emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } }); | |
93 | + emit('success'); | |
94 | 94 | createMessage.success(unref(isUpdate) ? '编辑成功' : '新增成功'); |
95 | 95 | } finally { |
96 | 96 | setModalProps({ confirmLoading: false }); | ... | ... |
... | ... | @@ -88,7 +88,7 @@ |
88 | 88 | const { createMessage } = useMessage(); |
89 | 89 | let searchInfo = reactive<Recordable>({}); |
90 | 90 | const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); |
91 | - const [registerTable, { reload, updateTableDataRecord }] = useTable({ | |
91 | + const [registerTable, { reload }] = useTable({ | |
92 | 92 | title: '账号列表', |
93 | 93 | api: getAccountList, |
94 | 94 | rowKey: 'id', |
... | ... | @@ -131,14 +131,8 @@ |
131 | 131 | }); |
132 | 132 | } |
133 | 133 | |
134 | - function handleSuccess({ isUpdate, values }) { | |
135 | - if (isUpdate) { | |
136 | - // 演示不刷新表格直接更新内部数据。 | |
137 | - // 注意:updateTableDataRecord要求表格的rowKey属性为string并且存在于每一行的record的keys中 | |
138 | - updateTableDataRecord(values.id, values); | |
139 | - } else { | |
140 | - reload(); | |
141 | - } | |
134 | + function handleSuccess() { | |
135 | + reload(); | |
142 | 136 | } |
143 | 137 | |
144 | 138 | function handleSelect(organization) { | ... | ... |