feat (farm): 农场首页

- 为生产计划随机一个在其地块范围内的坐标
This commit is contained in:
达富斌
2025-09-02 20:40:01 +08:00
parent b8f8f15802
commit 024249f524
4 changed files with 133 additions and 5 deletions

View File

@@ -167,7 +167,6 @@ public class HomeInfo {
private String plotName; private String plotName;
@Schema(description = "基地负责人") @Schema(description = "基地负责人")
private String manager; private String manager;
@Schema(description = "物种名称") @Schema(description = "物种名称")
private String plantSpeciesName; private String plantSpeciesName;
@Schema(description = "计划编号") @Schema(description = "计划编号")
@@ -188,5 +187,7 @@ public class HomeInfo {
private Integer planSubStatus; private Integer planSubStatus;
@Schema(description = "计划执行子状态-名称") @Schema(description = "计划执行子状态-名称")
private String planSubStatusName; private String planSubStatusName;
@Schema(description = "计划模型坐标")
private String planModelPoint;
} }
} }

View File

@@ -76,9 +76,9 @@ public class FarmingRecordJob implements JobHandler {
// 获取[进行中]状态的计划 // 获取[进行中]状态的计划
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::getId, e -> e, (v1, v2) -> v1));
List<String> taskIdList = plans.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).map(ProductionPlanDO::getId).toList(); List<String> taskIdList = plans.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).map(ProductionPlanDO::getId).toList();
// 获取引用模型集合
// 获取引用模型集合 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<>();

View File

@@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.farm.service.modelmanagement.ModelManagementServi
import cn.iocoder.yudao.module.farm.service.personnelmanagement.PersonnelManagementService; import cn.iocoder.yudao.module.farm.service.personnelmanagement.PersonnelManagementService;
import cn.iocoder.yudao.module.farm.service.plotinfo.PlotInfoService; 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.productionplan.ProductionPlanService;
import cn.iocoder.yudao.module.farm.utils.LeafletjsUtil;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -68,11 +69,20 @@ public class HomeServiceImpl implements HomeService {
BaseOverviewInfo baseOverviewInfo = this.getBaseOverviewInfo(baseObj, employeeNameMap); BaseOverviewInfo baseOverviewInfo = this.getBaseOverviewInfo(baseObj, employeeNameMap);
List<PlotPopupFrame> plotPopupFrames = this.getPlotPopupFrame(baseObj, employeeNameMap); List<PlotPopupFrame> plotPopupFrames = this.getPlotPopupFrame(baseObj, employeeNameMap);
List<PlotInfo> plotInfos = this.getPlotInfoList(baseId, employeeNameMap); List<PlotInfo> plotInfos = this.getPlotInfoList(baseId, employeeNameMap);
List<PlanInfo> planInfos = this.getPlanInfoList(baseId, "", null); // List<PlanInfo> planInfos = this.getPlanInfoList(baseId, "", null);
List<PlanInfo> planInfos = getPlans(plotInfos);
StatisticalInfo statisticalInfo = this.getStatisticalInfo(baseId); StatisticalInfo statisticalInfo = this.getStatisticalInfo(baseId);
return new HomeInfo(baseOverviewInfo, plotPopupFrames, plotInfos, planInfos, statisticalInfo); return new HomeInfo(baseOverviewInfo, plotPopupFrames, plotInfos, planInfos, statisticalInfo);
} }
private List<PlanInfo> getPlans(List<PlotInfo> plotInfos) {
List<PlanInfo> res = new ArrayList<>();
for (PlotInfo plotInfo : plotInfos) {
res.addAll(plotInfo.getPlotOrCropInfo().getPlanInfos());
}
return res;
}
private StatisticalInfo getStatisticalInfo(String baseId) { private StatisticalInfo getStatisticalInfo(String baseId) {
Integer taskCount = productionPlanService.getTodayTaskCount(baseId); Integer taskCount = productionPlanService.getTodayTaskCount(baseId);
Integer warningCount = 0; // TODO: 2025/9/1 告警数量 Integer warningCount = 0; // TODO: 2025/9/1 告警数量
@@ -163,6 +173,7 @@ public class HomeServiceImpl implements HomeService {
private List<PlanInfo> getPlanInfoList(String baseId,String plotId,String employeeName) { private List<PlanInfo> getPlanInfoList(String baseId,String plotId,String employeeName) {
List<PlanInfo> targetList = new ArrayList<>(); List<PlanInfo> targetList = new ArrayList<>();
PlotInfoDO plotObj = plotInfoService.getPlotInfoByPlotId(plotId);
List<ProductionPlanDO> plans = productionPlanService.getProductionPlans(baseId,plotId); List<ProductionPlanDO> plans = productionPlanService.getProductionPlans(baseId,plotId);
for (ProductionPlanDO e : plans) { for (ProductionPlanDO e : plans) {
String beingCropName = productionPlanService.getPlantSpeciesCodeForName(e.getPlantSpeciesCode()); String beingCropName = productionPlanService.getPlantSpeciesCodeForName(e.getPlantSpeciesCode());
@@ -184,12 +195,15 @@ public class HomeServiceImpl implements HomeService {
target.setPlanStatus(e.getPlanStatus()); target.setPlanStatus(e.getPlanStatus());
target.setPlanStatusName(PLAN_MAP.getOrDefault(e.getPlanStatus(),"未开始")); target.setPlanStatusName(PLAN_MAP.getOrDefault(e.getPlanStatus(),"未开始"));
target.setPlanSubStatus(e.getPlanSubStatus()); target.setPlanSubStatus(e.getPlanSubStatus());
target.setPlanSubStatusName(PLAN_MAP.getOrDefault(e.getPlanSubStatus(),"逾期未开始")); target.setPlanSubStatusName(PLAN_MAP.getOrDefault(e.getPlanSubStatus(), "逾期未开始"));
String pointsInPolygon = LeafletjsUtil.generateRandomPointsInPolygon(plotObj.getPoint());
target.setPlanModelPoint(pointsInPolygon);
targetList.add(target); targetList.add(target);
} }
return targetList; return targetList;
} }
@Override @Override
public OutlinedInfoVO getOutlinedInfo(String baseId) { public OutlinedInfoVO getOutlinedInfo(String baseId) {
OutlinedInfoVO res = new OutlinedInfoVO(); OutlinedInfoVO res = new OutlinedInfoVO();

View File

@@ -0,0 +1,113 @@
package cn.iocoder.yudao.module.farm.utils;
import lombok.Data;
import org.aspectj.bridge.Message;
import java.awt.geom.Path2D;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @description: 天地图工具类
* @author: binda
* @date: 2025/9/2 19:38
*/
public class LeafletjsUtil {
public static void main(String[] args) {
String s = "{\"marker\": null, \"polygon\": [{\"lat\": 28.99705470774261, \"lng\": 118.18360090255736}, {\"lat\": 28.99717666335354, \"lng\": 118.18385839462282}, {\"lat\": 28.99706408894856, \"lng\": 118.18441629409791}, {\"lat\": 28.996726364998096, \"lng\": 118.18449139595032}, {\"lat\": 28.99656688386018, \"lng\": 118.18440020084384}, {\"lat\": 28.996407307540014, \"lng\": 118.18392276763916}, {\"lat\": 28.99628249933895, \"lng\": 118.18372108295289}, {\"lat\": 28.99648245256991, \"lng\": 118.18348824977876}, {\"lat\": 28.99678265239978, \"lng\": 118.18330585956576}, {\"lat\": 28.99682017731722, \"lng\": 118.1834936141968}]}";
System.out.println(generateRandomPointsInPolygon(s));
}
public static String generateRandomPointsInPolygon(String pointJsonStr) {
List<Point> points = LeafletjsUtil.generateRandomPointsInPolygon(pointJsonStr, 3);
Point point = points.stream().findAny().get();
return "{\"lat\": "+point.getLat()+", \"lng\": "+point.getLng()+"}";
}
/**
* 在多边形内生成随机点
*/
public static List<Point> generateRandomPointsInPolygon(String pointJsonStr, int count) {
List<Point> polygon = parsePolygonFromJson(pointJsonStr);
List<Point> points = new ArrayList<>();
Random random = new Random();
// 计算多边形的边界框
double minLat = Double.MAX_VALUE;
double maxLat = Double.MIN_VALUE;
double minLng = Double.MAX_VALUE;
double maxLng = Double.MIN_VALUE;
for (Point point : polygon) {
minLat = Math.min(minLat, point.lat);
maxLat = Math.max(maxLat, point.lat);
minLng = Math.min(minLng, point.lng);
maxLng = Math.max(maxLng, point.lng);
}
// 创建多边形路径
Path2D.Double path = new Path2D.Double();
Point first = polygon.get(0);
path.moveTo(first.lng, first.lat);
for (int i = 1; i < polygon.size(); i++) {
Point point = polygon.get(i);
path.lineTo(point.lng, point.lat);
}
path.closePath();
// 生成随机点直到满足数量要求
while (points.size() < count) {
// 在边界框内生成随机点
double lat = minLat + random.nextDouble() * (maxLat - minLat);
double lng = minLng + random.nextDouble() * (maxLng - minLng);
// 检查点是否在多边形内
if (path.contains(lng, lat)) {
points.add(new Point(lat, lng));
}
}
return points;
}
public static List<Point> parsePolygonFromJson(String jsonString) {
List<Point> points = new ArrayList<>();
// 正则表达式匹配lat和lng
Pattern pattern = Pattern.compile("\"lat\":\\s*([\\d.]+),\\s*\"lng\":\\s*([\\d.]+)");
Matcher matcher = pattern.matcher(jsonString);
while (matcher.find()) {
double lat = Double.parseDouble(matcher.group(1));
double lng = Double.parseDouble(matcher.group(2));
points.add(new Point(lat, lng));
}
if (points.isEmpty()) {
throw new IllegalArgumentException("未找到有效的坐标数据");
}
return points;
}
/**
* 点类
*/
@Data
public static class Point {
double lat;
double lng;
public Point(double lat, double lng) {
this.lat = lat;
this.lng = lng;
}
}
}