diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/cropfarmingcenter/vo/FarmingRecordCreateReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/cropfarmingcenter/vo/FarmingRecordCreateReqVO.java index 2251ad7f..17d1e42f 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/cropfarmingcenter/vo/FarmingRecordCreateReqVO.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/cropfarmingcenter/vo/FarmingRecordCreateReqVO.java @@ -64,40 +64,4 @@ public class FarmingRecordCreateReqVO { @Schema(description = "租户id", example = "23744") private String tenantId; -// @Schema(description = "投入品列表") -// private List investGoodsList; -// -// @Schema(description = "投入品项目") -// @Data -// public static class InvestGoodsItem { -// @Schema(description = "投入品ID") -// private String inputsId; -// -// @Schema(description = "资产类型") -// private String assetType; -// -// @Schema(description = "用量") -// private BigDecimal dose; -// -// @Schema(description = "单位") -// private String unit; -// -// @Schema(description = "包装单位") -// private String packageUnit; -// -// @Schema(description = "稀释") -// private String diluted; -// -// @Schema(description = "用法") -// private String usage; -// -// @Schema(description = "投入品名称") -// private String inputsName; -// -// @Schema(description = "单位名称") -// private String unitName; -// -// @Schema(description = "包装单位名称") -// private String packageUnitName; -// } } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/dto/FrCreateEvent.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/dto/FrCreateEvent.java new file mode 100644 index 00000000..fd6a50a1 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/dto/FrCreateEvent.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.farm.event.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 创建农事记录 + * @author: binda + * @date: 2025/11/11 15:10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FrCreateEvent { + private String planId; +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/dto/GridBuildEvent.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/dto/GridBuildEvent.java index 0eb132ff..b957540c 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/dto/GridBuildEvent.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/dto/GridBuildEvent.java @@ -14,8 +14,8 @@ import lombok.NoArgsConstructor; @NoArgsConstructor public class GridBuildEvent { - String planNumber; - String plotCode; + private String planNumber; // 生产计划 唯一编号 + private String plotCode; // 地块编号 private Integer plannedQuantity; // 计划数量 private Integer remainingQuantity; // 剩余数量 private Integer totalQuantity; // 总数 diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/listeners/EventListeners.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/listeners/EventListeners.java index 24ce55f3..f60446ee 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/listeners/EventListeners.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/listeners/EventListeners.java @@ -4,8 +4,10 @@ import cn.hutool.core.util.IdUtil; import cn.iocoder.yudao.module.farm.dal.dataobject.plotinfo.PlotInfoDO; import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanUsedGridDO; import cn.iocoder.yudao.module.farm.dal.mysql.productionplan.ProductionPlanUsedGridMapper; +import cn.iocoder.yudao.module.farm.event.dto.FrCreateEvent; import cn.iocoder.yudao.module.farm.event.dto.GridBuildEvent; import cn.iocoder.yudao.module.farm.event.utils.GridCodeGenerator; +import cn.iocoder.yudao.module.farm.manager.perductionplan.ProductionPlanManager; import cn.iocoder.yudao.module.farm.service.plotinfo.PlotInfoService; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; @@ -21,41 +23,53 @@ import java.util.List; @Component public class EventListeners { + private final ProductionPlanManager productionPlanManager; private final PlotInfoService plotInfoService; private final ProductionPlanUsedGridMapper productionPlanUsedGridMapper; - public EventListeners(PlotInfoService plotInfoService, ProductionPlanUsedGridMapper productionPlanUsedGridMapper) { + public EventListeners(ProductionPlanManager productionPlanManager, PlotInfoService plotInfoService, ProductionPlanUsedGridMapper productionPlanUsedGridMapper) { + this.productionPlanManager = productionPlanManager; this.plotInfoService = plotInfoService; this.productionPlanUsedGridMapper = productionPlanUsedGridMapper; } + @Async + @EventListener + public void createFarmRecord(FrCreateEvent dto) { + + productionPlanManager.autoGenerateFarmRecord(dto.getPlanId()); + + } + @Async @EventListener public void buildGrid(GridBuildEvent dto) { + String planNumber = dto.getPlanNumber(); String plotCode = dto.getPlotCode(); - int plannedQuantity = dto.getPlannedQuantity(); // 计划数量 + int plannedQuantity = dto.getPlannedQuantity(); // 计划数量 int remainingQuantity = dto.getRemainingQuantity(); // 剩余数量 - int totalQuantity = dto.getTotalQuantity(); // 总数 + int totalQuantity = dto.getTotalQuantity(); // 总数 PlotInfoDO plotInfo = plotInfoService.getPlotInfo(plotCode); + // 生产网箱编码 List gridCodeRespVOS = GridCodeGenerator.generateGridCodes( totalQuantity, plannedQuantity, remainingQuantity, plotCode); - List list = gridCodeRespVOS.stream().map(e -> { - return new ProductionPlanUsedGridDO( - IdUtil.fastUUID(), - planNumber, - plotInfo.getBaseId(), - plotInfo.getId(), - plotInfo.getPlotId(), - e.getGridCode() - ); - }).toList(); + List list = gridCodeRespVOS.stream().map(e -> + new ProductionPlanUsedGridDO( + IdUtil.fastUUID(), + planNumber, + plotInfo.getBaseId(), + plotInfo.getId(), + plotInfo.getPlotId(), + e.getGridCode() + ) + ).toList(); productionPlanUsedGridMapper.insertBatch(list); } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/publisher/FarmRecordEventPublisher.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/publisher/FarmRecordEventPublisher.java new file mode 100644 index 00000000..39e95a27 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/publisher/FarmRecordEventPublisher.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.farm.event.publisher; + +import cn.iocoder.yudao.module.farm.event.dto.FrCreateEvent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Component; + +/** + * @description: 农事记录 事件 + * @author: binda + * @date: 2025/11/11 15:09 + */ +@Component +public class FarmRecordEventPublisher { + + @Autowired + private ApplicationEventPublisher eventPublisher; + + public void createFarmRecord(String planId) { + eventPublisher.publishEvent(new FrCreateEvent(planId)); + } + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/publisher/GridEventPublisher.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/publisher/GridEventPublisher.java index 9fc898f5..8064062f 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/publisher/GridEventPublisher.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/event/publisher/GridEventPublisher.java @@ -8,7 +8,7 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; /** - * @description: + * @description: 养殖类 网箱事件 * @author: binda * @date: 2025/11/10 16:10 */ @@ -25,8 +25,8 @@ public class GridEventPublisher { */ public void buildGrid(ProductionPlanRespVO updateReqVO) { - String planNumber = updateReqVO.getPlanNumber(); String plotCode = updateReqVO.getPlotId(); + String planNumber = updateReqVO.getPlanNumber(); // 总数 int totalQuantity = updateReqVO.getPlotGridNumber(); @@ -35,7 +35,8 @@ public class GridEventPublisher { // 剩余数量 int remainingQuantity = productionPlanService.getPredictedGridNumber(plotCode,totalQuantity); - eventPublisher.publishEvent(new GridBuildEvent(planNumber,plotCode,plannedQuantity, remainingQuantity, totalQuantity)); + eventPublisher.publishEvent(new GridBuildEvent(planNumber, plotCode, plannedQuantity, remainingQuantity, totalQuantity)); + } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/job/FarmingRecordJob.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/job/FarmingRecordJob.java index 07d61a92..676bcebd 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/job/FarmingRecordJob.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/job/FarmingRecordJob.java @@ -5,9 +5,8 @@ import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; import cn.iocoder.yudao.module.farm.controller.admin.cropfarmingcenter.vo.FarmingRecordSaveReqVO; import cn.iocoder.yudao.module.farm.dal.dataobject.modelfarmingoperation.ModelFarmingOperationDO; import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanDO; +import cn.iocoder.yudao.module.farm.manager.perductionplan.ProductionPlanManager; import cn.iocoder.yudao.module.farm.service.farmingrecord.FarmingRecordService; -import cn.iocoder.yudao.module.farm.service.inputlibrary.InputUsageRecordsService; -import cn.iocoder.yudao.module.farm.service.inputlibrary.InputsService; import cn.iocoder.yudao.module.farm.service.modelmanagement.ModelManagementService; import cn.iocoder.yudao.module.farm.service.productionplan.ProductionPlanService; import lombok.extern.slf4j.Slf4j; @@ -37,104 +36,101 @@ import static cn.iocoder.yudao.module.farm.enums.CommonConstants.*; @Slf4j public class FarmingRecordJob implements JobHandler { - private final ProductionPlanService productionPlanService; - private final FarmingRecordService farmingRecordService; - private final ModelManagementService modelManagementService; + private final ProductionPlanManager productionPlanManager; - public FarmingRecordJob(ProductionPlanService productionPlanService, FarmingRecordService farmingRecordService, ModelManagementService modelManagementService) { - this.productionPlanService = productionPlanService; - this.farmingRecordService = farmingRecordService; - this.modelManagementService = modelManagementService; + public FarmingRecordJob(ProductionPlanManager productionPlanManager) { + this.productionPlanManager = productionPlanManager; } @Override public String execute(String param) throws Exception { - List list = this.insertRecordHandler(); - for (FarmingRecordSaveReqVO e : list) { - List taskTime = e.getTaskTime(); - if (taskTime.size() != 2) { - continue; - } - - LocalDate today = LocalDate.now(); - LocalDate startDate = LocalDate.parse(taskTime.get(0)); - LocalDate endDate = LocalDate.parse(taskTime.get(1)); - boolean isStartToday = startDate.isEqual(today); - boolean isEndToday = endDate.isEqual(today); - - if (isStartToday) { - // 开始日期在今天 - e.setTaskStatus(FARMING_RECORD_STATUS_1); - farmingRecordService.createFarmingRecordForJob(e); - } - if (isEndToday) { - // 结束日期在今天 - e.setTaskStatus(FARMING_RECORD_STATUS_2); - farmingRecordService.updateFarmingRecord(e); - } - } + productionPlanManager.autoUpdateFarmRecordStatus(); +// List list = this.insertRecordHandler(); +// for (FarmingRecordSaveReqVO e : list) { +// List taskTime = e.getTaskTime(); +// if (taskTime.size() != 2) { +// continue; +// } +// +// LocalDate today = LocalDate.now(); +// LocalDate startDate = LocalDate.parse(taskTime.get(0)); +// LocalDate endDate = LocalDate.parse(taskTime.get(1)); +// boolean isStartToday = startDate.isEqual(today); +// boolean isEndToday = endDate.isEqual(today); +// +// if (isStartToday) { +// // 开始日期在今天 +// e.setTaskStatus(FARMING_RECORD_STATUS_1); +// farmingRecordService.createFarmingRecordForJob(e); +// } +// if (isEndToday) { +// // 结束日期在今天 +// e.setTaskStatus(FARMING_RECORD_STATUS_2); +// farmingRecordService.updateFarmingRecord(e); +// } +// } return "success"; } - private List insertRecordHandler() { - // 获取[进行中]状态的计划 - List plans = productionPlanService.getProductionPlans(); - Map planMap = plans.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).collect(Collectors.toMap(ProductionPlanDO::getId, e -> e, (v1, v2) -> v1)); - List taskIdList = plans.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).map(ProductionPlanDO::getId).collect(Collectors.toList()); - - // 获取引用模型集合 key: modelId; - Map> modelIdMap = modelManagementService.getRecordList(taskIdList); - - List farmingRecordSaveReqVOList = new ArrayList<>(); - for (Map.Entry> en : modelIdMap.entrySet()) { - String modelId = en.getKey(); - List operationList = en.getValue(); - - for (ModelFarmingOperationDO e : operationList) { - farmingRecordSaveReqVOList.add(this.buildFarmingRecord(planMap.get(modelId), e)); - } - } - return farmingRecordSaveReqVOList; - } - - - private FarmingRecordSaveReqVO buildFarmingRecord(ProductionPlanDO p, ModelFarmingOperationDO e) { - LocalDate productionStartDate = p.getProductionStartDate(); - // 从第startingPeriod天开始 - Integer startingPeriod = e.getStartingPeriod(); - // 用时天数 - Integer used = e.getUsed(); - // 农事记录开始日期 - LocalDate startDate = productionStartDate.plusDays(startingPeriod-1); - // 农事记录结束日期 - LocalDate endDate = startDate.plusDays(used); -// String taskTime = startDate + "," + endDate; - List taskTime = Arrays.asList(startDate.toString(), endDate.toString()); - - FarmingRecordSaveReqVO saveObj = new FarmingRecordSaveReqVO(); - saveObj.setTaskType(e.getFarmingId()); - saveObj.setTaskName(e.getFarmingName()); - saveObj.setTaskScope(p.getPlanNumber()); - saveObj.setTaskTime(taskTime); - saveObj.setTaskStartDate(startDate); - saveObj.setTaskEndDate(endDate); - saveObj.setProductionPlanId(p.getId()); - saveObj.setModelFarmingOperationId(e.getId()); - saveObj.setExecutor("系统"); - saveObj.setActualLaborCost(e.getUsed()); - saveObj.setFeedbackNotes(e.getDescription()); - saveObj.setFeedbackImageUrl(""); - saveObj.setFeedbackImageUrlList(e.getSketchList()); - saveObj.setBaseId(p.getBaseId()); - saveObj.setBaseName(p.getBaseName()); - saveObj.setPlotId(p.getPlotId()); - saveObj.setPlotName(p.getPlotName()); - saveObj.setTenantId(p.getTenantId()); - saveObj.setModelFarmingOperationId(e.getId()); - saveObj.setInputsIds(e.getInputsIds()); - - return saveObj; - } +// private List insertRecordHandler() { +// // 获取[进行中]状态的计划 +// List plans = productionPlanService.getProductionPlans(); +// Map planMap = plans.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).collect(Collectors.toMap(ProductionPlanDO::getSpeciesModelId, e -> e, (v1, v2) -> v1)); +// List taskIdList = plans.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).map(ProductionPlanDO::getId).collect(Collectors.toList()); +// +// // 获取引用模型集合 key: modelId; +// Map> modelIdMap = modelManagementService.getRecordList(taskIdList); +// +// List farmingRecordSaveReqVOList = new ArrayList<>(); +// for (Map.Entry> en : modelIdMap.entrySet()) { +// String modelId = en.getKey(); +// List operationList = en.getValue(); +// +// for (ModelFarmingOperationDO e : operationList) { +// farmingRecordSaveReqVOList.add(this.buildFarmingRecord(planMap.get(modelId), e)); +// } +// } +// return farmingRecordSaveReqVOList; +// } +// +// +// private FarmingRecordSaveReqVO buildFarmingRecord(ProductionPlanDO p, ModelFarmingOperationDO e) { +// LocalDate productionStartDate = p.getProductionStartDate(); +// // 从第startingPeriod天开始 +// Integer startingPeriod = e.getStartingPeriod(); +// // 用时天数 +// Integer used = e.getUsed(); +// // 农事记录开始日期 +// LocalDate startDate = productionStartDate.plusDays(startingPeriod-1); +// // 农事记录结束日期 +// LocalDate endDate = startDate.plusDays(used); +//// String taskTime = startDate + "," + endDate; +// List taskTime = Arrays.asList(startDate.toString(), endDate.toString()); +// +// FarmingRecordSaveReqVO saveObj = new FarmingRecordSaveReqVO(); +// saveObj.setTaskType(e.getFarmingId()); +// saveObj.setTaskName(e.getFarmingName()); +// saveObj.setTaskScope(p.getPlanNumber()); +// saveObj.setTaskTime(taskTime); +// saveObj.setTaskStartDate(startDate); +// saveObj.setTaskEndDate(endDate); +// saveObj.setProductionPlanId(p.getId()); +// saveObj.setModelFarmingOperationId(e.getId()); +// saveObj.setExecutor("系统"); +// saveObj.setActualLaborCost(e.getUsed()); +// saveObj.setFeedbackNotes(e.getDescription()); +// saveObj.setFeedbackImageUrl(""); +// saveObj.setFeedbackImageUrlList(e.getSketchList()); +// saveObj.setBaseId(p.getBaseId()); +// saveObj.setBaseName(p.getBaseName()); +// saveObj.setPlotId(p.getPlotId()); +// saveObj.setPlotName(p.getPlotName()); +// saveObj.setTenantId(p.getTenantId()); +// saveObj.setModelFarmingOperationId(e.getId()); +// saveObj.setInputsIds(e.getInputsIds()); +// saveObj.setTaskStatus(FARMING_RECORD_STATUS_1); +// return saveObj; +// } } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/perductionplan/ProductionPlanManager.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/perductionplan/ProductionPlanManager.java new file mode 100644 index 00000000..3466dd94 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/manager/perductionplan/ProductionPlanManager.java @@ -0,0 +1,127 @@ +package cn.iocoder.yudao.module.farm.manager.perductionplan; + +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.farm.controller.admin.cropfarmingcenter.vo.FarmingRecordSaveReqVO; +import cn.iocoder.yudao.module.farm.dal.dataobject.farmingrecord.FarmingRecordDO; +import cn.iocoder.yudao.module.farm.dal.dataobject.modelfarmingoperation.ModelFarmingOperationDO; +import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanDO; +import cn.iocoder.yudao.module.farm.enums.CommonConstants; +import cn.iocoder.yudao.module.farm.service.farmingrecord.FarmingRecordService; +import cn.iocoder.yudao.module.farm.service.messagecenter.MessageCenterService; +import cn.iocoder.yudao.module.farm.service.modelmanagement.ModelManagementService; +import cn.iocoder.yudao.module.farm.service.productionplan.ProductionPlanService; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static cn.iocoder.yudao.module.farm.enums.CommonConstants.FARMING_RECORD_STATUS_1; +import static cn.iocoder.yudao.module.farm.enums.CommonConstants.FARMING_RECORD_STATUS_2; + +/** + * @description: 生产计划, 农事计划 + * @author: binda + * @date: 2025/11/11 14:50 + */ +@Service +public class ProductionPlanManager { + + private final ProductionPlanService productionPlanService; + private final FarmingRecordService farmingRecordService; + private final ModelManagementService modelManagementService; + private final MessageCenterService messageCenterService; + + public ProductionPlanManager(ProductionPlanService productionPlanService, FarmingRecordService farmingRecordService, ModelManagementService modelManagementService, MessageCenterService messageCenterService) { + this.productionPlanService = productionPlanService; + this.farmingRecordService = farmingRecordService; + this.modelManagementService = modelManagementService; + this.messageCenterService = messageCenterService; + } + + /** + * 定时任务 创建农事记录: + * 1. 由用户自定义 + * 2. 由系统生成 (本方法) (从模型中获取农事记录) + * + * @param planId + */ + public void autoGenerateFarmRecord(String planId) { + + // 生产计划 + ProductionPlanDO planObj = productionPlanService.getProductionPlan(planId); + + // 模型管理 + List allOperations = modelManagementService.getRecordList(planId); + + // 创建农事记录 + farmingRecordService.createFarmingRecordByModel(planObj, allOperations); + + } + + /** + * 定时任务 刷新农事记录状态: + * 未开始 -> 开始状态 + * 开始 -> 结束 + */ + public void autoUpdateFarmRecordStatus() { + + Map> statusGroups = farmingRecordService.getFarmingRecordListByState(); + + this.isStartToday(statusGroups); + this.isEndToday(statusGroups); + + } + + /** + * 将开始日期在今天之前的的记录 状态修改为: 开始 + * + * @param statusGroups + */ + private void isStartToday(Map> statusGroups) { + List notStartedList = statusGroups.get(CommonConstants.FARMING_RECORD_STATUS_0); // 未开始组 + LocalDate today = LocalDate.now(); + + for (FarmingRecordDO e : notStartedList) { + LocalDate taskStartDate = e.getTaskStartDate(); + + boolean isStartToday = taskStartDate.isBefore(today) || taskStartDate.equals(today); + if (!isStartToday) { + continue; + } + + e.setTaskStatus(FARMING_RECORD_STATUS_1); + farmingRecordService.updateFarmingRecord(BeanUtils.toBean(e, FarmingRecordSaveReqVO.class)); + + // TODO: 2025/11/11 推送系统消息 + + } + } + + /** + * 将结束日期在今天之前的记录 状态修改为: 结束 + * + * @param statusGroups + */ + private void isEndToday(Map> statusGroups) { + List startedList = statusGroups.get(CommonConstants.FARMING_RECORD_STATUS_1); // 开始组 + LocalDate today = LocalDate.now(); + + for (FarmingRecordDO e : startedList) { + LocalDate taskEndDate = e.getTaskEndDate(); + boolean isEndToday = taskEndDate.isBefore(today) || taskEndDate.equals(today); + + if (!isEndToday) { + continue; + } + + e.setTaskStatus(FARMING_RECORD_STATUS_2); + farmingRecordService.updateFarmingRecord(BeanUtils.toBean(e, FarmingRecordSaveReqVO.class)); + + // TODO: 2025/11/11 推送系统消息 + + } + } + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/cropFarmingCenter/CropFarmingCenterServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/cropFarmingCenter/CropFarmingCenterServiceImpl.java index 79e33296..7341abb1 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/cropFarmingCenter/CropFarmingCenterServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/cropFarmingCenter/CropFarmingCenterServiceImpl.java @@ -34,6 +34,7 @@ import cn.iocoder.yudao.module.farm.dal.mysql.productionplan.ProductionPlanMappe import cn.iocoder.yudao.module.farm.dal.mysql.productionplan.ProductionPlanUsedGridMapper; import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMapper; import cn.iocoder.yudao.module.farm.enums.CommonConstants; +import cn.iocoder.yudao.module.farm.event.publisher.FarmRecordEventPublisher; import cn.iocoder.yudao.module.farm.event.publisher.GridEventPublisher; import cn.iocoder.yudao.module.farm.service.farmingnamemaintenance.FarmingNameMaintenanceService; import cn.iocoder.yudao.module.farm.service.farmingrecord.FarmingRecordService; @@ -93,13 +94,15 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService { private final FarmingTypeMaintenanceService farmingTypeMaintenanceService; private final FarmingNameMaintenanceService farmingNameMaintenanceService; private final DictDataService dictDataService; - private final GridEventPublisher gridEventPublisher; private final ProductionPlanService productionPlanService; + private final GridEventPublisher gridEventPublisher; + private final FarmRecordEventPublisher farmRecordEventPublisher; + public CropFarmingCenterServiceImpl(SpeciesLibraryMapper speciesLibraryMapper, PersonnelManagementMapper personnelManagementMapper, BaseInfoMapper baseInfoMapper, PlotInfoMapper plotInfoMapper, ProductionPlanMapper productionPlanMapper, ProductionPlanUsedGridMapper productionPlanUsedGridMapperMapper, FarmingRecordMapper farmingRecordMapper, InputUsageRecordsMapper inputUsageRecordsMapper, ModelManagementService modelManagementService, FarmingRecordService farmingRecordService, - FarmingRecordInputService farmingRecordInputService, PlotInfoService plotInfoService, SpeciesLibraryService speciesLibraryService, FarmingTypeMaintenanceService farmingTypeMaintenanceService, FarmingNameMaintenanceService farmingNameMaintenanceService, DictDataService dictDataService, GridEventPublisher gridEventPublisher, ProductionPlanService productionPlanService) { + FarmingRecordInputService farmingRecordInputService, PlotInfoService plotInfoService, SpeciesLibraryService speciesLibraryService, FarmingTypeMaintenanceService farmingTypeMaintenanceService, FarmingNameMaintenanceService farmingNameMaintenanceService, DictDataService dictDataService, GridEventPublisher gridEventPublisher, ProductionPlanService productionPlanService, FarmRecordEventPublisher farmRecordEventPublisher) { this.speciesLibraryMapper = speciesLibraryMapper; this.personnelManagementMapper = personnelManagementMapper; this.baseInfoMapper = baseInfoMapper; @@ -119,6 +122,7 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService { this.gridEventPublisher = gridEventPublisher; this.productionPlanService = productionPlanService; + this.farmRecordEventPublisher = farmRecordEventPublisher; } @Override @@ -799,14 +803,17 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService { double predictedArea = res.getPredictedArea(); double usagePercentage = (predictedArea / totalArea) * 100; - // 生成网箱编号 + // 第一步: 生成网箱编号 (步骤顺序不可修改) gridEventPublisher.buildGrid(res); - + // 第二步: 更新生产计划状态 updateReqVO.setTotalArea(totalArea); updateReqVO.setPredictedArea(predictedArea); updateReqVO.setUsagePercentage(usagePercentage); updateReqVO.setPlanStatus(CommonConstants.PLAN_STATUS_2); this.updateProductionPlan(updateReqVO); + + // 第三步: 创建模型管理-农事记录 + farmRecordEventPublisher.createFarmRecord(updateReqVO.getId()); return true; } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/farmingrecord/FarmingRecordService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/farmingrecord/FarmingRecordService.java index d05c79d3..810dbd60 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/farmingrecord/FarmingRecordService.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/farmingrecord/FarmingRecordService.java @@ -8,9 +8,12 @@ import cn.iocoder.yudao.module.farm.controller.admin.cropfarmingcenter.vo.Farmin import cn.iocoder.yudao.module.farm.controller.admin.cropfarmingcenter.vo.FarmingRecordCreateReqVO; import cn.iocoder.yudao.module.farm.dal.dataobject.farmingrecord.FarmingRecordDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.farm.dal.dataobject.modelfarmingoperation.ModelFarmingOperationDO; +import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanDO; import jakarta.validation.Valid; import java.util.List; +import java.util.Map; /** * 种植中心-农事基地-农事记录 Service 接口 @@ -97,4 +100,17 @@ public interface FarmingRecordService { */ CommonResult getFarmingDistributionChart(FarmingDistributionReqVO req); + /** + * 通过物种模型-农事记录 创建 农事记录 + * @param planObj + * @param value + */ + void createFarmingRecordByModel(ProductionPlanDO planObj, List value); + + /** + * 获取农事记录 + * @return + */ + Map> getFarmingRecordListByState(); + } \ No newline at end of file diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/farmingrecord/FarmingRecordServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/farmingrecord/FarmingRecordServiceImpl.java index a3d19ab3..f2fc3efe 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/farmingrecord/FarmingRecordServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/farmingrecord/FarmingRecordServiceImpl.java @@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.farm.dal.dataobject.farmingrecord.FarmingRecordDO import cn.iocoder.yudao.module.farm.dal.dataobject.farmingrecordinput.FarmingRecordInputDO; import cn.iocoder.yudao.module.farm.dal.dataobject.farmingtypemaintenance.FarmingTypeMaintenanceDO; import cn.iocoder.yudao.module.farm.dal.dataobject.inputlibrary.InputsDO; +import cn.iocoder.yudao.module.farm.dal.dataobject.modelfarmingoperation.ModelFarmingOperationDO; import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanDO; import cn.iocoder.yudao.module.farm.dal.mysql.farmingnamemaintenance.FarmingNameMaintenanceMapper; import cn.iocoder.yudao.module.farm.dal.mysql.farmingrecord.FarmingRecordMapper; @@ -29,11 +30,15 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.time.LocalDate; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser; +import static cn.iocoder.yudao.module.farm.enums.CommonConstants.FARMING_RECORD_STATUS_0; import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.FARMING_RECORD_NOT_EXISTS; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; @@ -219,6 +224,7 @@ public class FarmingRecordServiceImpl implements FarmingRecordService { saveReqVO.setPlotId(pp.getPlotId()); saveReqVO.setPlotName(pp.getPlotName()); saveReqVO.setTenantId(createReqVO.getTenantId()); + saveReqVO.setTaskStatus(FARMING_RECORD_STATUS_0); // 调用原有的创建方法 return createFarmingRecord(saveReqVO); @@ -291,4 +297,65 @@ public class FarmingRecordServiceImpl implements FarmingRecordService { FarmingDistributionRespVO res = farmingRecordMapper.getFarmingDistributionChart(req); return CommonResult.success(res); } + + @Override + public void createFarmingRecordByModel(ProductionPlanDO p, List value) { + LocalDate productionStartDate = p.getProductionStartDate(); + String planNumber = p.getPlanNumber(); + + for (ModelFarmingOperationDO e : value) { + // 从第startingPeriod天开始 + Integer startingPeriod = e.getStartingPeriod(); + // 用时天数 + Integer used = e.getUsed(); + // 农事记录开始日期 + LocalDate startDate = productionStartDate.plusDays(startingPeriod-1); + // 农事记录结束日期 + LocalDate endDate = startDate.plusDays(used); + List taskTime = Arrays.asList(startDate.toString(), endDate.toString()); + + FarmingRecordSaveReqVO saveObj = new FarmingRecordSaveReqVO(); + saveObj.setTaskStatus(FARMING_RECORD_STATUS_0); + saveObj.setTaskScope(planNumber); + saveObj.setTaskTime(taskTime); + saveObj.setTaskStartDate(startDate); + saveObj.setTaskEndDate(endDate); + saveObj.setTaskType(e.getFarmingId()); + saveObj.setTaskName(e.getFarmingName()); + saveObj.setModelFarmingOperationId(e.getId()); + saveObj.setActualLaborCost(e.getUsed()); + saveObj.setFeedbackNotes(e.getDescription()); + saveObj.setFeedbackImageUrlList(e.getSketchList()); + saveObj.setModelFarmingOperationId(e.getId()); + + saveObj.setInputsIds(e.getInputsIds()); + + saveObj.setExecutor("系统任务"); + saveObj.setFeedbackImageUrl(""); + saveObj.setProductionPlanId(p.getId()); + saveObj.setBaseId(p.getBaseId()); + saveObj.setBaseName(p.getBaseName()); + saveObj.setPlotId(p.getPlotId()); + saveObj.setPlotName(p.getPlotName()); + saveObj.setTenantId(p.getTenantId()); + + + this.createFarmingRecordForJob(saveObj); + } + + } + + @Override + public Map> getFarmingRecordListByState() { + + LambdaQueryWrapperX x = new LambdaQueryWrapperX<>(); + x.eq(FarmingRecordDO::getDeleted, CommonConstants.NO_CODE); + List frList = farmingRecordMapper.selectList(x); + + return frList.stream() + .filter(record -> record.getTaskStatus() != CommonConstants.FARMING_RECORD_STATUS_2) + .collect(Collectors.groupingBy(FarmingRecordDO::getTaskStatus)); + + } + } \ No newline at end of file diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/inputlibrary/InputUsageRecordsServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/inputlibrary/InputUsageRecordsServiceImpl.java index 3359e326..768cc0fd 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/inputlibrary/InputUsageRecordsServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/inputlibrary/InputUsageRecordsServiceImpl.java @@ -62,6 +62,7 @@ public class InputUsageRecordsServiceImpl implements InputUsageRecordsService { req.setSpec(Integer.valueOf(i.getInputSpec())); req.setUnit(Integer.valueOf(unit)); req.setTotalPrice(totalPrice); + req.setRemark("由系统自动生成."); this.createInputUsageRecords(req); } diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/modelmanagement/ModelManagementService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/modelmanagement/ModelManagementService.java index 867eb013..f200f694 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/modelmanagement/ModelManagementService.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/modelmanagement/ModelManagementService.java @@ -90,6 +90,7 @@ public interface ModelManagementService { * @return */ Map> getRecordList(List taskIdList); + List getRecordList(String taskId); /** * 通过物种ID 获取 模型管理信息 diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/modelmanagement/ModelManagementServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/modelmanagement/ModelManagementServiceImpl.java index 94382a9a..0c631b8e 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/modelmanagement/ModelManagementServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/modelmanagement/ModelManagementServiceImpl.java @@ -558,6 +558,13 @@ public class ModelManagementServiceImpl implements ModelManagementService { return resMap; } + @Override + public List getRecordList(String taskId) { + Map> modelMap = this.getRecordList(Arrays.asList(taskId)); + List allOperations = modelMap.values().stream().flatMap(List::stream).collect(Collectors.toList()); + return allOperations; + } + @Override public List getModelManagementForPlan(String speciesId) {