fix (farm): 首页,生产计划,微信登录

- 网箱编号规则 重构
- 微信登录,租户列表返回套餐信息
This commit is contained in:
达富斌
2025-11-10 21:50:08 +08:00
parent 90eb3ab7e1
commit ba9159c3c0
31 changed files with 522 additions and 107 deletions

View File

@@ -166,17 +166,7 @@ public class CropFarmingCenterController {
@Operation(summary = "生产计划-开始按钮")
@PutMapping("/production-plan/start")
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;
updateReqVO.setTotalArea(totalArea);
updateReqVO.setPredictedArea(predictedArea);
updateReqVO.setUsagePercentage(usagePercentage);
updateReqVO.setPlanStatus(CommonConstants.PLAN_STATUS_2);
cropFarmingCenterService.updateProductionPlan(updateReqVO);
return success(true);
return success(cropFarmingCenterService.startPlanning(updateReqVO));
}
@Operation(summary = "生产计划-结束按钮")
@@ -269,13 +259,6 @@ public class CropFarmingCenterController {
return success(res);
}
// @Operation(summary = "农事报表-农事任务分类统计")
// @GetMapping("/farming-report/chart/farm-type")
// public CommonResult<List<FarmTypeChartRespVO>> getFarmTypeChart(ChartCommonReqVO req) {
// List<FarmTypeChartRespVO> res = cropFarmingCenterService.getFarmTypeChart(req);
// return success(res);
// }
@Operation(summary = "农事报表-种植类信息")
@GetMapping("/farming-report/chart/species/plant")
public CommonResult<List<PlantChartRespVO>> getPlantChart(ChartCommonReqVO req) {

View File

@@ -24,6 +24,10 @@ public class FarmingReport1RespVO {
@Schema(description = "基地名称")
private String baseName;
private String plotName;
private String taskTypeID;
private String taskTypeName;
private String taskNameID;
private String taskName;
@Schema(description = "计划编号")
private String planNumber;

View File

@@ -74,7 +74,7 @@ public class ProductionPlanSaveReqVO {
private Double usagePercentage;
@Schema(description = "地块总网箱数")
private Integer plotGridNumber;
@Schema(description = "地块使用剩余网箱数")
@Schema(description = "地块计划使用网箱数")
private Integer predictedGridNumber;
@Schema(description = "备注")
private String remark;

View File

@@ -78,6 +78,10 @@ public class ProductionPlanUpdateReqVO {
private Double remainingArea;
@Schema(description = "占地面积")
private Double usagePercentage;
@Schema(description = "地块总网箱数")
private Integer plotGridNumber;
@Schema(description = "地块计划使用网箱数")
private Integer predictedGridNumber;
@Schema(description = "备注")
private String remark;

View File

@@ -78,9 +78,9 @@ public class BaseInfoRespVO {
@AllArgsConstructor
@NoArgsConstructor
public static class PlotInfo{
@Schema(description = "地块类型")
private Integer type;
private String typeName;
// @Schema(description = "地块类型")
// private Integer type;
// private String typeName;
@Schema(description = "地块ID")
private String plotId;
@Schema(description = "地块名称")

View File

@@ -1,20 +1,13 @@
package cn.iocoder.yudao.module.farm.controller.admin.managementcenter.basicdatamanagement.inputlibrary;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.basicdatamanagement.inputlibrary.vo.InputLibraryPageReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.basicdatamanagement.inputlibrary.vo.InputLibraryRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.basicdatamanagement.inputlibrary.vo.InputLibrarySaveReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.basicdatamanagement.inputlibrary.vo.inputs.*;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.basicdatamanagement.inputlibrary.vo.usagerecords.InputUsageRecordsPageReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.basicdatamanagement.inputlibrary.vo.usagerecords.InputUsageRecordsRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.basicdatamanagement.inputlibrary.vo.usagerecords.InputUsageRecordsSaveReqVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.inputlibrary.InputsDO;
import cn.iocoder.yudao.module.farm.manager.inputs.InputsManager;
import cn.iocoder.yudao.module.farm.service.inputlibrary.InputsService;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import org.springframework.validation.annotation.Validated;
@@ -22,21 +15,14 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.module.farm.dal.dataobject.inputlibrary.InputLibraryDO;
import cn.iocoder.yudao.module.farm.service.inputlibrary.InputLibraryService;
@Tag(name = "管理心中 - 基础数据管理 - 投入品库维护")
@RestController
@RequestMapping("/farm/input-library")
@@ -139,7 +125,7 @@ public class InputLibraryController {
@PostMapping("/usage-records/create")
@Operation(summary = "投入品使用日志-新增)")
public CommonResult<String> createInputUsageRecords(InputUsageRecordsSaveReqVO req) {
public CommonResult<String> createInputUsageRecords(@Valid @RequestBody InputUsageRecordsSaveReqVO req) {
inputsManager.createInputUsageRecords(req);
return success("success");
}

View File

@@ -19,6 +19,7 @@ public class InputUsageRecordsSaveReqVO {
@Schema(description = "投入品ID", example = "30559")
private String inputId;
private String inputName;
@Schema(description = "农事记录ID", example = "26500")
private String farmRecordId;
@@ -40,5 +41,6 @@ public class InputUsageRecordsSaveReqVO {
private String baseId;
private String plotId;
private String gridCode;
}

View File

@@ -59,4 +59,10 @@ public class InputUsageRecordsDO extends BaseDO {
*/
private String remark;
private String baseId;
private String baseName;
private String plotId;
private String plotName;
private String gridCode;
}

View File

@@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.farm.dal.dataobject.productionplan;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* @description: 生产计划 与 网箱 关系表
* @author: binda
* @date: 2025/11/10 15:23
*/
@TableName("farm_production_plan_used_grid")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductionPlanUsedGridDO extends BaseDO {
@TableId(type = IdType.INPUT)
private String id;
private String planNumber;
private String baseId;
// 取值来源: farm_plot_info.id
private String plotId;
// 取值来源: farm_plot_info.plot_id
private String plotCode;
private String gridCode;
}

View File

@@ -6,7 +6,9 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.farm.controller.admin.agreement.vo.AgreementReqVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.agreement.AgreementDO;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface AgreementMapper extends BaseMapperX<AgreementDO> {
@@ -14,4 +16,8 @@ public interface AgreementMapper extends BaseMapperX<AgreementDO> {
default PageResult<AgreementDO> selectPage(AgreementReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<AgreementDO>().orderByDesc(AgreementDO::getCreateTime));
}
@InterceptorIgnore(tenantLine = "true")
@Select("SELECT * FROM system_agreement WHERE deleted = 0 AND type = #{type}")
AgreementDO selectByType(String type);
}

View File

@@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.farm.dal.mysql.productionplan;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanUsedGridDO;
import org.apache.ibatis.annotations.Mapper;
/**
* @description:
* @author: binda
* @date: 2025/11/10 15:30
*/
@Mapper
public interface ProductionPlanUsedGridMapper extends BaseMapperX<ProductionPlanUsedGridDO> {
}

View File

@@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.farm.event.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @description:
* @author: binda
* @date: 2025/11/10 15:48
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GridBuildEvent {
String planNumber;
String plotCode;
private Integer plannedQuantity; // 计划数量
private Integer remainingQuantity; // 剩余数量
private Integer totalQuantity; // 总数
}

View File

@@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.farm.event.listeners;
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.GridBuildEvent;
import cn.iocoder.yudao.module.farm.event.utils.GridCodeGenerator;
import cn.iocoder.yudao.module.farm.service.plotinfo.PlotInfoService;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @description: 时间监听
* @author: binda
* @date: 2025/11/10 16:01
*/
@Component
public class EventListeners {
private final PlotInfoService plotInfoService;
private final ProductionPlanUsedGridMapper productionPlanUsedGridMapper;
public EventListeners(PlotInfoService plotInfoService, ProductionPlanUsedGridMapper productionPlanUsedGridMapper) {
this.plotInfoService = plotInfoService;
this.productionPlanUsedGridMapper = productionPlanUsedGridMapper;
}
@Async
@EventListener
public void buildGrid(GridBuildEvent dto) {
String planNumber = dto.getPlanNumber();
String plotCode = dto.getPlotCode();
int plannedQuantity = dto.getPlannedQuantity(); // 计划数量
int remainingQuantity = dto.getRemainingQuantity(); // 剩余数量
int totalQuantity = dto.getTotalQuantity(); // 总数
PlotInfoDO plotInfo = plotInfoService.getPlotInfo(plotCode);
List<GridCodeGenerator.GridCodeRespVO> gridCodeRespVOS = GridCodeGenerator.generateGridCodes(
totalQuantity,
plannedQuantity,
remainingQuantity,
plotCode);
List<ProductionPlanUsedGridDO> list = gridCodeRespVOS.stream().map(e -> {
return new ProductionPlanUsedGridDO(
IdUtil.fastUUID(),
planNumber,
plotInfo.getBaseId(),
plotInfo.getId(),
plotInfo.getPlotId(),
e.getGridCode()
);
}).toList();
productionPlanUsedGridMapper.insertBatch(list);
}
}

View File

@@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.farm.event.publisher;
import cn.iocoder.yudao.module.farm.controller.admin.cropfarmingcenter.vo.ProductionPlanRespVO;
import cn.iocoder.yudao.module.farm.event.dto.GridBuildEvent;
import cn.iocoder.yudao.module.farm.service.productionplan.ProductionPlanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
/**
* @description:
* @author: binda
* @date: 2025/11/10 16:10
*/
@Component
public class GridEventPublisher {
@Autowired
private ApplicationEventPublisher eventPublisher;
@Autowired
private ProductionPlanService productionPlanService;
/**
* 构建网箱编号
*/
public void buildGrid(ProductionPlanRespVO updateReqVO) {
String planNumber = updateReqVO.getPlanNumber();
String plotCode = updateReqVO.getPlotId();
// 总数
int totalQuantity = updateReqVO.getPlotGridNumber();
// 计划数量
int plannedQuantity = updateReqVO.getPredictedGridNumber();
// 剩余数量
int remainingQuantity = productionPlanService.getPredictedGridNumber(plotCode,totalQuantity);
eventPublisher.publishEvent(new GridBuildEvent(planNumber,plotCode,plannedQuantity, remainingQuantity, totalQuantity));
}
}

View File

@@ -0,0 +1,134 @@
package cn.iocoder.yudao.module.farm.event.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
/**
* @description: 网箱编号生成规则
* @author: binda
* @date: 2025/11/10 19:52
*/
public class GridCodeGenerator {
/**
* 生成网格编号响应列表
* @param total 总数
* @param planCount 计划使用数量
* @param remaining 剩余数量
* @param plotCode 编号前缀
* @return 网格编号响应列表
*/
public static List<GridCodeRespVO> generateGridCodes(int total, int planCount, int remaining, String plotCode) {
if (planCount <= 0) {
return new ArrayList<>();
}
if (planCount > total) {
throw new IllegalArgumentException("计划数量不能超过总数");
}
List<GridCodeRespVO> result = new ArrayList<>();
// 已使用数量
int used = total - remaining;
// 可用连续编号数量
int availableSequential = total - used;
if (planCount <= availableSequential) {
// 只需要连续编号
int start = used + 1;
int end = start + planCount - 1;
for (int i = start; i <= end; i++) {
GridCodeRespVO vo = new GridCodeRespVO();
vo.setPlotCode(plotCode);
vo.setGridCode(plotCode + "-" + formatNumber(i, total));
result.add(vo);
}
} else {
// 需要连续编号 + 从头跳号
// 第一部分:连续编号
int sequentialStart = used + 1;
int sequentialEnd = total;
for (int i = sequentialStart; i <= sequentialEnd; i++) {
GridCodeRespVO vo = new GridCodeRespVO();
vo.setPlotCode(plotCode);
vo.setGridCode(plotCode + "-" + formatNumber(i, total));
result.add(vo);
}
// 第二部分:从头跳号
int skipCount = planCount - availableSequential;
for (int i = 1; i <= skipCount; i++) {
GridCodeRespVO vo = new GridCodeRespVO();
vo.setPlotCode(plotCode);
vo.setGridCode(plotCode + "-" + formatNumber(i, total));
result.add(vo);
}
}
return result;
}
/**
* 格式化编号,如 1 -> 0001, 100 -> 0100
* @param number 原始数字
* @param total 总数(用于确定位数)
* @return 格式化后的编号字符串
*/
private static String formatNumber(int number, int total) {
// 根据总数确定位数,比如500需要3位,1000需要4位
int digits = String.valueOf(total).length();
return String.format("%0" + digits + "d", number);
}
/**
* 生成编号范围字符串(用于调试和显示)
*/
public static String generateRangeString(int total, int planCount, int remaining, String plotCode) {
if (planCount <= 0) return "无";
if (planCount > total) throw new IllegalArgumentException("计划数量超过总数");
int used = total - remaining;
int availableSequential = total - used;
if (planCount <= availableSequential) {
int start = used + 1;
int end = start + planCount - 1;
return plotCode + "-" + formatNumber(start, total) + " - " +
plotCode + "-" + formatNumber(end, total);
} else {
int sequentialStart = used + 1;
int sequentialEnd = total;
int skipCount = planCount - availableSequential;
return plotCode + "-" + formatNumber(sequentialStart, total) + " - " +
plotCode + "-" + formatNumber(sequentialEnd, total) + ", " +
plotCode + "-" + formatNumber(1, total) + " - " +
plotCode + "-" + formatNumber(skipCount, total);
}
}
/**
* 计算使用后的剩余数量
*/
public static int getNextRemaining(int total, int planCount, int currentRemaining) {
int used = total - currentRemaining;
if (planCount <= currentRemaining) {
return currentRemaining - planCount;
} else {
return total - (used + planCount);
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class GridCodeRespVO{
private String plotCode; // 编号前缀
private String gridCode; // 格式化后的编号(包含前缀)
}
}

View File

@@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.farm.service.agreement;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.farm.controller.admin.agreement.vo.AgreementAddVO;
import cn.iocoder.yudao.module.farm.controller.admin.agreement.vo.AgreementReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.agreement.vo.AgreementVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.agreement.AgreementDO;
import cn.iocoder.yudao.module.farm.dal.mysql.agreement.AgreementMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -57,6 +57,7 @@ public class AgreementServiceImpl implements AgreementService {
@Override
public CommonResult<AgreementDO> getAgreementByType(String type) {
return CommonResult.success(agreementMapper.selectOne(new QueryWrapper<AgreementDO>().eq("type", type)));
return CommonResult.success(agreementMapper.selectOne(new LambdaQueryWrapperX<AgreementDO>()
.eq(AgreementDO::getType, type), false));
}
}

View File

@@ -214,10 +214,10 @@ public class BaseInfoServiceImpl implements BaseInfoService {
for (PlotInfoDO p : plotInfoDOS) {
if (p.getBaseId().equals(key)) {
BigDecimal plotArea = p.getPlotArea();
double remainingArea = productionPlanService.getPredictedArea(p.getId(),plotArea);
double remainingArea = productionPlanService.getPredictedArea(p.getPlotId(),plotArea);
int plotGridNumber = p.getGridNumber();
int remainingGridNumber = productionPlanService.getPredictedGridNumber(p.getId(), plotGridNumber);
int remainingGridNumber = productionPlanService.getPredictedGridNumber(p.getPlotId(), plotGridNumber);
childList.add(new BaseNameRespVO.PlotInfoVO(
p.getPlotId(),
@@ -321,10 +321,10 @@ public class BaseInfoServiceImpl implements BaseInfoService {
// 户主
List<PlotLesseeDetailsRespVO> lesseeList = plotInfoService.getPlotLesseeList2(aDo.getId());
String plotManager = employeeMap.getOrDefault(aDo.getEmployeeId(), "系统");
String typeName = PLOT_TYPE_NAME_MAP.get(Integer.valueOf(aDo.getType()));
// String typeName = PLOT_TYPE_NAME_MAP.get(Integer.valueOf(aDo.getType()));
BaseInfoRespVO.PlotInfo target = new BaseInfoRespVO.PlotInfo(
Integer.valueOf(aDo.getType()),
typeName,
// Integer.valueOf(aDo.getType()),
// typeName,
aDo.getId(),
aDo.getPlotName(),
aDo.getPlotColor(),
@@ -347,33 +347,7 @@ public class BaseInfoServiceImpl implements BaseInfoService {
}
private List<ProductionPlanGridRespVO> packageGridInfo(String plotId) {
List<ProductionPlanGridRespVO> res = new ArrayList<>();
List<ProductionPlanDO> productionPlans = productionPlanService.getProductionPlans(plotId);
for (int j = 0; j < productionPlans.size(); j++) {
ProductionPlanDO p = productionPlans.get(j);
int predictedGridNumber = p.getPredictedGridNumber();
if (predictedGridNumber == 0) {
continue;
}
List<ProductionPlanGridRespVO.Row> rows = new ArrayList<>();
for (int i = 1; i < predictedGridNumber + 1; i++) {
ProductionPlanGridRespVO.Row row = new ProductionPlanGridRespVO.Row();
row.setSort(i);
row.setGridCode(plotId + "-" + String.format("%04d", i));
rows.add(row);
}
ProductionPlanGridRespVO g = new ProductionPlanGridRespVO();
g.setPlanNumber(p.getPlanNumber()+" ("+CommonConstants.PLAN_MAP.get(p.getPlanStatus())+")");
g.setColor(COLOR_MAP.getOrDefault(j+1,"#00FFFF"));
g.setRows(rows);
res.add(g);
}
return res;
return productionPlanService.getGridForPlanList(plotId);
}
@Override

View File

@@ -98,4 +98,7 @@ public interface CropFarmingCenterService {
List<FarmRecordForFarmNameChartRespVO> getFarmRecord4FarmNameChart(ChartCommonReqVO req);
List<InputUsageTrendChartRespVO> getInputUsageTrendChart(ChartCommonReqVO req);
Boolean startPlanning(ProductionPlanUpdateReqVO updateReqVO);
}

View File

@@ -31,13 +31,17 @@ import cn.iocoder.yudao.module.farm.dal.mysql.inputlibrary.InputUsageRecordsMapp
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.productionplan.ProductionPlanMapper;
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.GridEventPublisher;
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.farmingrecordinput.FarmingRecordInputService;
import cn.iocoder.yudao.module.farm.service.farmingtypemaintenance.FarmingTypeMaintenanceService;
import cn.iocoder.yudao.module.farm.service.modelmanagement.ModelManagementService;
import cn.iocoder.yudao.module.farm.service.plotinfo.PlotInfoService;
import cn.iocoder.yudao.module.farm.service.productionplan.ProductionPlanService;
import cn.iocoder.yudao.module.farm.service.specieslibrary.SpeciesLibraryService;
import cn.iocoder.yudao.module.farm.utils.BigDecimalUtil;
import cn.iocoder.yudao.module.farm.utils.StrHelperUtil;
@@ -76,6 +80,7 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
private final BaseInfoMapper baseInfoMapper;
private final PlotInfoMapper plotInfoMapper;
private final ProductionPlanMapper productionPlanMapper;
private final ProductionPlanUsedGridMapper productionPlanUsedGridMapperMapper;
private final FarmingRecordMapper farmingRecordMapper;
private final InputUsageRecordsMapper inputUsageRecordsMapper;
@@ -86,17 +91,21 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
private final PlotInfoService plotInfoService;
private final SpeciesLibraryService speciesLibraryService;
private final FarmingTypeMaintenanceService farmingTypeMaintenanceService;
private final FarmingNameMaintenanceService farmingNameMaintenanceService;
private final DictDataService dictDataService;
private final GridEventPublisher gridEventPublisher;
private final ProductionPlanService productionPlanService;
public CropFarmingCenterServiceImpl(SpeciesLibraryMapper speciesLibraryMapper, PersonnelManagementMapper personnelManagementMapper, BaseInfoMapper baseInfoMapper, PlotInfoMapper plotInfoMapper, ProductionPlanMapper productionPlanMapper,
FarmingRecordMapper farmingRecordMapper, InputUsageRecordsMapper inputUsageRecordsMapper, ModelManagementService modelManagementService,
ProductionPlanUsedGridMapper productionPlanUsedGridMapperMapper, FarmingRecordMapper farmingRecordMapper, InputUsageRecordsMapper inputUsageRecordsMapper, ModelManagementService modelManagementService,
FarmingRecordService farmingRecordService,
FarmingRecordInputService farmingRecordInputService, PlotInfoService plotInfoService, SpeciesLibraryService speciesLibraryService, FarmingTypeMaintenanceService farmingTypeMaintenanceService, DictDataService dictDataService) {
FarmingRecordInputService farmingRecordInputService, PlotInfoService plotInfoService, SpeciesLibraryService speciesLibraryService, FarmingTypeMaintenanceService farmingTypeMaintenanceService, FarmingNameMaintenanceService farmingNameMaintenanceService, DictDataService dictDataService, GridEventPublisher gridEventPublisher, ProductionPlanService productionPlanService) {
this.speciesLibraryMapper = speciesLibraryMapper;
this.personnelManagementMapper = personnelManagementMapper;
this.baseInfoMapper = baseInfoMapper;
this.plotInfoMapper = plotInfoMapper;
this.productionPlanMapper = productionPlanMapper;
this.productionPlanUsedGridMapperMapper = productionPlanUsedGridMapperMapper;
this.farmingRecordMapper = farmingRecordMapper;
this.inputUsageRecordsMapper = inputUsageRecordsMapper;
this.modelManagementService = modelManagementService;
@@ -105,8 +114,11 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
this.plotInfoService = plotInfoService;
this.speciesLibraryService = speciesLibraryService;
this.farmingTypeMaintenanceService = farmingTypeMaintenanceService;
this.farmingNameMaintenanceService = farmingNameMaintenanceService;
this.dictDataService = dictDataService;
this.gridEventPublisher = gridEventPublisher;
this.productionPlanService = productionPlanService;
}
@Override
@@ -439,25 +451,13 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
}
private void buildPlanGrid(ProductionPlanDO p, ProductionPlanResp2VO.ModelInfo m) {
Integer predictedGridNumber = p.getPredictedGridNumber();
String plotCode = p.getPlotId();
Integer predictedGridNumber = p.getPredictedGridNumber();
if (predictedGridNumber == 0) {
return;
}
List<ProductionPlanGridRespVO.Row> rows = new ArrayList<>();
for (int i = 1; i < predictedGridNumber + 1; i++) {
ProductionPlanGridRespVO.Row row = new ProductionPlanGridRespVO.Row();
row.setSort(i);
row.setGridCode(plotCode + "-" + String.format("%04d", i));
rows.add(row);
}
ProductionPlanGridRespVO planGridInfo = new ProductionPlanGridRespVO();
planGridInfo.setPlanNumber(p.getPlanNumber());
planGridInfo.setColor(COLOR_MAP.get(1));
planGridInfo.setRows(rows);
ProductionPlanGridRespVO planGridInfo = productionPlanService.getGridForPlan(p.getPlanNumber());
m.setPredictedGridNumber(predictedGridNumber);
m.setPlanGridInfo(planGridInfo);
@@ -733,7 +733,15 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
@Override
public List<FarmingReport1RespVO> getFarmReport(ChartCommonReqVO req) {
req.setTenantId(getLoginUser().getTenantId().toString());
Map<String, String> typeNameMap = farmingTypeMaintenanceService.getTypeNameById();
Map<String, String> nameMap = farmingNameMaintenanceService.getNameById();
List<FarmingReport1RespVO> list = inputUsageRecordsMapper.getFarmReport(req);
list.stream().forEach(e -> {
e.setTaskTypeName(typeNameMap.get(e.getTaskTypeID()));
e.setTaskName(nameMap.get(e.getTaskNameID()));
});
return list;
}
@@ -784,6 +792,24 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService {
return inputUsageRecordsMapper.getInputUsageTrendChart(req);
}
@Override
public Boolean startPlanning(ProductionPlanUpdateReqVO updateReqVO) {
ProductionPlanRespVO res = this.getProductionPlan(updateReqVO.getId());
double totalArea = res.getTotalArea();
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);
return true;
}
private ProductionPlanReportRespVO.Models convertToModel(ProductionPlanDO plan, Map<String, String> speciesName) {
String plantSpeciesName = speciesName.get(plan.getPlantSpeciesCode());
String planStatusName = PLAN_MAP.get(plan.getPlanStatus());

View File

@@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;
/**
* 农事名称维护 Service 接口
@@ -68,4 +69,5 @@ public interface FarmingNameMaintenanceService {
*/
List<FarmingNameMaintenanceTreeRespVO> getFarmingNameMaintenanceTree();
Map<String, String> getNameById();
}

View File

@@ -19,6 +19,7 @@ import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
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;
@@ -162,4 +163,16 @@ public class FarmingNameMaintenanceServiceImpl implements FarmingNameMaintenance
return result;
}
@Override
public Map<String, String> getNameById() {
List<FarmingNameMaintenanceDO> list = farmingNameMaintenanceMapper.selectList(FarmingNameMaintenanceDO::getTenantId, getLoginUser().getTenantId());
return list.stream()
.filter(item -> item != null &&
item.getUseStatus() != null &&
item.getUseStatus() == 1)
.collect(Collectors.toMap(
FarmingNameMaintenanceDO::getId,
FarmingNameMaintenanceDO::getFarmingName
));
}
}

View File

@@ -92,7 +92,7 @@ public class HomeServiceImpl implements HomeService {
// 基地集合
List<HomeInfo.BaseInfo> baseList = new ArrayList<>();
for (BaseInfoDO baseInfoDO : baseInfoService.getBaseInfosById(baseId)) {
baseList.add(this.getBaseInfo(baseInfoDO,employeeNameMap));
baseList.add(this.getBaseInfo(baseInfoDO));
}
return new HomeInfo(baseOverviewInfo, statisticalInfo,baseList);
@@ -106,17 +106,17 @@ public class HomeServiceImpl implements HomeService {
// 基地集合
List<HomeInfo.BaseInfo> baseList = new ArrayList<>();
for (BaseInfoDO baseInfoDO : baseInfoService.getBaseInfosById(baseId)) {
baseList.add(this.getBaseInfo(baseInfoDO,employeeNameMap));
baseList.add(this.getBaseInfo(baseInfoDO));
}
return new HomeInfo(null, null,baseList);
}
private BaseInfo getBaseInfo(BaseInfoDO baseObj, Map<String, String> employeeNameMap) {
private BaseInfo getBaseInfo(BaseInfoDO baseObj) {
String baseId = baseObj.getId();
String baseName = baseObj.getName();
String point = baseObj.getPoint();
List<PlotInfo> plotInfos = this.getPlotInfoList(baseObj, employeeNameMap);
List<PlotInfo> plotInfos = this.getPlotInfoList(baseObj);
return new BaseInfo(baseId,baseName,point,plotInfos);
}
@@ -211,7 +211,7 @@ public class HomeServiceImpl implements HomeService {
return t;
}
private List<PlotInfo> getPlotInfoList(BaseInfoDO baseObj,Map<String, String> employeeNameMap) {
private List<PlotInfo> getPlotInfoList(BaseInfoDO baseObj) {
List<PlotInfoDO> plotList = plotInfoService.getPlotInfos(baseObj.getId(), baseObj.getName());
List<PlotInfo> targetList = BeanUtils.toBean(plotList, PlotInfo.class);

View File

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.farm.service.productionplan;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.farm.controller.admin.api.vo.*;
import cn.iocoder.yudao.module.farm.controller.admin.cropfarmingcenter.vo.grid.ProductionPlanGridRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.digitalcockpit.vo.CropStatisticsRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.digitalcockpit.vo.YieldStatisticsRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.baseinfo.vo.BaseNamePlanRespVO;
@@ -235,4 +236,9 @@ public interface ProductionPlanService {
// private Integer cultivatingPlotAreaCount;
}
ProductionPlanGridRespVO getGridForPlan(String planNumber);
List<ProductionPlanGridRespVO> getGridForPlanList(String plotCode);
}

View File

@@ -5,14 +5,17 @@ import cn.hutool.core.util.IdUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.farm.controller.admin.api.vo.*;
import cn.iocoder.yudao.module.farm.controller.admin.cropfarmingcenter.vo.grid.ProductionPlanGridRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.digitalcockpit.vo.CropStatisticsRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.digitalcockpit.vo.YieldStatisticsRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.baseinfo.vo.BaseNamePlanRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.cropfarmingcenter.vo.productionplan.ProductionPlanPageReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.cropfarmingcenter.vo.productionplan.ProductionPlanSaveReqVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.baseinfo.BaseInfoDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanUsedGridDO;
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.productionplan.ProductionPlanUsedGridMapper;
import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMapper;
import cn.iocoder.yudao.module.farm.service.specieslibrary.SpeciesLibraryService;
import cn.iocoder.yudao.module.farm.utils.DateUtils;
@@ -54,6 +57,8 @@ public class ProductionPlanServiceImpl implements ProductionPlanService {
@Resource
private ProductionPlanMapper productionPlanMapper;
@Resource
private ProductionPlanUsedGridMapper productionPlanUsedGridMapperMapper;
@Resource
private SpeciesLibraryMapper speciesLibraryMapper;
@Resource
private SpeciesLibraryService speciesLibraryService;
@@ -314,7 +319,7 @@ public class ProductionPlanServiceImpl implements ProductionPlanService {
.filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2))
.mapToDouble(ProductionPlanDO::getPredictedArea)
.sum();
return plotArea.subtract(BigDecimal.valueOf(sum)).doubleValue();
return BigDecimal.valueOf(sum).subtract(plotArea).doubleValue();
}
@Override
@@ -470,4 +475,40 @@ public class ProductionPlanServiceImpl implements ProductionPlanService {
return null;
}
@Override
public ProductionPlanGridRespVO getGridForPlan(String planNumber) {
List<ProductionPlanUsedGridDO> pugList = productionPlanUsedGridMapperMapper.selectList(ProductionPlanUsedGridDO::getPlanNumber, planNumber);
List<ProductionPlanGridRespVO.Row> rows = new ArrayList<>();
for (int i = 0; i < pugList.size(); i++) {
rows.add(new ProductionPlanGridRespVO.Row(i + 1, pugList.get(i).getGridCode()));
}
rows.sort(Comparator.comparing(row ->
Integer.parseInt(row.getGridCode().split("-")[1])
));
ProductionPlanGridRespVO planGridInfo = new ProductionPlanGridRespVO();
planGridInfo.setPlanNumber(planNumber);
planGridInfo.setColor(COLOR_MAP.get(1));
planGridInfo.setRows(rows);
return planGridInfo;
}
@Override
public List<ProductionPlanGridRespVO> getGridForPlanList(String plotCode) {
List<ProductionPlanUsedGridDO> pugList = productionPlanUsedGridMapperMapper.selectList(ProductionPlanUsedGridDO::getPlotCode, plotCode);
Map<String, List<ProductionPlanUsedGridDO>> groupedMap = pugList.stream()
.collect(Collectors.groupingBy(ProductionPlanUsedGridDO::getPlanNumber));
List<ProductionPlanGridRespVO> res = new ArrayList<>();
for (Map.Entry<String, List<ProductionPlanUsedGridDO>> en : groupedMap.entrySet()) {
ProductionPlanGridRespVO plan = this.getGridForPlan(en.getKey());
res.add(plan);
}
return res;
}
}

View File

@@ -55,6 +55,8 @@
ffr.id AS farmRecordId,
ffr.base_name AS baseName,
ffr.plot_name AS plotName,
ffr.task_type AS taskTypeId,
ffr.task_name AS taskNameId,
ffr.task_scope AS planNumber,
ffr.task_start_date AS taskStartDate,
ffr.task_end_date AS taskEndDate,
@@ -84,10 +86,12 @@
ffr.id,
ffr.base_name,
ffr.plot_name,
ffr.task_type,
ffr.task_name,
ffr.task_scope,
ffr.task_start_date,
ffr.task_end_date
ORDER BY ffr.task_start_date DESC
ORDER BY inputTotalPrice DESC
</select>
<select id="getInputUsageByTypeChart"

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.farm.dal.mysql.productionplan.ProductionPlanUsedGridMapper">
</mapper>