AI识别同步进度计划

This commit is contained in:
lcj
2025-09-21 23:59:16 +08:00
parent 9ad44e727e
commit ce99cdd623
13 changed files with 691 additions and 12 deletions

View File

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

View File

@ -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<Long> matchPoints(List<Coordinate> pointsA, List<IdCoordinatePoint> pointsB, double radiusMeter) {
List<Long> 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<Coordinate> listA = List.of(
new Coordinate(107.13157999170879, 23.81760079310148),
new Coordinate(107.13201410826626, 23.814533669832148)
);
// B列表数据库里的点
List<IdCoordinatePoint> 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<Long> result = matchPoints(listA, listB, 4.4);
System.out.println("匹配到的桩点ID");
for (Long id : result) {
System.out.println(id);
}
}
}

View File

@ -117,4 +117,11 @@ public interface IFacPhotovoltaicPanelColumnService extends IService<FacPhotovol
TableDataInfo<FacPhotovoltaicPanelPartsByPanelNameVo> queryPageListByPanelName(FacPhotovoltaicPanelPartsQueryReq req,
PageQuery pageQuery);
/**
* 根据AI识别坐标更新完成数量
*
* @param projectId 项目id
* @param matchPoints 匹配的坐标点id
*/
void updateFinishNumberByCoordinate(Long projectId, List<Long> matchPoints);
}

View File

@ -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<String> photovoltaicPanelNameList);
/**
* 根据识别结果更新光伏板点完成数量
*
* @param projectId 项目id
* @param coordinateList 识别结果
* @param type 类型
*/
void updateFinishNumberByCoordinate(Long projectId, List<RecognizeConvertCoordinateResult> coordinateList, String type);
}

View File

@ -116,4 +116,12 @@ public interface IFacPhotovoltaicPanelPointService extends IService<FacPhotovolt
*/
TableDataInfo<FacPhotovoltaicPanelPartsByPanelNameVo> queryPageListByPanelName(FacPhotovoltaicPanelPartsQueryReq req,
PageQuery pageQuery);
/**
* 根据AI识别坐标更新完成数量
*
* @param projectId 项目id
* @param matchPoints 匹配的坐标点id
*/
void updateFinishNumberByCoordinate(Long projectId, List<Long> matchPoints);
}

View File

@ -117,4 +117,11 @@ public interface IFacPhotovoltaicPanelSupportService extends IService<FacPhotovo
TableDataInfo<FacPhotovoltaicPanelPartsByPanelNameVo> queryPageListByPanelName(FacPhotovoltaicPanelPartsQueryReq req,
PageQuery pageQuery);
/**
* 根据AI识别坐标更新完成数量
*
* @param projectId 项目id
* @param matchPoints 匹配的坐标点id
*/
void updateFinishNumberByCoordinate(Long projectId, List<Long> matchPoints);
}

View File

@ -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<FacPhotov
@Resource
private IPgsProgressCategoryService progressCategoryService;
@Lazy
@Resource
private IPgsProgressPlanService progressPlanService;
@Lazy
@Resource
private IPgsProgressPlanDetailService progressPlanDetailService;
/**
* 查询设施-光伏板立柱
*
@ -398,4 +413,119 @@ public class FacPhotovoltaicPanelColumnServiceImpl extends ServiceImpl<FacPhotov
return new TableDataInfo<>(result, panelNamePage.getTotal());
}
/**
* 根据AI识别坐标更新完成数量
*
* @param projectId 项目id
* @param matchPoints 匹配的坐标点id
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void updateFinishNumberByCoordinate(Long projectId, List<Long> matchPoints) {
// 获取数据
List<FacPhotovoltaicPanelColumn> 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<Long, List<FacPhotovoltaicPanelColumn>> mapByCategory = finishList.stream()
.collect(Collectors.groupingBy(FacPhotovoltaicPanelColumn::getProgressCategoryId));
// 判断当天是否有存在的计划
LocalDate now = LocalDate.now();
for (Map.Entry<Long, List<FacPhotovoltaicPanelColumn>> entry : mapByCategory.entrySet()) {
Long categoryId = entry.getKey();
List<FacPhotovoltaicPanelColumn> 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<PgsProgressPlanDetailFinishedVo> 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<PgsProgressPlanDetailFinishedVo> 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);
}
}
}
}
}
}

View File

@ -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<RecognizeConvertCoordinateResult> coordinateList,
String type) {
if (CollUtil.isEmpty(coordinateList)) {
return;
}
List<IdCoordinatePoint> idCoordinatePointList = getIdCoordinatePointList(projectId, type);
if (CollUtil.isEmpty(idCoordinatePointList)) {
return;
}
// 判断识别出来的坐标是否包含某个点
List<Coordinate> coordinates = coordinateList.stream().map(coordinate -> {
return new Coordinate(Double.parseDouble(coordinate.getLng()), Double.parseDouble(coordinate.getLat()));
}).toList();
List<Long> 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<IdCoordinatePoint> getIdCoordinatePointList(Long projectId, String type) {
if (type.equals(RecognizerTypeEnum.HOLE.getValue())) {
List<FacPhotovoltaicPanelPoint> 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<FacPhotovoltaicPanelColumn> 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<FacPhotovoltaicPanelSupport> 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();
}
/**
* 校验名称是否重复
*

View File

@ -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<FacPhotovo
@Resource
private IPgsProgressCategoryService progressCategoryService;
@Lazy
@Resource
private IPgsProgressPlanService progressPlanService;
@Lazy
@Resource
private IPgsProgressPlanDetailService progressPlanDetailService;
/**
* 查询设施-光伏板桩点
*
@ -398,4 +413,118 @@ public class FacPhotovoltaicPanelPointServiceImpl extends ServiceImpl<FacPhotovo
return new TableDataInfo<>(result, panelNamePage.getTotal());
}
/**
* 根据AI识别坐标更新完成数量
*
* @param projectId 项目id
* @param matchPoints 匹配的坐标点id
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void updateFinishNumberByCoordinate(Long projectId, List<Long> matchPoints) {
// 获取数据
List<FacPhotovoltaicPanelPoint> 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<Long, List<FacPhotovoltaicPanelPoint>> mapByCategory = finishList.stream()
.collect(Collectors.groupingBy(FacPhotovoltaicPanelPoint::getProgressCategoryId));
// 判断当天是否有存在的计划
LocalDate now = LocalDate.now();
for (Map.Entry<Long, List<FacPhotovoltaicPanelPoint>> entry : mapByCategory.entrySet()) {
Long categoryId = entry.getKey();
List<FacPhotovoltaicPanelPoint> 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<PgsProgressPlanDetailFinishedVo> 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<PgsProgressPlanDetailFinishedVo> 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);
}
}
}
}
}
}

View File

@ -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<FacPhotovoltaic
for (Map.Entry<Long, List<FacPhotovoltaicPanel>> entry : mapByCategory.entrySet()) {
Long categoryId = entry.getKey();
List<FacPhotovoltaicPanel> 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<PgsProgressPlanDetailFinishedVo> 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<PgsProgressPlanDetailFinishedVo> finishedVos = categoryList.stream().map(panel ->
new PgsProgressPlanDetailFinishedVo(panel.getId(), panel.getName(), FacFinishTypeEnum.AI.getValue())).toList();
if (StringUtils.isNotBlank(finishedDetail)) {
List<PgsProgressPlanDetailFinishedVo> finishedVoList = JSONUtil.toList(finishedDetail, PgsProgressPlanDetailFinishedVo.class);
finishedVoList.addAll(finishedVos);
@ -813,9 +816,66 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
planDetail.setFinishedDetail(JSONUtil.toJsonStr(finishedVos));
}
// 更新计划详情
progressPlanDetailService.updateById(planDetail);
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);
}
}
}
}

View File

@ -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.FacPhotovoltaicPanelSupport;
import org.dromara.facility.domain.dto.photovoltaicpanelparts.FacPhotovoltaicPanelPartsQueryReq;
import org.dromara.facility.domain.dto.photovoltaicpanelsupport.FacPhotovoltaicPanelSupportCreateReq;
import org.dromara.facility.domain.dto.photovoltaicpanelsupport.FacPhotovoltaicPanelSupportQueryReq;
import org.dromara.facility.domain.dto.photovoltaicpanelsupport.FacPhotovoltaicPanelSupportUpdateReq;
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.photovoltaicpanelsupport.FacPhotovoltaicPanelSupportVo;
import org.dromara.facility.mapper.FacPhotovoltaicPanelSupportMapper;
import org.dromara.facility.service.IFacMatrixService;
import org.dromara.facility.service.IFacPhotovoltaicPanelSupportService;
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 FacPhotovoltaicPanelSupportServiceImpl extends ServiceImpl<FacPhoto
@Resource
private IPgsProgressCategoryService progressCategoryService;
@Lazy
@Resource
private IPgsProgressPlanService progressPlanService;
@Lazy
@Resource
private IPgsProgressPlanDetailService progressPlanDetailService;
/**
* 查询设施-光伏板支架
*
@ -398,4 +413,118 @@ public class FacPhotovoltaicPanelSupportServiceImpl extends ServiceImpl<FacPhoto
return new TableDataInfo<>(result, panelNamePage.getTotal());
}
/**
* 根据AI识别坐标更新完成数量
*
* @param projectId 项目id
* @param matchPoints 匹配的坐标点id
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void updateFinishNumberByCoordinate(Long projectId, List<Long> matchPoints) {
// 获取数据
List<FacPhotovoltaicPanelSupport> 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<Long, List<FacPhotovoltaicPanelSupport>> mapByCategory = finishList.stream()
.collect(Collectors.groupingBy(FacPhotovoltaicPanelSupport::getProgressCategoryId));
// 判断当天是否有存在的计划
LocalDate now = LocalDate.now();
for (Map.Entry<Long, List<FacPhotovoltaicPanelSupport>> entry : mapByCategory.entrySet()) {
Long categoryId = entry.getKey();
List<FacPhotovoltaicPanelSupport> 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<PgsProgressPlanDetailFinishedVo> 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<PgsProgressPlanDetailFinishedVo> 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);
}
}
}
}
}
}

View File

@ -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) {

View File

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