mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 18:49:06 +08:00 
			
		
		
		
	新增:iot 产品
This commit is contained in:
		
							
								
								
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							| @ -17,12 +17,12 @@ | |||||||
|         <module>yudao-module-infra</module> |         <module>yudao-module-infra</module> | ||||||
|         <module>yudao-module-iot</module> |         <module>yudao-module-iot</module> | ||||||
|         <!--        <module>yudao-module-member</module>--> |         <!--        <module>yudao-module-member</module>--> | ||||||
| <!--        <module>yudao-module-bpm</module>--> |         <module>yudao-module-bpm</module> | ||||||
| <!--        <module>yudao-module-report</module>--> | <!--        <module>yudao-module-report</module>--> | ||||||
| <!--        <module>yudao-module-mp</module>--> | <!--        <module>yudao-module-mp</module>--> | ||||||
| <!--        <module>yudao-module-pay</module>--> | <!--        <module>yudao-module-pay</module>--> | ||||||
| <!--        <module>yudao-module-mall</module>--> | <!--        <module>yudao-module-mall</module>--> | ||||||
| <!--        <module>yudao-module-crm</module>--> |         <module>yudao-module-crm</module> | ||||||
| <!--        <module>yudao-module-erp</module>--> | <!--        <module>yudao-module-erp</module>--> | ||||||
| <!--        <module>yudao-module-ai</module>--> | <!--        <module>yudao-module-ai</module>--> | ||||||
|     </modules> |     </modules> | ||||||
|  | |||||||
| @ -0,0 +1,15 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.enums; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.exception.ErrorCode; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * iot 错误码枚举类 | ||||||
|  |  * <p> | ||||||
|  |  * iot 系统,使用 1-050-000-000 段 | ||||||
|  |  */ | ||||||
|  | public interface ErrorCodeConstants { | ||||||
|  |  | ||||||
|  |     // ========== 产品相关  1-050-001-000 ============ | ||||||
|  |     ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_050_001_000, "产品不存在"); | ||||||
|  |     ErrorCode PRODUCT_IDENTIFICATION_EXISTS = new ErrorCode(1_050_001_001, "产品标识已经存在"); | ||||||
|  | } | ||||||
| @ -0,0 +1,37 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.enums; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||||||
|  | import lombok.AllArgsConstructor; | ||||||
|  | import lombok.Getter; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 产品数据格式枚举类 | ||||||
|  |  * 1. 标准数据格式(JSON)2. 透传/自定义 | ||||||
|  |  */ | ||||||
|  | @AllArgsConstructor | ||||||
|  | @Getter | ||||||
|  | public enum ProductDataFormatEnum implements IntArrayValuable { | ||||||
|  |  | ||||||
|  |     JSON(1, "标准数据格式(JSON)"), | ||||||
|  |     SCRIPT(2, "透传/自定义"); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 类型 | ||||||
|  |      */ | ||||||
|  |     private final Integer type; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 描述 | ||||||
|  |      */ | ||||||
|  |     private final String description; | ||||||
|  |  | ||||||
|  |     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductDataFormatEnum::getType).toArray(); | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int[] array() { | ||||||
|  |         return ARRAYS; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.enums; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 产品设备类型常量 | ||||||
|  |  */ | ||||||
|  | public interface ProductDeviceTypeConstants { | ||||||
|  |  | ||||||
|  |     // ========== 产品设备类型  ============ | ||||||
|  |     String DEVICE = "device"; // 直连设备 | ||||||
|  |     String GATEWAY = "gateway"; // 网关设备 | ||||||
|  |     String GATEWAY_SUB = "gateway_sub"; // 网关子设备 | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.enums; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 产品传输协议类型常量 | ||||||
|  |  */ | ||||||
|  | public interface ProductProtocolTypeConstants { | ||||||
|  |  | ||||||
|  |     // ========== 产品传输协议类型  ============ | ||||||
|  |     String MQTT = "mqtt"; // MQTT | ||||||
|  |     String COAP = "coap"; // COAP | ||||||
|  |     String HTTP = "http"; // HTTP | ||||||
|  |     String HTTPS = "https"; // HTTPS | ||||||
|  | } | ||||||
| @ -0,0 +1,34 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.enums; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||||||
|  | import lombok.AllArgsConstructor; | ||||||
|  | import lombok.Getter; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 产品状态枚举类 | ||||||
|  |  * 禁用 启用 | ||||||
|  |  */ | ||||||
|  | @AllArgsConstructor | ||||||
|  | @Getter | ||||||
|  | public enum ProductStatusEnum implements IntArrayValuable { | ||||||
|  |  | ||||||
|  |     DISABLE(0, "禁用"), | ||||||
|  |     ENABLE(1, "启用"); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 类型 | ||||||
|  |      */ | ||||||
|  |     private final Integer type; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 描述 | ||||||
|  |      */ | ||||||
|  |     private final String description; | ||||||
|  |  | ||||||
|  |     public static final int[] ARRAYS = {1, 2}; | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int[] array() { | ||||||
|  |         return ARRAYS; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -47,6 +47,12 @@ | |||||||
|             <artifactId>yudao-spring-boot-starter-test</artifactId> |             <artifactId>yudao-spring-boot-starter-test</artifactId> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |  | ||||||
|  |         <!-- 工具类相关 --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>cn.iocoder.boot</groupId> | ||||||
|  |             <artifactId>yudao-spring-boot-starter-excel</artifactId> | ||||||
|  |         </dependency> | ||||||
|  |  | ||||||
|         <!-- mqtt --> |         <!-- mqtt --> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.eclipse.paho</groupId> |             <groupId>org.eclipse.paho</groupId> | ||||||
|  | |||||||
| @ -0,0 +1,93 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.controller.admin.product; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||||||
|  | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | ||||||
|  | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.ProductPageReqVO; | ||||||
|  | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.ProductRespVO; | ||||||
|  | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.ProductSaveReqVO; | ||||||
|  | import cn.iocoder.yudao.module.iot.dal.dataobject.product.ProductDO; | ||||||
|  | import cn.iocoder.yudao.module.iot.service.product.ProductService; | ||||||
|  | import io.swagger.v3.oas.annotations.Operation; | ||||||
|  | import io.swagger.v3.oas.annotations.Parameter; | ||||||
|  | import io.swagger.v3.oas.annotations.tags.Tag; | ||||||
|  | import jakarta.annotation.Resource; | ||||||
|  | import jakarta.servlet.http.HttpServletResponse; | ||||||
|  | import jakarta.validation.Valid; | ||||||
|  | import org.springframework.security.access.prepost.PreAuthorize; | ||||||
|  | import org.springframework.validation.annotation.Validated; | ||||||
|  | import org.springframework.web.bind.annotation.*; | ||||||
|  |  | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; | ||||||
|  | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||||
|  |  | ||||||
|  | @Tag(name = "管理后台 - iot 产品") | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/iot/product") | ||||||
|  | @Validated | ||||||
|  | public class ProductController { | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private ProductService productService; | ||||||
|  |  | ||||||
|  |     @PostMapping("/create") | ||||||
|  |     @Operation(summary = "创建产品") | ||||||
|  |     @PreAuthorize("@ss.hasPermission('iot:product:create')") | ||||||
|  |     public CommonResult<Long> createProduct(@Valid @RequestBody ProductSaveReqVO createReqVO) { | ||||||
|  |         return success(productService.createProduct(createReqVO)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PutMapping("/update") | ||||||
|  |     @Operation(summary = "更新产品") | ||||||
|  |     @PreAuthorize("@ss.hasPermission('iot:product:update')") | ||||||
|  |     public CommonResult<Boolean> updateProduct(@Valid @RequestBody ProductSaveReqVO updateReqVO) { | ||||||
|  |         productService.updateProduct(updateReqVO); | ||||||
|  |         return success(true); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @DeleteMapping("/delete") | ||||||
|  |     @Operation(summary = "删除产品") | ||||||
|  |     @Parameter(name = "id", description = "编号", required = true) | ||||||
|  |     @PreAuthorize("@ss.hasPermission('iot:product:delete')") | ||||||
|  |     public CommonResult<Boolean> deleteProduct(@RequestParam("id") Long id) { | ||||||
|  |         productService.deleteProduct(id); | ||||||
|  |         return success(true); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @GetMapping("/get") | ||||||
|  |     @Operation(summary = "获得产品") | ||||||
|  |     @Parameter(name = "id", description = "编号", required = true, example = "1024") | ||||||
|  |     @PreAuthorize("@ss.hasPermission('iot:product:query')") | ||||||
|  |     public CommonResult<ProductRespVO> getProduct(@RequestParam("id") Long id) { | ||||||
|  |         ProductDO product = productService.getProduct(id); | ||||||
|  |         return success(BeanUtils.toBean(product, ProductRespVO.class)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @GetMapping("/page") | ||||||
|  |     @Operation(summary = "获得产品分页") | ||||||
|  |     @PreAuthorize("@ss.hasPermission('iot:product:query')") | ||||||
|  |     public CommonResult<PageResult<ProductRespVO>> getProductPage(@Valid ProductPageReqVO pageReqVO) { | ||||||
|  |         PageResult<ProductDO> pageResult = productService.getProductPage(pageReqVO); | ||||||
|  |         return success(BeanUtils.toBean(pageResult, ProductRespVO.class)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @GetMapping("/export-excel") | ||||||
|  |     @Operation(summary = "导出产品 Excel") | ||||||
|  |     @PreAuthorize("@ss.hasPermission('iot:product:export')") | ||||||
|  |     @ApiAccessLog(operateType = EXPORT) | ||||||
|  |     public void exportProductExcel(@Valid ProductPageReqVO pageReqVO, | ||||||
|  |                                    HttpServletResponse response) throws IOException { | ||||||
|  |         pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); | ||||||
|  |         List<ProductDO> list = productService.getProductPage(pageReqVO).getList(); | ||||||
|  |         // 导出 Excel | ||||||
|  |         ExcelUtils.write(response, "产品.xls", "数据", ProductRespVO.class, | ||||||
|  |                 BeanUtils.toBean(list, ProductRespVO.class)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,58 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.controller.admin.product.vo; | ||||||
|  |  | ||||||
|  | import lombok.*; | ||||||
|  | import java.util.*; | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
|  | import org.springframework.format.annotation.DateTimeFormat; | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||||||
|  |  | ||||||
|  | @Schema(description = "管理后台 - iot 产品分页 Request VO") | ||||||
|  | @Data | ||||||
|  | @EqualsAndHashCode(callSuper = true) | ||||||
|  | @ToString(callSuper = true) | ||||||
|  | public class ProductPageReqVO extends PageParam { | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品名称", example = "李四") | ||||||
|  |     private String name; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品标识") | ||||||
|  |     private String identification; | ||||||
|  |  | ||||||
|  |     @Schema(description = "设备类型:device、gatway、gatway_sub", example = "1") | ||||||
|  |     private String deviceType; | ||||||
|  |  | ||||||
|  |     @Schema(description = "厂商名称", example = "李四") | ||||||
|  |     private String manufacturerName; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品型号") | ||||||
|  |     private String model; | ||||||
|  |  | ||||||
|  |     @Schema(description = "数据格式:1. 标准数据格式(JSON)2. 透传/自定义,脚本解析") | ||||||
|  |     private Integer dataFormat; | ||||||
|  |  | ||||||
|  |     @Schema(description = "设备接入平台的协议类型,默认为MQTT", example = "2") | ||||||
|  |     private String protocolType; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品描述", example = "随便") | ||||||
|  |     private String description; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品状态 (0: 启用, 1: 停用)", example = "2") | ||||||
|  |     private Integer status; | ||||||
|  |  | ||||||
|  |     @Schema(description = "物模型定义") | ||||||
|  |     private String metadata; | ||||||
|  |  | ||||||
|  |     @Schema(description = "消息协议ID") | ||||||
|  |     private Long messageProtocol; | ||||||
|  |  | ||||||
|  |     @Schema(description = "消息协议名称", example = "芋艿") | ||||||
|  |     private String protocolName; | ||||||
|  |  | ||||||
|  |     @Schema(description = "创建时间") | ||||||
|  |     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||||
|  |     private LocalDateTime[] createTime; | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,71 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.controller.admin.product.vo; | ||||||
|  |  | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | import lombok.*; | ||||||
|  | import java.util.*; | ||||||
|  | import org.springframework.format.annotation.DateTimeFormat; | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import com.alibaba.excel.annotation.*; | ||||||
|  |  | ||||||
|  | @Schema(description = "管理后台 - iot 产品 Response VO") | ||||||
|  | @Data | ||||||
|  | @ExcelIgnoreUnannotated | ||||||
|  | public class ProductRespVO { | ||||||
|  |  | ||||||
|  |     @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "778") | ||||||
|  |     @ExcelProperty("编号") | ||||||
|  |     private Long id; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") | ||||||
|  |     @ExcelProperty("产品名称") | ||||||
|  |     private String name; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|  |     @ExcelProperty("产品标识") | ||||||
|  |     private String identification; | ||||||
|  |  | ||||||
|  |     @Schema(description = "设备类型:device、gatway、gatway_sub", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||||||
|  |     @ExcelProperty("设备类型:device、gatway、gatway_sub") | ||||||
|  |     private String deviceType; | ||||||
|  |  | ||||||
|  |     @Schema(description = "厂商名称", example = "李四") | ||||||
|  |     @ExcelProperty("厂商名称") | ||||||
|  |     private String manufacturerName; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品型号") | ||||||
|  |     @ExcelProperty("产品型号") | ||||||
|  |     private String model; | ||||||
|  |  | ||||||
|  |     @Schema(description = "数据格式:1. 标准数据格式(JSON)2. 透传/自定义,脚本解析") | ||||||
|  |     @ExcelProperty("数据格式:1. 标准数据格式(JSON)2. 透传/自定义,脚本解析") | ||||||
|  |     private Integer dataFormat; | ||||||
|  |  | ||||||
|  |     @Schema(description = "设备接入平台的协议类型,默认为MQTT", example = "2") | ||||||
|  |     @ExcelProperty("设备接入平台的协议类型,默认为MQTT") | ||||||
|  |     private String protocolType; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品描述", example = "随便") | ||||||
|  |     @ExcelProperty("产品描述") | ||||||
|  |     private String description; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品状态 (0: 启用, 1: 停用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | ||||||
|  |     @ExcelProperty("产品状态 (0: 启用, 1: 停用)") | ||||||
|  |     private Integer status; | ||||||
|  |  | ||||||
|  |     @Schema(description = "物模型定义", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|  |     @ExcelProperty("物模型定义") | ||||||
|  |     private String metadata; | ||||||
|  |  | ||||||
|  |     @Schema(description = "消息协议ID", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|  |     @ExcelProperty("消息协议ID") | ||||||
|  |     private Long messageProtocol; | ||||||
|  |  | ||||||
|  |     @Schema(description = "消息协议名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") | ||||||
|  |     @ExcelProperty("消息协议名称") | ||||||
|  |     private String protocolName; | ||||||
|  |  | ||||||
|  |     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|  |     @ExcelProperty("创建时间") | ||||||
|  |     private LocalDateTime createTime; | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,54 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.controller.admin.product.vo; | ||||||
|  |  | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | import jakarta.validation.constraints.NotEmpty; | ||||||
|  | import lombok.Data; | ||||||
|  |  | ||||||
|  | @Schema(description = "管理后台 - iot 产品新增/修改 Request VO") | ||||||
|  | @Data | ||||||
|  | public class ProductSaveReqVO { | ||||||
|  |  | ||||||
|  |     @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "778") | ||||||
|  |     private Long id; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "温湿度") | ||||||
|  |     @NotEmpty(message = "产品名称不能为空") | ||||||
|  |     private String name; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品标识", example = "123456") | ||||||
|  |     private String identification; | ||||||
|  |  | ||||||
|  |     @Schema(description = "设备类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "device") | ||||||
|  |     @NotEmpty(message = "设备类型不能为空") | ||||||
|  |     private String deviceType; | ||||||
|  |  | ||||||
|  |     @Schema(description = "数据格式:1. 标准数据格式(JSON)2. 透传/自定义", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||||||
|  |     @NotEmpty(message = "数据格式不能为空") | ||||||
|  |     private Integer dataFormat; | ||||||
|  |  | ||||||
|  |     @Schema(description = "设备接入平台的协议类型,默认为MQTT", requiredMode = Schema.RequiredMode.REQUIRED, example = "mqtt") | ||||||
|  |     @NotEmpty(message = "设备接入平台的协议类型不能为空") | ||||||
|  |     private String protocolType; | ||||||
|  |  | ||||||
|  |     @Schema(description = "厂商名称", example = "电信") | ||||||
|  |     private String manufacturerName; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品型号", example = "wsd-01") | ||||||
|  |     private String model; | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品描述", example = "随便") | ||||||
|  |     private String description; | ||||||
|  |  | ||||||
|  | //    @Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | ||||||
|  | //    private Integer status; | ||||||
|  | // | ||||||
|  | //    @Schema(description = "物模型定义", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|  | //    private String metadata; | ||||||
|  | // | ||||||
|  | //    @Schema(description = "消息协议ID", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|  | //    private Long messageProtocol; | ||||||
|  | // | ||||||
|  | //    @Schema(description = "消息协议名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") | ||||||
|  | //    private String protocolName; | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,79 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.dal.dataobject.product; | ||||||
|  |  | ||||||
|  | import lombok.*; | ||||||
|  | import java.util.*; | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import com.baomidou.mybatisplus.annotation.*; | ||||||
|  | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * iot 产品 DO | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | @TableName("iot_product") | ||||||
|  | @KeySequence("iot_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | ||||||
|  | @Data | ||||||
|  | @EqualsAndHashCode(callSuper = true) | ||||||
|  | @ToString(callSuper = true) | ||||||
|  | @Builder | ||||||
|  | @NoArgsConstructor | ||||||
|  | @AllArgsConstructor | ||||||
|  | public class ProductDO extends BaseDO { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 编号 | ||||||
|  |      */ | ||||||
|  |     @TableId | ||||||
|  |     private Long id; | ||||||
|  |     /** | ||||||
|  |      * 产品名称 | ||||||
|  |      */ | ||||||
|  |     private String name; | ||||||
|  |     /** | ||||||
|  |      * 产品标识 | ||||||
|  |      */ | ||||||
|  |     private String identification; | ||||||
|  |     /** | ||||||
|  |      * 设备类型:device、gatway、gatway_sub | ||||||
|  |      */ | ||||||
|  |     private String deviceType; | ||||||
|  |     /** | ||||||
|  |      * 厂商名称 | ||||||
|  |      */ | ||||||
|  |     private String manufacturerName; | ||||||
|  |     /** | ||||||
|  |      * 产品型号 | ||||||
|  |      */ | ||||||
|  |     private String model; | ||||||
|  |     /** | ||||||
|  |      * 数据格式:1. 标准数据格式(JSON)2. 透传/自定义,脚本解析 | ||||||
|  |      */ | ||||||
|  |     private Integer dataFormat; | ||||||
|  |     /** | ||||||
|  |      * 设备接入平台的协议类型,默认为MQTT | ||||||
|  |      */ | ||||||
|  |     private String protocolType; | ||||||
|  |     /** | ||||||
|  |      * 产品描述 | ||||||
|  |      */ | ||||||
|  |     private String description; | ||||||
|  |     /** | ||||||
|  |      * 产品状态 (0: 启用, 1: 停用) | ||||||
|  |      */ | ||||||
|  |     private Integer status; | ||||||
|  |     /** | ||||||
|  |      * 物模型定义 | ||||||
|  |      */ | ||||||
|  |     private String metadata; | ||||||
|  |     /** | ||||||
|  |      * 消息协议ID | ||||||
|  |      */ | ||||||
|  |     private Long messageProtocol; | ||||||
|  |     /** | ||||||
|  |      * 消息协议名称 | ||||||
|  |      */ | ||||||
|  |     private String protocolName; | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.dal.mysql.product; | ||||||
|  |  | ||||||
|  | import java.util.*; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||||||
|  | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||||||
|  | import cn.iocoder.yudao.module.iot.dal.dataobject.product.ProductDO; | ||||||
|  | import jakarta.validation.constraints.NotEmpty; | ||||||
|  | import org.apache.ibatis.annotations.Mapper; | ||||||
|  | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.*; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * iot 产品 Mapper | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | @Mapper | ||||||
|  | public interface ProductMapper extends BaseMapperX<ProductDO> { | ||||||
|  |  | ||||||
|  |     default PageResult<ProductDO> selectPage(ProductPageReqVO reqVO) { | ||||||
|  |         return selectPage(reqVO, new LambdaQueryWrapperX<ProductDO>() | ||||||
|  |                 .likeIfPresent(ProductDO::getName, reqVO.getName()) | ||||||
|  |                 .eqIfPresent(ProductDO::getIdentification, reqVO.getIdentification()) | ||||||
|  |                 .eqIfPresent(ProductDO::getDeviceType, reqVO.getDeviceType()) | ||||||
|  |                 .likeIfPresent(ProductDO::getManufacturerName, reqVO.getManufacturerName()) | ||||||
|  |                 .eqIfPresent(ProductDO::getModel, reqVO.getModel()) | ||||||
|  |                 .eqIfPresent(ProductDO::getDataFormat, reqVO.getDataFormat()) | ||||||
|  |                 .eqIfPresent(ProductDO::getProtocolType, reqVO.getProtocolType()) | ||||||
|  |                 .eqIfPresent(ProductDO::getDescription, reqVO.getDescription()) | ||||||
|  |                 .eqIfPresent(ProductDO::getStatus, reqVO.getStatus()) | ||||||
|  |                 .eqIfPresent(ProductDO::getMetadata, reqVO.getMetadata()) | ||||||
|  |                 .eqIfPresent(ProductDO::getMessageProtocol, reqVO.getMessageProtocol()) | ||||||
|  |                 .likeIfPresent(ProductDO::getProtocolName, reqVO.getProtocolName()) | ||||||
|  |                 .betweenIfPresent(ProductDO::getCreateTime, reqVO.getCreateTime()) | ||||||
|  |                 .orderByDesc(ProductDO::getId)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     default ProductDO selectByIdentification(String identification){ | ||||||
|  |         return selectOne(new LambdaQueryWrapperX<ProductDO>().eq(ProductDO::getIdentification, identification)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,55 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.service.product; | ||||||
|  |  | ||||||
|  | import java.util.*; | ||||||
|  | import jakarta.validation.*; | ||||||
|  | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.*; | ||||||
|  | import cn.iocoder.yudao.module.iot.dal.dataobject.product.ProductDO; | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * iot 产品 Service 接口 | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | public interface ProductService { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 创建iot 产品 | ||||||
|  |      * | ||||||
|  |      * @param createReqVO 创建信息 | ||||||
|  |      * @return 编号 | ||||||
|  |      */ | ||||||
|  |     Long createProduct(@Valid ProductSaveReqVO createReqVO); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 更新iot 产品 | ||||||
|  |      * | ||||||
|  |      * @param updateReqVO 更新信息 | ||||||
|  |      */ | ||||||
|  |     void updateProduct(@Valid ProductSaveReqVO updateReqVO); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 删除iot 产品 | ||||||
|  |      * | ||||||
|  |      * @param id 编号 | ||||||
|  |      */ | ||||||
|  |     void deleteProduct(Long id); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 获得iot 产品 | ||||||
|  |      * | ||||||
|  |      * @param id 编号 | ||||||
|  |      * @return iot 产品 | ||||||
|  |      */ | ||||||
|  |     ProductDO getProduct(Long id); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 获得iot 产品分页 | ||||||
|  |      * | ||||||
|  |      * @param pageReqVO 分页查询 | ||||||
|  |      * @return iot 产品分页 | ||||||
|  |      */ | ||||||
|  |     PageResult<ProductDO> getProductPage(ProductPageReqVO pageReqVO); | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,95 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.service.product; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.util.IdUtil; | ||||||
|  | import cn.hutool.core.util.StrUtil; | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||||||
|  | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.ProductPageReqVO; | ||||||
|  | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.ProductSaveReqVO; | ||||||
|  | import cn.iocoder.yudao.module.iot.dal.dataobject.product.ProductDO; | ||||||
|  | import cn.iocoder.yudao.module.iot.dal.mysql.product.ProductMapper; | ||||||
|  | import jakarta.annotation.Resource; | ||||||
|  | import jakarta.validation.constraints.NotEmpty; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.validation.annotation.Validated; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||||
|  | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PRODUCT_IDENTIFICATION_EXISTS; | ||||||
|  | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PRODUCT_NOT_EXISTS; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * iot 产品 Service 实现类 | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | @Service | ||||||
|  | @Validated | ||||||
|  | public class ProductServiceImpl implements ProductService { | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private ProductMapper productMapper; | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Long createProduct(ProductSaveReqVO createReqVO) { | ||||||
|  |         // 不传自动生成产品标识 | ||||||
|  |         createIdentification(createReqVO); | ||||||
|  |         // 校验产品标识是否重复 | ||||||
|  |         validateProductIdentification(createReqVO.getIdentification()); | ||||||
|  |         // 插入 | ||||||
|  |         ProductDO product = BeanUtils.toBean(createReqVO, ProductDO.class); | ||||||
|  |         productMapper.insert(product); | ||||||
|  |         // 返回 | ||||||
|  |         return product.getId(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void validateProductIdentification(@NotEmpty(message = "产品标识不能为空") String identification) { | ||||||
|  |         if (productMapper.selectByIdentification(identification) != null) { | ||||||
|  |             throw exception(PRODUCT_IDENTIFICATION_EXISTS); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void createIdentification(ProductSaveReqVO createReqVO) { | ||||||
|  |         if (StrUtil.isNotBlank(createReqVO.getIdentification())) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         // 生成 19 位数字 | ||||||
|  |         createReqVO.setIdentification(String.valueOf(IdUtil.getSnowflake(1, 1).nextId())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void updateProduct(ProductSaveReqVO updateReqVO) { | ||||||
|  |         // 校验存在 | ||||||
|  |         validateProductExists(updateReqVO.getId()); | ||||||
|  |         // 更新 | ||||||
|  |         ProductDO updateObj = BeanUtils.toBean(updateReqVO, ProductDO.class); | ||||||
|  |         productMapper.updateById(updateObj); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void deleteProduct(Long id) { | ||||||
|  |         // 校验存在 | ||||||
|  |         validateProductExists(id); | ||||||
|  |         // 删除 | ||||||
|  |         productMapper.deleteById(id); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void validateProductExists(Long id) { | ||||||
|  |         if (productMapper.selectById(id) == null) { | ||||||
|  |             throw exception(PRODUCT_NOT_EXISTS); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public ProductDO getProduct(Long id) { | ||||||
|  |         return productMapper.selectById(id); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public PageResult<ProductDO> getProductPage(ProductPageReqVO pageReqVO) { | ||||||
|  |         return productMapper.selectPage(pageReqVO); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static void main(String[] args) { | ||||||
|  |         System.out.println(String.valueOf(IdUtil.getSnowflake(1, 1).nextId())); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||||||
|  | <mapper namespace="cn.iocoder.yudao.module.iot.dal.mysql.product.ProductMapper"> | ||||||
|  |  | ||||||
|  |     <!-- | ||||||
|  |         一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。 | ||||||
|  |         无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。 | ||||||
|  |         代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。 | ||||||
|  |         文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ | ||||||
|  |      --> | ||||||
|  |  | ||||||
|  | </mapper> | ||||||
| @ -0,0 +1,178 @@ | |||||||
|  | package cn.iocoder.yudao.module.iot.service.product; | ||||||
|  |  | ||||||
|  | import org.junit.jupiter.api.Disabled; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.springframework.boot.test.mock.mockito.MockBean; | ||||||
|  |  | ||||||
|  | import jakarta.annotation.Resource; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.*; | ||||||
|  | import cn.iocoder.yudao.module.iot.dal.dataobject.product.ProductDO; | ||||||
|  | import cn.iocoder.yudao.module.iot.dal.mysql.product.ProductMapper; | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
|  |  | ||||||
|  | import jakarta.annotation.Resource; | ||||||
|  | import org.springframework.context.annotation.Import; | ||||||
|  | import java.util.*; | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  |  | ||||||
|  | import static cn.hutool.core.util.RandomUtil.*; | ||||||
|  | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; | ||||||
|  | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; | ||||||
|  | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | ||||||
|  | import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; | ||||||
|  | import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; | ||||||
|  | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; | ||||||
|  | import static org.junit.jupiter.api.Assertions.*; | ||||||
|  | import static org.mockito.Mockito.*; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * {@link ProductServiceImpl} 的单元测试类 | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | @Import(ProductServiceImpl.class) | ||||||
|  | public class ProductServiceImplTest extends BaseDbUnitTest { | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private ProductServiceImpl productService; | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private ProductMapper productMapper; | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testCreateProduct_success() { | ||||||
|  |         // 准备参数 | ||||||
|  |         ProductSaveReqVO createReqVO = randomPojo(ProductSaveReqVO.class).setId(null); | ||||||
|  |  | ||||||
|  |         // 调用 | ||||||
|  |         Long productId = productService.createProduct(createReqVO); | ||||||
|  |         // 断言 | ||||||
|  |         assertNotNull(productId); | ||||||
|  |         // 校验记录的属性是否正确 | ||||||
|  |         ProductDO product = productMapper.selectById(productId); | ||||||
|  |         assertPojoEquals(createReqVO, product, "id"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testUpdateProduct_success() { | ||||||
|  |         // mock 数据 | ||||||
|  |         ProductDO dbProduct = randomPojo(ProductDO.class); | ||||||
|  |         productMapper.insert(dbProduct);// @Sql: 先插入出一条存在的数据 | ||||||
|  |         // 准备参数 | ||||||
|  |         ProductSaveReqVO updateReqVO = randomPojo(ProductSaveReqVO.class, o -> { | ||||||
|  |             o.setId(dbProduct.getId()); // 设置更新的 ID | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         // 调用 | ||||||
|  |         productService.updateProduct(updateReqVO); | ||||||
|  |         // 校验是否更新正确 | ||||||
|  |         ProductDO product = productMapper.selectById(updateReqVO.getId()); // 获取最新的 | ||||||
|  |         assertPojoEquals(updateReqVO, product); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testUpdateProduct_notExists() { | ||||||
|  |         // 准备参数 | ||||||
|  |         ProductSaveReqVO updateReqVO = randomPojo(ProductSaveReqVO.class); | ||||||
|  |  | ||||||
|  |         // 调用, 并断言异常 | ||||||
|  |         assertServiceException(() -> productService.updateProduct(updateReqVO), PRODUCT_NOT_EXISTS); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testDeleteProduct_success() { | ||||||
|  |         // mock 数据 | ||||||
|  |         ProductDO dbProduct = randomPojo(ProductDO.class); | ||||||
|  |         productMapper.insert(dbProduct);// @Sql: 先插入出一条存在的数据 | ||||||
|  |         // 准备参数 | ||||||
|  |         Long id = dbProduct.getId(); | ||||||
|  |  | ||||||
|  |         // 调用 | ||||||
|  |         productService.deleteProduct(id); | ||||||
|  |        // 校验数据不存在了 | ||||||
|  |        assertNull(productMapper.selectById(id)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testDeleteProduct_notExists() { | ||||||
|  |         // 准备参数 | ||||||
|  |         Long id = randomLongId(); | ||||||
|  |  | ||||||
|  |         // 调用, 并断言异常 | ||||||
|  |         assertServiceException(() -> productService.deleteProduct(id), PRODUCT_NOT_EXISTS); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 | ||||||
|  |     public void testGetProductPage() { | ||||||
|  |        // mock 数据 | ||||||
|  |        ProductDO dbProduct = randomPojo(ProductDO.class, o -> { // 等会查询到 | ||||||
|  |            o.setName(null); | ||||||
|  |            o.setIdentification(null); | ||||||
|  |            o.setDeviceType(null); | ||||||
|  |            o.setManufacturerName(null); | ||||||
|  |            o.setModel(null); | ||||||
|  |            o.setDataFormat(null); | ||||||
|  |            o.setProtocolType(null); | ||||||
|  |            o.setDescription(null); | ||||||
|  |            o.setStatus(null); | ||||||
|  |            o.setMetadata(null); | ||||||
|  |            o.setMessageProtocol(null); | ||||||
|  |            o.setProtocolName(null); | ||||||
|  |            o.setCreateTime(null); | ||||||
|  |        }); | ||||||
|  |        productMapper.insert(dbProduct); | ||||||
|  |        // 测试 name 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setName(null))); | ||||||
|  |        // 测试 identification 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setIdentification(null))); | ||||||
|  |        // 测试 deviceType 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setDeviceType(null))); | ||||||
|  |        // 测试 manufacturerName 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setManufacturerName(null))); | ||||||
|  |        // 测试 model 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setModel(null))); | ||||||
|  |        // 测试 dataFormat 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setDataFormat(null))); | ||||||
|  |        // 测试 protocolType 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setProtocolType(null))); | ||||||
|  |        // 测试 description 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setDescription(null))); | ||||||
|  |        // 测试 status 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setStatus(null))); | ||||||
|  |        // 测试 metadata 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setMetadata(null))); | ||||||
|  |        // 测试 messageProtocol 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setMessageProtocol(null))); | ||||||
|  |        // 测试 protocolName 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setProtocolName(null))); | ||||||
|  |        // 测试 createTime 不匹配 | ||||||
|  |        productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setCreateTime(null))); | ||||||
|  |        // 准备参数 | ||||||
|  |        ProductPageReqVO reqVO = new ProductPageReqVO(); | ||||||
|  |        reqVO.setName(null); | ||||||
|  |        reqVO.setIdentification(null); | ||||||
|  |        reqVO.setDeviceType(null); | ||||||
|  |        reqVO.setManufacturerName(null); | ||||||
|  |        reqVO.setModel(null); | ||||||
|  |        reqVO.setDataFormat(null); | ||||||
|  |        reqVO.setProtocolType(null); | ||||||
|  |        reqVO.setDescription(null); | ||||||
|  |        reqVO.setStatus(null); | ||||||
|  |        reqVO.setMetadata(null); | ||||||
|  |        reqVO.setMessageProtocol(null); | ||||||
|  |        reqVO.setProtocolName(null); | ||||||
|  |        reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); | ||||||
|  |  | ||||||
|  |        // 调用 | ||||||
|  |        PageResult<ProductDO> pageResult = productService.getProductPage(reqVO); | ||||||
|  |        // 断言 | ||||||
|  |        assertEquals(1, pageResult.getTotal()); | ||||||
|  |        assertEquals(1, pageResult.getList().size()); | ||||||
|  |        assertPojoEquals(dbProduct, pageResult.getList().get(0)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -46,11 +46,11 @@ | |||||||
|         <!--            <version>${revision}</version>--> |         <!--            <version>${revision}</version>--> | ||||||
|         <!--        </dependency>--> |         <!--        </dependency>--> | ||||||
|         <!-- 工作流。默认注释,保证编译速度 --> |         <!-- 工作流。默认注释,保证编译速度 --> | ||||||
|         <!--        <dependency>--> |                 <dependency> | ||||||
|         <!--            <groupId>cn.iocoder.boot</groupId>--> |                     <groupId>cn.iocoder.boot</groupId> | ||||||
|         <!--            <artifactId>yudao-module-bpm-biz</artifactId>--> |                     <artifactId>yudao-module-bpm-biz</artifactId> | ||||||
|         <!--            <version>${revision}</version>--> |                     <version>${revision}</version> | ||||||
|         <!--        </dependency>--> |                 </dependency> | ||||||
|         <!-- 支付服务。默认注释,保证编译速度 --> |         <!-- 支付服务。默认注释,保证编译速度 --> | ||||||
|         <!--        <dependency>--> |         <!--        <dependency>--> | ||||||
|         <!--            <groupId>cn.iocoder.boot</groupId>--> |         <!--            <groupId>cn.iocoder.boot</groupId>--> | ||||||
| @ -88,11 +88,11 @@ | |||||||
|         <!--        </dependency>--> |         <!--        </dependency>--> | ||||||
|  |  | ||||||
|         <!-- CRM 相关模块。默认注释,保证编译速度 --> |         <!-- CRM 相关模块。默认注释,保证编译速度 --> | ||||||
|         <!--        <dependency>--> |                 <dependency> | ||||||
|         <!--            <groupId>cn.iocoder.boot</groupId>--> |                     <groupId>cn.iocoder.boot</groupId> | ||||||
|         <!--            <artifactId>yudao-module-crm-biz</artifactId>--> |                     <artifactId>yudao-module-crm-biz</artifactId> | ||||||
|         <!--            <version>${revision}</version>--> |                     <version>${revision}</version> | ||||||
|         <!--        </dependency>--> |                 </dependency> | ||||||
|  |  | ||||||
|         <!-- ERP 相关模块。默认注释,保证编译速度 --> |         <!-- ERP 相关模块。默认注释,保证编译速度 --> | ||||||
|         <!--        <dependency>--> |         <!--        <dependency>--> | ||||||
|  | |||||||
| @ -174,6 +174,7 @@ logging: | |||||||
|     cn.iocoder.yudao.module.statistics.dal.mysql: debug |     cn.iocoder.yudao.module.statistics.dal.mysql: debug | ||||||
|     cn.iocoder.yudao.module.crm.dal.mysql: debug |     cn.iocoder.yudao.module.crm.dal.mysql: debug | ||||||
|     cn.iocoder.yudao.module.erp.dal.mysql: debug |     cn.iocoder.yudao.module.erp.dal.mysql: debug | ||||||
|  |     cn.iocoder.yudao.module.iot.dal.mysql: debug | ||||||
|     org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示 |     org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示 | ||||||
|  |  | ||||||
| debug: false | debug: false | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 安浩浩
					安浩浩