Commit 6c74ade6ea09f77e913877b0cb8d5cb0b7daa4a8

Authored by xp.Huang
2 parents 04c4d5ef 29fb75d0

Merge branch 'sqy_dev' into 'main'

'feat:(设备页面功能及接口调试)'

See merge request huang/yun-teng-iot-front!8
@@ -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') {