Commit 2932314ee0b838a822e63e3c225efc0fa41ca6a1

Authored by 安浩浩
1 parent 84bc5aec

修改:IOT 物模型接口优化

Showing 12 changed files with 400 additions and 569 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
... ... @@ -17,4 +17,5 @@ public interface ErrorCodeConstants {
17 17 // ========== IoT 产品物模型 1-050-002-000 ============
18 18 ErrorCode THINK_MODEL_FUNCTION_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在");
19 19 ErrorCode THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY = new ErrorCode(1_050_002_001, "ProductKey 对应的产品物模型已存在");
  20 + ErrorCode THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER = new ErrorCode(1_050_002_002, "产品物模型标识已存在");
20 21 }
... ...
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotThingModelTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.enums.product;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * IOT 物模型功能类型枚举类
  11 + *
  12 + * @author ahh
  13 + */
  14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum IotThingModelTypeEnum implements IntArrayValuable {
  17 +
  18 + /**
  19 + * 属性
  20 + */
  21 + PROPERTY(1, "属性"),
  22 + /**
  23 + * 服务
  24 + */
  25 + SERVICE(2, "服务"),
  26 + /**
  27 + * 事件
  28 + */
  29 + EVENT(3, "事件");
  30 +
  31 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(IotThingModelTypeEnum::getType).toArray();
  32 +
  33 + /**
  34 + * 类型
  35 + */
  36 + private final Integer type;
  37 + /**
  38 + * 描述
  39 + */
  40 + private final String description;
  41 +
  42 + @Override
  43 + public int[] array() {
  44 + return ARRAYS;
  45 + }
  46 +
  47 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/IotThinkModelFunctionController.http
... ... @@ -5,137 +5,28 @@ tenant-id: {{adminTenentId}}
5 5 Authorization: Bearer {{token}}
6 6  
7 7 {
8   - "productId": 1002,
9   - "productKey": "smart-sensor-002",
10   - "properties": [
11   - {
12   - "identifier": "Temperature",
13   - "name": "温度",
14   - "accessMode": "r",
15   - "required": true,
16   - "dataType": {
17   - "type": "float",
18   - "specs": {
19   - "min": -40.0,
20   - "max": 125.0,
21   - "step": 0.1,
22   - "unit": "℃"
23   - }
24   - },
25   - "description": "当前温度值"
  8 + "productId": 1001,
  9 + "productKey": "smart-sensor-001",
  10 + "identifier": "Temperature",
  11 + "name": "温度",
  12 + "description": "当前温度值",
  13 + "type": 1,
  14 + "property": {
  15 + "identifier": "Temperature",
  16 + "name": "温度",
  17 + "accessMode": "r",
  18 + "required": true,
  19 + "dataType": {
  20 + "type": "float",
  21 + "specs": {
  22 + "min": -40.0,
  23 + "max": 125.0,
  24 + "step": 0.1,
  25 + "unit": "℃"
  26 + }
26 27 },
27   - {
28   - "identifier": "Humidity",
29   - "name": "湿度",
30   - "accessMode": "r",
31   - "required": true,
32   - "dataType": {
33   - "type": "float",
34   - "specs": {
35   - "min": 0.0,
36   - "max": 100.0,
37   - "step": 0.1,
38   - "unit": "%"
39   - }
40   - },
41   - "description": "当前湿度值"
42   - },
43   - {
44   - "identifier": "GeoLocation",
45   - "name": "地理位置",
46   - "accessMode": "r",
47   - "required": false,
48   - "dataType": {
49   - "type": "struct",
50   - "specs": [
51   - {
52   - "identifier": "Longitude",
53   - "name": "经度",
54   - "dataType": {
55   - "type": "double",
56   - "specs": {
57   - "min": -180.0,
58   - "max": 180.0,
59   - "step": 0.000001,
60   - "unit": "°"
61   - }
62   - },
63   - "description": "设备所在位置的经度"
64   - },
65   - {
66   - "identifier": "Latitude",
67   - "name": "纬度",
68   - "dataType": {
69   - "type": "double",
70   - "specs": {
71   - "min": -90.0,
72   - "max": 90.0,
73   - "step": 0.000001,
74   - "unit": "°"
75   - }
76   - },
77   - "description": "设备所在位置的纬度"
78   - }
79   - ]
80   - },
81   - "description": "设备的地理位置信息"
82   - }
83   - ],
84   - "services": [
85   - {
86   - "identifier": "Reboot",
87   - "name": "重启设备",
88   - "callType": "async",
89   - "inputData": [],
90   - "description": "远程重启设备",
91   - "method": "thing.service.reboot"
92   - },
93   - {
94   - "identifier": "SetThreshold",
95   - "name": "设置温度阈值",
96   - "callType": "sync",
97   - "inputData": [
98   - {
99   - "identifier": "Threshold",
100   - "name": "阈值",
101   - "dataType": {
102   - "type": "float",
103   - "specs": {
104   - "min": -40.0,
105   - "max": 125.0,
106   - "step": 0.1,
107   - "unit": "℃"
108   - }
109   - },
110   - "description": "报警温度阈值"
111   - }
112   - ],
113   - "description": "设置设备的温度报警阈值",
114   - "method": "thing.service.setThreshold"
115   - }
116   - ],
117   - "events": [
118   - {
119   - "identifier": "HighTemperatureAlert",
120   - "name": "高温报警",
121   - "type": "alert",
122   - "outputData": [
123   - {
124   - "identifier": "CurrentTemperature",
125   - "name": "当前温度",
126   - "dataType": {
127   - "type": "float",
128   - "specs": {
129   - "unit": "℃"
130   - }
131   - },
132   - "description": "触发报警时的温度值"
133   - }
134   - ],
135   - "description": "当温度超过阈值时触发高温报警事件",
136   - "method": "thing.event.highTemperatureAlert"
137   - }
138   - ]
  28 + "description": "当前温度值"
  29 + }
139 30 }
140 31  
141 32  
... ... @@ -147,141 +38,37 @@ Authorization: Bearer {{token}}
147 38  
148 39 {
149 40 "id": 3,
150   - "productId": 1002,
151   - "productKey": "smart-sensor-002",
152   - "properties": [
153   - {
154   - "identifier": "Temperature",
155   - "name": "温度",
156   - "accessMode": "r",
157   - "required": true,
158   - "dataType": {
159   - "type": "float",
160   - "specs": {
161   - "min": -100.0,
162   - "max": 200.0,
163   - "step": 0.1,
164   - "unit": "℃"
165   - }
166   - },
167   - "description": "当前温度值"
168   - },
169   - {
170   - "identifier": "Humidity",
171   - "name": "湿度",
172   - "accessMode": "r",
173   - "required": true,
174   - "dataType": {
175   - "type": "float",
176   - "specs": {
177   - "min": 0.0,
178   - "max": 100.0,
179   - "step": 0.1,
180   - "unit": "%"
181   - }
182   - },
183   - "description": "当前湿度值"
184   - },
185   - {
186   - "identifier": "GeoLocation",
187   - "name": "地理位置",
188   - "accessMode": "r",
189   - "required": false,
190   - "dataType": {
191   - "type": "struct",
192   - "specs": [
193   - {
194   - "identifier": "Longitude",
195   - "name": "经度",
196   - "dataType": {
197   - "type": "double",
198   - "specs": {
199   - "min": -180.0,
200   - "max": 180.0,
201   - "step": 0.000001,
202   - "unit": "°"
203   - }
204   - },
205   - "description": "设备所在位置的经度"
206   - },
207   - {
208   - "identifier": "Latitude",
209   - "name": "纬度",
210   - "dataType": {
211   - "type": "double",
212   - "specs": {
213   - "min": -90.0,
214   - "max": 90.0,
215   - "step": 0.000001,
216   - "unit": "°"
217   - }
218   - },
219   - "description": "设备所在位置的纬度"
220   - }
221   - ]
222   - },
223   - "description": "设备的地理位置信息"
224   - }
225   - ],
226   - "services": [
227   - {
228   - "identifier": "Reboot",
229   - "name": "重启设备",
230   - "callType": "async",
231   - "inputData": [],
232   - "description": "远程重启设备",
233   - "method": "thing.service.reboot"
  41 + "productId": 1001,
  42 + "productKey": "smart-sensor-001",
  43 + "identifier": "Temperature",
  44 + "name": "温度",
  45 + "description": "当前温度值",
  46 + "type": 1,
  47 + "property": {
  48 + "identifier": "Temperature",
  49 + "name": "温度",
  50 + "accessMode": "r",
  51 + "required": true,
  52 + "dataType": {
  53 + "type": "float",
  54 + "specs": {
  55 + "min": -10.0,
  56 + "max": 100.0,
  57 + "step": 0.1,
  58 + "unit": "℃"
  59 + }
234 60 },
235   - {
236   - "identifier": "SetThreshold",
237   - "name": "设置温度阈值",
238   - "callType": "sync",
239   - "inputData": [
240   - {
241   - "identifier": "Threshold",
242   - "name": "阈值",
243   - "dataType": {
244   - "type": "float",
245   - "specs": {
246   - "min": -40.0,
247   - "max": 125.0,
248   - "step": 0.1,
249   - "unit": "℃"
250   - }
251   - },
252   - "description": "报警温度阈值"
253   - }
254   - ],
255   - "description": "设置设备的温度报警阈值",
256   - "method": "thing.service.setThreshold"
257   - }
258   - ],
259   - "events": [
260   - {
261   - "identifier": "HighTemperatureAlert",
262   - "name": "高温报警",
263   - "type": "alert",
264   - "outputData": [
265   - {
266   - "identifier": "CurrentTemperature",
267   - "name": "当前温度",
268   - "dataType": {
269   - "type": "float",
270   - "specs": {
271   - "unit": "℃"
272   - }
273   - },
274   - "description": "触发报警时的温度值"
275   - }
276   - ],
277   - "description": "当温度超过阈值时触发高温报警事件",
278   - "method": "thing.event.highTemperatureAlert"
279   - }
280   - ]
  61 + "description": "当前温度值"
  62 + }
281 63 }
282 64  
  65 +### 请求 /iot/think-model-function/get 接口 => 成功
  66 +GET {{baseUrl}}/iot/think-model-function/get?id=3
  67 +tenant-id: {{adminTenentId}}
  68 +Authorization: Bearer {{token}}
  69 +
283 70  
284   -### 请求 /iot/think-model-function/get-by-product-key 接口 => 成功
285   -GET {{baseUrl}}/iot/think-model-function/get-by-product-key?productKey=smart-sensor-002
  71 +### 请求 /iot/think-model-function/list-by-product-id 接口 => 成功
  72 +GET {{baseUrl}}/iot/think-model-function/list-by-product-id?productId=1001
286 73 tenant-id: {{adminTenentId}}
287 74 Authorization: Bearer {{token}}
288 75 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/IotThinkModelFunctionController.java
... ... @@ -15,6 +15,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
15 15 import org.springframework.validation.annotation.Validated;
16 16 import org.springframework.web.bind.annotation.*;
17 17  
  18 +import java.util.List;
  19 +
18 20 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
19 21  
20 22 @Tag(name = "管理后台 - IoT 产品物模型")
... ... @@ -50,23 +52,23 @@ public class IotThinkModelFunctionController {
50 52 return success(true);
51 53 }
52 54  
53   - @GetMapping("/get-by-product-key")
  55 + @GetMapping("/get")
54 56 @Operation(summary = "获得IoT 产品物模型")
55   - @Parameter(name = "productKey", description = "产品Key", required = true, example = "1024")
  57 + @Parameter(name = "id", description = "编号", required = true)
56 58 @PreAuthorize("@ss.hasPermission('iot:think-model-function:query')")
57   - public CommonResult<IotThinkModelFunctionRespVO> getThinkModelFunctionByProductKey(@RequestParam("productKey") String productKey) {
58   - IotThinkModelFunctionDO thinkModelFunction = thinkModelFunctionService.getThinkModelFunctionByProductKey(productKey);
  59 + public CommonResult<IotThinkModelFunctionRespVO> getThinkModelFunction(@RequestParam("id") Long id) {
  60 + IotThinkModelFunctionDO thinkModelFunction = thinkModelFunctionService.getThinkModelFunction(id);
59 61 IotThinkModelFunctionRespVO respVO = IotThinkModelFunctionConvert.INSTANCE.convert(thinkModelFunction);
60 62 return success(respVO);
61 63 }
62 64  
63   - @GetMapping("/get-by-product-id")
  65 + @GetMapping("/list-by-product-id")
64 66 @Operation(summary = "获得IoT 产品物模型")
65 67 @Parameter(name = "productId", description = "产品ID", required = true, example = "1024")
66 68 @PreAuthorize("@ss.hasPermission('iot:think-model-function:query')")
67   - public CommonResult<IotThinkModelFunctionRespVO> getThinkModelFunctionByProductId(@RequestParam("productId") Long productId) {
68   - IotThinkModelFunctionDO thinkModelFunction = thinkModelFunctionService.getThinkModelFunctionByProductId(productId);
69   - IotThinkModelFunctionRespVO respVO = IotThinkModelFunctionConvert.INSTANCE.convert(thinkModelFunction);
  69 + public CommonResult<List<IotThinkModelFunctionRespVO>> getThinkModelFunctionListByProductId(@RequestParam("productId") Long productId) {
  70 + List<IotThinkModelFunctionDO> thinkModelFunctionListByProductId = thinkModelFunctionService.getThinkModelFunctionListByProductId(productId);
  71 + List<IotThinkModelFunctionRespVO> respVO = IotThinkModelFunctionConvert.INSTANCE.convertList(thinkModelFunctionListByProductId);
70 72 return success(respVO);
71 73 }
72 74 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/vo/IotThinkModelFunctionRespVO.java
... ... @@ -21,20 +21,32 @@ public class IotThinkModelFunctionRespVO {
21 21 private Long id;
22 22  
23 23 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
  24 + private Long productId;
  25 +
  26 + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
24 27 @ExcelProperty("产品标识")
25 28 private String productKey;
26 29  
27   - @Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED)
28   - @ExcelProperty("属性列表")
29   - private List<ThingModelProperty> properties;
  30 + @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + private String identifier;
  32 +
  33 + @Schema(description = "功能名称", requiredMode = Schema.RequiredMode.REQUIRED)
  34 + private String name;
  35 +
  36 + @Schema(description = "功能描述", requiredMode = Schema.RequiredMode.REQUIRED)
  37 + private String description;
  38 +
  39 + @Schema(description = "功能类型", requiredMode = Schema.RequiredMode.REQUIRED)
  40 + private Integer type;
  41 +
  42 + @Schema(description = "属性", requiredMode = Schema.RequiredMode.REQUIRED)
  43 + private ThingModelProperty property;
30 44  
31   - @Schema(description = "服务列表")
32   - @ExcelProperty("服务列表")
33   - private List<ThingModelService> services;
  45 + @Schema(description = "服务", requiredMode = Schema.RequiredMode.REQUIRED)
  46 + private ThingModelEvent event;
34 47  
35   - @Schema(description = "事件列表")
36   - @ExcelProperty("事件列表")
37   - private List<ThingModelEvent> events;
  48 + @Schema(description = "事件", requiredMode = Schema.RequiredMode.REQUIRED)
  49 + private ThingModelService service;
38 50  
39 51 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
40 52 @ExcelProperty("创建时间")
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/vo/IotThinkModelFunctionSaveReqVO.java
1 1 package cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo;
2 2  
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 4 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent;
4 5 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
5 6 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService;
  7 +import cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum;
6 8 import io.swagger.v3.oas.annotations.media.Schema;
7 9 import jakarta.validation.constraints.NotEmpty;
8 10 import jakarta.validation.constraints.NotNull;
9 11 import lombok.Data;
10 12  
11   -import java.util.List;
12   -
13 13 @Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO")
14 14 @Data
15 15 public class IotThinkModelFunctionSaveReqVO {
... ... @@ -25,14 +25,29 @@ public class IotThinkModelFunctionSaveReqVO {
25 25 @NotEmpty(message = "产品标识不能为空")
26 26 private String productKey;
27 27  
28   - @Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED)
29   - @NotEmpty(message = "属性列表不能为空")
30   - private List<ThingModelProperty> properties;
  28 + @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED)
  29 + @NotEmpty(message = "功能标识不能为空")
  30 + private String identifier;
  31 +
  32 + @Schema(description = "功能名称", requiredMode = Schema.RequiredMode.REQUIRED)
  33 + @NotEmpty(message = "功能名称不能为空")
  34 + private String name;
  35 +
  36 + @Schema(description = "功能描述", requiredMode = Schema.RequiredMode.REQUIRED)
  37 + private String description;
  38 +
  39 + @Schema(description = "功能类型", requiredMode = Schema.RequiredMode.REQUIRED)
  40 + @NotNull(message = "功能类型不能为空")
  41 + @InEnum(IotThingModelTypeEnum.class)
  42 + private Integer type;
  43 +
  44 + @Schema(description = "属性", requiredMode = Schema.RequiredMode.REQUIRED)
  45 + private ThingModelProperty property;
31 46  
32   - @Schema(description = "服务列表")
33   - private List<ThingModelService> services;
  47 + @Schema(description = "服务", requiredMode = Schema.RequiredMode.REQUIRED)
  48 + private ThingModelService service;
34 49  
35   - @Schema(description = "事件列表")
36   - private List<ThingModelEvent> events;
  50 + @Schema(description = "事件", requiredMode = Schema.RequiredMode.REQUIRED)
  51 + private ThingModelEvent event;
37 52  
38 53 }
39 54 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/convert/thinkmodelfunction/IotThinkModelFunctionConvert.java
... ... @@ -6,82 +6,52 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingMode
6 6 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionRespVO;
7 7 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionSaveReqVO;
8 8 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
9   -import com.fasterxml.jackson.core.JsonProcessingException;
10   -import com.fasterxml.jackson.databind.ObjectMapper;
  9 +import cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum;
11 10 import org.mapstruct.Mapper;
12 11 import org.mapstruct.Mapping;
13 12 import org.mapstruct.factory.Mappers;
14 13  
15   -import java.util.ArrayList;
16 14 import java.util.List;
  15 +import java.util.Objects;
17 16  
18 17 @Mapper
19 18 public interface IotThinkModelFunctionConvert {
20 19  
21 20 IotThinkModelFunctionConvert INSTANCE = Mappers.getMapper(IotThinkModelFunctionConvert.class);
22 21  
23   - ObjectMapper objectMapper = new ObjectMapper();
24   -
25   - // 将 SaveReqVO 转换为 DO 对象,处理 properties, services, events 字段
26   - @Mapping(target = "properties", expression = "java(convertPropertiesToJson(bean.getProperties()))")
27   - @Mapping(target = "services", expression = "java(convertServicesToJson(bean.getServices()))")
28   - @Mapping(target = "events", expression = "java(convertEventsToJson(bean.getEvents()))")
  22 + // 将 SaveReqVO 转换为 DO
  23 + @Mapping(target = "property", expression = "java(convertToProperty(bean))")
  24 + @Mapping(target = "event", expression = "java(convertToEvent(bean))")
  25 + @Mapping(target = "service", expression = "java(convertToService(bean))")
29 26 IotThinkModelFunctionDO convert(IotThinkModelFunctionSaveReqVO bean);
30 27  
31   - default String convertPropertiesToJson(List<ThingModelProperty> properties) {
32   - try {
33   - return properties != null ? objectMapper.writeValueAsString(properties) : "[]";
34   - } catch (JsonProcessingException e) {
35   - throw new RuntimeException("序列化 properties 时发生错误", e);
  28 + default ThingModelProperty convertToProperty(IotThinkModelFunctionSaveReqVO bean) {
  29 + if (Objects.equals(bean.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
  30 + return bean.getProperty();
36 31 }
  32 + return null;
37 33 }
38 34  
39   - default String convertServicesToJson(List<ThingModelService> services) {
40   - try {
41   - return services != null ? objectMapper.writeValueAsString(services) : "[]";
42   - } catch (JsonProcessingException e) {
43   - throw new RuntimeException("序列化 services 时发生错误", e);
  35 + default ThingModelEvent convertToEvent(IotThinkModelFunctionSaveReqVO bean) {
  36 + if (Objects.equals(bean.getType(), IotThingModelTypeEnum.EVENT.getType())) {
  37 + return bean.getEvent();
44 38 }
  39 + return null;
45 40 }
46 41  
47   - default String convertEventsToJson(List<ThingModelEvent> events) {
48   - try {
49   - return events != null ? objectMapper.writeValueAsString(events) : "[]";
50   - } catch (JsonProcessingException e) {
51   - throw new RuntimeException("序列化 events 时发生错误", e);
  42 + default ThingModelService convertToService(IotThinkModelFunctionSaveReqVO bean) {
  43 + if (Objects.equals(bean.getType(), IotThingModelTypeEnum.SERVICE.getType())) {
  44 + return bean.getService();
52 45 }
  46 + return null;
53 47 }
54 48  
55   - // 将 DO 转换为 RespVO 对象,处理 properties, services, events 字段
56   - @Mapping(target = "properties", expression = "java(convertJsonToProperties(bean.getProperties()))")
57   - @Mapping(target = "services", expression = "java(convertJsonToServices(bean.getServices()))")
58   - @Mapping(target = "events", expression = "java(convertJsonToEvents(bean.getEvents()))")
  49 + // 将 DO 转换为 RespVO
  50 + @Mapping(target = "property", source = "property")
  51 + @Mapping(target = "event", source = "event")
  52 + @Mapping(target = "service", source = "service")
59 53 IotThinkModelFunctionRespVO convert(IotThinkModelFunctionDO bean);
60 54  
61   - default List<ThingModelProperty> convertJsonToProperties(String propertiesJson) {
62   - try {
63   - return propertiesJson != null ? objectMapper.readValue(propertiesJson, objectMapper.getTypeFactory().constructCollectionType(List.class, ThingModelProperty.class)) : new ArrayList<>();
64   - } catch (JsonProcessingException e) {
65   - throw new RuntimeException("反序列化 properties 时发生错误", e);
66   - }
67   - }
68   -
69   - default List<ThingModelService> convertJsonToServices(String servicesJson) {
70   - try {
71   - return servicesJson != null ? objectMapper.readValue(servicesJson, objectMapper.getTypeFactory().constructCollectionType(List.class, ThingModelService.class)) : new ArrayList<>();
72   - } catch (JsonProcessingException e) {
73   - throw new RuntimeException("反序列化 services 时发生错误", e);
74   - }
75   - }
76   -
77   - default List<ThingModelEvent> convertJsonToEvents(String eventsJson) {
78   - try {
79   - return eventsJson != null ? objectMapper.readValue(eventsJson, objectMapper.getTypeFactory().constructCollectionType(List.class, ThingModelEvent.class)) : new ArrayList<>();
80   - } catch (JsonProcessingException e) {
81   - throw new RuntimeException("反序列化 events 时发生错误", e);
82   - }
83   - }
84   -
85   - // 批量转换 DO 列表到 RespVO 列表
  55 + // 批量转换
86 56 List<IotThinkModelFunctionRespVO> convertList(List<IotThinkModelFunctionDO> list);
87   -}
88 57 \ No newline at end of file
  58 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thinkmodelfunction/IotThinkModelFunctionDO.java
1 1 package cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService;
4 7 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
5 8 import com.baomidou.mybatisplus.annotation.KeySequence;
  9 +import com.baomidou.mybatisplus.annotation.TableField;
6 10 import com.baomidou.mybatisplus.annotation.TableId;
7 11 import com.baomidou.mybatisplus.annotation.TableName;
8   -import lombok.*;
  12 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  13 +import lombok.AllArgsConstructor;
  14 +import lombok.Builder;
  15 +import lombok.Data;
  16 +import lombok.NoArgsConstructor;
9 17  
10 18 /**
11 19 * IoT 产品物模型功能 DO
12   - *
  20 + * <p>
13 21 * 每个 {@link IotProductDO} 和 {@link IotThinkModelFunctionDO} 是“一对多”的关系,它的每个属性、事件、服务都对应一条记录
14 22 *
15 23 * @author 芋道源码
16 24 */
17   -@TableName("iot_think_model_function")
  25 +@TableName(value = "iot_think_model_function", autoResultMap = true)
18 26 @KeySequence("iot_think_model_function_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
19 27 @Data
20 28 @Builder
... ... @@ -27,35 +35,56 @@ public class IotThinkModelFunctionDO extends BaseDO {
27 35 */
28 36 @TableId
29 37 private Long id;
30   - // TODO @haohao:是不是有一个 identifier,需要要有哈
31   - // TODO @haohao:name、description 属性,还有个类型
  38 +
  39 + /**
  40 + * 功能标识
  41 + */
  42 + private String identifier;
  43 + /**
  44 + * 功能名称
  45 + */
  46 + private String name;
  47 + /**
  48 + * 功能描述
  49 + */
  50 + private String description;
  51 +
32 52 /**
33 53 * 产品标识
34   - *
  54 + * <p>
35 55 * 关联 {@link IotProductDO#getId()}
36 56 */
37 57 private Long productId;
38 58 /**
39 59 * 产品标识
40   - *
  60 + * <p>
41 61 * 关联 {@link IotProductDO#getProductKey()}
42 62 */
43 63 private String productKey;
44 64  
45   - // TODO @haohao:是不是可以搞成 ThingModelProperty、ThingModelEvent、ThingModelService 进行存储
46 65 /**
47   - * 属性列表
  66 + * 功能类型
  67 + * <p>
  68 + * 枚举 {@link cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum}
  69 + */
  70 + private Integer type;
  71 +
  72 + /**
  73 + * 属性
48 74 */
49   - private String properties;
  75 + @TableField(typeHandler = JacksonTypeHandler.class)
  76 + private ThingModelProperty property;
50 77  
51 78 /**
52   - * 服务列表
  79 + * 事件
53 80 */
54   - private String services;
  81 + @TableField(typeHandler = JacksonTypeHandler.class)
  82 + private ThingModelEvent event;
55 83  
56 84 /**
57   - * 事件列表
  85 + * 服务
58 86 */
59   - private String events;
  87 + @TableField(typeHandler = JacksonTypeHandler.class)
  88 + private ThingModelService service;
60 89  
61 90 }
62 91 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thinkmodelfunction/IotThinkModelFunctionDO2.java deleted
1   -package cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction;
2   -
3   -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4   -import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent;
5   -import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
6   -import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
7   -import com.baomidou.mybatisplus.annotation.KeySequence;
8   -import com.baomidou.mybatisplus.annotation.TableId;
9   -import com.baomidou.mybatisplus.annotation.TableName;
10   -import lombok.AllArgsConstructor;
11   -import lombok.Builder;
12   -import lombok.Data;
13   -import lombok.NoArgsConstructor;
14   -
15   -/**
16   - * IoT 产品物模型功能 DO
17   - *
18   - * 每个 {@link IotProductDO} 和 {@link IotThinkModelFunctionDO2} 是“一对多”的关系,它的每个属性、事件、服务都对应一条记录
19   - *
20   - * @author 芋道源码
21   - */
22   -@TableName("iot_think_model_function")
23   -@KeySequence("iot_think_model_function_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
24   -@Data
25   -@Builder
26   -@NoArgsConstructor
27   -@AllArgsConstructor
28   -public class IotThinkModelFunctionDO2 extends BaseDO {
29   -
30   - /**
31   - * 物模型功能编号
32   - */
33   - @TableId
34   - private Long id;
35   -
36   - /**
37   - * 功能标识
38   - */
39   - private String identifier;
40   - /**
41   - * 功能名称
42   - */
43   - private String name;
44   - /**
45   - * 功能描述
46   - */
47   - private String description;
48   -
49   - /**
50   - * 产品标识
51   - *
52   - * 关联 {@link IotProductDO#getId()}
53   - */
54   - private Long productId;
55   - /**
56   - * 产品标识
57   - *
58   - * 关联 {@link IotProductDO#getProductKey()}
59   - */
60   - private String productKey;
61   -
62   - /**
63   - * 功能类型
64   - *
65   - * 1 - 属性
66   - * 2 - 服务
67   - * 3 - 事件
68   - */
69   - // TODO @haohao:枚举
70   - private Integer type;
71   -
72   - /**
73   - * 属性
74   - */
75   - private ThingModelProperty property;
76   - /**
77   - * 事件
78   - */
79   - private ThingModelEvent event;
80   - /**
81   - * 服务
82   - */
83   - private String service;
84   -
85   -}
86 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thinkmodelfunction/IotThinkModelFunctionMapper.java
... ... @@ -5,6 +5,8 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
5 5 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
6 6 import org.apache.ibatis.annotations.Mapper;
7 7  
  8 +import java.util.List;
  9 +
8 10 /**
9 11 * IoT 产品物模型 Mapper
10 12 *
... ... @@ -13,12 +15,17 @@ import org.apache.ibatis.annotations.Mapper;
13 15 @Mapper
14 16 public interface IotThinkModelFunctionMapper extends BaseMapperX<IotThinkModelFunctionDO> {
15 17  
16   - default IotThinkModelFunctionDO selectByProductKey(String productKey) {
17   - return selectOne(new LambdaQueryWrapperX<IotThinkModelFunctionDO>().eq(IotThinkModelFunctionDO::getProductKey, productKey));
  18 + default IotThinkModelFunctionDO selectByProductIdAndIdentifier(Long productId, String identifier) {
  19 + return selectOne(new LambdaQueryWrapperX<IotThinkModelFunctionDO>().eq(IotThinkModelFunctionDO::getProductId, productId)
  20 + .eq(IotThinkModelFunctionDO::getIdentifier, identifier));
18 21 }
19 22  
20   - default IotThinkModelFunctionDO selectByProductId(Long productId){
21   - return selectOne(new LambdaQueryWrapperX<IotThinkModelFunctionDO>().eq(IotThinkModelFunctionDO::getProductId, productId));
  23 + default List<IotThinkModelFunctionDO> selectListByProductId(Long productId) {
  24 + return selectList(new LambdaQueryWrapperX<IotThinkModelFunctionDO>().eq(IotThinkModelFunctionDO::getProductId, productId));
22 25 }
23 26  
  27 + default List<IotThinkModelFunctionDO> selectListByProductIdAndType(Long productId, Integer type) {
  28 + return selectList(new LambdaQueryWrapperX<IotThinkModelFunctionDO>().eq(IotThinkModelFunctionDO::getProductId, productId)
  29 + .eq(IotThinkModelFunctionDO::getType, type));
  30 + }
24 31 }
25 32 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thinkmodelfunction/IotThinkModelFunctionService.java
... ... @@ -4,6 +4,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThi
4 4 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
5 5 import jakarta.validation.Valid;
6 6  
  7 +import java.util.List;
  8 +
7 9 /**
8 10 * IoT 产品物模型 Service 接口
9 11 *
... ... @@ -19,33 +21,34 @@ public interface IotThinkModelFunctionService {
19 21 */
20 22 Long createThinkModelFunction(@Valid IotThinkModelFunctionSaveReqVO createReqVO);
21 23  
  24 +
22 25 /**
23   - * 删除IoT 产品物模型
  26 + * 更新IoT 产品物模型
24 27 *
25   - * @param id 编号
  28 + * @param updateReqVO 更新信息
26 29 */
27   - void deleteThinkModelFunction(Long id);
  30 + void updateThinkModelFunction(@Valid IotThinkModelFunctionSaveReqVO updateReqVO);
28 31  
29 32 /**
30   - * 获得IoT 产品物模型,通过产品Key
  33 + * 删除IoT 产品物模型
31 34 *
32   - * @param productKey 产品Key
33   - * @return IoT 产品物模型
  35 + * @param id 编号
34 36 */
35   - IotThinkModelFunctionDO getThinkModelFunctionByProductKey(String productKey);
  37 + void deleteThinkModelFunction(Long id);
36 38  
37 39 /**
38   - * 获得IoT 产品物模型,通过产品ID
  40 + * 获得IoT 产品物模型
39 41 *
40   - * @param productId 产品ID
  42 + * @param id 编号
41 43 * @return IoT 产品物模型
42 44 */
43   - IotThinkModelFunctionDO getThinkModelFunctionByProductId(Long productId);
  45 + IotThinkModelFunctionDO getThinkModelFunction(Long id);
44 46  
45 47 /**
46   - * 更新IoT 产品物模型
  48 + * 获得IoT 产品物模型列表
47 49 *
48   - * @param updateReqVO 更新信息
  50 + * @param productId 产品编号
  51 + * @return IoT 产品物模型列表
49 52 */
50   - void updateThinkModelFunction(@Valid IotThinkModelFunctionSaveReqVO updateReqVO);
  53 + List<IotThinkModelFunctionDO> getThinkModelFunctionListByProductId(Long productId);
51 54 }
52 55 \ 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
1 1 package cn.iocoder.yudao.module.iot.service.thinkmodelfunction;
2 2  
3   -import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.*;
  3 +import cn.iocoder.yudao.framework.common.validation.Telephone;
  4 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService;
4 7 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.dataType.ThingModelArgument;
5 8 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.dataType.ThingModelArraySpecs;
6 9 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.dataType.ThingModelArrayType;
... ... @@ -9,19 +12,20 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThi
9 12 import cn.iocoder.yudao.module.iot.convert.thinkmodelfunction.IotThinkModelFunctionConvert;
10 13 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
11 14 import cn.iocoder.yudao.module.iot.dal.mysql.thinkmodelfunction.IotThinkModelFunctionMapper;
12   -import com.fasterxml.jackson.core.JsonProcessingException;
13   -import com.fasterxml.jackson.databind.ObjectMapper;
  15 +import cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum;
14 16 import jakarta.annotation.Resource;
15 17 import lombok.extern.slf4j.Slf4j;
16 18 import org.springframework.stereotype.Service;
  19 +import org.springframework.transaction.annotation.Transactional;
17 20 import org.springframework.validation.annotation.Validated;
18 21  
19 22 import java.util.ArrayList;
20 23 import java.util.Collections;
21 24 import java.util.List;
  25 +import java.util.Objects;
22 26  
23 27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
24   -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY;
  28 +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER;
25 29 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_NOT_EXISTS;
26 30  
27 31 @Slf4j
... ... @@ -32,153 +36,133 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
32 36 @Resource
33 37 private IotThinkModelFunctionMapper thinkModelFunctionMapper;
34 38  
35   - private ObjectMapper objectMapper = new ObjectMapper();
36   -
37 39 @Override
38 40 public Long createThinkModelFunction(IotThinkModelFunctionSaveReqVO createReqVO) {
39   - log.info("创建物模型,参数:{}", createReqVO);
40   - // 验证 ProductKey 对应的产品物模型是否已存在
41   - validateThinkModelFunctionNotExistsByProductKey(createReqVO.getProductKey());
  41 + // 校验功能标识符在同一产品下是否唯一
  42 + validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier());
  43 +
42 44 // 转换请求对象为数据对象
43 45 IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(createReqVO);
44   - // 自动生成属性上报事件和属性设置、获取服务
45   - generateDefaultEventsAndServices(createReqVO, thinkModelFunction);
  46 +
46 47 // 插入数据库
47 48 thinkModelFunctionMapper.insert(thinkModelFunction);
48   - // 返回生成的 ID
49   - return thinkModelFunction.getId();
50   - }
51 49  
52   - private void validateThinkModelFunctionNotExistsByProductKey(String productKey) {
53   - if (thinkModelFunctionMapper.selectByProductKey(productKey) != null) {
54   - throw exception(THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY);
  50 + // 如果创建的是属性,需要更新默认的事件和服务
  51 + if (Objects.equals(createReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
  52 + generateDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey());
55 53 }
56   - }
57 54  
58   - @Override
59   - public void deleteThinkModelFunction(Long id) {
60   - log.info("删除物模型,id:{}", id);
61   - // 校验物模型是否存在
62   - validateThinkModelFunctionExists(id);
63   - // 删除物模型
64   - thinkModelFunctionMapper.deleteById(id);
  55 + // 返回生成的 ID
  56 + return thinkModelFunction.getId();
65 57 }
66 58  
67   - private void validateThinkModelFunctionExists(Long id) {
68   - if (thinkModelFunctionMapper.selectById(id) == null) {
69   - throw exception(THINK_MODEL_FUNCTION_NOT_EXISTS);
  59 + private void validateIdentifierUnique(Long productId, String identifier) {
  60 + IotThinkModelFunctionDO existingFunction = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, identifier);
  61 + if (existingFunction != null) {
  62 + throw exception(THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER);
70 63 }
71 64 }
72 65  
73 66 @Override
74   - public IotThinkModelFunctionDO getThinkModelFunctionByProductKey(String productKey) {
75   - return thinkModelFunctionMapper.selectByProductKey(productKey);
76   - }
77   -
78   - @Override
79   - public IotThinkModelFunctionDO getThinkModelFunctionByProductId(Long productId) {
80   - return thinkModelFunctionMapper.selectByProductId(productId);
81   - }
82   -
83   - @Override
84 67 public void updateThinkModelFunction(IotThinkModelFunctionSaveReqVO updateReqVO) {
85   - log.info("更新物模型,参数:{}", updateReqVO);
86   - // 校验物模型是否存在
  68 + // 校验功能是否存在
87 69 validateThinkModelFunctionExists(updateReqVO.getId());
88   - // 校验 ProductKey 是否唯一
89   - validateProductKeyUnique(updateReqVO.getId(), updateReqVO.getProductKey());
  70 +
  71 + // 校验功能标识符是否唯一
  72 + validateIdentifierUniqueForUpdate(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier());
  73 +
90 74 // 转换请求对象为数据对象
91 75 IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(updateReqVO);
92   - // 自动生成或更新属性上报事件和属性设置、获取服务
93   - generateDefaultEventsAndServices(updateReqVO, thinkModelFunction);
  76 +
94 77 // 更新数据库
95 78 thinkModelFunctionMapper.updateById(thinkModelFunction);
96   - }
97 79  
98   - private void validateProductKeyUnique(Long id, String productKey) {
99   - IotThinkModelFunctionDO existingFunction = thinkModelFunctionMapper.selectByProductKey(productKey);
100   - if (existingFunction != null && !existingFunction.getId().equals(id)) {
101   - throw exception(THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY);
  80 + // 如果更新的是属性,需要更新默认的事件和服务
  81 + if (Objects.equals(updateReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
  82 + generateDefaultEventsAndServices(updateReqVO.getProductId(), updateReqVO.getProductKey());
102 83 }
103 84 }
104 85  
105   - /**
106   - * 根据属性列表,自动生成属性上报事件和属性设置、获取服务
107   - */
108   - private void generateDefaultEventsAndServices(IotThinkModelFunctionSaveReqVO reqVO, IotThinkModelFunctionDO thinkModelFunction) {
109   - // 获取属性列表
110   - List<ThingModelProperty> properties = reqVO.getProperties();
111   - if (properties == null) {
112   - properties = new ArrayList<>();
  86 + private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) {
  87 + IotThinkModelFunctionDO existingFunction = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, identifier);
  88 + if (existingFunction != null && !existingFunction.getId().equals(id)) {
  89 + throw exception(THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER);
113 90 }
  91 + }
114 92  
115   - // 获取现有的事件和服务
116   - List<ThingModelEvent> existingEvents = reqVO.getEvents() != null ? new ArrayList<>(reqVO.getEvents()) : new ArrayList<>();
117   - List<ThingModelService> existingServices = reqVO.getServices() != null ? new ArrayList<>(reqVO.getServices()) : new ArrayList<>();
118   -
119   - // 生成或更新属性上报事件
120   - ThingModelEvent propertyPostEvent = generatePropertyPostEvent(properties);
121   - updateEventInList(existingEvents, propertyPostEvent);
122 93  
123   - // 生成或更新属性设置和获取服务
124   - ThingModelService propertySetService = generatePropertySetService(properties);
125   - updateServiceInList(existingServices, propertySetService);
  94 + @Override
  95 + public void deleteThinkModelFunction(Long id) {
  96 + // 校验功能是否存在
  97 + IotThinkModelFunctionDO functionDO = thinkModelFunctionMapper.selectById(id);
  98 + if (functionDO == null) {
  99 + throw exception(THINK_MODEL_FUNCTION_NOT_EXISTS);
  100 + }
126 101  
127   - ThingModelService propertyGetService = generatePropertyGetService(properties);
128   - updateServiceInList(existingServices, propertyGetService);
  102 + // 删除功能
  103 + thinkModelFunctionMapper.deleteById(id);
129 104  
130   - // 更新 thinkModelFunction 对象的 events 和 services 字段
131   - try {
132   - thinkModelFunction.setEvents(objectMapper.writeValueAsString(existingEvents));
133   - thinkModelFunction.setServices(objectMapper.writeValueAsString(existingServices));
134   - } catch (JsonProcessingException e) {
135   - throw new RuntimeException("序列化事件和服务时发生错误", e);
  105 + // 如果删除的是属性,需要更新默认的事件和服务
  106 + if (Objects.equals(functionDO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
  107 + generateDefaultEventsAndServices(functionDO.getProductId(), functionDO.getProductKey());
136 108 }
137 109 }
138 110  
139 111 /**
140   - * 在事件列表中更新或添加事件
  112 + * 校验功能是否存在
  113 + *
  114 + * @param id 功能编号
141 115 */
142   - private void updateEventInList(List<ThingModelEvent> events, ThingModelEvent newEvent) {
143   - if (newEvent == null) {
144   - return;
145   - }
146   - for (int i = 0; i < events.size(); i++) {
147   - ThingModelEvent event = events.get(i);
148   - if (event.getIdentifier().equals(newEvent.getIdentifier())) {
149   - // 更新已有的事件
150   - events.set(i, newEvent);
151   - return;
152   - }
  116 + private void validateThinkModelFunctionExists(Long id) {
  117 + if (thinkModelFunctionMapper.selectById(id) == null) {
  118 + throw exception(THINK_MODEL_FUNCTION_NOT_EXISTS);
153 119 }
154   - // 如果不存在,则添加新的事件
155   - events.add(newEvent);
  120 + }
  121 +
  122 + @Override
  123 + public IotThinkModelFunctionDO getThinkModelFunction(Long id) {
  124 + return thinkModelFunctionMapper.selectById(id);
  125 + }
  126 +
  127 + @Override
  128 + public List<IotThinkModelFunctionDO> getThinkModelFunctionListByProductId(Long productId) {
  129 + return thinkModelFunctionMapper.selectListByProductId(productId);
156 130 }
157 131  
158 132 /**
159   - * 在服务列表中更新或添加服务
  133 + * 生成默认的事件和服务
160 134 */
161   - private void updateServiceInList(List<ThingModelService> services, ThingModelService newService) {
162   - if (newService == null) {
163   - return;
  135 + public void generateDefaultEventsAndServices(Long productId, String productKey) {
  136 + // 获取当前产品的所有属性列表
  137 + List<IotThinkModelFunctionDO> propertyList = thinkModelFunctionMapper.selectListByProductIdAndType(productId, IotThingModelTypeEnum.PROPERTY.getType());
  138 +
  139 + // 生成属性上报事件
  140 + ThingModelEvent propertyPostEvent = generatePropertyPostEvent(propertyList);
  141 + if (propertyPostEvent != null) {
  142 + saveOrUpdateEvent(productId, productKey, propertyPostEvent);
164 143 }
165   - for (int i = 0; i < services.size(); i++) {
166   - ThingModelService service = services.get(i);
167   - if (service.getIdentifier().equals(newService.getIdentifier())) {
168   - // 更新已有的服务
169   - services.set(i, newService);
170   - return;
171   - }
  144 +
  145 + // 生成属性设置服务
  146 + ThingModelService propertySetService = generatePropertySetService(propertyList);
  147 + if (propertySetService != null) {
  148 + saveOrUpdateService(productId, productKey, propertySetService);
172 149 }
173   - // 如果不存在,则添加新的服务
174   - services.add(newService);
175   - }
176 150  
  151 + // 生成属性获取服务
  152 + ThingModelService propertyGetService = generatePropertyGetService(propertyList);
  153 + if (propertyGetService != null) {
  154 + saveOrUpdateService(productId, productKey, propertyGetService);
  155 + }
  156 + }
177 157  
178 158 /**
179 159 * 生成属性上报事件
180 160 */
181   - private ThingModelEvent generatePropertyPostEvent(List<ThingModelProperty> properties) {
  161 + private ThingModelEvent generatePropertyPostEvent(List<IotThinkModelFunctionDO> propertyList) {
  162 + if (propertyList == null || propertyList.isEmpty()) {
  163 + return null;
  164 + }
  165 +
182 166 ThingModelEvent event = new ThingModelEvent();
183 167 event.setIdentifier("post");
184 168 event.setName("属性上报");
... ... @@ -188,7 +172,8 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
188 172  
189 173 // 将属性列表转换为事件的输出参数
190 174 List<ThingModelArgument> outputData = new ArrayList<>();
191   - for (ThingModelProperty property : properties) {
  175 + for (IotThinkModelFunctionDO functionDO : propertyList) {
  176 + ThingModelProperty property = functionDO.getProperty();
192 177 ThingModelArgument arg = new ThingModelArgument();
193 178 arg.setIdentifier(property.getIdentifier());
194 179 arg.setName(property.getName());
... ... @@ -205,9 +190,14 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
205 190 /**
206 191 * 生成属性设置服务
207 192 */
208   - private ThingModelService generatePropertySetService(List<ThingModelProperty> properties) {
  193 + private ThingModelService generatePropertySetService(List<IotThinkModelFunctionDO> propertyList) {
  194 + if (propertyList == null || propertyList.isEmpty()) {
  195 + return null;
  196 + }
  197 +
209 198 List<ThingModelArgument> inputData = new ArrayList<>();
210   - for (ThingModelProperty property : properties) {
  199 + for (IotThinkModelFunctionDO functionDO : propertyList) {
  200 + ThingModelProperty property = functionDO.getProperty();
211 201 if ("w".equals(property.getAccessMode()) || "rw".equals(property.getAccessMode())) {
212 202 ThingModelArgument arg = new ThingModelArgument();
213 203 arg.setIdentifier(property.getIdentifier());
... ... @@ -239,9 +229,14 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
239 229 /**
240 230 * 生成属性获取服务
241 231 */
242   - private ThingModelService generatePropertyGetService(List<ThingModelProperty> properties) {
  232 + private ThingModelService generatePropertyGetService(List<IotThinkModelFunctionDO> propertyList) {
  233 + if (propertyList == null || propertyList.isEmpty()) {
  234 + return null;
  235 + }
  236 +
243 237 List<ThingModelArgument> outputData = new ArrayList<>();
244   - for (ThingModelProperty property : properties) {
  238 + for (IotThinkModelFunctionDO functionDO : propertyList) {
  239 + ThingModelProperty property = functionDO.getProperty();
245 240 if ("r".equals(property.getAccessMode()) || "rw".equals(property.getAccessMode())) {
246 241 ThingModelArgument arg = new ThingModelArgument();
247 242 arg.setIdentifier(property.getIdentifier());
... ... @@ -275,10 +270,8 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
275 270 ThingModelArrayType arrayType = new ThingModelArrayType();
276 271 arrayType.setType("array");
277 272 ThingModelArraySpecs arraySpecs = new ThingModelArraySpecs();
278   - // 不指定数组长度,size 可以为 0 或者省略
279 273 ThingModelTextType textType = new ThingModelTextType();
280 274 textType.setType("text");
281   - // 如果有需要,可以设置 TextType 的 specs,如长度限制
282 275 arraySpecs.setItem(textType);
283 276 arrayType.setSpecs(arraySpecs);
284 277  
... ... @@ -289,4 +282,54 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
289 282  
290 283 return service;
291 284 }
  285 +
  286 + /**
  287 + * 保存或更新事件
  288 + */
  289 + private void saveOrUpdateEvent(Long productId, String productKey, ThingModelEvent event) {
  290 + // 检查是否已存在相同的事件
  291 + IotThinkModelFunctionDO existingEvent = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, event.getIdentifier());
  292 + IotThinkModelFunctionDO functionDO = new IotThinkModelFunctionDO();
  293 + functionDO.setProductId(productId);
  294 + functionDO.setProductKey(productKey);
  295 + functionDO.setIdentifier(event.getIdentifier());
  296 + functionDO.setName(event.getName());
  297 + functionDO.setDescription(event.getDescription());
  298 + functionDO.setType(IotThingModelTypeEnum.EVENT.getType());
  299 + functionDO.setEvent(event);
  300 +
  301 + if (existingEvent != null) {
  302 + // 更新事件
  303 + functionDO.setId(existingEvent.getId());
  304 + thinkModelFunctionMapper.updateById(functionDO);
  305 + } else {
  306 + // 创建新的事件
  307 + thinkModelFunctionMapper.insert(functionDO);
  308 + }
  309 + }
  310 +
  311 + /**
  312 + * 保存或更新事服务
  313 + */
  314 + private void saveOrUpdateService(Long productId, String productKey, ThingModelService service) {
  315 + // 检查是否已存在相同的服务
  316 + IotThinkModelFunctionDO existingService = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, service.getIdentifier());
  317 + IotThinkModelFunctionDO functionDO = new IotThinkModelFunctionDO();
  318 + functionDO.setProductId(productId);
  319 + functionDO.setProductKey(productKey);
  320 + functionDO.setIdentifier(service.getIdentifier());
  321 + functionDO.setName(service.getName());
  322 + functionDO.setDescription(service.getDescription());
  323 + functionDO.setType(IotThingModelTypeEnum.SERVICE.getType());
  324 + functionDO.setService(service);
  325 +
  326 + if (existingService != null) {
  327 + // 更新服务
  328 + functionDO.setId(existingService.getId());
  329 + thinkModelFunctionMapper.updateById(functionDO);
  330 + } else {
  331 + // 创建新的服务
  332 + thinkModelFunctionMapper.insert(functionDO);
  333 + }
  334 + }
292 335 }
... ...