Commit 643e28938458a740b5975f99992533c0c10d70e0

Authored by 安浩浩
1 parent 6b9cca0b

【优化】IOT 设备管理

Showing 14 changed files with 110 additions and 120 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.java
... ... @@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
9 9 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO;
10 10 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceRespVO;
11 11 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO;
  12 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO;
12 13 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
13 14 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
14 15 import io.swagger.v3.oas.annotations.Operation;
... ... @@ -45,12 +46,9 @@ public class IotDeviceController {
45 46  
46 47 @PutMapping("/update-status")
47 48 @Operation(summary = "更新设备状态")
48   - @Parameter(name = "id", description = "编号", required = true)
49   - @Parameter(name = "status", description = "状态", required = true, example = "1")
50 49 @PreAuthorize("@ss.hasPermission('iot:device:update')")
51   - public CommonResult<Boolean> updateDeviceStatus(@RequestParam("id") Long id,
52   - @RequestParam("status") Integer status) {
53   - deviceService.updateDeviceStatus(id, status);
  50 + public CommonResult<Boolean> updateDeviceStatus(@Valid @RequestBody IotDeviceStatusUpdateReqVO updateReqVO) {
  51 + deviceService.updateDeviceStatus(updateReqVO);
54 52 return success(true);
55 53 }
56 54  
... ... @@ -88,17 +86,4 @@ public class IotDeviceController {
88 86 return success(BeanUtils.toBean(pageResult, IotDeviceRespVO.class));
89 87 }
90 88  
91   - @GetMapping("/export-excel")
92   - @Operation(summary = "导出设备 Excel")
93   - @PreAuthorize("@ss.hasPermission('iot:device:export')")
94   - @ApiAccessLog(operateType = EXPORT)
95   - public void exportDeviceExcel(@Valid IotDevicePageReqVO pageReqVO,
96   - HttpServletResponse response) throws IOException {
97   - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
98   - List<IotDeviceDO> list = deviceService.getDevicePage(pageReqVO).getList();
99   - // 导出 Excel
100   - ExcelUtils.write(response, "IoT 设备.xls", "数据", IotDeviceRespVO.class,
101   - BeanUtils.toBean(list, IotDeviceRespVO.class));
102   - }
103   -
104 89 }
105 90 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDevicePageReqVO.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 4 import cn.iocoder.yudao.framework.common.validation.InEnum;
5 5 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
  6 +import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
6 7 import io.swagger.v3.oas.annotations.media.Schema;
7 8 import lombok.Data;
8 9 import lombok.EqualsAndHashCode;
... ... @@ -28,6 +29,9 @@ public class IotDevicePageReqVO extends PageParam {
28 29 @Schema(description = "设备名称", example = "王五")
29 30 private String deviceName;
30 31  
  32 + @Schema(description = "备注名称", example = "张三")
  33 + private String nickname;
  34 +
31 35 @Schema(description = "产品编号", example = "26202")
32 36 private Long productId;
33 37  
... ... @@ -35,12 +39,9 @@ public class IotDevicePageReqVO extends PageParam {
35 39 private String productKey;
36 40  
37 41 @Schema(description = "设备类型", example = "1")
38   - // TODO @haohao:需要有个设备类型的枚举
  42 + @InEnum(IotProductDeviceTypeEnum.class)
39 43 private Integer deviceType;
40 44  
41   - @Schema(description = "备注名称", example = "张三")
42   - private String nickname;
43   -
44 45 @Schema(description = "网关设备 ID", example = "16380")
45 46 private Long gatewayId;
46 47  
... ... @@ -64,12 +65,6 @@ public class IotDevicePageReqVO extends PageParam {
64 65 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
65 66 private LocalDateTime[] activeTime;
66 67  
67   - @Schema(description = "设备的 IP 地址")
68   - private String ip;
69   -
70   - @Schema(description = "设备的固件版本")
71   - private String firmwareVersion;
72   -
73 68 @Schema(description = "设备密钥,用于设备认证,需安全存储")
74 69 private String deviceSecret;
75 70  
... ... @@ -85,21 +80,6 @@ public class IotDevicePageReqVO extends PageParam {
85 80 @Schema(description = "认证类型(如一机一密、动态注册)", example = "2")
86 81 private String authType;
87 82  
88   - @Schema(description = "设备位置的纬度,范围 -90.000000 ~ 90.000000")
89   - private BigDecimal latitude;
90   -
91   - @Schema(description = "设备位置的经度,范围 -180.000000 ~ 180.000000")
92   - private BigDecimal longitude;
93   -
94   - @Schema(description = "地区编码,符合国家地区编码标准,关联地区表", example = "16995")
95   - private Integer areaId;
96   -
97   - @Schema(description = "设备详细地址")
98   - private String address;
99   -
100   - @Schema(description = "设备序列号")
101   - private String serialNumber;
102   -
103 83 @Schema(description = "创建时间")
104 84 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
105 85 private LocalDateTime[] createTime;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDeviceRespVO.java
... ... @@ -25,7 +25,7 @@ public class IotDeviceRespVO {
25 25 private String deviceName;
26 26  
27 27 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202")
28   - @ExcelProperty("产品 ID")
  28 + @ExcelProperty("产品编号")
29 29 private Long productId;
30 30  
31 31 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
... ... @@ -41,7 +41,6 @@ public class IotDeviceRespVO {
41 41 private String nickname;
42 42  
43 43 @Schema(description = "网关设备 ID", example = "16380")
44   - @ExcelProperty("网关设备 ID")
45 44 private Long gatewayId;
46 45  
47 46 @Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
... ... @@ -64,14 +63,6 @@ public class IotDeviceRespVO {
64 63 @ExcelProperty("设备激活时间")
65 64 private LocalDateTime activeTime;
66 65  
67   - @Schema(description = "设备的 IP 地址")
68   - @ExcelProperty("设备的 IP 地址")
69   - private String ip;
70   -
71   - @Schema(description = "设备的固件版本")
72   - @ExcelProperty("设备的固件版本")
73   - private String firmwareVersion;
74   -
75 66 @Schema(description = "设备密钥,用于设备认证")
76 67 @ExcelProperty("设备密钥")
77 68 private String deviceSecret;
... ... @@ -92,27 +83,6 @@ public class IotDeviceRespVO {
92 83 @ExcelProperty("认证类型(如一机一密、动态注册)")
93 84 private String authType;
94 85  
95   - // TODO @haohao:经纬度:可能 double 就够啦
96   - @Schema(description = "设备位置的纬度,范围")
97   - @ExcelProperty("设备位置的纬度")
98   - private BigDecimal latitude;
99   -
100   - @Schema(description = "设备位置的经度")
101   - @ExcelProperty("设备位置的经度")
102   - private BigDecimal longitude;
103   -
104   - @Schema(description = "地区编码", example = "16995")
105   - @ExcelProperty("地区编码")
106   - private Integer areaId;
107   -
108   - @Schema(description = "设备详细地址")
109   - @ExcelProperty("设备详细地址")
110   - private String address;
111   -
112   - @Schema(description = "设备序列号")
113   - @ExcelProperty("设备序列号")
114   - private String serialNumber;
115   -
116 86 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
117 87 @ExcelProperty("创建时间")
118 88 private LocalDateTime createTime;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDeviceStatusUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import lombok.Data;
  8 +
  9 +@Schema(description = "管理后台 - IoT 设备状态更新 Request VO")
  10 +@Data
  11 +public class IotDeviceStatusUpdateReqVO {
  12 +
  13 + @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  14 + @NotNull(message = "设备编号不能为空")
  15 + private Long id;
  16 +
  17 + @Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  18 + @NotNull(message = "设备状态不能为空")
  19 + @InEnum(IotDeviceStatusEnum.class)
  20 + private Integer status;
  21 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/product/IotProductController.java
... ... @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 6 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductPageReqVO;
7 7 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductRespVO;
8 8 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductSaveReqVO;
  9 +import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductSimpleRespVO;
9 10 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
10 11 import cn.iocoder.yudao.module.iot.service.product.IotProductService;
11 12 import io.swagger.v3.oas.annotations.Operation;
... ... @@ -17,6 +18,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
17 18 import org.springframework.validation.annotation.Validated;
18 19 import org.springframework.web.bind.annotation.*;
19 20  
  21 +import java.util.List;
  22 +
20 23 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
21 24  
22 25 @Tag(name = "管理后台 - IoT 产品")
... ... @@ -80,4 +83,12 @@ public class IotProductController {
80 83 return success(BeanUtils.toBean(pageResult, IotProductRespVO.class));
81 84 }
82 85  
  86 + @GetMapping("/list-all-simple")
  87 + @Operation(summary = "获得所有产品列表")
  88 + @PreAuthorize("@ss.hasPermission('iot:product:query')")
  89 + public CommonResult<List<IotProductSimpleRespVO>> listAllSimpleProducts() {
  90 + List<IotProductDO> list = productService.listAllProducts();
  91 + return success(BeanUtils.toBean(list, IotProductSimpleRespVO.class));
  92 + }
  93 +
83 94 }
84 95 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/product/vo/IotProductSimpleRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.product.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - IoT 产品 Response VO")
  7 +@Data
  8 +public class IotProductSimpleRespVO {
  9 +
  10 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26087")
  11 + private Long id;
  12 +
  13 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
  14 + private String name;
  15 +
  16 +}
0 17 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDO.java
... ... @@ -50,34 +50,34 @@ public class IotDeviceDO extends BaseDO {
50 50  
51 51 /**
52 52 * 产品编号
53   - *
  53 + * <p>
54 54 * 关联 {@link IotProductDO#getId()}
55 55 */
56 56 private Long productId;
57 57 /**
58 58 * 产品标识
59   - *
  59 + * <p>
60 60 * 冗余 {@link IotProductDO#getProductKey()}
61 61 */
62 62 private String productKey;
63 63 /**
64 64 * 设备类型
65   - *
  65 + * <p>
66 66 * 冗余 {@link IotProductDO#getDeviceType()}
67 67 */
68 68 private Integer deviceType;
69 69  
70 70 /**
71 71 * 设备状态
72   - *
  72 + * <p>
73 73 * 枚举 {@link IotDeviceStatusEnum}
74 74 */
75 75 private Integer status;
76 76 /**
77 77 * 网关设备编号
78   - *
  78 + * <p>
79 79 * 子设备需要关联的网关设备 ID
80   - *
  80 + * <p>
81 81 * 关联 {@link IotDeviceDO#getId()}
82 82 */
83 83 private Long gatewayId;
... ... @@ -140,7 +140,7 @@ public class IotDeviceDO extends BaseDO {
140 140 private BigDecimal longitude;
141 141 /**
142 142 * 地区编码
143   - *
  143 + * <p>
144 144 * 关联 Area 的 id
145 145 */
146 146 private Integer areaId;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java
... ... @@ -29,18 +29,11 @@ public interface IotDeviceMapper extends BaseMapperX&lt;IotDeviceDO&gt; {
29 29 .betweenIfPresent(IotDeviceDO::getLastOnlineTime, reqVO.getLastOnlineTime())
30 30 .betweenIfPresent(IotDeviceDO::getLastOfflineTime, reqVO.getLastOfflineTime())
31 31 .betweenIfPresent(IotDeviceDO::getActiveTime, reqVO.getActiveTime())
32   - .eqIfPresent(IotDeviceDO::getIp, reqVO.getIp())
33   - .eqIfPresent(IotDeviceDO::getFirmwareVersion, reqVO.getFirmwareVersion())
34 32 .eqIfPresent(IotDeviceDO::getDeviceSecret, reqVO.getDeviceSecret())
35 33 .eqIfPresent(IotDeviceDO::getMqttClientId, reqVO.getMqttClientId())
36 34 .likeIfPresent(IotDeviceDO::getMqttUsername, reqVO.getMqttUsername())
37 35 .eqIfPresent(IotDeviceDO::getMqttPassword, reqVO.getMqttPassword())
38 36 .eqIfPresent(IotDeviceDO::getAuthType, reqVO.getAuthType())
39   - .eqIfPresent(IotDeviceDO::getLatitude, reqVO.getLatitude())
40   - .eqIfPresent(IotDeviceDO::getLongitude, reqVO.getLongitude())
41   - .eqIfPresent(IotDeviceDO::getAreaId, reqVO.getAreaId())
42   - .eqIfPresent(IotDeviceDO::getAddress, reqVO.getAddress())
43   - .eqIfPresent(IotDeviceDO::getSerialNumber, reqVO.getSerialNumber())
44 37 .betweenIfPresent(IotDeviceDO::getCreateTime, reqVO.getCreateTime())
45 38 .orderByDesc(IotDeviceDO::getId));
46 39 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/product/IotProductMapper.java
... ... @@ -25,4 +25,5 @@ public interface IotProductMapper extends BaseMapperX&lt;IotProductDO&gt; {
25 25 default IotProductDO selectByProductKey(String productKey) {
26 26 return selectOne(new LambdaQueryWrapperX<IotProductDO>().eq(IotProductDO::getProductKey, productKey));
27 27 }
  28 +
28 29 }
29 30 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
... ... @@ -6,11 +6,12 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 7 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO;
8 8 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO;
  9 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO;
9 10 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
10 11 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
11 12 import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper;
12   -import cn.iocoder.yudao.module.iot.dal.mysql.product.IotProductMapper;
13 13 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
  14 +import cn.iocoder.yudao.module.iot.service.product.IotProductService;
14 15 import jakarta.annotation.Resource;
15 16 import lombok.extern.slf4j.Slf4j;
16 17 import org.springframework.stereotype.Service;
... ... @@ -35,9 +36,8 @@ public class DeviceServiceImpl implements IotDeviceService {
35 36  
36 37 @Resource
37 38 private IotDeviceMapper deviceMapper;
38   - // TODO @haohao:不直接调用 productmapper,通过 productservice;每一个模型,不直接使用对方的
39 39 @Resource
40   - private IotProductMapper productMapper;
  40 + private IotProductService productService;
41 41  
42 42 /**
43 43 * 创建 IoT 设备
... ... @@ -49,7 +49,7 @@ public class DeviceServiceImpl implements IotDeviceService {
49 49 @Transactional(rollbackFor = Exception.class)
50 50 public Long createDevice(IotDeviceSaveReqVO createReqVO) {
51 51 // 1.1 校验产品是否存在
52   - IotProductDO product = productMapper.selectById(createReqVO.getProductId());
  52 + IotProductDO product = productService.getProduct(createReqVO.getProductId());
53 53 if (product == null) {
54 54 throw exception(PRODUCT_NOT_EXISTS);
55 55 }
... ... @@ -106,8 +106,7 @@ public class DeviceServiceImpl implements IotDeviceService {
106 106 * @return 生成的 deviceSecret
107 107 */
108 108 private String generateDeviceSecret() {
109   - // TODO @haohao:return IdUtil.fastSimpleUUID()
110   - return UUID.randomUUID().toString().replace("-", "");
  109 + return IdUtil.fastSimpleUUID();
111 110 }
112 111  
113 112 /**
... ... @@ -147,7 +146,6 @@ public class DeviceServiceImpl implements IotDeviceService {
147 146 * @return 生成的唯一 DeviceName
148 147 */
149 148 private String generateUniqueDeviceName(String productKey) {
150   - // TODO @haohao:业务逻辑里,尽量避免 while true。万一 bug = =;虽然这个不会哈。我先改了下
151 149 for (int i = 0; i < Short.MAX_VALUE; i++) {
152 150 String deviceName = IdUtil.fastSimpleUUID().substring(0, 20);
153 151 if (deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName) != null) {
... ... @@ -161,16 +159,11 @@ public class DeviceServiceImpl implements IotDeviceService {
161 159 @Transactional(rollbackFor = Exception.class)
162 160 public void updateDevice(IotDeviceSaveReqVO updateReqVO) {
163 161 // 校验存在
164   - IotDeviceDO existingDevice = validateDeviceExists(updateReqVO.getId());
  162 + validateDeviceExists(updateReqVO.getId());
165 163  
166 164 // 设备名称 和 产品 ID 不能修改
167   - // TODO @haohao:这种,直接设置为 null 就不会更新了。忽略前端的传参
168   - if (updateReqVO.getDeviceName() != null && !updateReqVO.getDeviceName().equals(existingDevice.getDeviceName())) {
169   - throw exception(DEVICE_NAME_CANNOT_BE_MODIFIED);
170   - }
171   - if (updateReqVO.getProductId() != null && !updateReqVO.getProductId().equals(existingDevice.getProductId())) {
172   - throw exception(DEVICE_PRODUCT_CANNOT_BE_MODIFIED);
173   - }
  165 + updateReqVO.setDeviceName(null);
  166 + updateReqVO.setProductId(null);
174 167  
175 168 // 更新 DO 对象
176 169 IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class);
... ... @@ -222,19 +215,12 @@ public class DeviceServiceImpl implements IotDeviceService {
222 215 }
223 216  
224 217 @Override
225   - public void updateDeviceStatus(Long id, Integer status) {
  218 + public void updateDeviceStatus(IotDeviceStatusUpdateReqVO updateReqVO) {
226 219 // 校验存在
227   - validateDeviceExists(id);
228   -
229   - // TODO @haohao:这个可以直接用 swagger 注解哈
230   - // 校验状态是否合法
231   - if (!IotDeviceStatusEnum.isValidStatus(status)) {
232   - throw exception(DEVICE_INVALID_DEVICE_STATUS);
233   - }
  220 + validateDeviceExists(updateReqVO.getId());
234 221  
235 222 // 更新状态和更新时间
236   - IotDeviceDO updateObj = new IotDeviceDO().setId(id).setStatus(status)
237   - .setStatusLastUpdateTime(LocalDateTime.now());
  223 + IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class);
238 224 deviceMapper.updateById(updateObj);
239 225 }
240 226  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
... ... @@ -53,9 +53,8 @@ public interface IotDeviceService {
53 53 /**
54 54 * 更新设备状态
55 55 *
56   - * @param id 编号
57   - * @param status 状态
  56 + * @param updateReqVO 更新信息
58 57 */
59   - void updateDeviceStatus(Long id, Integer status);
  58 + void updateDeviceStatus(IotDeviceStatusUpdateReqVO updateReqVO);
60 59  
61 60 }
62 61 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductService.java
... ... @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductSaveReq
6 6 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
7 7 import jakarta.validation.Valid;
8 8  
  9 +import java.util.List;
  10 +
9 11 /**
10 12 * IoT 产品 Service 接口
11 13 *
... ... @@ -58,4 +60,12 @@ public interface IotProductService {
58 60 * @param status 状态
59 61 */
60 62 void updateProductStatus(Long id, Integer status);
  63 +
  64 + /**
  65 + * 获得所有产品
  66 + *
  67 + * @return 产品列表
  68 + */
  69 + List<IotProductDO> listAllProducts();
  70 +
61 71 }
62 72 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductServiceImpl.java
... ... @@ -12,6 +12,7 @@ import jakarta.annotation.Resource;
12 12 import org.springframework.stereotype.Service;
13 13 import org.springframework.validation.annotation.Validated;
14 14  
  15 +import java.util.List;
15 16 import java.util.Objects;
16 17 import java.util.UUID;
17 18  
... ... @@ -113,4 +114,9 @@ public class IotProductServiceImpl implements IotProductService {
113 114 productMapper.updateById(updateObj);
114 115 }
115 116  
  117 + @Override
  118 + public List<IotProductDO> listAllProducts() {
  119 + return productMapper.selectList();
  120 + }
  121 +
116 122 }
117 123 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thinkmodelfunction/IotThinkModelFunctionServiceImpl.java
... ... @@ -24,6 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
24 24 import org.springframework.validation.annotation.Validated;
25 25  
26 26 import java.util.*;
  27 +import java.util.stream.Collectors;
27 28  
28 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
29 30 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
... ... @@ -176,22 +177,33 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
176 177 List<IotThinkModelFunctionDO> createList = diffResult.get(0); // 需要新增的
177 178 List<IotThinkModelFunctionDO> updateList = diffResult.get(1); // 需要更新的
178 179 List<IotThinkModelFunctionDO> deleteList = diffResult.get(2); // 需要删除的
  180 +
179 181 // 3.2 批量执行数据库操作
  182 + // 新增数据库中的新事件和服务列表
180 183 if (CollUtil.isNotEmpty(createList)) {
181 184 thinkModelFunctionMapper.insertBatch(createList);
182 185 }
  186 + // 更新数据库中的事件和服务列表
183 187 if (CollUtil.isNotEmpty(updateList)) {
184   - for (IotThinkModelFunctionDO updateFunc : updateList) {
185   - // 设置 ID,以便更新
  188 + // 首先,为每个需要更新的对象设置其对应的 ID
  189 + updateList.forEach(updateFunc -> {
186 190 IotThinkModelFunctionDO oldFunc = findFunctionByIdentifierAndType(
187 191 oldFunctionList, updateFunc.getIdentifier(), updateFunc.getType());
188 192 if (oldFunc != null) {
189 193 updateFunc.setId(oldFunc.getId());
190   - thinkModelFunctionMapper.updateById(updateFunc);
191 194 }
  195 + });
  196 + // 过滤掉没有设置 ID 的对象
  197 + List<IotThinkModelFunctionDO> validUpdateList = updateList.stream()
  198 + .filter(func -> func.getId() != null)
  199 + .collect(Collectors.toList());
  200 + // 执行批量更新
  201 + if (CollUtil.isNotEmpty(validUpdateList)) {
  202 + thinkModelFunctionMapper.updateBatch(validUpdateList);
192 203 }
193   - // TODO @haohao:seckillProductMapper.updateBatch(diffList.get(1)); 可以直接类似这么操作哇?
194 204 }
  205 +
  206 + // 删除数据库中的旧事件和服务列表
195 207 if (CollUtil.isNotEmpty(deleteList)) {
196 208 Set<Long> idsToDelete = CollectionUtils.convertSet(deleteList, IotThinkModelFunctionDO::getId);
197 209 thinkModelFunctionMapper.deleteByIds(idsToDelete);
... ...