Commit 6c74ade6ea09f77e913877b0cb8d5cb0b7daa4a8
Merge branch 'sqy_dev' into 'main'
'feat:(设备页面功能及接口调试)' See merge request huang/yun-teng-iot-front!8
Showing
5 changed files
with
132 additions
and
47 deletions
@@ -72,9 +72,17 @@ export const deviceProfile = () => { | @@ -72,9 +72,17 @@ export const deviceProfile = () => { | ||
72 | }); | 72 | }); |
73 | }; | 73 | }; |
74 | 74 | ||
75 | +// 创建或编辑设备 | ||
75 | export const createOrEditDevice = (data) => { | 76 | export const createOrEditDevice = (data) => { |
76 | return defHttp.post({ | 77 | return defHttp.post({ |
77 | url: DeviceManagerApi.DEVICE_URL, | 78 | url: DeviceManagerApi.DEVICE_URL, |
78 | data, | 79 | data, |
79 | }); | 80 | }); |
80 | }; | 81 | }; |
82 | + | ||
83 | +// 获取设备唯一token | ||
84 | +export const getDeviceToken = () => { | ||
85 | + return defHttp.get({ | ||
86 | + url: '/common', | ||
87 | + }); | ||
88 | +}; |
@@ -2,8 +2,8 @@ | @@ -2,8 +2,8 @@ | ||
2 | <BasicModal | 2 | <BasicModal |
3 | v-bind="$attrs" | 3 | v-bind="$attrs" |
4 | width="55rem" | 4 | width="55rem" |
5 | - @register="register" | ||
6 | :title="getTitle" | 5 | :title="getTitle" |
6 | + @register="register" | ||
7 | @cancel="handleCancel" | 7 | @cancel="handleCancel" |
8 | @ok="handleOk" | 8 | @ok="handleOk" |
9 | centered | 9 | centered |
@@ -15,25 +15,30 @@ | @@ -15,25 +15,30 @@ | ||
15 | </a-steps> | 15 | </a-steps> |
16 | </div> | 16 | </div> |
17 | <div class="mt-5"> | 17 | <div class="mt-5"> |
18 | - <DeviceStep1 @next="handleStep1Next" v-show="current === 0" ref="DeviceStep1Ref" /> | 18 | + <DeviceStep1 |
19 | + @next="handleStep1Next" | ||
20 | + v-show="current === 0" | ||
21 | + ref="DeviceStep1Ref" | ||
22 | + :deviceInfo="deviceInfo" | ||
23 | + /> | ||
19 | <DeviceStep2 | 24 | <DeviceStep2 |
20 | ref="DeviceStep2Ref" | 25 | ref="DeviceStep2Ref" |
21 | @prev="handleStepPrev" | 26 | @prev="handleStepPrev" |
22 | @next="handleStep2Next" | 27 | @next="handleStep2Next" |
23 | v-show="current === 1" | 28 | v-show="current === 1" |
24 | - v-if="initStep2" | ||
25 | /> | 29 | /> |
26 | </div> | 30 | </div> |
27 | </BasicModal> | 31 | </BasicModal> |
28 | </template> | 32 | </template> |
29 | <script lang="ts"> | 33 | <script lang="ts"> |
30 | - import { defineComponent, ref, computed, unref, reactive, toRefs } from 'vue'; | 34 | + import { defineComponent, ref, computed, unref } from 'vue'; |
31 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 35 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
32 | - import { createOrEditDevice } from '/@/api/device/deviceManager'; | 36 | + import { createOrEditDevice, getDeviceToken } from '/@/api/device/deviceManager'; |
33 | import DeviceStep1 from '/@/views/device/step/DeviceStep1.vue'; | 37 | import DeviceStep1 from '/@/views/device/step/DeviceStep1.vue'; |
34 | import DeviceStep2 from '/@/views/device/step/DeviceStep2.vue'; | 38 | import DeviceStep2 from '/@/views/device/step/DeviceStep2.vue'; |
35 | import { Steps } from 'ant-design-vue'; | 39 | import { Steps } from 'ant-design-vue'; |
36 | import { useMessage } from '/@/hooks/web/useMessage'; | 40 | import { useMessage } from '/@/hooks/web/useMessage'; |
41 | + | ||
37 | export default defineComponent({ | 42 | export default defineComponent({ |
38 | name: 'DeviceModal', | 43 | name: 'DeviceModal', |
39 | components: { | 44 | components: { |
@@ -46,27 +51,31 @@ | @@ -46,27 +51,31 @@ | ||
46 | props: { | 51 | props: { |
47 | userData: { type: Object }, | 52 | userData: { type: Object }, |
48 | }, | 53 | }, |
54 | + emits: ['reload'], | ||
49 | setup(_, { emit }) { | 55 | setup(_, { emit }) { |
50 | const DeviceStep1Ref = ref<InstanceType<typeof DeviceStep1>>(); | 56 | const DeviceStep1Ref = ref<InstanceType<typeof DeviceStep1>>(); |
51 | const DeviceStep2Ref = ref<InstanceType<typeof DeviceStep2>>(); | 57 | const DeviceStep2Ref = ref<InstanceType<typeof DeviceStep2>>(); |
52 | const { createMessage } = useMessage(); | 58 | const { createMessage } = useMessage(); |
53 | - const state = reactive({ | ||
54 | - initStep2: false, | ||
55 | - }); | ||
56 | const current = ref(0); | 59 | const current = ref(0); |
57 | const isUpdate = ref(true); | 60 | const isUpdate = ref(true); |
61 | + const deviceInfo = ref({}); | ||
58 | const getTitle = computed(() => (!unref(isUpdate) ? '新增设备' : '编辑设备')); | 62 | const getTitle = computed(() => (!unref(isUpdate) ? '新增设备' : '编辑设备')); |
59 | // 所有参数 | 63 | // 所有参数 |
60 | let stepState = ref(); | 64 | let stepState = ref(); |
61 | // 编辑回显 | 65 | // 编辑回显 |
62 | const [register, { closeModal }] = useModalInner((data) => { | 66 | const [register, { closeModal }] = useModalInner((data) => { |
63 | if (data.isUpdate) { | 67 | if (data.isUpdate) { |
64 | - DeviceStep1Ref.value?.parentSetFieldsValue(data.record); | ||
65 | - DeviceStep1Ref.value?.parentSetFieldsValue({ | 68 | + DeviceStep1Ref?.value?.parentSetFieldsValue(data.record); |
69 | + DeviceStep1Ref?.value?.parentSetFieldsValue({ | ||
66 | profile: data.record.deviceProfile.name, | 70 | profile: data.record.deviceProfile.name, |
67 | remark: data.record.deviceInfo.description, | 71 | remark: data.record.deviceInfo.description, |
68 | profileId: data.record.profileId, | 72 | profileId: data.record.profileId, |
69 | }); | 73 | }); |
74 | + deviceInfo.value = data.record.deviceInfo; | ||
75 | + } else { | ||
76 | + DeviceStep1Ref?.value?.parentResetDevicePic(); | ||
77 | + DeviceStep1Ref?.value?.parentResetPositionState(); | ||
78 | + deviceInfo.value = {}; | ||
70 | } | 79 | } |
71 | isUpdate.value = !!data?.isUpdate; | 80 | isUpdate.value = !!data?.isUpdate; |
72 | }); | 81 | }); |
@@ -78,12 +87,11 @@ | @@ -78,12 +87,11 @@ | ||
78 | // 下一步 | 87 | // 下一步 |
79 | function handleStep1Next(step1Values: any) { | 88 | function handleStep1Next(step1Values: any) { |
80 | current.value++; | 89 | current.value++; |
81 | - state.initStep2 = true; | ||
82 | - stepState = { ...step1Values }; | 90 | + stepState.value = { ...step1Values }; |
83 | } | 91 | } |
84 | // | 92 | // |
85 | function handleStep2Next(step2Values: any) { | 93 | function handleStep2Next(step2Values: any) { |
86 | - stepState = { ...stepState, ...step2Values }; | 94 | + stepState.value = { ...stepState, ...step2Values }; |
87 | } | 95 | } |
88 | function handleCancel() { | 96 | function handleCancel() { |
89 | current.value = 0; | 97 | current.value = 0; |
@@ -111,17 +119,40 @@ | @@ -111,17 +119,40 @@ | ||
111 | } | 119 | } |
112 | // 验证成功 --掉新增或者编辑接口 | 120 | // 验证成功 --掉新增或者编辑接口 |
113 | const msg = computed(() => (stepState.value.id ? '更新设备成功' : '新增设备成功')); | 121 | const msg = computed(() => (stepState.value.id ? '更新设备成功' : '新增设备成功')); |
114 | - await createOrEditDevice(stepState.value); | 122 | + console.log(stepState); |
123 | + if (stepState.value.id) { | ||
124 | + const editData = { | ||
125 | + ...stepState.value, | ||
126 | + deviceInfo: { | ||
127 | + avatar: DeviceStep1Ref.value?.devicePic, | ||
128 | + ...DeviceStep1Ref.value?.positionState, | ||
129 | + }, | ||
130 | + }; | ||
131 | + await createOrEditDevice(editData); | ||
132 | + } else { | ||
133 | + let deviceToken = await getDeviceToken(); | ||
134 | + // 需要携带唯一的设备token | ||
135 | + const createData = { | ||
136 | + ...stepState.value, | ||
137 | + deviceToken, | ||
138 | + deviceInfo: { | ||
139 | + avatar: DeviceStep1Ref.value?.devicePic, | ||
140 | + ...DeviceStep1Ref.value?.positionState, | ||
141 | + }, | ||
142 | + }; | ||
143 | + | ||
144 | + await createOrEditDevice(createData); | ||
145 | + } | ||
115 | createMessage.success(msg.value); | 146 | createMessage.success(msg.value); |
116 | emit('reload'); | 147 | emit('reload'); |
117 | } | 148 | } |
118 | return { | 149 | return { |
119 | - register, | ||
120 | getTitle, | 150 | getTitle, |
121 | current, | 151 | current, |
122 | DeviceStep1Ref, | 152 | DeviceStep1Ref, |
123 | DeviceStep2Ref, | 153 | DeviceStep2Ref, |
124 | - ...toRefs(state), | 154 | + deviceInfo, |
155 | + register, | ||
125 | handleStepPrev, | 156 | handleStepPrev, |
126 | handleStep1Next, | 157 | handleStep1Next, |
127 | handleStep2Next, | 158 | handleStep2Next, |
@@ -162,12 +162,12 @@ | @@ -162,12 +162,12 @@ | ||
162 | handleDelete, | 162 | handleDelete, |
163 | handleSuccess, | 163 | handleSuccess, |
164 | goDeviceProfile, | 164 | goDeviceProfile, |
165 | - DeviceTypeEnum, | ||
166 | - DeviceState, | ||
167 | handleSelect, | 165 | handleSelect, |
168 | - searchInfo, | ||
169 | registerModal, | 166 | registerModal, |
170 | handleReload, | 167 | handleReload, |
168 | + DeviceTypeEnum, | ||
169 | + DeviceState, | ||
170 | + searchInfo, | ||
171 | }; | 171 | }; |
172 | }, | 172 | }, |
173 | }); | 173 | }); |
@@ -41,12 +41,12 @@ | @@ -41,12 +41,12 @@ | ||
41 | <a-row :gutter="20" class="pt-4 pl-6"> | 41 | <a-row :gutter="20" class="pt-4 pl-6"> |
42 | <a-col :span="8"> | 42 | <a-col :span="8"> |
43 | <a-form-item label="经度"> | 43 | <a-form-item label="经度"> |
44 | - <Input type="input" v-model:value="positionState.lng" disabled /> | 44 | + <Input type="input" v-model:value="positionState.longitude" disabled /> |
45 | </a-form-item> | 45 | </a-form-item> |
46 | </a-col> | 46 | </a-col> |
47 | <a-col :span="8"> | 47 | <a-col :span="8"> |
48 | <a-form-item label="纬度"> | 48 | <a-form-item label="纬度"> |
49 | - <Input type="input" v-model:value="positionState.lat" disabled /> | 49 | + <Input type="input" v-model:value="positionState.latitude" disabled /> |
50 | </a-form-item> | 50 | </a-form-item> |
51 | </a-col> | 51 | </a-col> |
52 | </a-row> | 52 | </a-row> |
@@ -57,11 +57,10 @@ | @@ -57,11 +57,10 @@ | ||
57 | </div> | 57 | </div> |
58 | </template> | 58 | </template> |
59 | <script lang="ts"> | 59 | <script lang="ts"> |
60 | - import { defineComponent, ref, nextTick, unref, reactive } from 'vue'; | 60 | + import { defineComponent, ref, nextTick, unref, reactive, watch } from 'vue'; |
61 | import { BasicForm, useForm } from '/@/components/Form'; | 61 | import { BasicForm, useForm } from '/@/components/Form'; |
62 | import { step1Schemas } from './data'; | 62 | import { step1Schemas } from './data'; |
63 | import { useScript } from '/@/hooks/web/useScript'; | 63 | import { useScript } from '/@/hooks/web/useScript'; |
64 | - import { ScrollActionType } from '/@/components/Container/index'; | ||
65 | import { Input, Divider, Upload, message, Modal, Form, Row, Col } from 'ant-design-vue'; | 64 | import { Input, Divider, Upload, message, Modal, Form, Row, Col } from 'ant-design-vue'; |
66 | import { EnvironmentTwoTone, PlusOutlined } from '@ant-design/icons-vue'; | 65 | import { EnvironmentTwoTone, PlusOutlined } from '@ant-design/icons-vue'; |
67 | import { upload } from '/@/api/oss/ossFileUploader'; | 66 | import { upload } from '/@/api/oss/ossFileUploader'; |
@@ -82,12 +81,23 @@ | @@ -82,12 +81,23 @@ | ||
82 | [Row.name]: Row, | 81 | [Row.name]: Row, |
83 | [Col.name]: Col, | 82 | [Col.name]: Col, |
84 | }, | 83 | }, |
84 | + props: { | ||
85 | + deviceInfo: { | ||
86 | + type: Object, | ||
87 | + default: () => ({}), | ||
88 | + }, | ||
89 | + }, | ||
85 | emits: ['next'], | 90 | emits: ['next'], |
86 | - setup(_, { emit }) { | 91 | + setup(props, { emit }) { |
87 | const devicePic = ref(''); | 92 | const devicePic = ref(''); |
88 | - let positionState = reactive({ | ||
89 | - lng: '', | ||
90 | - lat: '', | 93 | + let positionState = reactive<{ |
94 | + longitude: string; | ||
95 | + latitude: string; | ||
96 | + description?: string; | ||
97 | + address: string; | ||
98 | + }>({ | ||
99 | + longitude: '', | ||
100 | + latitude: '', | ||
91 | address: '', | 101 | address: '', |
92 | }); | 102 | }); |
93 | const [register, { validate, resetFields, setFieldsValue, getFieldsValue }] = useForm({ | 103 | const [register, { validate, resetFields, setFieldsValue, getFieldsValue }] = useForm({ |
@@ -141,49 +151,62 @@ | @@ -141,49 +151,62 @@ | ||
141 | const visible = ref(false); | 151 | const visible = ref(false); |
142 | const selectPosition = () => { | 152 | const selectPosition = () => { |
143 | visible.value = true; | 153 | visible.value = true; |
144 | - initMap(); | 154 | + if (!positionState.longitude) { |
155 | + initMap('104.04666605565338', '30.543516387560476'); | ||
156 | + } else { | ||
157 | + initMap(positionState.longitude, positionState.latitude); | ||
158 | + } | ||
145 | }; | 159 | }; |
146 | 160 | ||
147 | // 地图 | 161 | // 地图 |
148 | const BAI_DU_MAP_URL = | 162 | const BAI_DU_MAP_URL = |
149 | 'https://api.map.baidu.com/getscript?v=3.0&ak=7uOPPyAHn2Y2ZryeQqHtcRqtIY374vKa'; | 163 | 'https://api.map.baidu.com/getscript?v=3.0&ak=7uOPPyAHn2Y2ZryeQqHtcRqtIY374vKa'; |
150 | const wrapRef = ref<HTMLDivElement | null>(null); | 164 | const wrapRef = ref<HTMLDivElement | null>(null); |
151 | - const scrollRef = ref<Nullable<ScrollActionType>>(null); | ||
152 | const { toPromise } = useScript({ src: BAI_DU_MAP_URL }); | 165 | const { toPromise } = useScript({ src: BAI_DU_MAP_URL }); |
153 | - async function initMap() { | 166 | + |
167 | + async function initMap(longitude, latitude) { | ||
154 | await toPromise(); | 168 | await toPromise(); |
155 | await nextTick(); | 169 | await nextTick(); |
156 | const wrapEl = unref(wrapRef); | 170 | const wrapEl = unref(wrapRef); |
157 | const BMap = (window as any).BMap; | 171 | const BMap = (window as any).BMap; |
158 | if (!wrapEl) return; | 172 | if (!wrapEl) return; |
173 | + let preMarker = null; | ||
159 | const map = new BMap.Map(wrapEl); | 174 | const map = new BMap.Map(wrapEl); |
160 | - const point = new BMap.Point(104.04813399999999, 30.54348986021446); | 175 | + let myIcon = new BMap.Icon( |
176 | + 'http://api.map.baidu.com/img/markers.png', | ||
177 | + new BMap.Size(40, 25), | ||
178 | + { | ||
179 | + offset: new BMap.Size(0, 0), // 指定定位位置 | ||
180 | + imageOffset: new BMap.Size(20, -260), // 设置图片偏移 | ||
181 | + } | ||
182 | + ); | ||
183 | + const point = new BMap.Point(Number(longitude), Number(latitude)); | ||
184 | + let marker = new BMap.Marker(point, { icon: myIcon }); | ||
185 | + if (marker) { | ||
186 | + map.removeOverlay(preMarker); | ||
187 | + } | ||
188 | + map.addOverlay(marker); | ||
189 | + preMarker = marker; | ||
161 | map.centerAndZoom(point, 15); | 190 | map.centerAndZoom(point, 15); |
162 | map.enableScrollWheelZoom(true); | 191 | map.enableScrollWheelZoom(true); |
163 | - let preMarker = null; | ||
164 | map.addEventListener('click', (e) => { | 192 | map.addEventListener('click', (e) => { |
165 | - const { lat, lng } = map.he; | ||
166 | - positionState.lat = lat + ''; | ||
167 | - positionState.lng = lng + ''; | 193 | + const { lat, lng } = e.point; |
194 | + console.log(lat, lng); | ||
195 | + positionState.latitude = lat + ''; | ||
196 | + positionState.longitude = lng + ''; | ||
168 | let gc = new BMap.Geocoder(); | 197 | let gc = new BMap.Geocoder(); |
169 | let newPoint = new BMap.Point(lng, lat); | 198 | let newPoint = new BMap.Point(lng, lat); |
199 | + | ||
200 | + // 添加锚点 | ||
170 | if (!e.overlay) { | 201 | if (!e.overlay) { |
171 | - let myIcon = new BMap.Icon( | ||
172 | - 'http://api.map.baidu.com/img/markers.png', | ||
173 | - new BMap.Size(40, 25), | ||
174 | - { | ||
175 | - offset: new BMap.Size(0, 0), // 指定定位位置 | ||
176 | - imageOffset: new BMap.Size(20, -260), // 设置图片偏移 | ||
177 | - } | ||
178 | - ); | ||
179 | let marker = new BMap.Marker(e.point, { icon: myIcon }); | 202 | let marker = new BMap.Marker(e.point, { icon: myIcon }); |
180 | map.removeOverlay(preMarker); | 203 | map.removeOverlay(preMarker); |
181 | map.addOverlay(marker); | 204 | map.addOverlay(marker); |
182 | preMarker = marker; | 205 | preMarker = marker; |
183 | } | 206 | } |
207 | + //获取详细的地址,精确到街道的名称 | ||
184 | gc.getLocation(newPoint, (rs) => { | 208 | gc.getLocation(newPoint, (rs) => { |
185 | let addComp = rs.addressComponents; | 209 | let addComp = rs.addressComponents; |
186 | - //获取详细的地址,精确到街道的名称 | ||
187 | let addrname = addComp.city + addComp.district + addComp.street + addComp.streetNumber; | 210 | let addrname = addComp.city + addComp.district + addComp.street + addComp.streetNumber; |
188 | positionState.address = addrname; | 211 | positionState.address = addrname; |
189 | }); | 212 | }); |
@@ -203,16 +226,38 @@ | @@ -203,16 +226,38 @@ | ||
203 | function parentSetFieldsValue(data) { | 226 | function parentSetFieldsValue(data) { |
204 | setFieldsValue(data); | 227 | setFieldsValue(data); |
205 | } | 228 | } |
206 | - | 229 | + // 父组件调用获取字段值的方法 |
207 | function parentGetFieldsValue() { | 230 | function parentGetFieldsValue() { |
208 | return getFieldsValue(); | 231 | return getFieldsValue(); |
209 | } | 232 | } |
210 | 233 | ||
234 | + // 父组件调用表单验证 | ||
211 | async function parentValidate() { | 235 | async function parentValidate() { |
212 | const valid = await validate(); | 236 | const valid = await validate(); |
213 | return valid; | 237 | return valid; |
214 | } | 238 | } |
215 | 239 | ||
240 | + // 父组件重置图片 | ||
241 | + function parentResetDevicePic() { | ||
242 | + devicePic.value = ''; | ||
243 | + } | ||
244 | + // 父组件重置位置 | ||
245 | + function parentResetPositionState() { | ||
246 | + for (let key in positionState) { | ||
247 | + positionState[key] = ''; | ||
248 | + } | ||
249 | + } | ||
250 | + | ||
251 | + watch( | ||
252 | + () => props.deviceInfo, | ||
253 | + (newValue) => { | ||
254 | + positionState.longitude = newValue.longitude; | ||
255 | + positionState.latitude = newValue.latitude; | ||
256 | + positionState.address = newValue.address; | ||
257 | + devicePic.value = newValue.avatar; | ||
258 | + } | ||
259 | + ); | ||
260 | + | ||
216 | return { | 261 | return { |
217 | resetFields, | 262 | resetFields, |
218 | positionState, | 263 | positionState, |
@@ -222,7 +267,6 @@ | @@ -222,7 +267,6 @@ | ||
222 | selectPosition, | 267 | selectPosition, |
223 | devicePic, | 268 | devicePic, |
224 | visible, | 269 | visible, |
225 | - scrollRef, | ||
226 | handleOk, | 270 | handleOk, |
227 | handleCancel, | 271 | handleCancel, |
228 | wrapRef, | 272 | wrapRef, |
@@ -230,6 +274,8 @@ | @@ -230,6 +274,8 @@ | ||
230 | parentSetFieldsValue, | 274 | parentSetFieldsValue, |
231 | parentGetFieldsValue, | 275 | parentGetFieldsValue, |
232 | parentValidate, | 276 | parentValidate, |
277 | + parentResetDevicePic, | ||
278 | + parentResetPositionState, | ||
233 | }; | 279 | }; |
234 | }, | 280 | }, |
235 | }); | 281 | }); |
@@ -117,7 +117,7 @@ | @@ -117,7 +117,7 @@ | ||
117 | }); | 117 | }); |
118 | 118 | ||
119 | // 切换凭证类型时,重置字段 | 119 | // 切换凭证类型时,重置字段 |
120 | - const handleChange = (value) => { | 120 | + const handleChange = (value: string) => { |
121 | if (value === 'Access token') { | 121 | if (value === 'Access token') { |
122 | resetCreantialsType(); | 122 | resetCreantialsType(); |
123 | } else if (value === 'X.509') { | 123 | } else if (value === 'X.509') { |