Commit 45638b35f401d477e0589ffbf20a4849e34d2223

Authored by YunaiV
1 parent 6892571a

feat(iot):【设备定位:100%】首页接入地图,基于 sequential-crafting-thacker.md 规划

yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.java
1 package cn.iocoder.yudao.module.iot.controller.admin.device; 1 package cn.iocoder.yudao.module.iot.controller.admin.device;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; 4 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.pojo.PageParam; 6 import cn.iocoder.yudao.framework.common.pojo.PageParam;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 9 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 10 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
9 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*; 11 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
10 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; 12 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
  13 +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
11 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; 14 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
  15 +import cn.iocoder.yudao.module.iot.service.product.IotProductService;
12 import io.swagger.v3.oas.annotations.Operation; 16 import io.swagger.v3.oas.annotations.Operation;
13 import io.swagger.v3.oas.annotations.Parameter; 17 import io.swagger.v3.oas.annotations.Parameter;
14 import io.swagger.v3.oas.annotations.Parameters; 18 import io.swagger.v3.oas.annotations.Parameters;
@@ -22,13 +26,12 @@ import org.springframework.web.bind.annotation.*; @@ -22,13 +26,12 @@ import org.springframework.web.bind.annotation.*;
22 import org.springframework.web.multipart.MultipartFile; 26 import org.springframework.web.multipart.MultipartFile;
23 27
24 import java.io.IOException; 28 import java.io.IOException;
25 -import java.util.Arrays;  
26 -import java.util.Collection;  
27 -import java.util.List; 29 +import java.util.*;
28 30
29 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; 31 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
30 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 32 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
31 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 33 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  34 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
32 35
33 @Tag(name = "管理后台 - IoT 设备") 36 @Tag(name = "管理后台 - IoT 设备")
34 @RestController 37 @RestController
@@ -38,6 +41,8 @@ public class IotDeviceController { @@ -38,6 +41,8 @@ public class IotDeviceController {
38 41
39 @Resource 42 @Resource
40 private IotDeviceService deviceService; 43 private IotDeviceService deviceService;
  44 + @Resource
  45 + private IotProductService productService;
41 46
42 @PostMapping("/create") 47 @PostMapping("/create")
43 @Operation(summary = "创建设备") 48 @Operation(summary = "创建设备")
@@ -135,6 +140,26 @@ public class IotDeviceController { @@ -135,6 +140,26 @@ public class IotDeviceController {
135 .setProductId(device.getProductId()).setState(device.getState()))); 140 .setProductId(device.getProductId()).setState(device.getState())));
136 } 141 }
137 142
  143 + @GetMapping("/location-list")
  144 + @Operation(summary = "获取设备位置列表", description = "获取有经纬度信息的设备列表,用于地图展示")
  145 + @PreAuthorize("@ss.hasPermission('iot:device:query')")
  146 + public CommonResult<List<IotDeviceRespVO>> getDeviceLocationList() {
  147 + // 1. 获取有位置信息的设备列表
  148 + List<IotDeviceDO> devices = deviceService.getDeviceListByHasLocation();
  149 + if (CollUtil.isEmpty(devices)) {
  150 + return success(Collections.emptyList());
  151 + }
  152 +
  153 + // 2. 转换并返回
  154 + Map<Long, IotProductDO> productMap = convertMap(productService.getProductList(), IotProductDO::getId);
  155 + return success(convertList(devices, device -> {
  156 + IotDeviceRespVO respVO = BeanUtils.toBean(device, IotDeviceRespVO.class);
  157 + MapUtils.findAndThen(productMap, device.getProductId(),
  158 + product -> respVO.setProductName(product.getName()));
  159 + return respVO;
  160 + }));
  161 + }
  162 +
138 @PostMapping("/import") 163 @PostMapping("/import")
139 @Operation(summary = "导入设备") 164 @Operation(summary = "导入设备")
140 @PreAuthorize("@ss.hasPermission('iot:device:import')") 165 @PreAuthorize("@ss.hasPermission('iot:device:import')")
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceRespVO.java
@@ -45,6 +45,9 @@ public class IotDeviceRespVO { @@ -45,6 +45,9 @@ public class IotDeviceRespVO {
45 @ExcelProperty("产品编号") 45 @ExcelProperty("产品编号")
46 private Long productId; 46 private Long productId;
47 47
  48 + @Schema(description = "产品名称", example = "温湿度传感器")
  49 + private String productName; // 只有部分接口返回,例如 getDeviceLocationList
  50 +
48 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) 51 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
49 @ExcelProperty("产品 Key") 52 @ExcelProperty("产品 Key")
50 private String productKey; 53 private String productKey;
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java
@@ -118,4 +118,15 @@ public interface IotDeviceMapper extends BaseMapperX&lt;IotDeviceDO&gt; { @@ -118,4 +118,15 @@ public interface IotDeviceMapper extends BaseMapperX&lt;IotDeviceDO&gt; {
118 )); 118 ));
119 } 119 }
120 120
  121 + /**
  122 + * 查询有位置信息的设备列表
  123 + *
  124 + * @return 设备列表
  125 + */
  126 + default List<IotDeviceDO> selectListByHasLocation() {
  127 + return selectList(new LambdaQueryWrapperX<IotDeviceDO>()
  128 + .isNotNull(IotDeviceDO::getLatitude)
  129 + .isNotNull(IotDeviceDO::getLongitude));
  130 + }
  131 +
121 } 132 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
@@ -281,4 +281,11 @@ public interface IotDeviceService { @@ -281,4 +281,11 @@ public interface IotDeviceService {
281 */ 281 */
282 void updateDeviceLocation(IotDeviceDO device, BigDecimal longitude, BigDecimal latitude); 282 void updateDeviceLocation(IotDeviceDO device, BigDecimal longitude, BigDecimal latitude);
283 283
  284 + /**
  285 + * 获得有位置信息的设备列表
  286 + *
  287 + * @return 设备列表
  288 + */
  289 + List<IotDeviceDO> getDeviceListByHasLocation();
  290 +
284 } 291 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
@@ -509,6 +509,11 @@ public class IotDeviceServiceImpl implements IotDeviceService { @@ -509,6 +509,11 @@ public class IotDeviceServiceImpl implements IotDeviceService {
509 deleteDeviceCache(device); 509 deleteDeviceCache(device);
510 } 510 }
511 511
  512 + @Override
  513 + public List<IotDeviceDO> getDeviceListByHasLocation() {
  514 + return deviceMapper.selectListByHasLocation();
  515 + }
  516 +
512 private IotDeviceServiceImpl getSelf() { 517 private IotDeviceServiceImpl getSelf() {
513 return SpringUtil.getBean(getClass()); 518 return SpringUtil.getBean(getClass());
514 } 519 }