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,4 +17,5 @@ public interface ErrorCodeConstants {
17 // ========== IoT 产品物模型 1-050-002-000 ============ 17 // ========== IoT 产品物模型 1-050-002-000 ============
18 ErrorCode THINK_MODEL_FUNCTION_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在"); 18 ErrorCode THINK_MODEL_FUNCTION_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在");
19 ErrorCode THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY = new ErrorCode(1_050_002_001, "ProductKey 对应的产品物模型已存在"); 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,137 +5,28 @@ tenant-id: {{adminTenentId}}
5 Authorization: Bearer {{token}} 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,141 +38,37 @@ Authorization: Bearer {{token}}
147 38
148 { 39 {
149 "id": 3, 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 tenant-id: {{adminTenentId}} 73 tenant-id: {{adminTenentId}}
287 Authorization: Bearer {{token}} 74 Authorization: Bearer {{token}}
288 \ No newline at end of file 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,6 +15,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
15 import org.springframework.validation.annotation.Validated; 15 import org.springframework.validation.annotation.Validated;
16 import org.springframework.web.bind.annotation.*; 16 import org.springframework.web.bind.annotation.*;
17 17
  18 +import java.util.List;
  19 +
18 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 20 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
19 21
20 @Tag(name = "管理后台 - IoT 产品物模型") 22 @Tag(name = "管理后台 - IoT 产品物模型")
@@ -50,23 +52,23 @@ public class IotThinkModelFunctionController { @@ -50,23 +52,23 @@ public class IotThinkModelFunctionController {
50 return success(true); 52 return success(true);
51 } 53 }
52 54
53 - @GetMapping("/get-by-product-key") 55 + @GetMapping("/get")
54 @Operation(summary = "获得IoT 产品物模型") 56 @Operation(summary = "获得IoT 产品物模型")
55 - @Parameter(name = "productKey", description = "产品Key", required = true, example = "1024") 57 + @Parameter(name = "id", description = "编号", required = true)
56 @PreAuthorize("@ss.hasPermission('iot:think-model-function:query')") 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 IotThinkModelFunctionRespVO respVO = IotThinkModelFunctionConvert.INSTANCE.convert(thinkModelFunction); 61 IotThinkModelFunctionRespVO respVO = IotThinkModelFunctionConvert.INSTANCE.convert(thinkModelFunction);
60 return success(respVO); 62 return success(respVO);
61 } 63 }
62 64
63 - @GetMapping("/get-by-product-id") 65 + @GetMapping("/list-by-product-id")
64 @Operation(summary = "获得IoT 产品物模型") 66 @Operation(summary = "获得IoT 产品物模型")
65 @Parameter(name = "productId", description = "产品ID", required = true, example = "1024") 67 @Parameter(name = "productId", description = "产品ID", required = true, example = "1024")
66 @PreAuthorize("@ss.hasPermission('iot:think-model-function:query')") 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 return success(respVO); 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,20 +21,32 @@ public class IotThinkModelFunctionRespVO {
21 private Long id; 21 private Long id;
22 22
23 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) 23 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
  24 + private Long productId;
  25 +
  26 + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
24 @ExcelProperty("产品标识") 27 @ExcelProperty("产品标识")
25 private String productKey; 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 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 51 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
40 @ExcelProperty("创建时间") 52 @ExcelProperty("创建时间")
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/vo/IotThinkModelFunctionSaveReqVO.java
1 package cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo; 1 package cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo;
2 2
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent; 4 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent;
4 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty; 5 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
5 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService; 6 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService;
  7 +import cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum;
6 import io.swagger.v3.oas.annotations.media.Schema; 8 import io.swagger.v3.oas.annotations.media.Schema;
7 import jakarta.validation.constraints.NotEmpty; 9 import jakarta.validation.constraints.NotEmpty;
8 import jakarta.validation.constraints.NotNull; 10 import jakarta.validation.constraints.NotNull;
9 import lombok.Data; 11 import lombok.Data;
10 12
11 -import java.util.List;  
12 -  
13 @Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO") 13 @Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO")
14 @Data 14 @Data
15 public class IotThinkModelFunctionSaveReqVO { 15 public class IotThinkModelFunctionSaveReqVO {
@@ -25,14 +25,29 @@ public class IotThinkModelFunctionSaveReqVO { @@ -25,14 +25,29 @@ public class IotThinkModelFunctionSaveReqVO {
25 @NotEmpty(message = "产品标识不能为空") 25 @NotEmpty(message = "产品标识不能为空")
26 private String productKey; 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 \ No newline at end of file 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,82 +6,52 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingMode
6 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionRespVO; 6 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionRespVO;
7 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionSaveReqVO; 7 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionSaveReqVO;
8 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; 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 import org.mapstruct.Mapper; 10 import org.mapstruct.Mapper;
12 import org.mapstruct.Mapping; 11 import org.mapstruct.Mapping;
13 import org.mapstruct.factory.Mappers; 12 import org.mapstruct.factory.Mappers;
14 13
15 -import java.util.ArrayList;  
16 import java.util.List; 14 import java.util.List;
  15 +import java.util.Objects;
17 16
18 @Mapper 17 @Mapper
19 public interface IotThinkModelFunctionConvert { 18 public interface IotThinkModelFunctionConvert {
20 19
21 IotThinkModelFunctionConvert INSTANCE = Mappers.getMapper(IotThinkModelFunctionConvert.class); 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 IotThinkModelFunctionDO convert(IotThinkModelFunctionSaveReqVO bean); 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 IotThinkModelFunctionRespVO convert(IotThinkModelFunctionDO bean); 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 List<IotThinkModelFunctionRespVO> convertList(List<IotThinkModelFunctionDO> list); 56 List<IotThinkModelFunctionRespVO> convertList(List<IotThinkModelFunctionDO> list);
87 -}  
88 \ No newline at end of file 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 package cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction; 1 package cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 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 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; 7 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
5 import com.baomidou.mybatisplus.annotation.KeySequence; 8 import com.baomidou.mybatisplus.annotation.KeySequence;
  9 +import com.baomidou.mybatisplus.annotation.TableField;
6 import com.baomidou.mybatisplus.annotation.TableId; 10 import com.baomidou.mybatisplus.annotation.TableId;
7 import com.baomidou.mybatisplus.annotation.TableName; 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 * IoT 产品物模型功能 DO 19 * IoT 产品物模型功能 DO
12 - * 20 + * <p>
13 * 每个 {@link IotProductDO} 和 {@link IotThinkModelFunctionDO} 是“一对多”的关系,它的每个属性、事件、服务都对应一条记录 21 * 每个 {@link IotProductDO} 和 {@link IotThinkModelFunctionDO} 是“一对多”的关系,它的每个属性、事件、服务都对应一条记录
14 * 22 *
15 * @author 芋道源码 23 * @author 芋道源码
16 */ 24 */
17 -@TableName("iot_think_model_function") 25 +@TableName(value = "iot_think_model_function", autoResultMap = true)
18 @KeySequence("iot_think_model_function_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 26 @KeySequence("iot_think_model_function_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
19 @Data 27 @Data
20 @Builder 28 @Builder
@@ -27,35 +35,56 @@ public class IotThinkModelFunctionDO extends BaseDO { @@ -27,35 +35,56 @@ public class IotThinkModelFunctionDO extends BaseDO {
27 */ 35 */
28 @TableId 36 @TableId
29 private Long id; 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 * 关联 {@link IotProductDO#getId()} 55 * 关联 {@link IotProductDO#getId()}
36 */ 56 */
37 private Long productId; 57 private Long productId;
38 /** 58 /**
39 * 产品标识 59 * 产品标识
40 - * 60 + * <p>
41 * 关联 {@link IotProductDO#getProductKey()} 61 * 关联 {@link IotProductDO#getProductKey()}
42 */ 62 */
43 private String productKey; 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 \ No newline at end of file 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 \ No newline at end of file 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,6 +5,8 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
6 import org.apache.ibatis.annotations.Mapper; 6 import org.apache.ibatis.annotations.Mapper;
7 7
  8 +import java.util.List;
  9 +
8 /** 10 /**
9 * IoT 产品物模型 Mapper 11 * IoT 产品物模型 Mapper
10 * 12 *
@@ -13,12 +15,17 @@ import org.apache.ibatis.annotations.Mapper; @@ -13,12 +15,17 @@ import org.apache.ibatis.annotations.Mapper;
13 @Mapper 15 @Mapper
14 public interface IotThinkModelFunctionMapper extends BaseMapperX<IotThinkModelFunctionDO> { 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 \ No newline at end of file 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,6 +4,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThi
4 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; 4 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
5 import jakarta.validation.Valid; 5 import jakarta.validation.Valid;
6 6
  7 +import java.util.List;
  8 +
7 /** 9 /**
8 * IoT 产品物模型 Service 接口 10 * IoT 产品物模型 Service 接口
9 * 11 *
@@ -19,33 +21,34 @@ public interface IotThinkModelFunctionService { @@ -19,33 +21,34 @@ public interface IotThinkModelFunctionService {
19 */ 21 */
20 Long createThinkModelFunction(@Valid IotThinkModelFunctionSaveReqVO createReqVO); 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 * @return IoT 产品物模型 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 \ No newline at end of file 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 package cn.iocoder.yudao.module.iot.service.thinkmodelfunction; 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 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.dataType.ThingModelArgument; 7 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.dataType.ThingModelArgument;
5 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.dataType.ThingModelArraySpecs; 8 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.dataType.ThingModelArraySpecs;
6 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.dataType.ThingModelArrayType; 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,19 +12,20 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThi
9 import cn.iocoder.yudao.module.iot.convert.thinkmodelfunction.IotThinkModelFunctionConvert; 12 import cn.iocoder.yudao.module.iot.convert.thinkmodelfunction.IotThinkModelFunctionConvert;
10 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; 13 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
11 import cn.iocoder.yudao.module.iot.dal.mysql.thinkmodelfunction.IotThinkModelFunctionMapper; 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 import jakarta.annotation.Resource; 16 import jakarta.annotation.Resource;
15 import lombok.extern.slf4j.Slf4j; 17 import lombok.extern.slf4j.Slf4j;
16 import org.springframework.stereotype.Service; 18 import org.springframework.stereotype.Service;
  19 +import org.springframework.transaction.annotation.Transactional;
17 import org.springframework.validation.annotation.Validated; 20 import org.springframework.validation.annotation.Validated;
18 21
19 import java.util.ArrayList; 22 import java.util.ArrayList;
20 import java.util.Collections; 23 import java.util.Collections;
21 import java.util.List; 24 import java.util.List;
  25 +import java.util.Objects;
22 26
23 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 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 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_NOT_EXISTS; 29 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_NOT_EXISTS;
26 30
27 @Slf4j 31 @Slf4j
@@ -32,153 +36,133 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -32,153 +36,133 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
32 @Resource 36 @Resource
33 private IotThinkModelFunctionMapper thinkModelFunctionMapper; 37 private IotThinkModelFunctionMapper thinkModelFunctionMapper;
34 38
35 - private ObjectMapper objectMapper = new ObjectMapper();  
36 -  
37 @Override 39 @Override
38 public Long createThinkModelFunction(IotThinkModelFunctionSaveReqVO createReqVO) { 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 IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(createReqVO); 45 IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(createReqVO);
44 - // 自动生成属性上报事件和属性设置、获取服务  
45 - generateDefaultEventsAndServices(createReqVO, thinkModelFunction); 46 +
46 // 插入数据库 47 // 插入数据库
47 thinkModelFunctionMapper.insert(thinkModelFunction); 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 @Override 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 public void updateThinkModelFunction(IotThinkModelFunctionSaveReqVO updateReqVO) { 67 public void updateThinkModelFunction(IotThinkModelFunctionSaveReqVO updateReqVO) {
85 - log.info("更新物模型,参数:{}", updateReqVO);  
86 - // 校验物模型是否存在 68 + // 校验功能是否存在
87 validateThinkModelFunctionExists(updateReqVO.getId()); 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 IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(updateReqVO); 75 IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(updateReqVO);
92 - // 自动生成或更新属性上报事件和属性设置、获取服务  
93 - generateDefaultEventsAndServices(updateReqVO, thinkModelFunction); 76 +
94 // 更新数据库 77 // 更新数据库
95 thinkModelFunctionMapper.updateById(thinkModelFunction); 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 ThingModelEvent event = new ThingModelEvent(); 166 ThingModelEvent event = new ThingModelEvent();
183 event.setIdentifier("post"); 167 event.setIdentifier("post");
184 event.setName("属性上报"); 168 event.setName("属性上报");
@@ -188,7 +172,8 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -188,7 +172,8 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
188 172
189 // 将属性列表转换为事件的输出参数 173 // 将属性列表转换为事件的输出参数
190 List<ThingModelArgument> outputData = new ArrayList<>(); 174 List<ThingModelArgument> outputData = new ArrayList<>();
191 - for (ThingModelProperty property : properties) { 175 + for (IotThinkModelFunctionDO functionDO : propertyList) {
  176 + ThingModelProperty property = functionDO.getProperty();
192 ThingModelArgument arg = new ThingModelArgument(); 177 ThingModelArgument arg = new ThingModelArgument();
193 arg.setIdentifier(property.getIdentifier()); 178 arg.setIdentifier(property.getIdentifier());
194 arg.setName(property.getName()); 179 arg.setName(property.getName());
@@ -205,9 +190,14 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -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 List<ThingModelArgument> inputData = new ArrayList<>(); 198 List<ThingModelArgument> inputData = new ArrayList<>();
210 - for (ThingModelProperty property : properties) { 199 + for (IotThinkModelFunctionDO functionDO : propertyList) {
  200 + ThingModelProperty property = functionDO.getProperty();
211 if ("w".equals(property.getAccessMode()) || "rw".equals(property.getAccessMode())) { 201 if ("w".equals(property.getAccessMode()) || "rw".equals(property.getAccessMode())) {
212 ThingModelArgument arg = new ThingModelArgument(); 202 ThingModelArgument arg = new ThingModelArgument();
213 arg.setIdentifier(property.getIdentifier()); 203 arg.setIdentifier(property.getIdentifier());
@@ -239,9 +229,14 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -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 List<ThingModelArgument> outputData = new ArrayList<>(); 237 List<ThingModelArgument> outputData = new ArrayList<>();
244 - for (ThingModelProperty property : properties) { 238 + for (IotThinkModelFunctionDO functionDO : propertyList) {
  239 + ThingModelProperty property = functionDO.getProperty();
245 if ("r".equals(property.getAccessMode()) || "rw".equals(property.getAccessMode())) { 240 if ("r".equals(property.getAccessMode()) || "rw".equals(property.getAccessMode())) {
246 ThingModelArgument arg = new ThingModelArgument(); 241 ThingModelArgument arg = new ThingModelArgument();
247 arg.setIdentifier(property.getIdentifier()); 242 arg.setIdentifier(property.getIdentifier());
@@ -275,10 +270,8 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -275,10 +270,8 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
275 ThingModelArrayType arrayType = new ThingModelArrayType(); 270 ThingModelArrayType arrayType = new ThingModelArrayType();
276 arrayType.setType("array"); 271 arrayType.setType("array");
277 ThingModelArraySpecs arraySpecs = new ThingModelArraySpecs(); 272 ThingModelArraySpecs arraySpecs = new ThingModelArraySpecs();
278 - // 不指定数组长度,size 可以为 0 或者省略  
279 ThingModelTextType textType = new ThingModelTextType(); 273 ThingModelTextType textType = new ThingModelTextType();
280 textType.setType("text"); 274 textType.setType("text");
281 - // 如果有需要,可以设置 TextType 的 specs,如长度限制  
282 arraySpecs.setItem(textType); 275 arraySpecs.setItem(textType);
283 arrayType.setSpecs(arraySpecs); 276 arrayType.setSpecs(arraySpecs);
284 277
@@ -289,4 +282,54 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -289,4 +282,54 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
289 282
290 return service; 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 }