fix (farm): 基地管理,生产计划

- 基地-地块二级联动 添加剩余地块面积
- 生产计划-开始按钮 计算剩余面积,占比比例
- 修改生产计划分页查询,满足甘特图返回响应结构
-
This commit is contained in:
达富斌
2025-08-30 22:27:25 +08:00
parent 809eabce10
commit be61bc8523
19 changed files with 319 additions and 128 deletions

View File

@@ -34,9 +34,9 @@ public class BaseNamePlanRespVO {
@NoArgsConstructor @NoArgsConstructor
public static class PlotInfoVO { public static class PlotInfoVO {
@Schema(description = "地块ID") @Schema(description = "地块ID")
private String plotId; private String id;
@Schema(description = "地块名称") @Schema(description = "地块名称")
private String plotName; private String name;
private List<PlanInfoVO> children; private List<PlanInfoVO> children;
} }
@@ -44,6 +44,8 @@ public class BaseNamePlanRespVO {
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public static class PlanInfoVO { public static class PlanInfoVO {
private String id;
private String name;
@Schema(description = "计划编号") @Schema(description = "计划编号")
private String planNumber; private String planNumber;
@JsonFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd")

View File

@@ -40,7 +40,7 @@ public class BaseNameRespVO {
private BigDecimal plotArea; private BigDecimal plotArea;
@Schema(description = "剩余面积") @Schema(description = "剩余面积")
private BigDecimal remainingArea; private Double remainingArea;
} }
public BaseNameRespVO(String id, String name) { public BaseNameRespVO(String id, String name) {

View File

@@ -4,6 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanRespVO; import cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanPage2ReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanResp2VO;
import cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanUpdateReqVO; import cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanUpdateReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.farmingrecord.vo.FarmingRecordPageReqVO; import cn.iocoder.yudao.module.farm.controller.admin.farmingrecord.vo.FarmingRecordPageReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.farmingrecord.vo.FarmingRecordRespVO; import cn.iocoder.yudao.module.farm.controller.admin.farmingrecord.vo.FarmingRecordRespVO;
@@ -47,17 +49,24 @@ public class CropFarmingCenterController {
this.farmingRecordService = farmingRecordService; this.farmingRecordService = farmingRecordService;
} }
// // 生产计划
// @GetMapping("/production-plan/page")
// @Operation(summary = "生产计划-分页")
// public CommonResult<PageResult<ProductionPlanRespVO>> getProductionPlanPage(@Valid cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanPageReqVO pageReqVO) {
// return success(cropFarmingCenterService.getProductionPlanPage(pageReqVO));
// }
// 生产计划 // 生产计划
@GetMapping("/production-plan/page") @GetMapping("/production-plan/page")
@Operation(summary = "生产计划-分页") @Operation(summary = "生产计划-分页")
public CommonResult<PageResult<ProductionPlanRespVO>> getProductionPlanPage(@Valid cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanPageReqVO pageReqVO) { public CommonResult<PageResult<ProductionPlanResp2VO>> getProductionPlanPage(@Valid ProductionPlanPage2ReqVO pageReqVO) {
return success(cropFarmingCenterService.getProductionPlanPage(pageReqVO)); return success(cropFarmingCenterService.getProductionPlanPage2(pageReqVO));
} }
@GetMapping("/production-plan/get/{id}") @GetMapping("/production-plan/get/{id}")
@Operation(summary = "生产计划-查看") @Operation(summary = "生产计划-查看")
public CommonResult<cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanRespVO> getProductionPlan(@PathVariable("id") String id) { public CommonResult<ProductionPlanRespVO> getProductionPlan(@PathVariable("id") String id) {
cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanRespVO res = cropFarmingCenterService.getProductionPlan(id); ProductionPlanRespVO res = cropFarmingCenterService.getProductionPlan(id);
return success(res); return success(res);
} }
@@ -96,6 +105,15 @@ public class CropFarmingCenterController {
@Operation(summary = "生产计划-开始按钮") @Operation(summary = "生产计划-开始按钮")
@PutMapping("/production-plan/start") @PutMapping("/production-plan/start")
public CommonResult<Boolean> startPlanning(@RequestBody ProductionPlanUpdateReqVO updateReqVO) { public CommonResult<Boolean> startPlanning(@RequestBody ProductionPlanUpdateReqVO updateReqVO) {
ProductionPlanRespVO res = cropFarmingCenterService.getProductionPlan(updateReqVO.getId());
double totalArea = res.getTotalArea();
double predictedArea = res.getPredictedArea();
double usagePercentage = (predictedArea / totalArea) * 100;
// String result = String.format("%.1f%%", percentage);
updateReqVO.setTotalArea(totalArea);
updateReqVO.setPredictedArea(predictedArea);
updateReqVO.setUsagePercentage(usagePercentage);
updateReqVO.setPlanStatus(CommonConstants.PLAN_STATUS_2); updateReqVO.setPlanStatus(CommonConstants.PLAN_STATUS_2);
cropFarmingCenterService.updateProductionPlan(updateReqVO); cropFarmingCenterService.updateProductionPlan(updateReqVO);
return success(true); return success(true);

View File

@@ -15,7 +15,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
* @date: 2025/8/20 17:58 * @date: 2025/8/20 17:58
*/ */
@Data @Data
public class ProductionPlanPageReqVO extends PageParam { public class ProductionPlanPage2ReqVO extends PageParam {
@Schema(description = "基地id", example = "29734") @Schema(description = "基地id", example = "29734")
private String baseId; private String baseId;
@@ -23,7 +23,7 @@ public class ProductionPlanPageReqVO extends PageParam {
@Schema(description = "地块ID", example = "19246") @Schema(description = "地块ID", example = "19246")
private String plotId; private String plotId;
@Schema(description = "排产开始日期") @Schema(description = "排产日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDate[] productionStartDate; private LocalDate[] productionStartDate;

View File

@@ -0,0 +1,118 @@
package cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDate;
/**
* @description: 针对于前端甘特图的响应实体
* @author: binda
* @date: 2025/8/30 14:17
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProductionPlanResp2VO {
@Schema(description = "框架ID")
private Integer id;
@Schema(description = "框架父类ID")
private Integer parent;
@Schema(description = "open")
private boolean open;
@Schema(description = "框架类型")
private String type;
@Schema(description = "抬头")
private String text;
@Schema(description = "地块数量")
private int size;
@Schema(description = "计划编号")
private String planNumber;
@Schema(description = "种植物种-编码")
private String plantSpeciesCode;
@Schema(description = "种植物种-名称")
private String plantSpeciesName;
@Schema(description = "排产开始日期")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate productionStartDate;
@Schema(description = "排产结束日期")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate productionEndDate;
@Schema(description = "采收开始日期")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate harvestStartDate;
@Schema(description = "计划执行状态")
private Integer planStatus;
@Schema(description = "计划执行状态-名称")
private String planStatusName;
@Schema(description = "逾期天数")
private Integer overdueDays;
@Schema(description = "排产间隔天数")
private Integer intervalDays;
@Schema(description = "预计产量")
private Integer predictedYields;
@Schema(description = "计划概括信息")
private PlanOverview planOverview;
@Schema(description = "模型信息")
private ModelInfo modelInfo;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class ModelInfo{
@Schema(description = "模型id")
private String id;
@Schema(description = "模型名称")
private String modelName;
@Schema(description = "物种图片")
private String speciesImage;
@Schema(description = "种植物种-名称")
private String plantSpeciesName;
@Schema(description = "计划编号")
private String planNumber;
@Schema(description = "计划执行状态")
private Integer planStatus;
@Schema(description = "计划执行状态-名称")
private String planStatusName;
@Schema(description = "计划执行子状态")
private Integer planSubStatus;
@Schema(description = "计划执行子状态-名称")
private String planSubStatusName;
@Schema(description = "生命周期-名称")
private String cycleName;
@Schema(description = "种植面积")
private Double predictedArea;
@Schema(description = "预计产量")
private Integer predictedYields;
@Schema(description = "任务进度")
private String progressBar;
@Schema(description = "基地名称")
private String baseName;
@Schema(description = "基地负责人")
private String baseManager;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class PlanOverview{
@Schema(description = "总面积")
private BigDecimal totalArea;
@Schema(description = "计划总数")
private Integer planCount;
@Schema(description = "已完成-计划个数")
private Integer planCompletedCount;
@Schema(description = "进行中-计划个数")
private Integer planInProgressCount;
@Schema(description = "逾期-计划个数")
private Integer planOverdueCount;
}
}

View File

@@ -90,12 +90,11 @@ public class ProductionPlanRespVO {
private Double totalArea; private Double totalArea;
@Schema(description = "计划面积") @Schema(description = "计划面积")
private Double predictedArea; private Double predictedArea;
@Deprecated
@Schema(description = "剩余面积") @Schema(description = "剩余面积")
private Double remainingArea; private Double remainingArea;
// @Schema(description = "可用面积")
// private Double usableArea;
@Schema(description = "占地面积(百分比)") @Schema(description = "占地面积(百分比)")
private Integer usagePercentage; private Double usagePercentage;
@Schema(description = "备注") @Schema(description = "备注")
private String remark; private String remark;

View File

@@ -67,10 +67,11 @@ public class ProductionPlanSaveReqVO {
private Double totalArea; private Double totalArea;
@Schema(description = "计划面积") @Schema(description = "计划面积")
private Double predictedArea; private Double predictedArea;
@Deprecated
@Schema(description = "剩余面积") @Schema(description = "剩余面积")
private Double remainingArea; private Double remainingArea;
@Schema(description = "占地面积") @Schema(description = "占地面积")
private Integer usagePercentage; private Double usagePercentage;
@Schema(description = "备注") @Schema(description = "备注")
private String remark; private String remark;
} }

View File

@@ -73,10 +73,11 @@ public class ProductionPlanUpdateReqVO {
private Double totalArea; private Double totalArea;
@Schema(description = "计划面积") @Schema(description = "计划面积")
private Double predictedArea; private Double predictedArea;
@Deprecated
@Schema(description = "剩余面积") @Schema(description = "剩余面积")
private Double remainingArea; private Double remainingArea;
@Schema(description = "占地面积") @Schema(description = "占地面积")
private Integer usagePercentage; private Double usagePercentage;
@Schema(description = "备注") @Schema(description = "备注")
private String remark; private String remark;

View File

@@ -331,7 +331,7 @@ public class DictController {
} }
@GetMapping("/list/base-name-plan") @GetMapping("/list/base-name-plan")
@Operation(summary = "字典数据维护-下拉框列表-基地,地块,任务三级联动") @Operation(summary = "字典数据维护-下拉框列表-基地,地块,计划三级联动")
public CommonResult<List<BaseNamePlanRespVO>> getBaseNameAndPlanList() { public CommonResult<List<BaseNamePlanRespVO>> getBaseNameAndPlanList() {
List<BaseNamePlanRespVO> res = productionPlanService.getBaseNameAndPlanList(); List<BaseNamePlanRespVO> res = productionPlanService.getBaseNameAndPlanList();
return success(res); return success(res);
@@ -358,103 +358,4 @@ public class DictController {
return success(BeanUtils.toBean(res, SysDictTypeCodeRespVO.class)); return success(BeanUtils.toBean(res, SysDictTypeCodeRespVO.class));
} }
@Operation(summary = "字典数据维护-下拉框列表-投入品规格-单位1")
@GetMapping("/list/units/1")
public CommonResult<List<CommonDictRespVO>> getUnits1List() {
// todo 后续维护到字典表
List<CommonDictRespVO> list = Arrays.asList(
new CommonDictRespVO("1", "吨", 1),
new CommonDictRespVO("2", "千克", 1),
new CommonDictRespVO("3", "斤", 1),
new CommonDictRespVO("4", "立方米", 1),
new CommonDictRespVO("5", "米", 1),
new CommonDictRespVO("6", "克", 1)
);
return success(list);
}
@Operation(summary = "字典数据维护-下拉框列表-投入品规格-单位2")
@GetMapping("/list/units/2")
public CommonResult<List<CommonDictRespVO>> getUnits2List() {
// todo 后续维护到字典表
List<CommonDictRespVO> list = Arrays.asList(
new CommonDictRespVO("1", "包", 1),
new CommonDictRespVO("2", "袋", 1),
new CommonDictRespVO("3", "桶", 1),
new CommonDictRespVO("4", "车", 1),
new CommonDictRespVO("5", "捆", 1),
new CommonDictRespVO("6", "立方米", 1),
new CommonDictRespVO("7", "箱", 1)
);
return success(list);
}
@Operation(summary = "字典数据维护-下拉框列表-灾害类型")
@GetMapping("/list/disaster")
public CommonResult<List<CommonDictRespVO>> getDisasterDataList() {
// todo 后续维护到字典表
List<CommonDictRespVO> list = Arrays.asList(
new CommonDictRespVO("1", "虫害", 1),
new CommonDictRespVO("2", "病害", 1),
new CommonDictRespVO("3", "草害", 1)
);
return success(list);
}
@Operation(summary = "字典数据维护-下拉框列表-气象灾害名称")
@GetMapping("/list/weather/disaster")
public CommonResult<List<CommonDictRespVO>> getWeatherDisasterDataList() {
// todo 后续维护到字典表
List<CommonDictRespVO> list = Arrays.asList(
new CommonDictRespVO("1", "洪水", 1),
new CommonDictRespVO("2", "内涝", 1),
new CommonDictRespVO("3", "渍涝", 1),
new CommonDictRespVO("4", "洪涝", 1),
new CommonDictRespVO("5", "农业干旱", 1),
new CommonDictRespVO("6", "台风", 1),
new CommonDictRespVO("7", "暴雨", 1),
new CommonDictRespVO("8", "暴雪", 1),
new CommonDictRespVO("9", "寒潮", 1),
new CommonDictRespVO("10", "大风", 1),
new CommonDictRespVO("11", "沙尘暴", 1),
new CommonDictRespVO("12", "高温", 1),
new CommonDictRespVO("13", "干热风", 1),
new CommonDictRespVO("14", "下击暴流", 1),
new CommonDictRespVO("15", "冰雹", 1),
new CommonDictRespVO("16", "霜冻", 1),
new CommonDictRespVO("17", "貍", 1),
new CommonDictRespVO("18", "雷雨大风", 1),
new CommonDictRespVO("19", "道路结冰", 1),
new CommonDictRespVO("20", "干旱", 1),
new CommonDictRespVO("21", "高温中暑", 1),
new CommonDictRespVO("22", "森林火险", 1),
new CommonDictRespVO("23", "草原火险", 1),
new CommonDictRespVO("24", "冰冻", 1),
new CommonDictRespVO("25", "低温雨雪冰冻", 1),
new CommonDictRespVO("26", "大雪", 1),
new CommonDictRespVO("27", "寒冷", 1),
new CommonDictRespVO("28", "连阴雨", 1),
new CommonDictRespVO("29", "渍涝风险", 1),
new CommonDictRespVO("30", "强降雨", 1),
new CommonDictRespVO("31", "强降温", 1),
new CommonDictRespVO("32", "雪灾", 1),
new CommonDictRespVO("33", "雷暴", 1),
new CommonDictRespVO("34", "降温", 1),
new CommonDictRespVO("35", "台风暴雨", 1),
new CommonDictRespVO("36", "严寒", 1),
new CommonDictRespVO("37", "沙尘", 1),
new CommonDictRespVO("38", "低温", 1),
new CommonDictRespVO("39", "雷暴大风", 1),
new CommonDictRespVO("40", "持续低温", 1),
new CommonDictRespVO("41", "台风海浪", 1),
new CommonDictRespVO("42", "森林(草原)火险", 1)
);
return success(list);
}
} }

View File

@@ -89,11 +89,12 @@ public class ProductionPlanDO extends BaseDO {
/** /**
* 剩余面积 * 剩余面积
*/ */
@Deprecated
private Double remainingArea; private Double remainingArea;
/** /**
* 占地面积 * 占地面积
*/ */
private Integer usagePercentage; private Double usagePercentage;
/** /**
* 备注 * 备注
*/ */

View File

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.farm.dal.mysql.productionplan;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanPage2ReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanRespVO; import cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.productionplan.vo.ProductionPlanPageReqVO; import cn.iocoder.yudao.module.farm.controller.admin.productionplan.vo.ProductionPlanPageReqVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanDO; import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanDO;
@@ -34,7 +35,7 @@ public interface ProductionPlanMapper extends BaseMapperX<ProductionPlanDO> {
); );
} }
default PageResult<ProductionPlanDO> selectPage2(cn.iocoder.yudao.module.farm.controller.admin.cropFarmingCenter.vo.ProductionPlanPageReqVO reqVO) { default PageResult<ProductionPlanDO> selectPage2(ProductionPlanPage2ReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductionPlanDO>() return selectPage(reqVO, new LambdaQueryWrapperX<ProductionPlanDO>()
.betweenIfPresent(ProductionPlanDO::getProductionStartDate, .betweenIfPresent(ProductionPlanDO::getProductionStartDate,
reqVO.getProductionStartDate() != null ? reqVO.getProductionStartDate()[0] : null, reqVO.getProductionStartDate() != null ? reqVO.getProductionStartDate()[0] : null,

View File

@@ -69,4 +69,10 @@ public class CommonConstants {
public final static Integer COMMON_DISASTER = 1; // 一般灾害 public final static Integer COMMON_DISASTER = 1; // 一般灾害
public final static Integer WEATHER_DISASTER = 2; // 气象灾害 public final static Integer WEATHER_DISASTER = 2; // 气象灾害
public final static String DHTMLX_GANTT_TYPE_1 = "project";
public final static String DHTMLX_GANTT_TYPE_2 = "rightside";
public final static Boolean DHTMLX_GANTT_OPEN_TRUE = true;
public final static Boolean DHTMLX_GANTT_OPEN_FALSE = false;
} }

View File

@@ -12,7 +12,6 @@ import cn.iocoder.yudao.module.farm.dal.dataobject.plotinfo.PlotInfoDO;
import cn.iocoder.yudao.module.farm.dal.mysql.baseinfo.BaseInfoMapper; import cn.iocoder.yudao.module.farm.dal.mysql.baseinfo.BaseInfoMapper;
import cn.iocoder.yudao.module.farm.dal.mysql.gridinfo.GridInfoMapper; import cn.iocoder.yudao.module.farm.dal.mysql.gridinfo.GridInfoMapper;
import cn.iocoder.yudao.module.farm.dal.mysql.personnelmanagement.PersonnelManagementMapper; import cn.iocoder.yudao.module.farm.dal.mysql.personnelmanagement.PersonnelManagementMapper;
import cn.iocoder.yudao.module.farm.dal.mysql.plotinfo.PlotInfoMapper;
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.service.plotinfo.PlotInfoService; import cn.iocoder.yudao.module.farm.service.plotinfo.PlotInfoService;
@@ -127,9 +126,7 @@ public class BaseInfoServiceImpl implements BaseInfoService {
@Override @Override
public List<BaseNameRespVO> getBaseNameList() { public List<BaseNameRespVO> getBaseNameList() {
List<BaseNameRespVO> res = new ArrayList<>(); List<BaseNameRespVO> res = new ArrayList<>();
// 地块 // 地块
List<PlotInfoDO> plotInfoDOS = plotInfoService.getPlotInfos(); List<PlotInfoDO> plotInfoDOS = plotInfoService.getPlotInfos();
// 基地 // 基地
@@ -143,7 +140,7 @@ public class BaseInfoServiceImpl implements BaseInfoService {
List<BaseNameRespVO.PlotInfoVO> childList = new ArrayList<>(); List<BaseNameRespVO.PlotInfoVO> childList = new ArrayList<>();
for (PlotInfoDO aDo : plotInfoDOS) { for (PlotInfoDO aDo : plotInfoDOS) {
if (aDo.getBaseId().equals(key)) { if (aDo.getBaseId().equals(key)) {
BigDecimal remainingArea = BigDecimal.valueOf(2.00); // todo double remainingArea = productionPlanService.getRemainingArea(aDo.getBaseId());
childList.add(new BaseNameRespVO.PlotInfoVO(aDo.getPlotId(), aDo.getPlotName(), aDo.getPlotArea(),remainingArea)); childList.add(new BaseNameRespVO.PlotInfoVO(aDo.getPlotId(), aDo.getPlotName(), aDo.getPlotArea(),remainingArea));
} }
} }

View File

@@ -24,7 +24,8 @@ public interface CropFarmingCenterService {
void updateProductionPlan(ProductionPlanUpdateReqVO updateReqVO); void updateProductionPlan(ProductionPlanUpdateReqVO updateReqVO);
PageResult<ProductionPlanRespVO> getProductionPlanPage(ProductionPlanPageReqVO reqVO); PageResult<ProductionPlanRespVO> getProductionPlanPage(ProductionPlanPage2ReqVO reqVO);
PageResult<ProductionPlanResp2VO> getProductionPlanPage2(ProductionPlanPage2ReqVO reqVO);
int getCropCount(Long tenantId); int getCropCount(Long tenantId);

View File

@@ -12,10 +12,15 @@ import cn.iocoder.yudao.module.farm.controller.admin.modelfarmingoperation.vo.Mo
import cn.iocoder.yudao.module.farm.controller.admin.modelmanagement.vo.ModelManagementRespVO; import cn.iocoder.yudao.module.farm.controller.admin.modelmanagement.vo.ModelManagementRespVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.baseinfo.BaseInfoDO; import cn.iocoder.yudao.module.farm.dal.dataobject.baseinfo.BaseInfoDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.modelfarmingoperationinput.ModelFarmingOperationInputDO; import cn.iocoder.yudao.module.farm.dal.dataobject.modelfarmingoperationinput.ModelFarmingOperationInputDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.modelmanagement.ModelManagementDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.personnelmanagement.PersonnelManagementDO;
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.ProductionPlanDO; import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.specieslibrary.SpeciesLibraryDO;
import cn.iocoder.yudao.module.farm.dal.mysql.baseinfo.BaseInfoMapper; import cn.iocoder.yudao.module.farm.dal.mysql.baseinfo.BaseInfoMapper;
import cn.iocoder.yudao.module.farm.dal.mysql.personnelmanagement.PersonnelManagementMapper;
import cn.iocoder.yudao.module.farm.dal.mysql.productionplan.ProductionPlanMapper; import cn.iocoder.yudao.module.farm.dal.mysql.productionplan.ProductionPlanMapper;
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.service.farmingrecord.FarmingRecordService; import cn.iocoder.yudao.module.farm.service.farmingrecord.FarmingRecordService;
import cn.iocoder.yudao.module.farm.service.farmingrecordinput.FarmingRecordInputService; import cn.iocoder.yudao.module.farm.service.farmingrecordinput.FarmingRecordInputService;
@@ -39,6 +44,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
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.*; import static cn.iocoder.yudao.module.farm.enums.CommonConstants.*;
import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.PRODUCTION_PLAN_NOT_EXISTS; import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.PRODUCTION_PLAN_NOT_EXISTS;
import static java.util.stream.Collectors.*;
/** /**
* @description: 种植中心 * @description: 种植中心
@@ -49,6 +55,8 @@ import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.PRODUCTION_P
@Slf4j @Slf4j
public class CropFarmingCenterServiceImpl implements CropFarmingCenterService { public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
private final SpeciesLibraryMapper speciesLibraryMapper;
private final PersonnelManagementMapper personnelManagementMapper;
private final BaseInfoMapper baseInfoMapper; private final BaseInfoMapper baseInfoMapper;
private final ProductionPlanMapper productionPlanMapper; private final ProductionPlanMapper productionPlanMapper;
private final ModelManagementService modelManagementService; private final ModelManagementService modelManagementService;
@@ -56,10 +64,12 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
private final FarmingRecordInputService farmingRecordInputService; private final FarmingRecordInputService farmingRecordInputService;
private final PlotInfoService plotInfoService; private final PlotInfoService plotInfoService;
public CropFarmingCenterServiceImpl(BaseInfoMapper baseInfoMapper, ProductionPlanMapper productionPlanMapper, public CropFarmingCenterServiceImpl(SpeciesLibraryMapper speciesLibraryMapper, PersonnelManagementMapper personnelManagementMapper, BaseInfoMapper baseInfoMapper, ProductionPlanMapper productionPlanMapper,
ModelManagementService modelManagementService, ModelManagementService modelManagementService,
FarmingRecordService farmingRecordService, FarmingRecordService farmingRecordService,
FarmingRecordInputService farmingRecordInputService, PlotInfoService plotInfoService) { FarmingRecordInputService farmingRecordInputService, PlotInfoService plotInfoService) {
this.speciesLibraryMapper = speciesLibraryMapper;
this.personnelManagementMapper = personnelManagementMapper;
this.baseInfoMapper = baseInfoMapper; this.baseInfoMapper = baseInfoMapper;
this.productionPlanMapper = productionPlanMapper; this.productionPlanMapper = productionPlanMapper;
this.modelManagementService = modelManagementService; this.modelManagementService = modelManagementService;
@@ -72,8 +82,8 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
public void createProductionPlan(ProductionPlanSaveReqVO reqVO) { public void createProductionPlan(ProductionPlanSaveReqVO reqVO) {
String speciesModelId = reqVO.getSpeciesModelId(); String speciesModelId = reqVO.getSpeciesModelId();
Map<String, String> baseNameMap = baseInfoMapper.selectList().stream().collect(Collectors.toMap(BaseInfoDO::getId, BaseInfoDO::getName, (v1, v2) -> v1)); Map<String, String> baseNameMap = baseInfoMapper.selectList().stream().collect(toMap(BaseInfoDO::getId, BaseInfoDO::getName, (v1, v2) -> v1));
Map<String, String> plotNameMap = plotInfoService.getPlotInfos().stream().collect(Collectors.toMap(PlotInfoDO::getPlotId, PlotInfoDO::getPlotName, (v1, v2) -> v1)); Map<String, String> plotNameMap = plotInfoService.getPlotInfos().stream().collect(toMap(PlotInfoDO::getPlotId, PlotInfoDO::getPlotName, (v1, v2) -> v1));
List<ProductionPlanSaveReqVO.CultivationArea> cultivationAreaList = reqVO.getCultivationAreaList(); List<ProductionPlanSaveReqVO.CultivationArea> cultivationAreaList = reqVO.getCultivationAreaList();
List<ProductionPlanDO> list = new ArrayList<>(); List<ProductionPlanDO> list = new ArrayList<>();
@@ -92,7 +102,7 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
obj.setPredictedYields(e.getPredictedYields()); obj.setPredictedYields(e.getPredictedYields());
obj.setTotalArea(e.getTotalArea()); obj.setTotalArea(e.getTotalArea());
obj.setPredictedArea(e.getPredictedArea()); obj.setPredictedArea(e.getPredictedArea());
obj.setRemainingArea(e.getRemainingArea()); // obj.setRemainingArea(e.getRemainingArea());
obj.setUsagePercentage(e.getUsagePercentage()); obj.setUsagePercentage(e.getUsagePercentage());
obj.setRemark(e.getRemark()); obj.setRemark(e.getRemark());
@@ -221,7 +231,7 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
} }
@Override @Override
public PageResult<ProductionPlanRespVO> getProductionPlanPage(ProductionPlanPageReqVO reqVO) { public PageResult<ProductionPlanRespVO> getProductionPlanPage(ProductionPlanPage2ReqVO reqVO) {
PageResult<ProductionPlanDO> productionPlanDOPageResult = productionPlanMapper.selectPage2(reqVO); PageResult<ProductionPlanDO> productionPlanDOPageResult = productionPlanMapper.selectPage2(reqVO);
PageResult<ProductionPlanRespVO> resultData = BeanUtils.toBean(productionPlanDOPageResult, ProductionPlanRespVO.class); PageResult<ProductionPlanRespVO> resultData = BeanUtils.toBean(productionPlanDOPageResult, ProductionPlanRespVO.class);
@@ -260,6 +270,117 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
} }
@Override
public PageResult<ProductionPlanResp2VO> getProductionPlanPage2(ProductionPlanPage2ReqVO reqVO) {
Map<String, String> speciesNameMap = speciesLibraryMapper.selectList().stream().collect(toMap(SpeciesLibraryDO::getId, SpeciesLibraryDO::getCultivarName, (v1, v2) -> v1));
Map<String, String> employeeNameMap = personnelManagementMapper.selectList().stream().collect(toMap(PersonnelManagementDO::getId, PersonnelManagementDO::getName, (v1, v2) -> v1));
PageResult<ProductionPlanDO> productionPlanDOPageResult = productionPlanMapper.selectPage2(reqVO);
List<ProductionPlanDO> planList = productionPlanDOPageResult.getList();
Map<String, List<ProductionPlanDO>> plansByBaseName = planList.stream().collect(Collectors.groupingBy(ProductionPlanDO::getBaseName, toList()));
List<ProductionPlanResp2VO> roots = new ArrayList<>();
int id = 1;
for (Map.Entry<String, List<ProductionPlanDO>> entry : plansByBaseName.entrySet()) {
String baseName = entry.getKey();
List<ProductionPlanDO> plans = entry.getValue();
ProductionPlanResp2VO root = new ProductionPlanResp2VO();
root.setId(id);
root.setParent(0);
root.setType(DHTMLX_GANTT_TYPE_1);
root.setOpen(DHTMLX_GANTT_OPEN_TRUE);
root.setText(baseName);
root.setSize(plans.size());
List<ProductionPlanResp2VO> nodes = this.loopPlanList(root, plans, speciesNameMap, employeeNameMap);
roots.addAll(nodes);
id += nodes.size();
}
return new PageResult<ProductionPlanResp2VO>(roots, (long) roots.size());
}
private List<ProductionPlanResp2VO> loopPlanList(ProductionPlanResp2VO currentParentNode,
List<ProductionPlanDO> subPlans,
Map<String, String> speciesNameMap,
Map<String, String> employeeNameMap) {
int parent = currentParentNode.getId();
int id = currentParentNode.getId() + 1;
List<ProductionPlanResp2VO> nodes = new ArrayList<>();
nodes.add(currentParentNode);
for (ProductionPlanDO subPlan : subPlans) {
ProductionPlanResp2VO subNode = new ProductionPlanResp2VO();
subNode.setId(id);
subNode.setParent(parent);
subNode.setType(DHTMLX_GANTT_TYPE_2);
subNode.setOpen(DHTMLX_GANTT_OPEN_TRUE);
subNode.setText(speciesNameMap.get(subPlan.getPlantSpeciesCode()));
subNode.setPlantSpeciesCode(subPlan.getPlantSpeciesCode());
subNode.setPlantSpeciesName(speciesNameMap.get(subPlan.getPlantSpeciesCode()));
subNode.setPlanNumber(subPlan.getPlanNumber());
subNode.setPlanStatus(subPlan.getPlanStatus());
subNode.setPlanStatusName(PLAN_MAP.getOrDefault(subPlan.getPlanStatus(),""));
subNode.setProductionStartDate(subPlan.getProductionStartDate());
subNode.setProductionEndDate(subPlan.getProductionEndDate());
subNode.setHarvestStartDate(subPlan.getHarvestStartDate());
subNode.setPredictedYields(subPlan.getPredictedYields());
subNode.setOverdueDays(this.countOverdueDays(subPlan));
subNode.setIntervalDays(this.countIntervalDays(subPlan));
subNode.setPlanOverview(this.getPlanOverview(subPlan));
subNode.setModelInfo(this.getModelManagement(subPlan,employeeNameMap));
nodes.add(subNode);
id++;
}
return nodes;
}
public ProductionPlanResp2VO.PlanOverview getPlanOverview(ProductionPlanDO planObj) {
BaseInfoDO baseObj = baseInfoMapper.selectOne("id", planObj.getBaseId());
ProductionPlanRespVO.PlanOverview source = productionPlanMapper.getPlanOverview(planObj.getBaseId());
source.setTotalArea(baseObj.getArea());
return BeanUtils.toBean(source, ProductionPlanResp2VO.PlanOverview.class);
}
public ProductionPlanResp2VO.ModelInfo getModelManagement(ProductionPlanDO planObj,Map<String, String> employeeNameMap) {
BaseInfoDO baseObj = baseInfoMapper.selectOne("id", planObj.getBaseId());
String employeeId = baseObj.getManager();
ModelManagementDO modelManagementDo = modelManagementService.getModelManagement("id", planObj.getSpeciesModelId());
ProductionPlanResp2VO.ModelInfo modelInfo = new ProductionPlanResp2VO.ModelInfo();
modelInfo.setId(modelManagementDo.getId());
modelInfo.setModelName(modelManagementDo.getModelName());
modelInfo.setSpeciesImage(modelManagementDo.getSpeciesImage());
modelInfo.setPlantSpeciesName(modelManagementDo.getSpeciesName());
modelInfo.setPlanNumber(planObj.getPlanNumber());
modelInfo.setPlanStatus(planObj.getPlanStatus());
modelInfo.setPlanSubStatus(ObjectUtils.defaultIfNull(planObj.getPlanSubStatus(), planObj.getPlanStatus()));
modelInfo.setPlanStatusName(PLAN_MAP.getOrDefault(planObj.getPlanStatus(), ""));
modelInfo.setPlanSubStatusName(PLAN_MAP.getOrDefault(planObj.getPlanSubStatus(), ""));
modelInfo.setCycleName(modelManagementDo.getCycleName());
modelInfo.setPredictedArea(planObj.getPredictedArea());
modelInfo.setPredictedYields(planObj.getPredictedYields());
modelInfo.setProgressBar("1/10"); // TODO: 2025/8/30
modelInfo.setBaseName(planObj.getBaseName());
modelInfo.setBaseManager(employeeNameMap.get(employeeId)); // 分割,
return modelInfo;
}
private int countIntervalDays(ProductionPlanDO aDo) {
LocalDate productionStartDate = aDo.getProductionStartDate();
LocalDate productionEndDate = aDo.getProductionEndDate();
Period period = Period.between(productionStartDate, productionEndDate);
return period.getDays();
}
private int countOverdueDays(ProductionPlanDO aDo) {
ProductionPlanRespVO productionPlanRespVO = BeanUtils.toBean(aDo, ProductionPlanRespVO.class);
return this.countOverdueDays(productionPlanRespVO);
}
private int countOverdueDays(ProductionPlanRespVO vo) { private int countOverdueDays(ProductionPlanRespVO vo) {
Integer planStatus = vo.getPlanStatus(); Integer planStatus = vo.getPlanStatus();
Integer planSubStatus = vo.getPlanSubStatus(); Integer planSubStatus = vo.getPlanSubStatus();

View File

@@ -55,6 +55,7 @@ public interface ModelManagementService {
*/ */
ModelManagementRespVO getModelManagement(String id); ModelManagementRespVO getModelManagement(String id);
ModelManagementDO getModelManagement(String field,String id);
/** /**
* 获得模型管理分页 * 获得模型管理分页
* *

View File

@@ -232,6 +232,11 @@ public class ModelManagementServiceImpl implements ModelManagementService {
modelManagementMapper.updateById(existing); modelManagementMapper.updateById(existing);
} }
@Override
public ModelManagementDO getModelManagement(String field,String id) {
return modelManagementMapper.selectOne(field,id);
}
@Override @Override
public void deleteModelManagement(String id) { public void deleteModelManagement(String id) {
// 校验存在 // 校验存在

View File

@@ -112,4 +112,11 @@ public interface ProductionPlanService {
* @return * @return
*/ */
int getGrowingPlotCount(String baseId); int getGrowingPlotCount(String baseId);
/**
* 计算在种地块面积
* @param baseId
* @return
*/
double getRemainingArea(String baseId);
} }

View File

@@ -142,13 +142,15 @@ public class ProductionPlanServiceImpl implements ProductionPlanService {
// 创建地块响应对象 // 创建地块响应对象
BaseNamePlanRespVO.PlotInfoVO plotVO = new BaseNamePlanRespVO.PlotInfoVO(); BaseNamePlanRespVO.PlotInfoVO plotVO = new BaseNamePlanRespVO.PlotInfoVO();
plotVO.setPlotId(plotId); plotVO.setId(plotId);
plotVO.setPlotName(plotPlans.get(0).getPlotName()); // 取第一个计划的地块名称 plotVO.setName(plotPlans.get(0).getPlotName()); // 取第一个计划的地块名称
plotVO.setChildren(new ArrayList<>()); plotVO.setChildren(new ArrayList<>());
// 创建计划信息列表 // 创建计划信息列表
for (ProductionPlanDO plan : plotPlans) { for (ProductionPlanDO plan : plotPlans) {
BaseNamePlanRespVO.PlanInfoVO planVO = new BaseNamePlanRespVO.PlanInfoVO(); BaseNamePlanRespVO.PlanInfoVO planVO = new BaseNamePlanRespVO.PlanInfoVO();
planVO.setId(plan.getPlanNumber());
planVO.setName(plan.getPlanNumber());
planVO.setPlanNumber(plan.getPlanNumber()); planVO.setPlanNumber(plan.getPlanNumber());
planVO.setProductionStartDate(plan.getProductionStartDate()); planVO.setProductionStartDate(plan.getProductionStartDate());
planVO.setProductionEndDate(plan.getProductionEndDate()); planVO.setProductionEndDate(plan.getProductionEndDate());
@@ -203,4 +205,13 @@ public class ProductionPlanServiceImpl implements ProductionPlanService {
return (int) count; return (int) count;
} }
@Override
public double getRemainingArea(String baseId) {
List<ProductionPlanDO> planList = productionPlanMapper.selectList("base_id", baseId);
return planList.stream()
.filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2))
.mapToDouble(ProductionPlanDO::getPredictedArea)
.sum();
}
} }