diff --git a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java index 5973c4e027..1016e76529 100644 --- a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java +++ b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java @@ -56,4 +56,8 @@ public interface ErrorCodeConstants { ErrorCode RECIPE_POINT_NOT_EXISTS = new ErrorCode(1_003_000_000, "手动配置参数表(绑定配方)不存在"); ErrorCode RECIPE_DEVICE_ATTRIBUTE_NOT_EXISTS = new ErrorCode(1_003_000_000, "配方配置(关联采集设备模型-点位管理)不存在"); + ErrorCode RECIPE_CODE_DUPLICATE = new ErrorCode(1_003_000_004, "编码已存在"); + ErrorCode RECIPE_CODE_EMPTY = new ErrorCode(1_003_000_005, "配方编码不能为空"); + ErrorCode RECIPE_PLAN_DETAIL_NOT_EXISTS = new ErrorCode(1_003_000_006, "配方计划详情表(配方库)不存在"); + } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipe/RecipeController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipe/RecipeController.java index be84fbb309..5ad269f9f6 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipe/RecipeController.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipe/RecipeController.java @@ -71,13 +71,21 @@ public class RecipeController { return success(BeanUtils.toBean(recipe, RecipeRespVO.class)); } - @GetMapping("/page") - @Operation(summary = "获得配方管理主分页") - @PreAuthorize("@ss.hasPermission('iot:recipe:query')") - public CommonResult> getRecipePage(@Valid RecipePageReqVO pageReqVO) { - PageResult pageResult = recipeService.getRecipePage(pageReqVO); - return success(BeanUtils.toBean(pageResult, RecipeRespVO.class)); - } +// @GetMapping("/page") +// @Operation(summary = "获得配方管理主分页") +// @PreAuthorize("@ss.hasPermission('iot:recipe:query')") +// public CommonResult> getRecipePage(@Valid RecipePageReqVO pageReqVO) { +// PageResult pageResult = recipeService.getRecipePage(pageReqVO); +// return success(BeanUtils.toBean(pageResult, RecipeRespVO.class)); +// } +@GetMapping("/page") +@Operation(summary = "获得配方管理主分页") +@PreAuthorize("@ss.hasPermission('iot:recipe:query')") +public CommonResult> getRecipePage(@Valid RecipePageReqVO pageReqVO) { + // 直接调用实现类的方法,无类型转换 + PageResult pageResult = recipeService.getRecipePageWithDeviceId(pageReqVO); + return success(pageResult); +} @GetMapping("/export-excel") @Operation(summary = "导出配方管理主 Excel") diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipe/vo/RecipeRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipe/vo/RecipeRespVO.java index e7d1662619..80dec1c437 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipe/vo/RecipeRespVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipe/vo/RecipeRespVO.java @@ -52,4 +52,8 @@ public class RecipeRespVO { // @ExcelProperty("数据单位") private String dataUnit; + @Schema(description = "关联设备ID", example = "1001") +// @ExcelProperty("关联设备ID") + private Long deviceId; + } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/RecipeDeviceAttributeController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/RecipeDeviceAttributeController.java index eaf6859330..ad41f6fc8b 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/RecipeDeviceAttributeController.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/RecipeDeviceAttributeController.java @@ -45,12 +45,18 @@ public class RecipeDeviceAttributeController { return success(recipeDeviceAttributeService.createRecipeDeviceAttributeBatch(createReqVO)); } +// @PutMapping("/update") +// @Operation(summary = "更新配方配置(关联采集设备模型-点位管理)") +// @PreAuthorize("@ss.hasPermission('iot:recipe-device-attribute:update')") +// public CommonResult updateRecipeDeviceAttribute(@Valid @RequestBody RecipeDeviceAttributeSaveReqVO updateReqVO) { +// recipeDeviceAttributeService.updateRecipeDeviceAttribute(updateReqVO); +// return success(true); +// } @PutMapping("/update") - @Operation(summary = "更新配方配置(关联采集设备模型-点位管理)") - @PreAuthorize("@ss.hasPermission('iot:recipe-device-attribute:update')") - public CommonResult updateRecipeDeviceAttribute(@Valid @RequestBody RecipeDeviceAttributeSaveReqVO updateReqVO) { - recipeDeviceAttributeService.updateRecipeDeviceAttribute(updateReqVO); - return success(true); + @Operation(summary = "更新配方设备属性(先删后增)") + public CommonResult update(@Valid @RequestBody RecipeDeviceAttributeUpdateReqVO reqVO) { + Boolean success = recipeDeviceAttributeService.updateRecipeDeviceAttribute(reqVO); + return success(success); // 返回是否成功(和create接口返回格式一致) } @DeleteMapping("/delete") @@ -71,12 +77,19 @@ public class RecipeDeviceAttributeController { return success(BeanUtils.toBean(recipeDeviceAttribute, RecipeDeviceAttributeRespVO.class)); } +// @GetMapping("/page") +// @Operation(summary = "获得配方配置(关联采集设备模型-点位管理)分页") +// @PreAuthorize("@ss.hasPermission('iot:recipe-device-attribute:query')") +// public CommonResult> getRecipeDeviceAttributePage(@Valid RecipeDeviceAttributePageReqVO pageReqVO) { +// PageResult pageResult = recipeDeviceAttributeService.getRecipeDeviceAttributePage(pageReqVO); +// return success(BeanUtils.toBean(pageResult, RecipeDeviceAttributeRespVO.class)); +// } @GetMapping("/page") - @Operation(summary = "获得配方配置(关联采集设备模型-点位管理)分页") - @PreAuthorize("@ss.hasPermission('iot:recipe-device-attribute:query')") - public CommonResult> getRecipeDeviceAttributePage(@Valid RecipeDeviceAttributePageReqVO pageReqVO) { - PageResult pageResult = recipeDeviceAttributeService.getRecipeDeviceAttributePage(pageReqVO); - return success(BeanUtils.toBean(pageResult, RecipeDeviceAttributeRespVO.class)); + @Operation(summary = "分页查询配方配置") + public CommonResult> page(RecipeDeviceAttributePageReqVO reqVO) { + // 替换为关联查询方法 + PageResult pageResult = recipeDeviceAttributeService.selectPageWithAttribute(reqVO); + return success(pageResult); } @GetMapping("/export-excel") diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/vo/RecipeDeviceAttributePageRespDTO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/vo/RecipeDeviceAttributePageRespDTO.java new file mode 100644 index 0000000000..010f1c73b7 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/vo/RecipeDeviceAttributePageRespDTO.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.iot.controller.admin.recipedeviceattribute.vo; + +import lombok.Data; + +/** + * 配方设备属性分页返回DTO + * + * @author 自定义作者名 + */ +@Data +public class RecipeDeviceAttributePageRespDTO { + + /** + * 主键ID + */ + private Long id; + + + private Long attributeId; + + /** + * 属性名称 + */ + private String attributeName; + + /** + * 属性类型 + */ + private String attributeType; + + /** + * 数据类型 + */ + private String dataType; + + /** + * 数据单位 + */ + private String dataUnit; + + + + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/vo/RecipeDeviceAttributeRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/vo/RecipeDeviceAttributeRespVO.java index e427ad223e..d32851777e 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/vo/RecipeDeviceAttributeRespVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/vo/RecipeDeviceAttributeRespVO.java @@ -44,4 +44,34 @@ public class RecipeDeviceAttributeRespVO { @ExcelProperty("创建时间") private LocalDateTime createTime; -} \ No newline at end of file +} +// +//@Data +//@ExcelIgnoreUnannotated +//public class RecipeDeviceAttributeRespVO { +// // 1. 来自iot_recipe_device_attribute表的主键 +// @Schema(description = "配方配置ID", requiredMode = Schema.RequiredMode.REQUIRED) +// @ExcelProperty("配方配置ID") +// private Long id; +// +// // 2. 来自iot_device_attribute表的关联字段(核心展示字段) +// @Schema(description = "设备属性ID", requiredMode = Schema.RequiredMode.REQUIRED) +// @ExcelProperty("配方配置ID") +// private Long attributeId; // 关联iot_device_attribute.id +// +// @Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED) +// @ExcelProperty("属性名称") +// private String attributeName; // 关联iot_device_attribute.attribute_name +// +// @Schema(description = "属性类型", requiredMode = Schema.RequiredMode.REQUIRED) +// @ExcelProperty("属性类型") +// private String attributeType; // 关联iot_device_attribute.attribute_type +// +// @Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED) +// @ExcelProperty("数据类型") +// private String dataType; // 关联iot_device_attribute.data_type +// +// @Schema(description = "数据单位", requiredMode = Schema.RequiredMode.REQUIRED) +// @ExcelProperty("数据单位") +// private String dataUnit; // 关联iot_device_attribute.data_unit +//} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/vo/RecipeDeviceAttributeUpdateReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/vo/RecipeDeviceAttributeUpdateReqVO.java new file mode 100644 index 0000000000..b8213aa90c --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipedeviceattribute/vo/RecipeDeviceAttributeUpdateReqVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.iot.controller.admin.recipedeviceattribute.vo; + +import lombok.Data; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 配方设备属性更新VO(先删后增) + * + * @author 内蒙必硕 + */ +@Data +public class RecipeDeviceAttributeUpdateReqVO { + + /** 配方ID(必传) */ + @NotNull(message = "配方ID不能为空") + private Long recipeId; + + /** 要关联的attribute_id集合(允许为空,为空则仅删除) */ + private List ids; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/RecipePlanDetailController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/RecipePlanDetailController.java new file mode 100644 index 0000000000..3a9cf8beec --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/RecipePlanDetailController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.iot.controller.admin.recipeplandetail; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.iot.controller.admin.recipeplandetail.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.recipeplandetail.RecipePlanDetailDO; +import cn.iocoder.yudao.module.iot.service.recipeplandetail.RecipePlanDetailService; + +@Tag(name = "管理后台 - 配方计划详情表(配方库)") +@RestController +@RequestMapping("/iot/recipe-plan-detail") +@Validated +public class RecipePlanDetailController { + + @Resource + private RecipePlanDetailService recipePlanDetailService; + + @PostMapping("/create") + @Operation(summary = "创建配方计划详情表(配方库)") + @PreAuthorize("@ss.hasPermission('iot:recipe-plan-detail:create')") + public CommonResult createRecipePlanDetail(@Valid @RequestBody RecipePlanDetailSaveReqVO createReqVO) { + return success(recipePlanDetailService.createRecipePlanDetail(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新配方计划详情表(配方库)") + @PreAuthorize("@ss.hasPermission('iot:recipe-plan-detail:update')") + public CommonResult updateRecipePlanDetail(@Valid @RequestBody RecipePlanDetailSaveReqVO updateReqVO) { + recipePlanDetailService.updateRecipePlanDetail(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除配方计划详情表(配方库)") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('iot:recipe-plan-detail:delete')") + public CommonResult deleteRecipePlanDetail(@RequestParam("id") Long id) { + recipePlanDetailService.deleteRecipePlanDetail(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得配方计划详情表(配方库)") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('iot:recipe-plan-detail:query')") + public CommonResult getRecipePlanDetail(@RequestParam("id") Long id) { + RecipePlanDetailDO recipePlanDetail = recipePlanDetailService.getRecipePlanDetail(id); + return success(BeanUtils.toBean(recipePlanDetail, RecipePlanDetailRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得配方计划详情表(配方库)分页") + @PreAuthorize("@ss.hasPermission('iot:recipe-plan-detail:query')") + public CommonResult> getRecipePlanDetailPage(@Valid RecipePlanDetailPageReqVO pageReqVO) { + PageResult pageResult = recipePlanDetailService.getRecipePlanDetailPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, RecipePlanDetailRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出配方计划详情表(配方库) Excel") + @PreAuthorize("@ss.hasPermission('iot:recipe-plan-detail:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportRecipePlanDetailExcel(@Valid RecipePlanDetailPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = recipePlanDetailService.getRecipePlanDetailPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "配方计划详情表(配方库).xls", "数据", RecipePlanDetailRespVO.class, + BeanUtils.toBean(list, RecipePlanDetailRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/vo/RecipePlanDetailPageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/vo/RecipePlanDetailPageReqVO.java new file mode 100644 index 0000000000..be02b2911d --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/vo/RecipePlanDetailPageReqVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.iot.controller.admin.recipeplandetail.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 = "管理后台 - 配方计划详情表(配方库)分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class RecipePlanDetailPageReqVO extends PageParam { + + @Schema(description = "编码(新建时输入)") + private String code; + + @Schema(description = "名称(新建时输入)", example = "李四") + private String name; + + @Schema(description = "关联配方(关联iot_recipe表的id)", example = "2489") + private Long recipeId; + + @Schema(description = "关联计划(关联mes_plan表的id)", example = "28398") + private Long planId; + + @Schema(description = "来源(新增/生产中)") + private String source; + + @Schema(description = "是否启用") + private Boolean isEnable; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/vo/RecipePlanDetailRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/vo/RecipePlanDetailRespVO.java new file mode 100644 index 0000000000..20f7f315a5 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/vo/RecipePlanDetailRespVO.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.iot.controller.admin.recipeplandetail.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import com.alibaba.excel.annotation.ExcelProperty; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 配方计划详情表(配方库) Response VO") +@Data +public class RecipePlanDetailRespVO { + + @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "19016") + @ExcelProperty("主键ID") + private Long id; + + @Schema(description = "编码(新建时输入)", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("编码(新建时输入)") + private String code; + + @Schema(description = "名称(新建时输入)", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + @ExcelProperty("名称(新建时输入)") + private String name; + + @Schema(description = "关联配方ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2489") + @ExcelProperty("关联配方ID") + private Long recipeId; + + @Schema(description = "配方名称", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("配方名称") + private String recipeName; // 新增关联字段 + + @Schema(description = "关联计划ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "28398") + @ExcelProperty("关联计划ID") + private Long planId; + + @Schema(description = "计划编码", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("计划编码") + private String planCode; // 新增关联字段 + + @Schema(description = "来源(新增/生产中)") + @ExcelProperty("来源(新增/生产中)") + private String source; + + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("是否启用") + private Boolean isEnable; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/vo/RecipePlanDetailSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/vo/RecipePlanDetailSaveReqVO.java new file mode 100644 index 0000000000..fca5e3de42 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/recipeplandetail/vo/RecipePlanDetailSaveReqVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.iot.controller.admin.recipeplandetail.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 配方计划详情表(配方库)新增/修改 Request VO") +@Data +public class RecipePlanDetailSaveReqVO { + + @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "19016") + private Long id; + + @Schema(description = "编码(新建时输入)", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "编码(新建时输入)不能为空") + private String code; + + @Schema(description = "名称(新建时输入)", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + @NotEmpty(message = "名称(新建时输入)不能为空") + private String name; + + @Schema(description = "关联配方(关联iot_recipe表的id)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2489") + @NotNull(message = "关联配方(关联iot_recipe表的id)不能为空") + private Long recipeId; + + @Schema(description = "关联计划(关联mes_plan表的id)", requiredMode = Schema.RequiredMode.REQUIRED, example = "28398") + @NotNull(message = "关联计划(关联mes_plan表的id)不能为空") + private Long planId; + + @Schema(description = "来源(新增/生产中)") + private String source; + + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "是否启用不能为空") + private Boolean isEnable; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/recipedeviceattribute/RecipeDeviceAttributeDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/recipedeviceattribute/RecipeDeviceAttributeDO.java index dd0f3af07e..b861415655 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/recipedeviceattribute/RecipeDeviceAttributeDO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/recipedeviceattribute/RecipeDeviceAttributeDO.java @@ -52,4 +52,5 @@ public class RecipeDeviceAttributeDO extends BaseDO { */ private String dataUnit; + } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/recipeplandetail/RecipePlanDetailDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/recipeplandetail/RecipePlanDetailDO.java new file mode 100644 index 0000000000..fd9f279241 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/recipeplandetail/RecipePlanDetailDO.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.iot.dal.dataobject.recipeplandetail; + +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; + +/** + * 配方计划详情表(配方库) DO + * + * @author 内蒙必硕 + */ +@TableName("iot_recipe_plan_detail") +@KeySequence("iot_recipe_plan_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class RecipePlanDetailDO extends BaseDO { + + /** + * 主键ID + */ + @TableId + private Long id; + /** + * 编码(新建时输入) + */ + private String code; + /** + * 名称(新建时输入) + */ + private String name; + /** + * 关联配方(关联iot_recipe表的id) + */ + private Long recipeId; + /** + * 关联计划(关联mes_plan表的id) + */ + private Long planId; + /** + * 来源(新增/生产中) + */ + private String source; + /** + * 是否启用 + */ + private Boolean isEnable; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/recipeplandetail/RecipePlanDetailWithRelationsDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/recipeplandetail/RecipePlanDetailWithRelationsDO.java new file mode 100644 index 0000000000..c3ccd3bc96 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/recipeplandetail/RecipePlanDetailWithRelationsDO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.iot.dal.dataobject.recipeplandetail; + +import lombok.Data; +import java.time.LocalDateTime; + +/** + * 包含关联信息的配方计划详情DO + */ +@Data +public class RecipePlanDetailWithRelationsDO { + private Long id; + private String code; + private String name; + private Long recipeId; + private String recipeName; // 来自iot_recipe表 + private Long planId; + private String planCode; // 来自mes_plan表 + private String source; + private Boolean isEnable; + private LocalDateTime createTime; +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/recipedeviceattribute/RecipeDeviceAttributeMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/recipedeviceattribute/RecipeDeviceAttributeMapper.java index 6aa3f816a5..c25d80108b 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/recipedeviceattribute/RecipeDeviceAttributeMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/recipedeviceattribute/RecipeDeviceAttributeMapper.java @@ -1,13 +1,53 @@ -package cn.iocoder.yudao.module.iot.dal.mysql.recipedeviceattribute; +//package cn.iocoder.yudao.module.iot.dal.mysql.recipedeviceattribute; +// +//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.recipedeviceattribute.RecipeDeviceAttributeDO; +//import org.apache.ibatis.annotations.Mapper; +//import cn.iocoder.yudao.module.iot.controller.admin.recipedeviceattribute.vo.*; +// +///** +// * 配方配置(关联采集设备模型-点位管理) Mapper +// * +// * @author 内蒙必硕 +// */ +//@Mapper +//public interface RecipeDeviceAttributeMapper extends BaseMapperX { +// +// default PageResult selectPage(RecipeDeviceAttributePageReqVO reqVO) { +// return selectPage(reqVO, new LambdaQueryWrapperX() +// .eqIfPresent(RecipeDeviceAttributeDO::getRecipeId, reqVO.getRecipeId()) +// .eqIfPresent(RecipeDeviceAttributeDO::getAttributeId, reqVO.getAttributeId()) +// .likeIfPresent(RecipeDeviceAttributeDO::getAttributeName, reqVO.getAttributeName()) +// .eqIfPresent(RecipeDeviceAttributeDO::getAttributeType, reqVO.getAttributeType()) +// .eqIfPresent(RecipeDeviceAttributeDO::getDataType, reqVO.getDataType()) +// .eqIfPresent(RecipeDeviceAttributeDO::getDataUnit, reqVO.getDataUnit()) +// .betweenIfPresent(RecipeDeviceAttributeDO::getCreateTime, reqVO.getCreateTime()) +// .orderByDesc(RecipeDeviceAttributeDO::getId)); +// } +// +// +// +//} -import java.util.*; +package cn.iocoder.yudao.module.iot.dal.mysql.recipedeviceattribute; 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.recipedeviceattribute.RecipeDeviceAttributeDO; +import cn.iocoder.yudao.module.iot.controller.admin.recipedeviceattribute.vo.RecipeDeviceAttributePageReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.recipedeviceattribute.vo.RecipeDeviceAttributePageRespDTO; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Mapper; -import cn.iocoder.yudao.module.iot.controller.admin.recipedeviceattribute.vo.*; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; /** * 配方配置(关联采集设备模型-点位管理) Mapper @@ -17,6 +57,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.recipedeviceattribute.vo.*; @Mapper public interface RecipeDeviceAttributeMapper extends BaseMapperX { + // 原有分页方法(保留) default PageResult selectPage(RecipeDeviceAttributePageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() .eqIfPresent(RecipeDeviceAttributeDO::getRecipeId, reqVO.getRecipeId()) @@ -29,4 +70,32 @@ public interface RecipeDeviceAttributeMapper extends BaseMapperX", + "SELECT rda.id, rda.attribute_id, dcm.attribute_name, dcm.attribute_type, dcm.data_type, dcm.data_unit", + "FROM iot_recipe_device_attribute rda", + "LEFT JOIN iot_device_contact_model dcm ON rda.attribute_id = dcm.id", + "WHERE 1=1", + " AND rda.deleted = 0", + "", + " AND rda.recipe_id = #{reqVO.recipeId}", + "", + "", + " AND dcm.attribute_name LIKE CONCAT('%', #{reqVO.attributeName}, '%')", + "", + "ORDER BY rda.id DESC", + "" + }) + List selectPageWithAttribute( + Page page, // 分页参数(由插件自动填充) + @Param("reqVO") RecipeDeviceAttributePageReqVO reqVO); + + // 封装成芋道的PageResult(默认方法,复用框架逻辑) + default PageResult selectPageWithAttributeWrap(RecipeDeviceAttributePageReqVO reqVO) { + Page page = new Page<>(reqVO.getPageNo(), reqVO.getPageSize()); + List list = selectPageWithAttribute(page, reqVO); + return new PageResult<>(list, page.getTotal()); + } + } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/recipeplandetail/RecipePlanDetailMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/recipeplandetail/RecipePlanDetailMapper.java new file mode 100644 index 0000000000..32ca893138 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/recipeplandetail/RecipePlanDetailMapper.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.iot.dal.mysql.recipeplandetail; + +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.recipeplandetail.RecipePlanDetailDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.iot.controller.admin.recipeplandetail.vo.*; + +/** + * 配方计划详情表(配方库) Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface RecipePlanDetailMapper extends BaseMapperX { + + default PageResult selectPage(RecipePlanDetailPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(RecipePlanDetailDO::getCode, reqVO.getCode()) + .likeIfPresent(RecipePlanDetailDO::getName, reqVO.getName()) + .eqIfPresent(RecipePlanDetailDO::getRecipeId, reqVO.getRecipeId()) + .eqIfPresent(RecipePlanDetailDO::getPlanId, reqVO.getPlanId()) + .eqIfPresent(RecipePlanDetailDO::getSource, reqVO.getSource()) + .eqIfPresent(RecipePlanDetailDO::getIsEnable, reqVO.getIsEnable()) + .betweenIfPresent(RecipePlanDetailDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(RecipePlanDetailDO::getId)); + } + + // 新增关联查询分页方法 +// PageResult selectPageWithRelations(@Param("req") RecipePlanDetailPageReqVO reqVO); + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipe/RecipeService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipe/RecipeService.java index 892f1fc80a..e4aab6ea9d 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipe/RecipeService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipe/RecipeService.java @@ -52,4 +52,21 @@ public interface RecipeService { */ PageResult getRecipePage(RecipePageReqVO pageReqVO); + // ========== 新增:声明带deviceId的方法 ========== + /** + * 获得配方管理主分页(包含deviceId字段) + * + * @param pageReqVO 分页查询 + * @return 配方管理主分页(含deviceId) + */ + PageResult getRecipePageWithDeviceId(RecipePageReqVO pageReqVO); + + /** + * 获得单个配方管理主(包含deviceId字段) + * + * @param id 编号 + * @return 配方管理主(含deviceId) + */ + RecipeRespVO getRecipeWithDeviceId(Long id); + } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipe/RecipeServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipe/RecipeServiceImpl.java index 6a4733a301..3cf1757593 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipe/RecipeServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipe/RecipeServiceImpl.java @@ -1,21 +1,129 @@ +//package cn.iocoder.yudao.module.iot.service.recipe; +// +//import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants; +//import org.springframework.stereotype.Service; +//import javax.annotation.Resource; +//import org.springframework.validation.annotation.Validated; +//import org.springframework.transaction.annotation.Transactional; +// +//import java.util.*; +//import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.*; +//import cn.iocoder.yudao.module.iot.dal.dataobject.recipe.RecipeDO; +//import cn.iocoder.yudao.framework.common.pojo.PageResult; +//import cn.iocoder.yudao.framework.common.pojo.PageParam; +//import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +// +//import cn.iocoder.yudao.module.iot.dal.mysql.recipe.RecipeMapper; +//import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper; +// +//import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +//import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; +// +//import cn.iocoder.yudao.framework.common.exception.ServiceException; +//import cn.hutool.core.util.StrUtil; +//import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +//import cn.iocoder.yudao.framework.common.exception.ServiceException; +// +//import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; // 引入现有DeviceDO +//import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper; // 引入现有DeviceMapper +// +///** +// * 配方管理主 Service 实现类 +// * +// * @author 内蒙必硕 +// */ +//@Service +//@Validated +//public class RecipeServiceImpl implements RecipeService { +// +// @Resource +// private RecipeMapper recipeMapper; +// +//// @Override +//// public Long createRecipe(RecipeSaveReqVO createReqVO) { +//// // 插入 +//// RecipeDO recipe = BeanUtils.toBean(createReqVO, RecipeDO.class); +//// recipeMapper.insert(recipe); +//// // 返回 +//// return recipe.getId(); +//// } +//@Override +//public Long createRecipe(RecipeSaveReqVO createReqVO) { +// String recipeCode = createReqVO.getRecipeCode(); +// +// // 1. 校验recipeCode不为空(使用新增的RECIPE_CODE_EMPTY错误码) +// if (StrUtil.isBlank(recipeCode)) { +// throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_EMPTY); +// } +// +// // 2. 校验recipeCode是否重复(使用新增的RECIPE_CODE_DUPLICATE错误码) +// boolean exists = recipeMapper.exists( +// new LambdaQueryWrapperX().eq(RecipeDO::getRecipeCode, recipeCode) +// ); +// if (exists) { +// throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_DUPLICATE); +// } +// +// // ========== 原有逻辑保持不变 ========== +// RecipeDO recipe = BeanUtils.toBean(createReqVO, RecipeDO.class); +// recipeMapper.insert(recipe); +// return recipe.getId(); +//} +// +// @Override +// public void updateRecipe(RecipeSaveReqVO updateReqVO) { +// // 校验存在 +// validateRecipeExists(updateReqVO.getId()); +// // 更新 +// RecipeDO updateObj = BeanUtils.toBean(updateReqVO, RecipeDO.class); +// recipeMapper.updateById(updateObj); +// } +// +// @Override +// public void deleteRecipe(Long id) { +// // 校验存在 +// validateRecipeExists(id); +// // 删除 +// recipeMapper.deleteById(id); +// } +// +// private void validateRecipeExists(Long id) { +// if (recipeMapper.selectById(id) == null) { +// throw exception(RECIPE_NOT_EXISTS); +// } +// } +// +// @Override +// public RecipeDO getRecipe(Long id) { +// return recipeMapper.selectById(id); +// } +// +//} package cn.iocoder.yudao.module.iot.service.recipe; -import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import org.springframework.validation.annotation.Validated; -import org.springframework.transaction.annotation.Transactional; - -import java.util.*; -import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.*; +import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants; +import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipePageReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipeRespVO; +import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipeSaveReqVO; +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.recipe.RecipeDO; +import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper; +import cn.iocoder.yudao.module.iot.dal.mysql.recipe.RecipeMapper; +import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.hutool.core.util.StrUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; -import cn.iocoder.yudao.module.iot.dal.mysql.recipe.RecipeMapper; +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.RECIPE_NOT_EXISTS; /** * 配方管理主 Service 实现类 @@ -28,30 +136,37 @@ public class RecipeServiceImpl implements RecipeService { @Resource private RecipeMapper recipeMapper; + @Resource + private DeviceMapper deviceMapper; // 注入现有DeviceMapper + // ========== 原有方法保持不变 ========== @Override public Long createRecipe(RecipeSaveReqVO createReqVO) { - // 插入 + String recipeCode = createReqVO.getRecipeCode(); + if (StrUtil.isBlank(recipeCode)) { + throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_EMPTY); + } + boolean exists = recipeMapper.exists( + new LambdaQueryWrapperX().eq(RecipeDO::getRecipeCode, recipeCode) + ); + if (exists) { + throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_DUPLICATE); + } RecipeDO recipe = BeanUtils.toBean(createReqVO, RecipeDO.class); recipeMapper.insert(recipe); - // 返回 return recipe.getId(); } @Override public void updateRecipe(RecipeSaveReqVO updateReqVO) { - // 校验存在 validateRecipeExists(updateReqVO.getId()); - // 更新 RecipeDO updateObj = BeanUtils.toBean(updateReqVO, RecipeDO.class); recipeMapper.updateById(updateObj); } @Override public void deleteRecipe(Long id) { - // 校验存在 validateRecipeExists(id); - // 删除 recipeMapper.deleteById(id); } @@ -71,4 +186,65 @@ public class RecipeServiceImpl implements RecipeService { return recipeMapper.selectPage(pageReqVO); } + // ========== 新增带deviceId的方法(改为public,供Controller直接调用) ========== + /** + * 分页查询配方,包含deviceId字段 + */ + public PageResult getRecipePageWithDeviceId(RecipePageReqVO pageReqVO) { + // 1. 查询配方分页数据 + PageResult recipePage = recipeMapper.selectPage(pageReqVO); + List recipeList = recipePage.getList(); + if (recipeList.isEmpty()) { + return PageResult.empty(recipePage.getTotal()); + } + + // 2. 提取所有machineName,批量查询deviceId(避免N+1查询) + List machineNames = recipeList.stream() + .map(RecipeDO::getMachineName) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + + // 调用现有DeviceMapper查询设备名称->ID映射 + List deviceList = deviceMapper.selectList( + new LambdaQueryWrapperX().in(DeviceDO::getDeviceName, machineNames) + ); + // 构建设备名称到ID的映射(处理重复名称,取第一个) + Map deviceName2IdMap = new HashMap<>(); + for (DeviceDO device : deviceList) { + deviceName2IdMap.putIfAbsent(device.getDeviceName(), device.getId()); + } + + // 3. 转换为VO并设置deviceId + List respVOList = new ArrayList<>(); + for (RecipeDO recipe : recipeList) { + RecipeRespVO respVO = BeanUtils.toBean(recipe, RecipeRespVO.class); + // 根据machineName关联设置deviceId + respVO.setDeviceId(deviceName2IdMap.get(recipe.getMachineName())); + respVOList.add(respVO); + } + + return new PageResult<>(respVOList, recipePage.getTotal()); + } + + /** + * 查询单个配方,包含deviceId字段 + */ + public RecipeRespVO getRecipeWithDeviceId(Long id) { + RecipeDO recipe = getRecipe(id); + if (recipe == null) { + return null; + } + RecipeRespVO respVO = BeanUtils.toBean(recipe, RecipeRespVO.class); + // 关联查询deviceId + if (recipe.getMachineName() != null) { + DeviceDO device = deviceMapper.selectOne( + new LambdaQueryWrapperX().eq(DeviceDO::getDeviceName, recipe.getMachineName()) + ); + if (device != null) { + respVO.setDeviceId(device.getId()); + } + } + return respVO; + } } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipedeviceattribute/RecipeDeviceAttributeService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipedeviceattribute/RecipeDeviceAttributeService.java index e6d541dbcd..5be305d89f 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipedeviceattribute/RecipeDeviceAttributeService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipedeviceattribute/RecipeDeviceAttributeService.java @@ -27,7 +27,7 @@ public interface RecipeDeviceAttributeService { * * @param updateReqVO 更新信息 */ - void updateRecipeDeviceAttribute(@Valid RecipeDeviceAttributeSaveReqVO updateReqVO); +// void updateRecipeDeviceAttribute(@Valid RecipeDeviceAttributeSaveReqVO updateReqVO); /** * 删除配方配置(关联采集设备模型-点位管理) @@ -54,4 +54,11 @@ public interface RecipeDeviceAttributeService { Boolean createRecipeDeviceAttributeBatch(RecipeDeviceAttributeSaveReqVO createReqVO); + PageResult selectPageWithAttribute(RecipeDeviceAttributePageReqVO reqVO); + Boolean updateRecipeDeviceAttribute(RecipeDeviceAttributeUpdateReqVO reqVO); + + + + + } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipedeviceattribute/RecipeDeviceAttributeServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipedeviceattribute/RecipeDeviceAttributeServiceImpl.java index a6ce0dc952..60d4d1fee3 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipedeviceattribute/RecipeDeviceAttributeServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipedeviceattribute/RecipeDeviceAttributeServiceImpl.java @@ -24,6 +24,12 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; // 或芋道的Col import java.util.List; import java.util.stream.Collectors; + +import cn.iocoder.yudao.module.iot.controller.admin.recipedeviceattribute.vo.RecipeDeviceAttributePageReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.recipedeviceattribute.vo.RecipeDeviceAttributePageRespDTO; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; + //import cn.iocoder.yudao.framework.common.util.bean.BeanUtils; // 确保BeanUtils的导入正确 /** @@ -74,15 +80,47 @@ public class RecipeDeviceAttributeServiceImpl implements RecipeDeviceAttributeSe return insertSuccess; } - @Override - public void updateRecipeDeviceAttribute(RecipeDeviceAttributeSaveReqVO updateReqVO) { - // 校验存在 - validateRecipeDeviceAttributeExists(updateReqVO.getId()); - // 更新 - RecipeDeviceAttributeDO updateObj = BeanUtils.toBean(updateReqVO, RecipeDeviceAttributeDO.class); - recipeDeviceAttributeMapper.updateById(updateObj); +// @Override +// public void updateRecipeDeviceAttribute(RecipeDeviceAttributeSaveReqVO updateReqVO) { +// // 校验存在 +// validateRecipeDeviceAttributeExists(updateReqVO.getId()); +// // 更新 +// RecipeDeviceAttributeDO updateObj = BeanUtils.toBean(updateReqVO, RecipeDeviceAttributeDO.class); +// recipeDeviceAttributeMapper.updateById(updateObj); +// } +@Override +@Transactional(rollbackFor = Exception.class) // 事务保证原子性 +public Boolean updateRecipeDeviceAttribute(RecipeDeviceAttributeUpdateReqVO reqVO) { + // 1. 非空校验:recipeId不能为空(和create保持一致的校验风格) + if (reqVO.getRecipeId() == null) { + throw new IllegalArgumentException("更新失败:配方ID(recipeId)不能为空"); } + // 步骤1:删除该recipeId下的所有旧记录 + LambdaQueryWrapper deleteWrapper = new LambdaQueryWrapper<>(); + deleteWrapper.eq(RecipeDeviceAttributeDO::getRecipeId, reqVO.getRecipeId()); + recipeDeviceAttributeMapper.delete(deleteWrapper); + + // 步骤2:如果ids不为空,批量创建新记录(复用create的Bean拷贝+流式处理风格) + Boolean insertSuccess = true; // 默认成功(无ids时直接返回成功) + if (!CollectionUtils.isEmpty(reqVO.getIds())) { + List attributeList = reqVO.getIds().stream() + .map(attributeId -> { + // 复用create的Bean拷贝逻辑,保持代码风格一致 + RecipeDeviceAttributeDO attributeDO = BeanUtils.toBean(reqVO, RecipeDeviceAttributeDO.class); + attributeDO.setAttributeId(attributeId); + return attributeDO; + }) + .collect(Collectors.toList()); + + // 复用create的批量插入逻辑,返回插入结果 + insertSuccess = recipeDeviceAttributeMapper.insertBatch(attributeList); + } + + // 返回最终结果(删除必成功,插入结果决定最终返回值) + return insertSuccess; +} + @Override public void deleteRecipeDeviceAttribute(Long id) { // 校验存在 @@ -107,4 +145,9 @@ public class RecipeDeviceAttributeServiceImpl implements RecipeDeviceAttributeSe return recipeDeviceAttributeMapper.selectPage(pageReqVO); } + @Override + public PageResult selectPageWithAttribute(RecipeDeviceAttributePageReqVO reqVO) { + return recipeDeviceAttributeMapper.selectPageWithAttributeWrap(reqVO); + } + } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipeplandetail/RecipePlanDetailService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipeplandetail/RecipePlanDetailService.java new file mode 100644 index 0000000000..428989f463 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipeplandetail/RecipePlanDetailService.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.iot.service.recipeplandetail; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.iot.controller.admin.recipeplandetail.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.recipeplandetail.RecipePlanDetailDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * 配方计划详情表(配方库) Service 接口 + * + * @author 内蒙必硕 + */ +public interface RecipePlanDetailService { + + /** + * 创建配方计划详情表(配方库) + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createRecipePlanDetail(@Valid RecipePlanDetailSaveReqVO createReqVO); + + /** + * 更新配方计划详情表(配方库) + * + * @param updateReqVO 更新信息 + */ + void updateRecipePlanDetail(@Valid RecipePlanDetailSaveReqVO updateReqVO); + + /** + * 删除配方计划详情表(配方库) + * + * @param id 编号 + */ + void deleteRecipePlanDetail(Long id); + + /** + * 获得配方计划详情表(配方库) + * + * @param id 编号 + * @return 配方计划详情表(配方库) + */ + RecipePlanDetailDO getRecipePlanDetail(Long id); + + /** + * 获得配方计划详情表(配方库)分页 + * + * @param pageReqVO 分页查询 + * @return 配方计划详情表(配方库)分页 + */ + PageResult getRecipePlanDetailPage(RecipePlanDetailPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipeplandetail/RecipePlanDetailServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipeplandetail/RecipePlanDetailServiceImpl.java new file mode 100644 index 0000000000..91cdd70aac --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/recipeplandetail/RecipePlanDetailServiceImpl.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.iot.service.recipeplandetail; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.iot.controller.admin.recipeplandetail.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.recipeplandetail.RecipePlanDetailDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.iot.dal.mysql.recipeplandetail.RecipePlanDetailMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; + +/** + * 配方计划详情表(配方库) Service 实现类 + * + * @author 内蒙必硕 + */ +@Service +@Validated +public class RecipePlanDetailServiceImpl implements RecipePlanDetailService { + + @Resource + private RecipePlanDetailMapper recipePlanDetailMapper; + + @Override + public Long createRecipePlanDetail(RecipePlanDetailSaveReqVO createReqVO) { + // 插入 + RecipePlanDetailDO recipePlanDetail = BeanUtils.toBean(createReqVO, RecipePlanDetailDO.class); + recipePlanDetailMapper.insert(recipePlanDetail); + // 返回 + return recipePlanDetail.getId(); + } + + @Override + public void updateRecipePlanDetail(RecipePlanDetailSaveReqVO updateReqVO) { + // 校验存在 + validateRecipePlanDetailExists(updateReqVO.getId()); + // 更新 + RecipePlanDetailDO updateObj = BeanUtils.toBean(updateReqVO, RecipePlanDetailDO.class); + recipePlanDetailMapper.updateById(updateObj); + } + + @Override + public void deleteRecipePlanDetail(Long id) { + // 校验存在 + validateRecipePlanDetailExists(id); + // 删除 + recipePlanDetailMapper.deleteById(id); + } + + private void validateRecipePlanDetailExists(Long id) { + if (recipePlanDetailMapper.selectById(id) == null) { + throw exception(RECIPE_PLAN_DETAIL_NOT_EXISTS); + } + } + + @Override + public RecipePlanDetailDO getRecipePlanDetail(Long id) { + return recipePlanDetailMapper.selectById(id); + } + + @Override + public PageResult getRecipePlanDetailPage(RecipePlanDetailPageReqVO pageReqVO) { + return recipePlanDetailMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/recipeplandetail/RecipePlanDetailMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/recipeplandetail/RecipePlanDetailMapper.xml new file mode 100644 index 0000000000..85f78f994e --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/recipeplandetail/RecipePlanDetailMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file