fix (farm): 养殖类型租户

- 网箱编号 生成方式异步处理
- 农事记录生成方式 从生产计划-开始按钮触发
- 农事记录状态 通过定时任务触发
This commit is contained in:
达富斌
2025-11-11 19:07:59 +08:00
parent ba9159c3c0
commit 30d9274454
14 changed files with 391 additions and 150 deletions

View File

@@ -64,40 +64,4 @@ public class FarmingRecordCreateReqVO {
@Schema(description = "租户id", example = "23744") @Schema(description = "租户id", example = "23744")
private String tenantId; private String tenantId;
// @Schema(description = "投入品列表")
// private List<InvestGoodsItem> 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;
// }
} }

View File

@@ -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;
}

View File

@@ -14,8 +14,8 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor @NoArgsConstructor
public class GridBuildEvent { public class GridBuildEvent {
String planNumber; private String planNumber; // 生产计划 唯一编号
String plotCode; private String plotCode; // 地块编号
private Integer plannedQuantity; // 计划数量 private Integer plannedQuantity; // 计划数量
private Integer remainingQuantity; // 剩余数量 private Integer remainingQuantity; // 剩余数量
private Integer totalQuantity; // 总数 private Integer totalQuantity; // 总数

View File

@@ -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.plotinfo.PlotInfoDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanUsedGridDO; 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.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.dto.GridBuildEvent;
import cn.iocoder.yudao.module.farm.event.utils.GridCodeGenerator; 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 cn.iocoder.yudao.module.farm.service.plotinfo.PlotInfoService;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
@@ -21,17 +23,28 @@ import java.util.List;
@Component @Component
public class EventListeners { public class EventListeners {
private final ProductionPlanManager productionPlanManager;
private final PlotInfoService plotInfoService; private final PlotInfoService plotInfoService;
private final ProductionPlanUsedGridMapper productionPlanUsedGridMapper; 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.plotInfoService = plotInfoService;
this.productionPlanUsedGridMapper = productionPlanUsedGridMapper; this.productionPlanUsedGridMapper = productionPlanUsedGridMapper;
} }
@Async
@EventListener
public void createFarmRecord(FrCreateEvent dto) {
productionPlanManager.autoGenerateFarmRecord(dto.getPlanId());
}
@Async @Async
@EventListener @EventListener
public void buildGrid(GridBuildEvent dto) { public void buildGrid(GridBuildEvent dto) {
String planNumber = dto.getPlanNumber(); String planNumber = dto.getPlanNumber();
String plotCode = dto.getPlotCode(); String plotCode = dto.getPlotCode();
int plannedQuantity = dto.getPlannedQuantity(); // 计划数量 int plannedQuantity = dto.getPlannedQuantity(); // 计划数量
@@ -40,22 +53,23 @@ public class EventListeners {
PlotInfoDO plotInfo = plotInfoService.getPlotInfo(plotCode); PlotInfoDO plotInfo = plotInfoService.getPlotInfo(plotCode);
// 生产网箱编码
List<GridCodeGenerator.GridCodeRespVO> gridCodeRespVOS = GridCodeGenerator.generateGridCodes( List<GridCodeGenerator.GridCodeRespVO> gridCodeRespVOS = GridCodeGenerator.generateGridCodes(
totalQuantity, totalQuantity,
plannedQuantity, plannedQuantity,
remainingQuantity, remainingQuantity,
plotCode); plotCode);
List<ProductionPlanUsedGridDO> list = gridCodeRespVOS.stream().map(e -> { List<ProductionPlanUsedGridDO> list = gridCodeRespVOS.stream().map(e ->
return new ProductionPlanUsedGridDO( new ProductionPlanUsedGridDO(
IdUtil.fastUUID(), IdUtil.fastUUID(),
planNumber, planNumber,
plotInfo.getBaseId(), plotInfo.getBaseId(),
plotInfo.getId(), plotInfo.getId(),
plotInfo.getPlotId(), plotInfo.getPlotId(),
e.getGridCode() e.getGridCode()
); )
}).toList(); ).toList();
productionPlanUsedGridMapper.insertBatch(list); productionPlanUsedGridMapper.insertBatch(list);
} }

View File

@@ -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));
}
}

View File

@@ -8,7 +8,7 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* @description: * @description: 养殖类 网箱事件
* @author: binda * @author: binda
* @date: 2025/11/10 16:10 * @date: 2025/11/10 16:10
*/ */
@@ -25,8 +25,8 @@ public class GridEventPublisher {
*/ */
public void buildGrid(ProductionPlanRespVO updateReqVO) { public void buildGrid(ProductionPlanRespVO updateReqVO) {
String planNumber = updateReqVO.getPlanNumber();
String plotCode = updateReqVO.getPlotId(); String plotCode = updateReqVO.getPlotId();
String planNumber = updateReqVO.getPlanNumber();
// 总数 // 总数
int totalQuantity = updateReqVO.getPlotGridNumber(); int totalQuantity = updateReqVO.getPlotGridNumber();
@@ -35,7 +35,8 @@ public class GridEventPublisher {
// 剩余数量 // 剩余数量
int remainingQuantity = productionPlanService.getPredictedGridNumber(plotCode,totalQuantity); int remainingQuantity = productionPlanService.getPredictedGridNumber(plotCode,totalQuantity);
eventPublisher.publishEvent(new GridBuildEvent(planNumber,plotCode,plannedQuantity, remainingQuantity, totalQuantity)); eventPublisher.publishEvent(new GridBuildEvent(planNumber, plotCode, plannedQuantity, remainingQuantity, totalQuantity));
} }

View File

@@ -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.controller.admin.cropfarmingcenter.vo.FarmingRecordSaveReqVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.modelfarmingoperation.ModelFarmingOperationDO; 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.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.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.modelmanagement.ModelManagementService;
import cn.iocoder.yudao.module.farm.service.productionplan.ProductionPlanService; import cn.iocoder.yudao.module.farm.service.productionplan.ProductionPlanService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -37,104 +36,101 @@ import static cn.iocoder.yudao.module.farm.enums.CommonConstants.*;
@Slf4j @Slf4j
public class FarmingRecordJob implements JobHandler { public class FarmingRecordJob implements JobHandler {
private final ProductionPlanService productionPlanService; private final ProductionPlanManager productionPlanManager;
private final FarmingRecordService farmingRecordService;
private final ModelManagementService modelManagementService;
public FarmingRecordJob(ProductionPlanService productionPlanService, FarmingRecordService farmingRecordService, ModelManagementService modelManagementService) { public FarmingRecordJob(ProductionPlanManager productionPlanManager) {
this.productionPlanService = productionPlanService; this.productionPlanManager = productionPlanManager;
this.farmingRecordService = farmingRecordService;
this.modelManagementService = modelManagementService;
} }
@Override @Override
public String execute(String param) throws Exception { public String execute(String param) throws Exception {
List<FarmingRecordSaveReqVO> list = this.insertRecordHandler(); productionPlanManager.autoUpdateFarmRecordStatus();
for (FarmingRecordSaveReqVO e : list) { // List<FarmingRecordSaveReqVO> list = this.insertRecordHandler();
List<String> taskTime = e.getTaskTime(); // for (FarmingRecordSaveReqVO e : list) {
if (taskTime.size() != 2) { // List<String> taskTime = e.getTaskTime();
continue; // if (taskTime.size() != 2) {
} // continue;
// }
LocalDate today = LocalDate.now(); //
LocalDate startDate = LocalDate.parse(taskTime.get(0)); // LocalDate today = LocalDate.now();
LocalDate endDate = LocalDate.parse(taskTime.get(1)); // LocalDate startDate = LocalDate.parse(taskTime.get(0));
boolean isStartToday = startDate.isEqual(today); // LocalDate endDate = LocalDate.parse(taskTime.get(1));
boolean isEndToday = endDate.isEqual(today); // boolean isStartToday = startDate.isEqual(today);
// boolean isEndToday = endDate.isEqual(today);
if (isStartToday) { //
// 开始日期在今天 // if (isStartToday) {
e.setTaskStatus(FARMING_RECORD_STATUS_1); // // 开始日期在今天
farmingRecordService.createFarmingRecordForJob(e); // e.setTaskStatus(FARMING_RECORD_STATUS_1);
} // farmingRecordService.createFarmingRecordForJob(e);
if (isEndToday) { // }
// 结束日期在今天 // if (isEndToday) {
e.setTaskStatus(FARMING_RECORD_STATUS_2); // // 结束日期在今天
farmingRecordService.updateFarmingRecord(e); // e.setTaskStatus(FARMING_RECORD_STATUS_2);
} // farmingRecordService.updateFarmingRecord(e);
} // }
// }
return "success"; return "success";
} }
private List<FarmingRecordSaveReqVO> insertRecordHandler() { // private List<FarmingRecordSaveReqVO> insertRecordHandler() {
// 获取[进行中]状态的计划 // // 获取[进行中]状态的计划
List<ProductionPlanDO> plans = productionPlanService.getProductionPlans(); // List<ProductionPlanDO> plans = productionPlanService.getProductionPlans();
Map<String, ProductionPlanDO> planMap = plans.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).collect(Collectors.toMap(ProductionPlanDO::getId, e -> e, (v1, v2) -> v1)); // Map<String, ProductionPlanDO> planMap = plans.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).collect(Collectors.toMap(ProductionPlanDO::getSpeciesModelId, e -> e, (v1, v2) -> v1));
List<String> taskIdList = plans.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).map(ProductionPlanDO::getId).collect(Collectors.toList()); // List<String> taskIdList = plans.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).map(ProductionPlanDO::getId).collect(Collectors.toList());
//
// 获取引用模型集合 key: modelId; // // 获取引用模型集合 key: modelId;
Map<String, List<ModelFarmingOperationDO>> modelIdMap = modelManagementService.getRecordList(taskIdList); // Map<String, List<ModelFarmingOperationDO>> modelIdMap = modelManagementService.getRecordList(taskIdList);
//
List<FarmingRecordSaveReqVO> farmingRecordSaveReqVOList = new ArrayList<>(); // List<FarmingRecordSaveReqVO> farmingRecordSaveReqVOList = new ArrayList<>();
for (Map.Entry<String, List<ModelFarmingOperationDO>> en : modelIdMap.entrySet()) { // for (Map.Entry<String, List<ModelFarmingOperationDO>> en : modelIdMap.entrySet()) {
String modelId = en.getKey(); // String modelId = en.getKey();
List<ModelFarmingOperationDO> operationList = en.getValue(); // List<ModelFarmingOperationDO> operationList = en.getValue();
//
for (ModelFarmingOperationDO e : operationList) { // for (ModelFarmingOperationDO e : operationList) {
farmingRecordSaveReqVOList.add(this.buildFarmingRecord(planMap.get(modelId), e)); // farmingRecordSaveReqVOList.add(this.buildFarmingRecord(planMap.get(modelId), e));
} // }
} // }
return farmingRecordSaveReqVOList; // return farmingRecordSaveReqVOList;
} // }
//
//
private FarmingRecordSaveReqVO buildFarmingRecord(ProductionPlanDO p, ModelFarmingOperationDO e) { // private FarmingRecordSaveReqVO buildFarmingRecord(ProductionPlanDO p, ModelFarmingOperationDO e) {
LocalDate productionStartDate = p.getProductionStartDate(); // LocalDate productionStartDate = p.getProductionStartDate();
// 从第startingPeriod天开始 // // 从第startingPeriod天开始
Integer startingPeriod = e.getStartingPeriod(); // Integer startingPeriod = e.getStartingPeriod();
// 用时天数 // // 用时天数
Integer used = e.getUsed(); // Integer used = e.getUsed();
// 农事记录开始日期 // // 农事记录开始日期
LocalDate startDate = productionStartDate.plusDays(startingPeriod-1); // LocalDate startDate = productionStartDate.plusDays(startingPeriod-1);
// 农事记录结束日期 // // 农事记录结束日期
LocalDate endDate = startDate.plusDays(used); // LocalDate endDate = startDate.plusDays(used);
// String taskTime = startDate + "," + endDate; //// String taskTime = startDate + "," + endDate;
List<String> taskTime = Arrays.asList(startDate.toString(), endDate.toString()); // List<String> taskTime = Arrays.asList(startDate.toString(), endDate.toString());
//
FarmingRecordSaveReqVO saveObj = new FarmingRecordSaveReqVO(); // FarmingRecordSaveReqVO saveObj = new FarmingRecordSaveReqVO();
saveObj.setTaskType(e.getFarmingId()); // saveObj.setTaskType(e.getFarmingId());
saveObj.setTaskName(e.getFarmingName()); // saveObj.setTaskName(e.getFarmingName());
saveObj.setTaskScope(p.getPlanNumber()); // saveObj.setTaskScope(p.getPlanNumber());
saveObj.setTaskTime(taskTime); // saveObj.setTaskTime(taskTime);
saveObj.setTaskStartDate(startDate); // saveObj.setTaskStartDate(startDate);
saveObj.setTaskEndDate(endDate); // saveObj.setTaskEndDate(endDate);
saveObj.setProductionPlanId(p.getId()); // saveObj.setProductionPlanId(p.getId());
saveObj.setModelFarmingOperationId(e.getId()); // saveObj.setModelFarmingOperationId(e.getId());
saveObj.setExecutor("系统"); // saveObj.setExecutor("系统");
saveObj.setActualLaborCost(e.getUsed()); // saveObj.setActualLaborCost(e.getUsed());
saveObj.setFeedbackNotes(e.getDescription()); // saveObj.setFeedbackNotes(e.getDescription());
saveObj.setFeedbackImageUrl(""); // saveObj.setFeedbackImageUrl("");
saveObj.setFeedbackImageUrlList(e.getSketchList()); // saveObj.setFeedbackImageUrlList(e.getSketchList());
saveObj.setBaseId(p.getBaseId()); // saveObj.setBaseId(p.getBaseId());
saveObj.setBaseName(p.getBaseName()); // saveObj.setBaseName(p.getBaseName());
saveObj.setPlotId(p.getPlotId()); // saveObj.setPlotId(p.getPlotId());
saveObj.setPlotName(p.getPlotName()); // saveObj.setPlotName(p.getPlotName());
saveObj.setTenantId(p.getTenantId()); // saveObj.setTenantId(p.getTenantId());
saveObj.setModelFarmingOperationId(e.getId()); // saveObj.setModelFarmingOperationId(e.getId());
saveObj.setInputsIds(e.getInputsIds()); // saveObj.setInputsIds(e.getInputsIds());
// saveObj.setTaskStatus(FARMING_RECORD_STATUS_1);
return saveObj; // return saveObj;
} // }
} }

View File

@@ -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<ModelFarmingOperationDO> allOperations = modelManagementService.getRecordList(planId);
// 创建农事记录
farmingRecordService.createFarmingRecordByModel(planObj, allOperations);
}
/**
* 定时任务 刷新农事记录状态:
* 未开始 -> 开始状态
* 开始 -> 结束
*/
public void autoUpdateFarmRecordStatus() {
Map<Integer, List<FarmingRecordDO>> statusGroups = farmingRecordService.getFarmingRecordListByState();
this.isStartToday(statusGroups);
this.isEndToday(statusGroups);
}
/**
* 将开始日期在今天之前的的记录 状态修改为: 开始
*
* @param statusGroups
*/
private void isStartToday(Map<Integer, List<FarmingRecordDO>> statusGroups) {
List<FarmingRecordDO> 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<Integer, List<FarmingRecordDO>> statusGroups) {
List<FarmingRecordDO> 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 推送系统消息
}
}
}

View File

@@ -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.productionplan.ProductionPlanUsedGridMapper;
import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMapper; import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMapper;
import cn.iocoder.yudao.module.farm.enums.CommonConstants; 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.event.publisher.GridEventPublisher;
import cn.iocoder.yudao.module.farm.service.farmingnamemaintenance.FarmingNameMaintenanceService; import cn.iocoder.yudao.module.farm.service.farmingnamemaintenance.FarmingNameMaintenanceService;
import cn.iocoder.yudao.module.farm.service.farmingrecord.FarmingRecordService; import cn.iocoder.yudao.module.farm.service.farmingrecord.FarmingRecordService;
@@ -93,13 +94,15 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
private final FarmingTypeMaintenanceService farmingTypeMaintenanceService; private final FarmingTypeMaintenanceService farmingTypeMaintenanceService;
private final FarmingNameMaintenanceService farmingNameMaintenanceService; private final FarmingNameMaintenanceService farmingNameMaintenanceService;
private final DictDataService dictDataService; private final DictDataService dictDataService;
private final GridEventPublisher gridEventPublisher;
private final ProductionPlanService productionPlanService; private final ProductionPlanService productionPlanService;
private final GridEventPublisher gridEventPublisher;
private final FarmRecordEventPublisher farmRecordEventPublisher;
public CropFarmingCenterServiceImpl(SpeciesLibraryMapper speciesLibraryMapper, PersonnelManagementMapper personnelManagementMapper, BaseInfoMapper baseInfoMapper, PlotInfoMapper plotInfoMapper, ProductionPlanMapper productionPlanMapper, public CropFarmingCenterServiceImpl(SpeciesLibraryMapper speciesLibraryMapper, PersonnelManagementMapper personnelManagementMapper, BaseInfoMapper baseInfoMapper, PlotInfoMapper plotInfoMapper, ProductionPlanMapper productionPlanMapper,
ProductionPlanUsedGridMapper productionPlanUsedGridMapperMapper, FarmingRecordMapper farmingRecordMapper, InputUsageRecordsMapper inputUsageRecordsMapper, ModelManagementService modelManagementService, ProductionPlanUsedGridMapper productionPlanUsedGridMapperMapper, FarmingRecordMapper farmingRecordMapper, InputUsageRecordsMapper inputUsageRecordsMapper, ModelManagementService modelManagementService,
FarmingRecordService farmingRecordService, 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.speciesLibraryMapper = speciesLibraryMapper;
this.personnelManagementMapper = personnelManagementMapper; this.personnelManagementMapper = personnelManagementMapper;
this.baseInfoMapper = baseInfoMapper; this.baseInfoMapper = baseInfoMapper;
@@ -119,6 +122,7 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
this.gridEventPublisher = gridEventPublisher; this.gridEventPublisher = gridEventPublisher;
this.productionPlanService = productionPlanService; this.productionPlanService = productionPlanService;
this.farmRecordEventPublisher = farmRecordEventPublisher;
} }
@Override @Override
@@ -799,14 +803,17 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
double predictedArea = res.getPredictedArea(); double predictedArea = res.getPredictedArea();
double usagePercentage = (predictedArea / totalArea) * 100; double usagePercentage = (predictedArea / totalArea) * 100;
// 生成网箱编号 // 第一步: 生成网箱编号 (步骤顺序不可修改)
gridEventPublisher.buildGrid(res); gridEventPublisher.buildGrid(res);
// 第二步: 更新生产计划状态
updateReqVO.setTotalArea(totalArea); updateReqVO.setTotalArea(totalArea);
updateReqVO.setPredictedArea(predictedArea); updateReqVO.setPredictedArea(predictedArea);
updateReqVO.setUsagePercentage(usagePercentage); updateReqVO.setUsagePercentage(usagePercentage);
updateReqVO.setPlanStatus(CommonConstants.PLAN_STATUS_2); updateReqVO.setPlanStatus(CommonConstants.PLAN_STATUS_2);
this.updateProductionPlan(updateReqVO); this.updateProductionPlan(updateReqVO);
// 第三步: 创建模型管理-农事记录
farmRecordEventPublisher.createFarmRecord(updateReqVO.getId());
return true; return true;
} }

View File

@@ -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.controller.admin.cropfarmingcenter.vo.FarmingRecordCreateReqVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.farmingrecord.FarmingRecordDO; import cn.iocoder.yudao.module.farm.dal.dataobject.farmingrecord.FarmingRecordDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult; 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 jakarta.validation.Valid;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 种植中心-农事基地-农事记录 Service 接口 * 种植中心-农事基地-农事记录 Service 接口
@@ -97,4 +100,17 @@ public interface FarmingRecordService {
*/ */
CommonResult<FarmingDistributionRespVO> getFarmingDistributionChart(FarmingDistributionReqVO req); CommonResult<FarmingDistributionRespVO> getFarmingDistributionChart(FarmingDistributionReqVO req);
/**
* 通过物种模型-农事记录 创建 农事记录
* @param planObj
* @param value
*/
void createFarmingRecordByModel(ProductionPlanDO planObj, List<ModelFarmingOperationDO> value);
/**
* 获取农事记录
* @return
*/
Map<Integer, List<FarmingRecordDO>> getFarmingRecordListByState();
} }

View File

@@ -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.farmingrecordinput.FarmingRecordInputDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.farmingtypemaintenance.FarmingTypeMaintenanceDO; 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.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.dataobject.productionplan.ProductionPlanDO;
import cn.iocoder.yudao.module.farm.dal.mysql.farmingnamemaintenance.FarmingNameMaintenanceMapper; import cn.iocoder.yudao.module.farm.dal.mysql.farmingnamemaintenance.FarmingNameMaintenanceMapper;
import cn.iocoder.yudao.module.farm.dal.mysql.farmingrecord.FarmingRecordMapper; 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 org.springframework.validation.annotation.Validated;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; 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.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser; 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 static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.FARMING_RECORD_NOT_EXISTS;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
@@ -219,6 +224,7 @@ public class FarmingRecordServiceImpl implements FarmingRecordService {
saveReqVO.setPlotId(pp.getPlotId()); saveReqVO.setPlotId(pp.getPlotId());
saveReqVO.setPlotName(pp.getPlotName()); saveReqVO.setPlotName(pp.getPlotName());
saveReqVO.setTenantId(createReqVO.getTenantId()); saveReqVO.setTenantId(createReqVO.getTenantId());
saveReqVO.setTaskStatus(FARMING_RECORD_STATUS_0);
// 调用原有的创建方法 // 调用原有的创建方法
return createFarmingRecord(saveReqVO); return createFarmingRecord(saveReqVO);
@@ -291,4 +297,65 @@ public class FarmingRecordServiceImpl implements FarmingRecordService {
FarmingDistributionRespVO res = farmingRecordMapper.getFarmingDistributionChart(req); FarmingDistributionRespVO res = farmingRecordMapper.getFarmingDistributionChart(req);
return CommonResult.success(res); return CommonResult.success(res);
} }
@Override
public void createFarmingRecordByModel(ProductionPlanDO p, List<ModelFarmingOperationDO> 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<String> 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<Integer, List<FarmingRecordDO>> getFarmingRecordListByState() {
LambdaQueryWrapperX<FarmingRecordDO> x = new LambdaQueryWrapperX<>();
x.eq(FarmingRecordDO::getDeleted, CommonConstants.NO_CODE);
List<FarmingRecordDO> frList = farmingRecordMapper.selectList(x);
return frList.stream()
.filter(record -> record.getTaskStatus() != CommonConstants.FARMING_RECORD_STATUS_2)
.collect(Collectors.groupingBy(FarmingRecordDO::getTaskStatus));
}
} }

View File

@@ -62,6 +62,7 @@ public class InputUsageRecordsServiceImpl implements InputUsageRecordsService {
req.setSpec(Integer.valueOf(i.getInputSpec())); req.setSpec(Integer.valueOf(i.getInputSpec()));
req.setUnit(Integer.valueOf(unit)); req.setUnit(Integer.valueOf(unit));
req.setTotalPrice(totalPrice); req.setTotalPrice(totalPrice);
req.setRemark("由系统自动生成.");
this.createInputUsageRecords(req); this.createInputUsageRecords(req);
} }

View File

@@ -90,6 +90,7 @@ public interface ModelManagementService {
* @return * @return
*/ */
Map<String, List<ModelFarmingOperationDO>> getRecordList(List<String> taskIdList); Map<String, List<ModelFarmingOperationDO>> getRecordList(List<String> taskIdList);
List<ModelFarmingOperationDO> getRecordList(String taskId);
/** /**
* 通过物种ID 获取 模型管理信息 * 通过物种ID 获取 模型管理信息

View File

@@ -558,6 +558,13 @@ public class ModelManagementServiceImpl implements ModelManagementService {
return resMap; return resMap;
} }
@Override
public List<ModelFarmingOperationDO> getRecordList(String taskId) {
Map<String, List<ModelFarmingOperationDO>> modelMap = this.getRecordList(Arrays.asList(taskId));
List<ModelFarmingOperationDO> allOperations = modelMap.values().stream().flatMap(List::stream).collect(Collectors.toList());
return allOperations;
}
@Override @Override
public List<ModelManagementForPlanRespVO> getModelManagementForPlan(String speciesId) { public List<ModelManagementForPlanRespVO> getModelManagementForPlan(String speciesId) {