From ce99cdd623d965789101775f821c1aacb5d03187 Mon Sep 17 00:00:00 2001 From: lcj <2331845269@qq.com> Date: Sun, 21 Sep 2025 23:59:16 +0800 Subject: [PATCH] =?UTF-8?q?AI=E8=AF=86=E5=88=AB=E5=90=8C=E6=AD=A5=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/domain/IdCoordinatePoint.java | 25 ++++ .../dromara/common/utils/JtsPointMatcher.java | 93 ++++++++++++ .../IFacPhotovoltaicPanelColumnService.java | 7 + .../IFacPhotovoltaicPanelPartsService.java | 10 ++ .../IFacPhotovoltaicPanelPointService.java | 8 ++ .../IFacPhotovoltaicPanelSupportService.java | 7 + ...FacPhotovoltaicPanelColumnServiceImpl.java | 132 +++++++++++++++++- .../FacPhotovoltaicPanelPartsServiceImpl.java | 81 +++++++++++ .../FacPhotovoltaicPanelPointServiceImpl.java | 131 ++++++++++++++++- .../impl/FacPhotovoltaicPanelServiceImpl.java | 74 +++++++++- ...acPhotovoltaicPanelSupportServiceImpl.java | 131 ++++++++++++++++- .../IncSyncPlanDetail2ConstructionValue.java | 2 +- .../dronemanager/DroneRequestUtils.java | 2 +- 13 files changed, 691 insertions(+), 12 deletions(-) create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/domain/IdCoordinatePoint.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JtsPointMatcher.java diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/domain/IdCoordinatePoint.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/domain/IdCoordinatePoint.java new file mode 100644 index 00000000..b1229dd4 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/domain/IdCoordinatePoint.java @@ -0,0 +1,25 @@ +package org.dromara.common.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author lilemy + * @date 2025-09-21 22:07 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class IdCoordinatePoint { + + /** + * id + */ + private Long id; + + /** + * 点位置 107.13162414986301,23.817601041770256 + */ + private String positions; +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JtsPointMatcher.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JtsPointMatcher.java new file mode 100644 index 00000000..0b9e9a87 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JtsPointMatcher.java @@ -0,0 +1,93 @@ +package org.dromara.common.utils; + +import org.dromara.common.domain.IdCoordinatePoint; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.util.GeometricShapeFactory; + +import java.util.ArrayList; +import java.util.List; + +public class JtsPointMatcher { + + private static final GeometryFactory geometryFactory = new GeometryFactory(); + + // 经纬度转米:近似计算(1度纬度约111,320米,经度要乘cos(lat)修正) + private static double meterToDegreeLat(double meter) { + return meter / 111320.0; + } + + private static double meterToDegreeLon(double meter, double lat) { + return meter / (111320.0 * Math.cos(Math.toRadians(lat))); + } + + // 根据中心点生成半径为 meter 的圆形 Polygon + public static Polygon createCircle(double lon, double lat, double radiusMeter) { + double radiusDegX = meterToDegreeLon(radiusMeter, lat); + double radiusDegY = meterToDegreeLat(radiusMeter); + + GeometricShapeFactory shapeFactory = new GeometricShapeFactory(geometryFactory); + shapeFactory.setNumPoints(32); // 圆的精度,越大越圆 + shapeFactory.setCentre(new Coordinate(lon, lat)); + shapeFactory.setWidth(2 * radiusDegX); + shapeFactory.setHeight(2 * radiusDegY); + + return shapeFactory.createCircle(); + } + + /** + * @param pointsA 需要匹配的坐标点 + * @param pointsB 光伏板桩点(数据库数据) + * @param radiusMeter 半径(米) + * @return 匹配到的 pointsB 的 id + */ + public static List matchPoints(List pointsA, List pointsB, double radiusMeter) { + List matched = new ArrayList<>(); + for (Coordinate pA : pointsA) { + Point pointA = geometryFactory.createPoint(pA); + for (IdCoordinatePoint pvPoint : pointsB) { + // positions 字段 -> Coordinate + String[] posArr = pvPoint.getPositions().split(","); + double lon = Double.parseDouble(posArr[0]); + double lat = Double.parseDouble(posArr[1]); + Polygon circle = createCircle(lon, lat, radiusMeter); + + if (circle.contains(pointA)) { + matched.add(pvPoint.getId()); + break; // 找到一个就够 + } + } + } + return matched; + } + + public static void main(String[] args) { + // A列表:待匹配点 + List listA = List.of( + new Coordinate(107.13157999170879, 23.81760079310148), + new Coordinate(107.13201410826626, 23.814533669832148) + ); + + // B列表:数据库里的点 + List listB = new ArrayList<>(); + + IdCoordinatePoint p1 = new IdCoordinatePoint(); + p1.setId(1L); + p1.setPositions("107.13162414986301,23.817601041770256"); // 很近 + listB.add(p1); + + IdCoordinatePoint p2 = new IdCoordinatePoint(); + p2.setId(2L); + p2.setPositions("107.08827916132982,23.877744707721714"); // 很远 + listB.add(p2); + + List result = matchPoints(listA, listB, 4.4); + + System.out.println("匹配到的桩点ID:"); + for (Long id : result) { + System.out.println(id); + } + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelColumnService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelColumnService.java index d2b33645..c79cbd5c 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelColumnService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelColumnService.java @@ -117,4 +117,11 @@ public interface IFacPhotovoltaicPanelColumnService extends IService queryPageListByPanelName(FacPhotovoltaicPanelPartsQueryReq req, PageQuery pageQuery); + /** + * 根据AI识别坐标更新完成数量 + * + * @param projectId 项目id + * @param matchPoints 匹配的坐标点id + */ + void updateFinishNumberByCoordinate(Long projectId, List matchPoints); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelPartsService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelPartsService.java index 087004df..ec563245 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelPartsService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelPartsService.java @@ -9,6 +9,7 @@ import org.dromara.facility.domain.dto.photovoltaicpanelparts.FacPhotovoltaicPan import org.dromara.facility.domain.dto.photovoltaicpanelparts.FacPhotovoltaicPanelPartsCreateReq; import org.dromara.facility.domain.dto.photovoltaicpanelparts.FacPhotovoltaicPanelPartsQueryReq; import org.dromara.facility.domain.vo.photovoltaicpanelparts.FacPhotovoltaicPanelPartsByPanelNameVo; +import org.dromara.manager.recognizermanager.vo.RecognizeConvertCoordinateResult; import java.util.Collection; import java.util.Date; @@ -100,4 +101,13 @@ public interface IFacPhotovoltaicPanelPartsService { */ Boolean updatePartsFinishStatus(String workType, Date finishDate, Long projectId, Long matrixId, List photovoltaicPanelNameList); + /** + * 根据识别结果更新光伏板点完成数量 + * + * @param projectId 项目id + * @param coordinateList 识别结果 + * @param type 类型 + */ + void updateFinishNumberByCoordinate(Long projectId, List coordinateList, String type); + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelPointService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelPointService.java index 5f75eee5..e64853c1 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelPointService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelPointService.java @@ -116,4 +116,12 @@ public interface IFacPhotovoltaicPanelPointService extends IService queryPageListByPanelName(FacPhotovoltaicPanelPartsQueryReq req, PageQuery pageQuery); + + /** + * 根据AI识别坐标更新完成数量 + * + * @param projectId 项目id + * @param matchPoints 匹配的坐标点id + */ + void updateFinishNumberByCoordinate(Long projectId, List matchPoints); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelSupportService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelSupportService.java index fae7b69c..8e480406 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelSupportService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/IFacPhotovoltaicPanelSupportService.java @@ -117,4 +117,11 @@ public interface IFacPhotovoltaicPanelSupportService extends IService queryPageListByPanelName(FacPhotovoltaicPanelPartsQueryReq req, PageQuery pageQuery); + /** + * 根据AI识别坐标更新完成数量 + * + * @param projectId 项目id + * @param matchPoints 匹配的坐标点id + */ + void updateFinishNumberByCoordinate(Long projectId, List matchPoints); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelColumnServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelColumnServiceImpl.java index 1c7ce291..8b0f6c41 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelColumnServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelColumnServiceImpl.java @@ -13,27 +13,34 @@ import org.dromara.common.core.utils.ObjectUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.facility.domain.FacPhotovoltaicPanelColumn; import org.dromara.facility.domain.dto.photovoltaicpanelcolumn.FacPhotovoltaicPanelColumnCreateReq; import org.dromara.facility.domain.dto.photovoltaicpanelcolumn.FacPhotovoltaicPanelColumnQueryReq; import org.dromara.facility.domain.dto.photovoltaicpanelcolumn.FacPhotovoltaicPanelColumnUpdateReq; import org.dromara.facility.domain.dto.photovoltaicpanelparts.FacPhotovoltaicPanelPartsQueryReq; import org.dromara.facility.domain.enums.FacFinishStatusEnum; +import org.dromara.facility.domain.enums.FacFinishTypeEnum; import org.dromara.facility.domain.vo.photovoltaicpanelcolumn.FacPhotovoltaicPanelColumnVo; import org.dromara.facility.domain.vo.photovoltaicpanelparts.FacPhotovoltaicPanelPartsByPanelNameVo; import org.dromara.facility.mapper.FacPhotovoltaicPanelColumnMapper; import org.dromara.facility.service.IFacMatrixService; import org.dromara.facility.service.IFacPhotovoltaicPanelColumnService; import org.dromara.progress.domain.PgsProgressCategory; +import org.dromara.progress.domain.PgsProgressPlan; +import org.dromara.progress.domain.PgsProgressPlanDetail; +import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailFinishedVo; import org.dromara.progress.service.IPgsProgressCategoryService; +import org.dromara.progress.service.IPgsProgressPlanDetailService; +import org.dromara.progress.service.IPgsProgressPlanService; import org.dromara.project.service.IBusProjectService; import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; +import java.time.LocalDate; import java.util.*; import java.util.stream.Collectors; @@ -56,6 +63,14 @@ public class FacPhotovoltaicPanelColumnServiceImpl extends ServiceImpl(result, panelNamePage.getTotal()); } + /** + * 根据AI识别坐标更新完成数量 + * + * @param projectId 项目id + * @param matchPoints 匹配的坐标点id + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void updateFinishNumberByCoordinate(Long projectId, List matchPoints) { + // 获取数据 + List finishList = this.listByIds(matchPoints); + // 更新完成状态 + finishList.forEach(finish -> { + finish.setStatus(FacFinishStatusEnum.FINISH.getValue()); + finish.setFinishType(FacFinishTypeEnum.AI.getValue()); + }); + boolean update = this.updateBatchById(finishList); + if (update) { + Map> mapByCategory = finishList.stream() + .collect(Collectors.groupingBy(FacPhotovoltaicPanelColumn::getProgressCategoryId)); + // 判断当天是否有存在的计划 + LocalDate now = LocalDate.now(); + for (Map.Entry> entry : mapByCategory.entrySet()) { + Long categoryId = entry.getKey(); + List categoryList = entry.getValue(); + // 计算数量 + BigDecimal size = BigDecimal.valueOf(categoryList.size()); + PgsProgressPlanDetail planDetail = progressPlanDetailService.lambdaQuery() + .eq(PgsProgressPlanDetail::getProjectId, projectId) + .eq(PgsProgressPlanDetail::getProgressCategoryId, categoryId) + .eq(PgsProgressPlanDetail::getDate, now) + .one(); + // 完成详情 + List finishedVos = categoryList.stream().map(panel -> + new PgsProgressPlanDetailFinishedVo(panel.getId(), panel.getName(), FacFinishTypeEnum.AI.getValue())).toList(); + if (planDetail != null) { + // 存在,则更新对应计划详情的数量 + planDetail.setAiFill(planDetail.getAiFill().add(size)); + planDetail.setFinishedNumber(planDetail.getFinishedNumber().add(size)); + // 添加完成详情 + String finishedDetail = planDetail.getFinishedDetail(); + if (StringUtils.isNotBlank(finishedDetail)) { + List finishedVoList = JSONUtil.toList(finishedDetail, PgsProgressPlanDetailFinishedVo.class); + finishedVoList.addAll(finishedVos); + planDetail.setFinishedDetail(JSONUtil.toJsonStr(finishedVoList)); + } else { + planDetail.setFinishedDetail(JSONUtil.toJsonStr(finishedVos)); + } + // 更新计划详情 + boolean result1 = progressPlanDetailService.updateById(planDetail); + if (!result1) { + throw new ServiceException("更新进度计划详情失败,数据库操作失败", HttpStatus.ERROR); + } + // 更新计划数量 + Long planId = planDetail.getProgressPlanId(); + PgsProgressPlan plan = new PgsProgressPlan(); + plan.setId(planId); + plan.setFinishedNumber(plan.getFinishedNumber().add(size)); + boolean result2 = progressPlanService.updateById(plan); + if (!result2) { + throw new ServiceException("更新进度计划失败,数据库操作失败", HttpStatus.ERROR); + } + // 更新进度数量 + PgsProgressCategory category = new PgsProgressCategory(); + category.setId(categoryId); + category.setCompleted(category.getCompleted().add(size)); + boolean result3 = progressCategoryService.updateById(category); + if (!result3) { + throw new ServiceException("更新进度类别失败,数据库操作失败", HttpStatus.ERROR); + } + } else { + // 如果不存在,获取类别详情 + PgsProgressCategory category = progressCategoryService.getById(categoryId); + // 则创建计划 + PgsProgressPlan plan = new PgsProgressPlan(); + plan.setProjectId(projectId); + plan.setMatrixId(category.getMatrixId()); + plan.setMatrixName(category.getMatrixName()); + plan.setProgressCategoryId(categoryId); + plan.setProgressCategoryName(category.getName()); + plan.setStartDate(now); + plan.setEndDate(now); + plan.setPlanNumber(size); + plan.setFinishedNumber(size); + plan.setDelayNumber(BigDecimal.ZERO); + boolean result1 = progressPlanService.save(plan); + if (!result1) { + throw new ServiceException("创建进度计划失败,数据库操作失败", HttpStatus.ERROR); + } + // 创建计划详情 + PgsProgressPlanDetail newPlanDetail = new PgsProgressPlanDetail(); + newPlanDetail.setProjectId(projectId); + newPlanDetail.setProgressPlanId(plan.getId()); + newPlanDetail.setProgressCategoryId(categoryId); + newPlanDetail.setDate(now); + newPlanDetail.setPlanNumber(size); + newPlanDetail.setFinishedNumber(size); + newPlanDetail.setFinishedDetail(JSONUtil.toJsonStr(finishedVos)); + newPlanDetail.setAiFill(size); + boolean result2 = progressPlanDetailService.save(newPlanDetail); + if (!result2) { + throw new ServiceException("创建进度计划详情失败,数据库操作失败", HttpStatus.ERROR); + } + // 更新进度数量 + category.setCompleted(category.getCompleted().add(size)); + boolean result3 = progressCategoryService.updateById(category); + if (!result3) { + throw new ServiceException("更新进度类别失败,数据库操作失败", HttpStatus.ERROR); + } + } + } + } + } + + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPartsServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPartsServiceImpl.java index 0dccdf0b..e8f9b806 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPartsServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPartsServiceImpl.java @@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.domain.IdCoordinatePoint; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; @@ -17,6 +18,7 @@ import org.dromara.common.sse.dto.SeeMessageContentDto; import org.dromara.common.sse.dto.SseMessageDto; import org.dromara.common.sse.utils.SseMessageUtils; import org.dromara.common.utils.JSTUtil; +import org.dromara.common.utils.JtsPointMatcher; import org.dromara.facility.constant.FacRedisKeyConstant; import org.dromara.facility.domain.FacPhotovoltaicPanel; import org.dromara.facility.domain.FacPhotovoltaicPanelColumn; @@ -30,10 +32,13 @@ import org.dromara.facility.domain.enums.FacFinishStatusEnum; import org.dromara.facility.domain.enums.FacFinishTypeEnum; import org.dromara.facility.domain.vo.photovoltaicpanelparts.FacPhotovoltaicPanelPartsByPanelNameVo; import org.dromara.facility.service.*; +import org.dromara.manager.recognizermanager.enums.RecognizerTypeEnum; +import org.dromara.manager.recognizermanager.vo.RecognizeConvertCoordinateResult; import org.dromara.progress.constant.PgsProgressCategoryConstant; import org.dromara.progress.domain.PgsProgressCategory; import org.dromara.progress.service.IPgsProgressCategoryService; import org.dromara.project.service.IBusProjectService; +import org.locationtech.jts.geom.Coordinate; import org.springframework.beans.BeanUtils; import org.springframework.context.annotation.Lazy; import org.springframework.dao.DataAccessException; @@ -812,6 +817,82 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan return true; } + /** + * 根据识别结果更新光伏板点完成数量 + * + * @param projectId 项目id + * @param coordinateList 识别结果 + * @param type 类型 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void updateFinishNumberByCoordinate(Long projectId, + List coordinateList, + String type) { + if (CollUtil.isEmpty(coordinateList)) { + return; + } + List idCoordinatePointList = getIdCoordinatePointList(projectId, type); + if (CollUtil.isEmpty(idCoordinatePointList)) { + return; + } + // 判断识别出来的坐标是否包含某个点 + List coordinates = coordinateList.stream().map(coordinate -> { + return new Coordinate(Double.parseDouble(coordinate.getLng()), Double.parseDouble(coordinate.getLat())); + }).toList(); + List matchPoints = JtsPointMatcher.matchPoints(coordinates, idCoordinatePointList, 1.0); + if (CollUtil.isEmpty(matchPoints)) { + return; + } + // 根据类型,更新对应数据 + if (type.equals(RecognizerTypeEnum.HOLE.getValue())) { + photovoltaicPanelPointService.updateFinishNumberByCoordinate(projectId, matchPoints); + } else if (type.equals(RecognizerTypeEnum.PILE.getValue())) { + photovoltaicPanelColumnService.updateFinishNumberByCoordinate(projectId, matchPoints); + } else if (type.equals(RecognizerTypeEnum.SHELVES.getValue())) { + photovoltaicPanelSupportService.updateFinishNumberByCoordinate(projectId, matchPoints); + } + } + + /** + * 获取指定项目指定类型数据 + * + * @param projectId 项目id + * @param type 类型 + * @return id、坐标 + */ + private List getIdCoordinatePointList(Long projectId, String type) { + if (type.equals(RecognizerTypeEnum.HOLE.getValue())) { + List list = photovoltaicPanelPointService.lambdaQuery() + .eq(FacPhotovoltaicPanelPoint::getProjectId, projectId) + .ne(FacPhotovoltaicPanelPoint::getStatus, FacFinishStatusEnum.FINISH.getValue()) + .list(); + if (CollUtil.isNotEmpty(list)) { + return list.stream().map(point -> + new IdCoordinatePoint(point.getId(), point.getPositions())).toList(); + } + } else if (type.equals(RecognizerTypeEnum.PILE.getValue())) { + List list = photovoltaicPanelColumnService.lambdaQuery() + .eq(FacPhotovoltaicPanelColumn::getProjectId, projectId) + .ne(FacPhotovoltaicPanelColumn::getStatus, FacFinishStatusEnum.FINISH.getValue()) + .list(); + if (CollUtil.isNotEmpty(list)) { + return list.stream().map(column -> + new IdCoordinatePoint(column.getId(), column.getPositions())).toList(); + } + } else if (type.equals(RecognizerTypeEnum.SHELVES.getValue())) { + List list = photovoltaicPanelSupportService.lambdaQuery() + .eq(FacPhotovoltaicPanelSupport::getProjectId, projectId) + .ne(FacPhotovoltaicPanelSupport::getStatus, FacFinishStatusEnum.FINISH.getValue()) + .list(); + if (CollUtil.isNotEmpty(list)) { + return list.stream().map(column -> + new IdCoordinatePoint(column.getId(), column.getPositions())).toList(); + } + } + return List.of(); + } + /** * 校验名称是否重复 * diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPointServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPointServiceImpl.java index 332833db..a9ba74d7 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPointServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPointServiceImpl.java @@ -13,27 +13,34 @@ import org.dromara.common.core.utils.ObjectUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.facility.domain.FacPhotovoltaicPanelPoint; import org.dromara.facility.domain.dto.photovoltaicpanelparts.FacPhotovoltaicPanelPartsQueryReq; import org.dromara.facility.domain.dto.photovoltaicpanelpoint.FacPhotovoltaicPanelPointCreateReq; import org.dromara.facility.domain.dto.photovoltaicpanelpoint.FacPhotovoltaicPanelPointQueryReq; import org.dromara.facility.domain.dto.photovoltaicpanelpoint.FacPhotovoltaicPanelPointUpdateReq; import org.dromara.facility.domain.enums.FacFinishStatusEnum; +import org.dromara.facility.domain.enums.FacFinishTypeEnum; import org.dromara.facility.domain.vo.photovoltaicpanelparts.FacPhotovoltaicPanelPartsByPanelNameVo; import org.dromara.facility.domain.vo.photovoltaicpanelpoint.FacPhotovoltaicPanelPointVo; import org.dromara.facility.mapper.FacPhotovoltaicPanelPointMapper; import org.dromara.facility.service.IFacMatrixService; import org.dromara.facility.service.IFacPhotovoltaicPanelPointService; import org.dromara.progress.domain.PgsProgressCategory; +import org.dromara.progress.domain.PgsProgressPlan; +import org.dromara.progress.domain.PgsProgressPlanDetail; +import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailFinishedVo; import org.dromara.progress.service.IPgsProgressCategoryService; +import org.dromara.progress.service.IPgsProgressPlanDetailService; +import org.dromara.progress.service.IPgsProgressPlanService; import org.dromara.project.service.IBusProjectService; import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; +import java.time.LocalDate; import java.util.*; import java.util.stream.Collectors; @@ -56,6 +63,14 @@ public class FacPhotovoltaicPanelPointServiceImpl extends ServiceImpl(result, panelNamePage.getTotal()); } + /** + * 根据AI识别坐标更新完成数量 + * + * @param projectId 项目id + * @param matchPoints 匹配的坐标点id + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void updateFinishNumberByCoordinate(Long projectId, List matchPoints) { + // 获取数据 + List finishList = this.listByIds(matchPoints); + // 更新完成状态 + finishList.forEach(finish -> { + finish.setStatus(FacFinishStatusEnum.FINISH.getValue()); + finish.setFinishType(FacFinishTypeEnum.AI.getValue()); + }); + boolean update = this.updateBatchById(finishList); + if (update) { + Map> mapByCategory = finishList.stream() + .collect(Collectors.groupingBy(FacPhotovoltaicPanelPoint::getProgressCategoryId)); + // 判断当天是否有存在的计划 + LocalDate now = LocalDate.now(); + for (Map.Entry> entry : mapByCategory.entrySet()) { + Long categoryId = entry.getKey(); + List categoryList = entry.getValue(); + // 计算数量 + BigDecimal size = BigDecimal.valueOf(categoryList.size()); + PgsProgressPlanDetail planDetail = progressPlanDetailService.lambdaQuery() + .eq(PgsProgressPlanDetail::getProjectId, projectId) + .eq(PgsProgressPlanDetail::getProgressCategoryId, categoryId) + .eq(PgsProgressPlanDetail::getDate, now) + .one(); + // 完成详情 + List finishedVos = categoryList.stream().map(panel -> + new PgsProgressPlanDetailFinishedVo(panel.getId(), panel.getName(), FacFinishTypeEnum.AI.getValue())).toList(); + if (planDetail != null) { + // 存在,则更新对应计划详情的数量 + planDetail.setAiFill(planDetail.getAiFill().add(size)); + planDetail.setFinishedNumber(planDetail.getFinishedNumber().add(size)); + // 添加完成详情 + String finishedDetail = planDetail.getFinishedDetail(); + if (StringUtils.isNotBlank(finishedDetail)) { + List finishedVoList = JSONUtil.toList(finishedDetail, PgsProgressPlanDetailFinishedVo.class); + finishedVoList.addAll(finishedVos); + planDetail.setFinishedDetail(JSONUtil.toJsonStr(finishedVoList)); + } else { + planDetail.setFinishedDetail(JSONUtil.toJsonStr(finishedVos)); + } + // 更新计划详情 + boolean result1 = progressPlanDetailService.updateById(planDetail); + if (!result1) { + throw new ServiceException("更新进度计划详情失败,数据库操作失败", HttpStatus.ERROR); + } + // 更新计划数量 + Long planId = planDetail.getProgressPlanId(); + PgsProgressPlan plan = new PgsProgressPlan(); + plan.setId(planId); + plan.setFinishedNumber(plan.getFinishedNumber().add(size)); + boolean result2 = progressPlanService.updateById(plan); + if (!result2) { + throw new ServiceException("更新进度计划失败,数据库操作失败", HttpStatus.ERROR); + } + // 更新进度数量 + PgsProgressCategory category = new PgsProgressCategory(); + category.setId(categoryId); + category.setCompleted(category.getCompleted().add(size)); + boolean result3 = progressCategoryService.updateById(category); + if (!result3) { + throw new ServiceException("更新进度类别失败,数据库操作失败", HttpStatus.ERROR); + } + } else { + // 如果不存在,获取类别详情 + PgsProgressCategory category = progressCategoryService.getById(categoryId); + // 则创建计划 + PgsProgressPlan plan = new PgsProgressPlan(); + plan.setProjectId(projectId); + plan.setMatrixId(category.getMatrixId()); + plan.setMatrixName(category.getMatrixName()); + plan.setProgressCategoryId(categoryId); + plan.setProgressCategoryName(category.getName()); + plan.setStartDate(now); + plan.setEndDate(now); + plan.setPlanNumber(size); + plan.setFinishedNumber(size); + plan.setDelayNumber(BigDecimal.ZERO); + boolean result1 = progressPlanService.save(plan); + if (!result1) { + throw new ServiceException("创建进度计划失败,数据库操作失败", HttpStatus.ERROR); + } + // 创建计划详情 + PgsProgressPlanDetail newPlanDetail = new PgsProgressPlanDetail(); + newPlanDetail.setProjectId(projectId); + newPlanDetail.setProgressPlanId(plan.getId()); + newPlanDetail.setProgressCategoryId(categoryId); + newPlanDetail.setDate(now); + newPlanDetail.setPlanNumber(size); + newPlanDetail.setFinishedNumber(size); + newPlanDetail.setFinishedDetail(JSONUtil.toJsonStr(finishedVos)); + newPlanDetail.setAiFill(size); + boolean result2 = progressPlanDetailService.save(newPlanDetail); + if (!result2) { + throw new ServiceException("创建进度计划详情失败,数据库操作失败", HttpStatus.ERROR); + } + // 更新进度数量 + category.setCompleted(category.getCompleted().add(size)); + boolean result3 = progressCategoryService.updateById(category); + if (!result3) { + throw new ServiceException("更新进度类别失败,数据库操作失败", HttpStatus.ERROR); + } + } + } + } + } + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelServiceImpl.java index 2062e63b..c1c9c025 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelServiceImpl.java @@ -37,6 +37,7 @@ import org.dromara.facility.service.IFacPhotovoltaicPanelService; import org.dromara.manager.recognizermanager.vo.RecognizeConvertCoordinateResult; import org.dromara.progress.constant.PgsProgressCategoryConstant; import org.dromara.progress.domain.PgsProgressCategory; +import org.dromara.progress.domain.PgsProgressPlan; import org.dromara.progress.domain.PgsProgressPlanDetail; import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailFinishedVo; import org.dromara.progress.service.IPgsProgressCategoryService; @@ -791,20 +792,22 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl> entry : mapByCategory.entrySet()) { Long categoryId = entry.getKey(); List categoryList = entry.getValue(); - int size = categoryList.size(); + // 计算数量 + BigDecimal size = BigDecimal.valueOf(categoryList.size()); PgsProgressPlanDetail planDetail = progressPlanDetailService.lambdaQuery() .eq(PgsProgressPlanDetail::getProjectId, projectId) .eq(PgsProgressPlanDetail::getProgressCategoryId, categoryId) .eq(PgsProgressPlanDetail::getDate, now) .one(); + // 完成详情 + List finishedVos = categoryList.stream().map(panel -> + new PgsProgressPlanDetailFinishedVo(panel.getId(), panel.getName(), FacFinishTypeEnum.AI.getValue())).toList(); if (planDetail != null) { // 存在,则更新对应计划详情的数量 - planDetail.setAiFill(planDetail.getAiFill().add(BigDecimal.valueOf(size))); - planDetail.setFinishedNumber(planDetail.getFinishedNumber().add(BigDecimal.valueOf(size))); + planDetail.setAiFill(planDetail.getAiFill().add(size)); + planDetail.setFinishedNumber(planDetail.getFinishedNumber().add(size)); // 添加完成详情 String finishedDetail = planDetail.getFinishedDetail(); - List finishedVos = categoryList.stream().map(panel -> - new PgsProgressPlanDetailFinishedVo(panel.getId(), panel.getName(), FacFinishTypeEnum.AI.getValue())).toList(); if (StringUtils.isNotBlank(finishedDetail)) { List finishedVoList = JSONUtil.toList(finishedDetail, PgsProgressPlanDetailFinishedVo.class); finishedVoList.addAll(finishedVos); @@ -813,9 +816,66 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl(result, panelNamePage.getTotal()); } + /** + * 根据AI识别坐标更新完成数量 + * + * @param projectId 项目id + * @param matchPoints 匹配的坐标点id + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void updateFinishNumberByCoordinate(Long projectId, List matchPoints) { + // 获取数据 + List finishList = this.listByIds(matchPoints); + // 更新完成状态 + finishList.forEach(finish -> { + finish.setStatus(FacFinishStatusEnum.FINISH.getValue()); + finish.setFinishType(FacFinishTypeEnum.AI.getValue()); + }); + boolean update = this.updateBatchById(finishList); + if (update) { + Map> mapByCategory = finishList.stream() + .collect(Collectors.groupingBy(FacPhotovoltaicPanelSupport::getProgressCategoryId)); + // 判断当天是否有存在的计划 + LocalDate now = LocalDate.now(); + for (Map.Entry> entry : mapByCategory.entrySet()) { + Long categoryId = entry.getKey(); + List categoryList = entry.getValue(); + // 计算数量 + BigDecimal size = BigDecimal.valueOf(categoryList.size()); + PgsProgressPlanDetail planDetail = progressPlanDetailService.lambdaQuery() + .eq(PgsProgressPlanDetail::getProjectId, projectId) + .eq(PgsProgressPlanDetail::getProgressCategoryId, categoryId) + .eq(PgsProgressPlanDetail::getDate, now) + .one(); + // 完成详情 + List finishedVos = categoryList.stream().map(panel -> + new PgsProgressPlanDetailFinishedVo(panel.getId(), panel.getName(), FacFinishTypeEnum.AI.getValue())).toList(); + if (planDetail != null) { + // 存在,则更新对应计划详情的数量 + planDetail.setAiFill(planDetail.getAiFill().add(size)); + planDetail.setFinishedNumber(planDetail.getFinishedNumber().add(size)); + // 添加完成详情 + String finishedDetail = planDetail.getFinishedDetail(); + if (StringUtils.isNotBlank(finishedDetail)) { + List finishedVoList = JSONUtil.toList(finishedDetail, PgsProgressPlanDetailFinishedVo.class); + finishedVoList.addAll(finishedVos); + planDetail.setFinishedDetail(JSONUtil.toJsonStr(finishedVoList)); + } else { + planDetail.setFinishedDetail(JSONUtil.toJsonStr(finishedVos)); + } + // 更新计划详情 + boolean result1 = progressPlanDetailService.updateById(planDetail); + if (!result1) { + throw new ServiceException("更新进度计划详情失败,数据库操作失败", HttpStatus.ERROR); + } + // 更新计划数量 + Long planId = planDetail.getProgressPlanId(); + PgsProgressPlan plan = new PgsProgressPlan(); + plan.setId(planId); + plan.setFinishedNumber(plan.getFinishedNumber().add(size)); + boolean result2 = progressPlanService.updateById(plan); + if (!result2) { + throw new ServiceException("更新进度计划失败,数据库操作失败", HttpStatus.ERROR); + } + // 更新进度数量 + PgsProgressCategory category = new PgsProgressCategory(); + category.setId(categoryId); + category.setCompleted(category.getCompleted().add(size)); + boolean result3 = progressCategoryService.updateById(category); + if (!result3) { + throw new ServiceException("更新进度类别失败,数据库操作失败", HttpStatus.ERROR); + } + } else { + // 如果不存在,获取类别详情 + PgsProgressCategory category = progressCategoryService.getById(categoryId); + // 则创建计划 + PgsProgressPlan plan = new PgsProgressPlan(); + plan.setProjectId(projectId); + plan.setMatrixId(category.getMatrixId()); + plan.setMatrixName(category.getMatrixName()); + plan.setProgressCategoryId(categoryId); + plan.setProgressCategoryName(category.getName()); + plan.setStartDate(now); + plan.setEndDate(now); + plan.setPlanNumber(size); + plan.setFinishedNumber(size); + plan.setDelayNumber(BigDecimal.ZERO); + boolean result1 = progressPlanService.save(plan); + if (!result1) { + throw new ServiceException("创建进度计划失败,数据库操作失败", HttpStatus.ERROR); + } + // 创建计划详情 + PgsProgressPlanDetail newPlanDetail = new PgsProgressPlanDetail(); + newPlanDetail.setProjectId(projectId); + newPlanDetail.setProgressPlanId(plan.getId()); + newPlanDetail.setProgressCategoryId(categoryId); + newPlanDetail.setDate(now); + newPlanDetail.setPlanNumber(size); + newPlanDetail.setFinishedNumber(size); + newPlanDetail.setFinishedDetail(JSONUtil.toJsonStr(finishedVos)); + newPlanDetail.setAiFill(size); + boolean result2 = progressPlanDetailService.save(newPlanDetail); + if (!result2) { + throw new ServiceException("创建进度计划详情失败,数据库操作失败", HttpStatus.ERROR); + } + // 更新进度数量 + category.setCompleted(category.getCompleted().add(size)); + boolean result3 = progressCategoryService.updateById(category); + if (!result3) { + throw new ServiceException("更新进度类别失败,数据库操作失败", HttpStatus.ERROR); + } + } + } + } + } + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncPlanDetail2ConstructionValue.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncPlanDetail2ConstructionValue.java index fa0b7fe3..18653726 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncPlanDetail2ConstructionValue.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncPlanDetail2ConstructionValue.java @@ -26,7 +26,7 @@ public class IncSyncPlanDetail2ConstructionValue { */ @Scheduled(cron = "0 0 1 * * ?") public void run() { - LocalDate yesterday = LocalDate.now().minusDays(1); + LocalDate yesterday = LocalDate.now().minusWeeks(1); log.info("执行定时任务:同步 {} 计划详情到施工产值", yesterday); Boolean synced = progressPlanDetailService.syncPlanDetail2ConstructionValue(yesterday, null); if (synced) { diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneRequestUtils.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneRequestUtils.java index 0146a1d1..bec341a0 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneRequestUtils.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneRequestUtils.java @@ -50,7 +50,7 @@ public class DroneRequestUtils { } String body = response.body(); JSONObject obj = JSONUtil.parseObj(body); - if (!obj.get("code").equals("200")) { + if (!obj.getStr("code").equals("200")) { log.error("{},状态码:{},{}", errorMsg, obj.get("code"), obj.get("msg")); throw new ServiceException(errorMsg + obj.get("msg")); }