mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	修改:IOT 物模型接口优化
This commit is contained in:
		| @@ -17,4 +17,5 @@ public interface ErrorCodeConstants { | ||||
|     // ========== IoT 产品物模型 1-050-002-000 ============ | ||||
|     ErrorCode THINK_MODEL_FUNCTION_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在"); | ||||
|     ErrorCode THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY = new ErrorCode(1_050_002_001, "ProductKey 对应的产品物模型已存在"); | ||||
|     ErrorCode THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER = new ErrorCode(1_050_002_002, "产品物模型标识已存在"); | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,47 @@ | ||||
| package cn.iocoder.yudao.module.iot.enums.product; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Getter; | ||||
|  | ||||
| import java.util.Arrays; | ||||
|  | ||||
| /** | ||||
|  * IOT 物模型功能类型枚举类 | ||||
|  * | ||||
|  * @author ahh | ||||
|  */ | ||||
| @AllArgsConstructor | ||||
| @Getter | ||||
| public enum IotThingModelTypeEnum implements IntArrayValuable { | ||||
|  | ||||
|     /** | ||||
|      * 属性 | ||||
|      */ | ||||
|     PROPERTY(1, "属性"), | ||||
|     /** | ||||
|      * 服务 | ||||
|      */ | ||||
|     SERVICE(2, "服务"), | ||||
|     /** | ||||
|      * 事件 | ||||
|      */ | ||||
|     EVENT(3, "事件"); | ||||
|  | ||||
|     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(IotThingModelTypeEnum::getType).toArray(); | ||||
|  | ||||
|     /** | ||||
|      * 类型 | ||||
|      */ | ||||
|     private final Integer type; | ||||
|     /** | ||||
|      * 描述 | ||||
|      */ | ||||
|     private final String description; | ||||
|  | ||||
|     @Override | ||||
|     public int[] array() { | ||||
|         return ARRAYS; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -5,137 +5,28 @@ tenant-id: {{adminTenentId}} | ||||
| Authorization: Bearer {{token}} | ||||
|  | ||||
| { | ||||
|   "productId": 1002, | ||||
|   "productKey": "smart-sensor-002", | ||||
|   "properties": [ | ||||
|     { | ||||
|       "identifier": "Temperature", | ||||
|       "name": "温度", | ||||
|       "accessMode": "r", | ||||
|       "required": true, | ||||
|       "dataType": { | ||||
|         "type": "float", | ||||
|         "specs": { | ||||
|           "min": -40.0, | ||||
|           "max": 125.0, | ||||
|           "step": 0.1, | ||||
|           "unit": "℃" | ||||
|         } | ||||
|       }, | ||||
|       "description": "当前温度值" | ||||
|   "productId": 1001, | ||||
|   "productKey": "smart-sensor-001", | ||||
|   "identifier": "Temperature", | ||||
|   "name": "温度", | ||||
|   "description": "当前温度值", | ||||
|   "type": 1, | ||||
|   "property": { | ||||
|     "identifier": "Temperature", | ||||
|     "name": "温度", | ||||
|     "accessMode": "r", | ||||
|     "required": true, | ||||
|     "dataType": { | ||||
|       "type": "float", | ||||
|       "specs": { | ||||
|         "min": -40.0, | ||||
|         "max": 125.0, | ||||
|         "step": 0.1, | ||||
|         "unit": "℃" | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "identifier": "Humidity", | ||||
|       "name": "湿度", | ||||
|       "accessMode": "r", | ||||
|       "required": true, | ||||
|       "dataType": { | ||||
|         "type": "float", | ||||
|         "specs": { | ||||
|           "min": 0.0, | ||||
|           "max": 100.0, | ||||
|           "step": 0.1, | ||||
|           "unit": "%" | ||||
|         } | ||||
|       }, | ||||
|       "description": "当前湿度值" | ||||
|     }, | ||||
|     { | ||||
|       "identifier": "GeoLocation", | ||||
|       "name": "地理位置", | ||||
|       "accessMode": "r", | ||||
|       "required": false, | ||||
|       "dataType": { | ||||
|         "type": "struct", | ||||
|         "specs": [ | ||||
|           { | ||||
|             "identifier": "Longitude", | ||||
|             "name": "经度", | ||||
|             "dataType": { | ||||
|               "type": "double", | ||||
|               "specs": { | ||||
|                 "min": -180.0, | ||||
|                 "max": 180.0, | ||||
|                 "step": 0.000001, | ||||
|                 "unit": "°" | ||||
|               } | ||||
|             }, | ||||
|             "description": "设备所在位置的经度" | ||||
|           }, | ||||
|           { | ||||
|             "identifier": "Latitude", | ||||
|             "name": "纬度", | ||||
|             "dataType": { | ||||
|               "type": "double", | ||||
|               "specs": { | ||||
|                 "min": -90.0, | ||||
|                 "max": 90.0, | ||||
|                 "step": 0.000001, | ||||
|                 "unit": "°" | ||||
|               } | ||||
|             }, | ||||
|             "description": "设备所在位置的纬度" | ||||
|           } | ||||
|         ] | ||||
|       }, | ||||
|       "description": "设备的地理位置信息" | ||||
|     } | ||||
|   ], | ||||
|   "services": [ | ||||
|     { | ||||
|       "identifier": "Reboot", | ||||
|       "name": "重启设备", | ||||
|       "callType": "async", | ||||
|       "inputData": [], | ||||
|       "description": "远程重启设备", | ||||
|       "method": "thing.service.reboot" | ||||
|     }, | ||||
|     { | ||||
|       "identifier": "SetThreshold", | ||||
|       "name": "设置温度阈值", | ||||
|       "callType": "sync", | ||||
|       "inputData": [ | ||||
|         { | ||||
|           "identifier": "Threshold", | ||||
|           "name": "阈值", | ||||
|           "dataType": { | ||||
|             "type": "float", | ||||
|             "specs": { | ||||
|               "min": -40.0, | ||||
|               "max": 125.0, | ||||
|               "step": 0.1, | ||||
|               "unit": "℃" | ||||
|             } | ||||
|           }, | ||||
|           "description": "报警温度阈值" | ||||
|         } | ||||
|       ], | ||||
|       "description": "设置设备的温度报警阈值", | ||||
|       "method": "thing.service.setThreshold" | ||||
|     } | ||||
|   ], | ||||
|   "events": [ | ||||
|     { | ||||
|       "identifier": "HighTemperatureAlert", | ||||
|       "name": "高温报警", | ||||
|       "type": "alert", | ||||
|       "outputData": [ | ||||
|         { | ||||
|           "identifier": "CurrentTemperature", | ||||
|           "name": "当前温度", | ||||
|           "dataType": { | ||||
|             "type": "float", | ||||
|             "specs": { | ||||
|               "unit": "℃" | ||||
|             } | ||||
|           }, | ||||
|           "description": "触发报警时的温度值" | ||||
|         } | ||||
|       ], | ||||
|       "description": "当温度超过阈值时触发高温报警事件", | ||||
|       "method": "thing.event.highTemperatureAlert" | ||||
|     } | ||||
|   ] | ||||
|     "description": "当前温度值" | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -147,141 +38,37 @@ Authorization: Bearer {{token}} | ||||
|  | ||||
| { | ||||
|   "id": 3, | ||||
|   "productId": 1002, | ||||
|   "productKey": "smart-sensor-002", | ||||
|   "properties": [ | ||||
|     { | ||||
|       "identifier": "Temperature", | ||||
|       "name": "温度", | ||||
|       "accessMode": "r", | ||||
|       "required": true, | ||||
|       "dataType": { | ||||
|         "type": "float", | ||||
|         "specs": { | ||||
|           "min": -100.0, | ||||
|           "max": 200.0, | ||||
|           "step": 0.1, | ||||
|           "unit": "℃" | ||||
|         } | ||||
|       }, | ||||
|       "description": "当前温度值" | ||||
|   "productId": 1001, | ||||
|   "productKey": "smart-sensor-001", | ||||
|   "identifier": "Temperature", | ||||
|   "name": "温度", | ||||
|   "description": "当前温度值", | ||||
|   "type": 1, | ||||
|   "property": { | ||||
|     "identifier": "Temperature", | ||||
|     "name": "温度", | ||||
|     "accessMode": "r", | ||||
|     "required": true, | ||||
|     "dataType": { | ||||
|       "type": "float", | ||||
|       "specs": { | ||||
|         "min": -10.0, | ||||
|         "max": 100.0, | ||||
|         "step": 0.1, | ||||
|         "unit": "℃" | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "identifier": "Humidity", | ||||
|       "name": "湿度", | ||||
|       "accessMode": "r", | ||||
|       "required": true, | ||||
|       "dataType": { | ||||
|         "type": "float", | ||||
|         "specs": { | ||||
|           "min": 0.0, | ||||
|           "max": 100.0, | ||||
|           "step": 0.1, | ||||
|           "unit": "%" | ||||
|         } | ||||
|       }, | ||||
|       "description": "当前湿度值" | ||||
|     }, | ||||
|     { | ||||
|       "identifier": "GeoLocation", | ||||
|       "name": "地理位置", | ||||
|       "accessMode": "r", | ||||
|       "required": false, | ||||
|       "dataType": { | ||||
|         "type": "struct", | ||||
|         "specs": [ | ||||
|           { | ||||
|             "identifier": "Longitude", | ||||
|             "name": "经度", | ||||
|             "dataType": { | ||||
|               "type": "double", | ||||
|               "specs": { | ||||
|                 "min": -180.0, | ||||
|                 "max": 180.0, | ||||
|                 "step": 0.000001, | ||||
|                 "unit": "°" | ||||
|               } | ||||
|             }, | ||||
|             "description": "设备所在位置的经度" | ||||
|           }, | ||||
|           { | ||||
|             "identifier": "Latitude", | ||||
|             "name": "纬度", | ||||
|             "dataType": { | ||||
|               "type": "double", | ||||
|               "specs": { | ||||
|                 "min": -90.0, | ||||
|                 "max": 90.0, | ||||
|                 "step": 0.000001, | ||||
|                 "unit": "°" | ||||
|               } | ||||
|             }, | ||||
|             "description": "设备所在位置的纬度" | ||||
|           } | ||||
|         ] | ||||
|       }, | ||||
|       "description": "设备的地理位置信息" | ||||
|     } | ||||
|   ], | ||||
|   "services": [ | ||||
|     { | ||||
|       "identifier": "Reboot", | ||||
|       "name": "重启设备", | ||||
|       "callType": "async", | ||||
|       "inputData": [], | ||||
|       "description": "远程重启设备", | ||||
|       "method": "thing.service.reboot" | ||||
|     }, | ||||
|     { | ||||
|       "identifier": "SetThreshold", | ||||
|       "name": "设置温度阈值", | ||||
|       "callType": "sync", | ||||
|       "inputData": [ | ||||
|         { | ||||
|           "identifier": "Threshold", | ||||
|           "name": "阈值", | ||||
|           "dataType": { | ||||
|             "type": "float", | ||||
|             "specs": { | ||||
|               "min": -40.0, | ||||
|               "max": 125.0, | ||||
|               "step": 0.1, | ||||
|               "unit": "℃" | ||||
|             } | ||||
|           }, | ||||
|           "description": "报警温度阈值" | ||||
|         } | ||||
|       ], | ||||
|       "description": "设置设备的温度报警阈值", | ||||
|       "method": "thing.service.setThreshold" | ||||
|     } | ||||
|   ], | ||||
|   "events": [ | ||||
|     { | ||||
|       "identifier": "HighTemperatureAlert", | ||||
|       "name": "高温报警", | ||||
|       "type": "alert", | ||||
|       "outputData": [ | ||||
|         { | ||||
|           "identifier": "CurrentTemperature", | ||||
|           "name": "当前温度", | ||||
|           "dataType": { | ||||
|             "type": "float", | ||||
|             "specs": { | ||||
|               "unit": "℃" | ||||
|             } | ||||
|           }, | ||||
|           "description": "触发报警时的温度值" | ||||
|         } | ||||
|       ], | ||||
|       "description": "当温度超过阈值时触发高温报警事件", | ||||
|       "method": "thing.event.highTemperatureAlert" | ||||
|     } | ||||
|   ] | ||||
|     "description": "当前温度值" | ||||
|   } | ||||
| } | ||||
|  | ||||
| ### 请求 /iot/think-model-function/get 接口 => 成功 | ||||
| GET {{baseUrl}}/iot/think-model-function/get?id=3 | ||||
| tenant-id: {{adminTenentId}} | ||||
| Authorization: Bearer {{token}} | ||||
|  | ||||
| ### 请求 /iot/think-model-function/get-by-product-key 接口 => 成功 | ||||
| GET {{baseUrl}}/iot/think-model-function/get-by-product-key?productKey=smart-sensor-002 | ||||
|  | ||||
| ### 请求 /iot/think-model-function/list-by-product-id 接口 => 成功 | ||||
| GET {{baseUrl}}/iot/think-model-function/list-by-product-id?productId=1001 | ||||
| tenant-id: {{adminTenentId}} | ||||
| Authorization: Bearer {{token}} | ||||
| @@ -15,6 +15,8 @@ import org.springframework.security.access.prepost.PreAuthorize; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||
|  | ||||
| @Tag(name = "管理后台 - IoT 产品物模型") | ||||
| @@ -50,23 +52,23 @@ public class IotThinkModelFunctionController { | ||||
|         return success(true); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/get-by-product-key") | ||||
|     @GetMapping("/get") | ||||
|     @Operation(summary = "获得IoT 产品物模型") | ||||
|     @Parameter(name = "productKey", description = "产品Key", required = true, example = "1024") | ||||
|     @Parameter(name = "id", description = "编号", required = true) | ||||
|     @PreAuthorize("@ss.hasPermission('iot:think-model-function:query')") | ||||
|     public CommonResult<IotThinkModelFunctionRespVO> getThinkModelFunctionByProductKey(@RequestParam("productKey") String productKey) { | ||||
|         IotThinkModelFunctionDO thinkModelFunction = thinkModelFunctionService.getThinkModelFunctionByProductKey(productKey); | ||||
|     public CommonResult<IotThinkModelFunctionRespVO> getThinkModelFunction(@RequestParam("id") Long id) { | ||||
|         IotThinkModelFunctionDO thinkModelFunction = thinkModelFunctionService.getThinkModelFunction(id); | ||||
|         IotThinkModelFunctionRespVO respVO = IotThinkModelFunctionConvert.INSTANCE.convert(thinkModelFunction); | ||||
|         return success(respVO); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/get-by-product-id") | ||||
|     @GetMapping("/list-by-product-id") | ||||
|     @Operation(summary = "获得IoT 产品物模型") | ||||
|     @Parameter(name = "productId", description = "产品ID", required = true, example = "1024") | ||||
|     @PreAuthorize("@ss.hasPermission('iot:think-model-function:query')") | ||||
|     public CommonResult<IotThinkModelFunctionRespVO> getThinkModelFunctionByProductId(@RequestParam("productId") Long productId) { | ||||
|         IotThinkModelFunctionDO thinkModelFunction = thinkModelFunctionService.getThinkModelFunctionByProductId(productId); | ||||
|         IotThinkModelFunctionRespVO respVO = IotThinkModelFunctionConvert.INSTANCE.convert(thinkModelFunction); | ||||
|     public CommonResult<List<IotThinkModelFunctionRespVO>> getThinkModelFunctionListByProductId(@RequestParam("productId") Long productId) { | ||||
|         List<IotThinkModelFunctionDO> thinkModelFunctionListByProductId = thinkModelFunctionService.getThinkModelFunctionListByProductId(productId); | ||||
|         List<IotThinkModelFunctionRespVO> respVO = IotThinkModelFunctionConvert.INSTANCE.convertList(thinkModelFunctionListByProductId); | ||||
|         return success(respVO); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -20,21 +20,33 @@ public class IotThinkModelFunctionRespVO { | ||||
|     @ExcelProperty("产品ID") | ||||
|     private Long id; | ||||
|  | ||||
|     @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private Long productId; | ||||
|  | ||||
|     @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     @ExcelProperty("产品标识") | ||||
|     private String productKey; | ||||
|  | ||||
|     @Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     @ExcelProperty("属性列表") | ||||
|     private List<ThingModelProperty> properties; | ||||
|     @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private String identifier; | ||||
|  | ||||
|     @Schema(description = "服务列表") | ||||
|     @ExcelProperty("服务列表") | ||||
|     private List<ThingModelService> services; | ||||
|     @Schema(description = "功能名称", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private String name; | ||||
|  | ||||
|     @Schema(description = "事件列表") | ||||
|     @ExcelProperty("事件列表") | ||||
|     private List<ThingModelEvent> events; | ||||
|     @Schema(description = "功能描述", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private String description; | ||||
|  | ||||
|     @Schema(description = "功能类型", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private Integer type; | ||||
|  | ||||
|     @Schema(description = "属性", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private ThingModelProperty property; | ||||
|  | ||||
|     @Schema(description = "服务", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private ThingModelEvent event; | ||||
|  | ||||
|     @Schema(description = "事件", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private ThingModelService service; | ||||
|  | ||||
|     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     @ExcelProperty("创建时间") | ||||
|   | ||||
| @@ -1,15 +1,15 @@ | ||||
| package cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.validation.InEnum; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService; | ||||
| import cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import jakarta.validation.constraints.NotEmpty; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO") | ||||
| @Data | ||||
| public class IotThinkModelFunctionSaveReqVO { | ||||
| @@ -25,14 +25,29 @@ public class IotThinkModelFunctionSaveReqVO { | ||||
|     @NotEmpty(message = "产品标识不能为空") | ||||
|     private String productKey; | ||||
|  | ||||
|     @Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     @NotEmpty(message = "属性列表不能为空") | ||||
|     private List<ThingModelProperty> properties; | ||||
|     @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     @NotEmpty(message = "功能标识不能为空") | ||||
|     private String identifier; | ||||
|  | ||||
|     @Schema(description = "服务列表") | ||||
|     private List<ThingModelService> services; | ||||
|     @Schema(description = "功能名称", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     @NotEmpty(message = "功能名称不能为空") | ||||
|     private String name; | ||||
|  | ||||
|     @Schema(description = "事件列表") | ||||
|     private List<ThingModelEvent> events; | ||||
|     @Schema(description = "功能描述", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private String description; | ||||
|  | ||||
|     @Schema(description = "功能类型", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     @NotNull(message = "功能类型不能为空") | ||||
|     @InEnum(IotThingModelTypeEnum.class) | ||||
|     private Integer type; | ||||
|  | ||||
|     @Schema(description = "属性", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private ThingModelProperty property; | ||||
|  | ||||
|     @Schema(description = "服务", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private ThingModelService service; | ||||
|  | ||||
|     @Schema(description = "事件", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     private ThingModelEvent event; | ||||
|  | ||||
| } | ||||
| @@ -6,82 +6,52 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingMode | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionRespVO; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionSaveReqVO; | ||||
| import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; | ||||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum; | ||||
| import org.mapstruct.Mapper; | ||||
| import org.mapstruct.Mapping; | ||||
| import org.mapstruct.factory.Mappers; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
|  | ||||
| @Mapper | ||||
| public interface IotThinkModelFunctionConvert { | ||||
|  | ||||
|     IotThinkModelFunctionConvert INSTANCE = Mappers.getMapper(IotThinkModelFunctionConvert.class); | ||||
|  | ||||
|     ObjectMapper objectMapper = new ObjectMapper(); | ||||
|  | ||||
|     // 将 SaveReqVO 转换为 DO 对象,处理 properties, services, events 字段 | ||||
|     @Mapping(target = "properties", expression = "java(convertPropertiesToJson(bean.getProperties()))") | ||||
|     @Mapping(target = "services", expression = "java(convertServicesToJson(bean.getServices()))") | ||||
|     @Mapping(target = "events", expression = "java(convertEventsToJson(bean.getEvents()))") | ||||
|     // 将 SaveReqVO 转换为 DO | ||||
|     @Mapping(target = "property", expression = "java(convertToProperty(bean))") | ||||
|     @Mapping(target = "event", expression = "java(convertToEvent(bean))") | ||||
|     @Mapping(target = "service", expression = "java(convertToService(bean))") | ||||
|     IotThinkModelFunctionDO convert(IotThinkModelFunctionSaveReqVO bean); | ||||
|  | ||||
|     default String convertPropertiesToJson(List<ThingModelProperty> properties) { | ||||
|         try { | ||||
|             return properties != null ? objectMapper.writeValueAsString(properties) : "[]"; | ||||
|         } catch (JsonProcessingException e) { | ||||
|             throw new RuntimeException("序列化 properties 时发生错误", e); | ||||
|     default ThingModelProperty convertToProperty(IotThinkModelFunctionSaveReqVO bean) { | ||||
|         if (Objects.equals(bean.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { | ||||
|             return bean.getProperty(); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     default String convertServicesToJson(List<ThingModelService> services) { | ||||
|         try { | ||||
|             return services != null ? objectMapper.writeValueAsString(services) : "[]"; | ||||
|         } catch (JsonProcessingException e) { | ||||
|             throw new RuntimeException("序列化 services 时发生错误", e); | ||||
|     default ThingModelEvent convertToEvent(IotThinkModelFunctionSaveReqVO bean) { | ||||
|         if (Objects.equals(bean.getType(), IotThingModelTypeEnum.EVENT.getType())) { | ||||
|             return bean.getEvent(); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     default String convertEventsToJson(List<ThingModelEvent> events) { | ||||
|         try { | ||||
|             return events != null ? objectMapper.writeValueAsString(events) : "[]"; | ||||
|         } catch (JsonProcessingException e) { | ||||
|             throw new RuntimeException("序列化 events 时发生错误", e); | ||||
|     default ThingModelService convertToService(IotThinkModelFunctionSaveReqVO bean) { | ||||
|         if (Objects.equals(bean.getType(), IotThingModelTypeEnum.SERVICE.getType())) { | ||||
|             return bean.getService(); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     // 将 DO 转换为 RespVO 对象,处理 properties, services, events 字段 | ||||
|     @Mapping(target = "properties", expression = "java(convertJsonToProperties(bean.getProperties()))") | ||||
|     @Mapping(target = "services", expression = "java(convertJsonToServices(bean.getServices()))") | ||||
|     @Mapping(target = "events", expression = "java(convertJsonToEvents(bean.getEvents()))") | ||||
|     // 将 DO 转换为 RespVO | ||||
|     @Mapping(target = "property", source = "property") | ||||
|     @Mapping(target = "event", source = "event") | ||||
|     @Mapping(target = "service", source = "service") | ||||
|     IotThinkModelFunctionRespVO convert(IotThinkModelFunctionDO bean); | ||||
|  | ||||
|     default List<ThingModelProperty> convertJsonToProperties(String propertiesJson) { | ||||
|         try { | ||||
|             return propertiesJson != null ? objectMapper.readValue(propertiesJson, objectMapper.getTypeFactory().constructCollectionType(List.class, ThingModelProperty.class)) : new ArrayList<>(); | ||||
|         } catch (JsonProcessingException e) { | ||||
|             throw new RuntimeException("反序列化 properties 时发生错误", e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     default List<ThingModelService> convertJsonToServices(String servicesJson) { | ||||
|         try { | ||||
|             return servicesJson != null ? objectMapper.readValue(servicesJson, objectMapper.getTypeFactory().constructCollectionType(List.class, ThingModelService.class)) : new ArrayList<>(); | ||||
|         } catch (JsonProcessingException e) { | ||||
|             throw new RuntimeException("反序列化 services 时发生错误", e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     default List<ThingModelEvent> convertJsonToEvents(String eventsJson) { | ||||
|         try { | ||||
|             return eventsJson != null ? objectMapper.readValue(eventsJson, objectMapper.getTypeFactory().constructCollectionType(List.class, ThingModelEvent.class)) : new ArrayList<>(); | ||||
|         } catch (JsonProcessingException e) { | ||||
|             throw new RuntimeException("反序列化 events 时发生错误", e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // 批量转换 DO 列表到 RespVO 列表 | ||||
|     // 批量转换 | ||||
|     List<IotThinkModelFunctionRespVO> convertList(List<IotThinkModelFunctionDO> list); | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,20 +1,28 @@ | ||||
| package cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService; | ||||
| import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | ||||
| import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.*; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Builder; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
|  | ||||
| /** | ||||
|  * IoT 产品物模型功能 DO | ||||
|  * | ||||
|  * <p> | ||||
|  * 每个 {@link IotProductDO} 和 {@link IotThinkModelFunctionDO} 是“一对多”的关系,它的每个属性、事件、服务都对应一条记录 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @TableName("iot_think_model_function") | ||||
| @TableName(value = "iot_think_model_function", autoResultMap = true) | ||||
| @KeySequence("iot_think_model_function_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | ||||
| @Data | ||||
| @Builder | ||||
| @@ -27,35 +35,56 @@ public class IotThinkModelFunctionDO extends BaseDO { | ||||
|      */ | ||||
|     @TableId | ||||
|     private Long id; | ||||
|     // TODO @haohao:是不是有一个 identifier,需要要有哈 | ||||
|     // TODO @haohao:name、description 属性,还有个类型 | ||||
|  | ||||
|     /** | ||||
|      * 功能标识 | ||||
|      */ | ||||
|     private String identifier; | ||||
|     /** | ||||
|      * 功能名称 | ||||
|      */ | ||||
|     private String name; | ||||
|     /** | ||||
|      * 功能描述 | ||||
|      */ | ||||
|     private String description; | ||||
|  | ||||
|     /** | ||||
|      * 产品标识 | ||||
|      * | ||||
|      * <p> | ||||
|      * 关联 {@link IotProductDO#getId()} | ||||
|      */ | ||||
|     private Long productId; | ||||
|     /** | ||||
|      * 产品标识 | ||||
|      * | ||||
|      * <p> | ||||
|      * 关联 {@link IotProductDO#getProductKey()} | ||||
|      */ | ||||
|     private String productKey; | ||||
|  | ||||
|     // TODO @haohao:是不是可以搞成 ThingModelProperty、ThingModelEvent、ThingModelService 进行存储 | ||||
|     /** | ||||
|      * 属性列表 | ||||
|      * 功能类型 | ||||
|      * <p> | ||||
|      * 枚举 {@link cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum} | ||||
|      */ | ||||
|     private String properties; | ||||
|     private Integer type; | ||||
|  | ||||
|     /** | ||||
|      * 服务列表 | ||||
|      * 属性 | ||||
|      */ | ||||
|     private String services; | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private ThingModelProperty property; | ||||
|  | ||||
|     /** | ||||
|      * 事件列表 | ||||
|      * 事件 | ||||
|      */ | ||||
|     private String events; | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private ThingModelEvent event; | ||||
|  | ||||
|     /** | ||||
|      * 服务 | ||||
|      */ | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private ThingModelService service; | ||||
|  | ||||
| } | ||||
| @@ -1,85 +0,0 @@ | ||||
| package cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty; | ||||
| import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | ||||
| import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Builder; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
|  | ||||
| /** | ||||
|  * IoT 产品物模型功能 DO | ||||
|  * | ||||
|  * 每个 {@link IotProductDO} 和 {@link IotThinkModelFunctionDO2} 是“一对多”的关系,它的每个属性、事件、服务都对应一条记录 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @TableName("iot_think_model_function") | ||||
| @KeySequence("iot_think_model_function_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | ||||
| @Data | ||||
| @Builder | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| public class IotThinkModelFunctionDO2 extends BaseDO { | ||||
|  | ||||
|     /** | ||||
|      * 物模型功能编号 | ||||
|      */ | ||||
|     @TableId | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 功能标识 | ||||
|      */ | ||||
|     private String identifier; | ||||
|     /** | ||||
|      * 功能名称 | ||||
|      */ | ||||
|     private String name; | ||||
|     /** | ||||
|      * 功能描述 | ||||
|      */ | ||||
|     private String description; | ||||
|  | ||||
|     /** | ||||
|      * 产品标识 | ||||
|      * | ||||
|      * 关联 {@link IotProductDO#getId()} | ||||
|      */ | ||||
|     private Long productId; | ||||
|     /** | ||||
|      * 产品标识 | ||||
|      * | ||||
|      * 关联 {@link IotProductDO#getProductKey()} | ||||
|      */ | ||||
|     private String productKey; | ||||
|  | ||||
|     /** | ||||
|      * 功能类型 | ||||
|      * | ||||
|      * 1 - 属性 | ||||
|      * 2 - 服务 | ||||
|      * 3 - 事件 | ||||
|      */ | ||||
|     // TODO @haohao:枚举 | ||||
|     private Integer type; | ||||
|  | ||||
|     /** | ||||
|      * 属性 | ||||
|      */ | ||||
|     private ThingModelProperty property; | ||||
|     /** | ||||
|      * 事件 | ||||
|      */ | ||||
|     private ThingModelEvent event; | ||||
|     /** | ||||
|      * 服务 | ||||
|      */ | ||||
|     private String service; | ||||
|  | ||||
| } | ||||
| @@ -5,6 +5,8 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||||
| import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; | ||||
| import org.apache.ibatis.annotations.Mapper; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * IoT 产品物模型 Mapper | ||||
|  * | ||||
| @@ -13,12 +15,17 @@ import org.apache.ibatis.annotations.Mapper; | ||||
| @Mapper | ||||
| public interface IotThinkModelFunctionMapper extends BaseMapperX<IotThinkModelFunctionDO> { | ||||
|  | ||||
|     default IotThinkModelFunctionDO selectByProductKey(String productKey) { | ||||
|         return selectOne(new LambdaQueryWrapperX<IotThinkModelFunctionDO>().eq(IotThinkModelFunctionDO::getProductKey, productKey)); | ||||
|     default IotThinkModelFunctionDO selectByProductIdAndIdentifier(Long productId, String identifier) { | ||||
|         return selectOne(new LambdaQueryWrapperX<IotThinkModelFunctionDO>().eq(IotThinkModelFunctionDO::getProductId, productId) | ||||
|                 .eq(IotThinkModelFunctionDO::getIdentifier, identifier)); | ||||
|     } | ||||
|  | ||||
|     default IotThinkModelFunctionDO selectByProductId(Long productId){ | ||||
|         return selectOne(new LambdaQueryWrapperX<IotThinkModelFunctionDO>().eq(IotThinkModelFunctionDO::getProductId, productId)); | ||||
|     default List<IotThinkModelFunctionDO> selectListByProductId(Long productId) { | ||||
|         return selectList(new LambdaQueryWrapperX<IotThinkModelFunctionDO>().eq(IotThinkModelFunctionDO::getProductId, productId)); | ||||
|     } | ||||
|  | ||||
|     default List<IotThinkModelFunctionDO> selectListByProductIdAndType(Long productId, Integer type) { | ||||
|         return selectList(new LambdaQueryWrapperX<IotThinkModelFunctionDO>().eq(IotThinkModelFunctionDO::getProductId, productId) | ||||
|                 .eq(IotThinkModelFunctionDO::getType, type)); | ||||
|     } | ||||
| } | ||||
| @@ -4,6 +4,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThi | ||||
| import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; | ||||
| import jakarta.validation.Valid; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * IoT 产品物模型 Service 接口 | ||||
|  * | ||||
| @@ -19,6 +21,14 @@ public interface IotThinkModelFunctionService { | ||||
|      */ | ||||
|     Long createThinkModelFunction(@Valid IotThinkModelFunctionSaveReqVO createReqVO); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 更新IoT 产品物模型 | ||||
|      * | ||||
|      * @param updateReqVO 更新信息 | ||||
|      */ | ||||
|     void updateThinkModelFunction(@Valid IotThinkModelFunctionSaveReqVO updateReqVO); | ||||
|  | ||||
|     /** | ||||
|      * 删除IoT 产品物模型 | ||||
|      * | ||||
| @@ -27,25 +37,18 @@ public interface IotThinkModelFunctionService { | ||||
|     void deleteThinkModelFunction(Long id); | ||||
|  | ||||
|     /** | ||||
|      * 获得IoT 产品物模型,通过产品Key | ||||
|      * 获得IoT 产品物模型 | ||||
|      * | ||||
|      * @param productKey 产品Key | ||||
|      * @param id 编号 | ||||
|      * @return IoT 产品物模型 | ||||
|      */ | ||||
|     IotThinkModelFunctionDO getThinkModelFunctionByProductKey(String productKey); | ||||
|     IotThinkModelFunctionDO getThinkModelFunction(Long id); | ||||
|  | ||||
|     /** | ||||
|      * 获得IoT 产品物模型,通过产品ID | ||||
|      * 获得IoT 产品物模型列表 | ||||
|      * | ||||
|      * @param productId 产品ID | ||||
|      * @return IoT 产品物模型 | ||||
|      * @param productId 产品编号 | ||||
|      * @return IoT 产品物模型列表 | ||||
|      */ | ||||
|     IotThinkModelFunctionDO getThinkModelFunctionByProductId(Long productId); | ||||
|  | ||||
|     /** | ||||
|      * 更新IoT 产品物模型 | ||||
|      * | ||||
|      * @param updateReqVO 更新信息 | ||||
|      */ | ||||
|     void updateThinkModelFunction(@Valid IotThinkModelFunctionSaveReqVO updateReqVO); | ||||
|     List<IotThinkModelFunctionDO> getThinkModelFunctionListByProductId(Long productId); | ||||
| } | ||||
| @@ -1,6 +1,9 @@ | ||||
| package cn.iocoder.yudao.module.iot.service.thinkmodelfunction; | ||||
|  | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.*; | ||||
| import cn.iocoder.yudao.framework.common.validation.Telephone; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.dataType.ThingModelArgument; | ||||
| import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.dataType.ThingModelArraySpecs; | ||||
| 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 | ||||
| import cn.iocoder.yudao.module.iot.convert.thinkmodelfunction.IotThinkModelFunctionConvert; | ||||
| import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; | ||||
| import cn.iocoder.yudao.module.iot.dal.mysql.thinkmodelfunction.IotThinkModelFunctionMapper; | ||||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum; | ||||
| import jakarta.annotation.Resource; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||
| import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY; | ||||
| import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER; | ||||
| import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_NOT_EXISTS; | ||||
|  | ||||
| @Slf4j | ||||
| @@ -32,38 +36,83 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe | ||||
|     @Resource | ||||
|     private IotThinkModelFunctionMapper thinkModelFunctionMapper; | ||||
|  | ||||
|     private ObjectMapper objectMapper = new ObjectMapper(); | ||||
|  | ||||
|     @Override | ||||
|     public Long createThinkModelFunction(IotThinkModelFunctionSaveReqVO createReqVO) { | ||||
|         log.info("创建物模型,参数:{}", createReqVO); | ||||
|         // 验证 ProductKey 对应的产品物模型是否已存在 | ||||
|         validateThinkModelFunctionNotExistsByProductKey(createReqVO.getProductKey()); | ||||
|         // 校验功能标识符在同一产品下是否唯一 | ||||
|         validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier()); | ||||
|  | ||||
|         // 转换请求对象为数据对象 | ||||
|         IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(createReqVO); | ||||
|         // 自动生成属性上报事件和属性设置、获取服务 | ||||
|         generateDefaultEventsAndServices(createReqVO, thinkModelFunction); | ||||
|  | ||||
|         // 插入数据库 | ||||
|         thinkModelFunctionMapper.insert(thinkModelFunction); | ||||
|  | ||||
|         // 如果创建的是属性,需要更新默认的事件和服务 | ||||
|         if (Objects.equals(createReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { | ||||
|             generateDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey()); | ||||
|         } | ||||
|  | ||||
|         // 返回生成的 ID | ||||
|         return thinkModelFunction.getId(); | ||||
|     } | ||||
|  | ||||
|     private void validateThinkModelFunctionNotExistsByProductKey(String productKey) { | ||||
|         if (thinkModelFunctionMapper.selectByProductKey(productKey) != null) { | ||||
|             throw exception(THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY); | ||||
|     private void validateIdentifierUnique(Long productId, String identifier) { | ||||
|         IotThinkModelFunctionDO existingFunction = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, identifier); | ||||
|         if (existingFunction != null) { | ||||
|             throw exception(THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void deleteThinkModelFunction(Long id) { | ||||
|         log.info("删除物模型,id:{}", id); | ||||
|         // 校验物模型是否存在 | ||||
|         validateThinkModelFunctionExists(id); | ||||
|         // 删除物模型 | ||||
|         thinkModelFunctionMapper.deleteById(id); | ||||
|     public void updateThinkModelFunction(IotThinkModelFunctionSaveReqVO updateReqVO) { | ||||
|         // 校验功能是否存在 | ||||
|         validateThinkModelFunctionExists(updateReqVO.getId()); | ||||
|  | ||||
|         // 校验功能标识符是否唯一 | ||||
|         validateIdentifierUniqueForUpdate(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier()); | ||||
|  | ||||
|         // 转换请求对象为数据对象 | ||||
|         IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(updateReqVO); | ||||
|  | ||||
|         // 更新数据库 | ||||
|         thinkModelFunctionMapper.updateById(thinkModelFunction); | ||||
|  | ||||
|         // 如果更新的是属性,需要更新默认的事件和服务 | ||||
|         if (Objects.equals(updateReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { | ||||
|             generateDefaultEventsAndServices(updateReqVO.getProductId(), updateReqVO.getProductKey()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) { | ||||
|         IotThinkModelFunctionDO existingFunction = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, identifier); | ||||
|         if (existingFunction != null && !existingFunction.getId().equals(id)) { | ||||
|             throw exception(THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public void deleteThinkModelFunction(Long id) { | ||||
|         // 校验功能是否存在 | ||||
|         IotThinkModelFunctionDO functionDO = thinkModelFunctionMapper.selectById(id); | ||||
|         if (functionDO == null) { | ||||
|             throw exception(THINK_MODEL_FUNCTION_NOT_EXISTS); | ||||
|         } | ||||
|  | ||||
|         // 删除功能 | ||||
|         thinkModelFunctionMapper.deleteById(id); | ||||
|  | ||||
|         // 如果删除的是属性,需要更新默认的事件和服务 | ||||
|         if (Objects.equals(functionDO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { | ||||
|             generateDefaultEventsAndServices(functionDO.getProductId(), functionDO.getProductKey()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 校验功能是否存在 | ||||
|      * | ||||
|      * @param id 功能编号 | ||||
|      */ | ||||
|     private void validateThinkModelFunctionExists(Long id) { | ||||
|         if (thinkModelFunctionMapper.selectById(id) == null) { | ||||
|             throw exception(THINK_MODEL_FUNCTION_NOT_EXISTS); | ||||
| @@ -71,114 +120,49 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public IotThinkModelFunctionDO getThinkModelFunctionByProductKey(String productKey) { | ||||
|         return thinkModelFunctionMapper.selectByProductKey(productKey); | ||||
|     public IotThinkModelFunctionDO getThinkModelFunction(Long id) { | ||||
|         return thinkModelFunctionMapper.selectById(id); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public IotThinkModelFunctionDO getThinkModelFunctionByProductId(Long productId) { | ||||
|         return thinkModelFunctionMapper.selectByProductId(productId); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void updateThinkModelFunction(IotThinkModelFunctionSaveReqVO updateReqVO) { | ||||
|         log.info("更新物模型,参数:{}", updateReqVO); | ||||
|         // 校验物模型是否存在 | ||||
|         validateThinkModelFunctionExists(updateReqVO.getId()); | ||||
|         // 校验 ProductKey 是否唯一 | ||||
|         validateProductKeyUnique(updateReqVO.getId(), updateReqVO.getProductKey()); | ||||
|         // 转换请求对象为数据对象 | ||||
|         IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(updateReqVO); | ||||
|         // 自动生成或更新属性上报事件和属性设置、获取服务 | ||||
|         generateDefaultEventsAndServices(updateReqVO, thinkModelFunction); | ||||
|         // 更新数据库 | ||||
|         thinkModelFunctionMapper.updateById(thinkModelFunction); | ||||
|     } | ||||
|  | ||||
|     private void validateProductKeyUnique(Long id, String productKey) { | ||||
|         IotThinkModelFunctionDO existingFunction = thinkModelFunctionMapper.selectByProductKey(productKey); | ||||
|         if (existingFunction != null && !existingFunction.getId().equals(id)) { | ||||
|             throw exception(THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY); | ||||
|         } | ||||
|     public List<IotThinkModelFunctionDO> getThinkModelFunctionListByProductId(Long productId) { | ||||
|         return thinkModelFunctionMapper.selectListByProductId(productId); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 根据属性列表,自动生成属性上报事件和属性设置、获取服务 | ||||
|      * 生成默认的事件和服务 | ||||
|      */ | ||||
|     private void generateDefaultEventsAndServices(IotThinkModelFunctionSaveReqVO reqVO, IotThinkModelFunctionDO thinkModelFunction) { | ||||
|         // 获取属性列表 | ||||
|         List<ThingModelProperty> properties = reqVO.getProperties(); | ||||
|         if (properties == null) { | ||||
|             properties = new ArrayList<>(); | ||||
|     public void generateDefaultEventsAndServices(Long productId, String productKey) { | ||||
|         // 获取当前产品的所有属性列表 | ||||
|         List<IotThinkModelFunctionDO> propertyList = thinkModelFunctionMapper.selectListByProductIdAndType(productId, IotThingModelTypeEnum.PROPERTY.getType()); | ||||
|  | ||||
|         // 生成属性上报事件 | ||||
|         ThingModelEvent propertyPostEvent = generatePropertyPostEvent(propertyList); | ||||
|         if (propertyPostEvent != null) { | ||||
|             saveOrUpdateEvent(productId, productKey, propertyPostEvent); | ||||
|         } | ||||
|  | ||||
|         // 获取现有的事件和服务 | ||||
|         List<ThingModelEvent> existingEvents = reqVO.getEvents() != null ? new ArrayList<>(reqVO.getEvents()) : new ArrayList<>(); | ||||
|         List<ThingModelService> existingServices = reqVO.getServices() != null ? new ArrayList<>(reqVO.getServices()) : new ArrayList<>(); | ||||
|         // 生成属性设置服务 | ||||
|         ThingModelService propertySetService = generatePropertySetService(propertyList); | ||||
|         if (propertySetService != null) { | ||||
|             saveOrUpdateService(productId, productKey, propertySetService); | ||||
|         } | ||||
|  | ||||
|         // 生成或更新属性上报事件 | ||||
|         ThingModelEvent propertyPostEvent = generatePropertyPostEvent(properties); | ||||
|         updateEventInList(existingEvents, propertyPostEvent); | ||||
|  | ||||
|         // 生成或更新属性设置和获取服务 | ||||
|         ThingModelService propertySetService = generatePropertySetService(properties); | ||||
|         updateServiceInList(existingServices, propertySetService); | ||||
|  | ||||
|         ThingModelService propertyGetService = generatePropertyGetService(properties); | ||||
|         updateServiceInList(existingServices, propertyGetService); | ||||
|  | ||||
|         // 更新 thinkModelFunction 对象的 events 和 services 字段 | ||||
|         try { | ||||
|             thinkModelFunction.setEvents(objectMapper.writeValueAsString(existingEvents)); | ||||
|             thinkModelFunction.setServices(objectMapper.writeValueAsString(existingServices)); | ||||
|         } catch (JsonProcessingException e) { | ||||
|             throw new RuntimeException("序列化事件和服务时发生错误", e); | ||||
|         // 生成属性获取服务 | ||||
|         ThingModelService propertyGetService = generatePropertyGetService(propertyList); | ||||
|         if (propertyGetService != null) { | ||||
|             saveOrUpdateService(productId, productKey, propertyGetService); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 在事件列表中更新或添加事件 | ||||
|      */ | ||||
|     private void updateEventInList(List<ThingModelEvent> events, ThingModelEvent newEvent) { | ||||
|         if (newEvent == null) { | ||||
|             return; | ||||
|         } | ||||
|         for (int i = 0; i < events.size(); i++) { | ||||
|             ThingModelEvent event = events.get(i); | ||||
|             if (event.getIdentifier().equals(newEvent.getIdentifier())) { | ||||
|                 // 更新已有的事件 | ||||
|                 events.set(i, newEvent); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         // 如果不存在,则添加新的事件 | ||||
|         events.add(newEvent); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 在服务列表中更新或添加服务 | ||||
|      */ | ||||
|     private void updateServiceInList(List<ThingModelService> services, ThingModelService newService) { | ||||
|         if (newService == null) { | ||||
|             return; | ||||
|         } | ||||
|         for (int i = 0; i < services.size(); i++) { | ||||
|             ThingModelService service = services.get(i); | ||||
|             if (service.getIdentifier().equals(newService.getIdentifier())) { | ||||
|                 // 更新已有的服务 | ||||
|                 services.set(i, newService); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         // 如果不存在,则添加新的服务 | ||||
|         services.add(newService); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 生成属性上报事件 | ||||
|      */ | ||||
|     private ThingModelEvent generatePropertyPostEvent(List<ThingModelProperty> properties) { | ||||
|     private ThingModelEvent generatePropertyPostEvent(List<IotThinkModelFunctionDO> propertyList) { | ||||
|         if (propertyList == null || propertyList.isEmpty()) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         ThingModelEvent event = new ThingModelEvent(); | ||||
|         event.setIdentifier("post"); | ||||
|         event.setName("属性上报"); | ||||
| @@ -188,7 +172,8 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe | ||||
|  | ||||
|         // 将属性列表转换为事件的输出参数 | ||||
|         List<ThingModelArgument> outputData = new ArrayList<>(); | ||||
|         for (ThingModelProperty property : properties) { | ||||
|         for (IotThinkModelFunctionDO functionDO : propertyList) { | ||||
|             ThingModelProperty property = functionDO.getProperty(); | ||||
|             ThingModelArgument arg = new ThingModelArgument(); | ||||
|             arg.setIdentifier(property.getIdentifier()); | ||||
|             arg.setName(property.getName()); | ||||
| @@ -205,9 +190,14 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe | ||||
|     /** | ||||
|      * 生成属性设置服务 | ||||
|      */ | ||||
|     private ThingModelService generatePropertySetService(List<ThingModelProperty> properties) { | ||||
|     private ThingModelService generatePropertySetService(List<IotThinkModelFunctionDO> propertyList) { | ||||
|         if (propertyList == null || propertyList.isEmpty()) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         List<ThingModelArgument> inputData = new ArrayList<>(); | ||||
|         for (ThingModelProperty property : properties) { | ||||
|         for (IotThinkModelFunctionDO functionDO : propertyList) { | ||||
|             ThingModelProperty property = functionDO.getProperty(); | ||||
|             if ("w".equals(property.getAccessMode()) || "rw".equals(property.getAccessMode())) { | ||||
|                 ThingModelArgument arg = new ThingModelArgument(); | ||||
|                 arg.setIdentifier(property.getIdentifier()); | ||||
| @@ -239,9 +229,14 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe | ||||
|     /** | ||||
|      * 生成属性获取服务 | ||||
|      */ | ||||
|     private ThingModelService generatePropertyGetService(List<ThingModelProperty> properties) { | ||||
|     private ThingModelService generatePropertyGetService(List<IotThinkModelFunctionDO> propertyList) { | ||||
|         if (propertyList == null || propertyList.isEmpty()) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         List<ThingModelArgument> outputData = new ArrayList<>(); | ||||
|         for (ThingModelProperty property : properties) { | ||||
|         for (IotThinkModelFunctionDO functionDO : propertyList) { | ||||
|             ThingModelProperty property = functionDO.getProperty(); | ||||
|             if ("r".equals(property.getAccessMode()) || "rw".equals(property.getAccessMode())) { | ||||
|                 ThingModelArgument arg = new ThingModelArgument(); | ||||
|                 arg.setIdentifier(property.getIdentifier()); | ||||
| @@ -275,10 +270,8 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe | ||||
|         ThingModelArrayType arrayType = new ThingModelArrayType(); | ||||
|         arrayType.setType("array"); | ||||
|         ThingModelArraySpecs arraySpecs = new ThingModelArraySpecs(); | ||||
|         // 不指定数组长度,size 可以为 0 或者省略 | ||||
|         ThingModelTextType textType = new ThingModelTextType(); | ||||
|         textType.setType("text"); | ||||
|         // 如果有需要,可以设置 TextType 的 specs,如长度限制 | ||||
|         arraySpecs.setItem(textType); | ||||
|         arrayType.setSpecs(arraySpecs); | ||||
|  | ||||
| @@ -289,4 +282,54 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe | ||||
|  | ||||
|         return service; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 保存或更新事件 | ||||
|      */ | ||||
|     private void saveOrUpdateEvent(Long productId, String productKey, ThingModelEvent event) { | ||||
|         // 检查是否已存在相同的事件 | ||||
|         IotThinkModelFunctionDO existingEvent = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, event.getIdentifier()); | ||||
|         IotThinkModelFunctionDO functionDO = new IotThinkModelFunctionDO(); | ||||
|         functionDO.setProductId(productId); | ||||
|         functionDO.setProductKey(productKey); | ||||
|         functionDO.setIdentifier(event.getIdentifier()); | ||||
|         functionDO.setName(event.getName()); | ||||
|         functionDO.setDescription(event.getDescription()); | ||||
|         functionDO.setType(IotThingModelTypeEnum.EVENT.getType()); | ||||
|         functionDO.setEvent(event); | ||||
|  | ||||
|         if (existingEvent != null) { | ||||
|             // 更新事件 | ||||
|             functionDO.setId(existingEvent.getId()); | ||||
|             thinkModelFunctionMapper.updateById(functionDO); | ||||
|         } else { | ||||
|             // 创建新的事件 | ||||
|             thinkModelFunctionMapper.insert(functionDO); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 保存或更新事服务 | ||||
|      */ | ||||
|     private void saveOrUpdateService(Long productId, String productKey, ThingModelService service) { | ||||
|         // 检查是否已存在相同的服务 | ||||
|         IotThinkModelFunctionDO existingService = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, service.getIdentifier()); | ||||
|         IotThinkModelFunctionDO functionDO = new IotThinkModelFunctionDO(); | ||||
|         functionDO.setProductId(productId); | ||||
|         functionDO.setProductKey(productKey); | ||||
|         functionDO.setIdentifier(service.getIdentifier()); | ||||
|         functionDO.setName(service.getName()); | ||||
|         functionDO.setDescription(service.getDescription()); | ||||
|         functionDO.setType(IotThingModelTypeEnum.SERVICE.getType()); | ||||
|         functionDO.setService(service); | ||||
|  | ||||
|         if (existingService != null) { | ||||
|             // 更新服务 | ||||
|             functionDO.setId(existingService.getId()); | ||||
|             thinkModelFunctionMapper.updateById(functionDO); | ||||
|         } else { | ||||
|             // 创建新的服务 | ||||
|             thinkModelFunctionMapper.insert(functionDO); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 安浩浩
					安浩浩