大图合并、进度计划日报
This commit is contained in:
@ -336,8 +336,8 @@ ys7:
|
||||
app-key: 3acf9f1a43dc4209841e0893003db0a2
|
||||
app-secret: 09e29c70ae1161fbc3ce2030fc09ba2e
|
||||
job:
|
||||
capture-enabled: true # 控制是否启用萤石抓拍任务
|
||||
device-sync-enabled: true # 控制是否同步萤石设备
|
||||
capture-enabled: false # 控制是否启用萤石抓拍任务
|
||||
device-sync-enabled: false # 控制是否同步萤石设备
|
||||
# 斯巴达算法
|
||||
sparta:
|
||||
url: http://119.3.204.120:8040
|
||||
|
||||
@ -33,6 +33,11 @@ public class DroDroneBigPicture extends BaseEntity {
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 任务ID
|
||||
*/
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
|
||||
@ -35,13 +35,18 @@ public class DroDroneBigPictureBo extends BaseEntity {
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
@NotNull(message = "项目ID不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@NotNull(message = "项目ID不能为空", groups = {AddGroup.class})
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 任务ID
|
||||
*/
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
@NotBlank(message = "任务名称不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@NotBlank(message = "任务名称不能为空", groups = {AddGroup.class})
|
||||
private String taskName;
|
||||
|
||||
/**
|
||||
|
||||
@ -38,6 +38,12 @@ public class DroDroneBigPictureVo implements Serializable {
|
||||
@ExcelProperty(value = "项目ID")
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 任务ID
|
||||
*/
|
||||
@ExcelProperty(value = "任务ID")
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
|
||||
@ -75,4 +75,18 @@ public interface IDroDroneBigPictureService extends IService<DroDroneBigPicture>
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 是否合成完成
|
||||
*
|
||||
* @param picture 大图信息
|
||||
*/
|
||||
String isSynthesisCompleted(DroDroneBigPicture picture);
|
||||
|
||||
/**
|
||||
* 是否合成完成
|
||||
*
|
||||
* @param pictureVo 大图信息
|
||||
*/
|
||||
String isSynthesisCompleted(DroDroneBigPictureVo pictureVo);
|
||||
}
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
package org.dromara.drone.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
@ -16,11 +18,16 @@ import org.dromara.drone.domain.bo.DroDroneBigPictureBo;
|
||||
import org.dromara.drone.domain.vo.DroDroneBigPictureVo;
|
||||
import org.dromara.drone.mapper.DroDroneBigPictureMapper;
|
||||
import org.dromara.drone.service.IDroDroneBigPictureService;
|
||||
import org.dromara.manager.dronemanager.DroneManager;
|
||||
import org.dromara.manager.dronemanager.vo.DroneImgMergeProgressVo;
|
||||
import org.dromara.manager.dronemanager.vo.DroneImgMergeUrlVo;
|
||||
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailAINumberReq;
|
||||
import org.dromara.progress.service.IPgsProgressPlanDetailService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -31,6 +38,7 @@ import java.util.Map;
|
||||
* @author lilemy
|
||||
* @date 2025-11-15
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictureMapper, DroDroneBigPicture>
|
||||
@ -40,6 +48,9 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
@Resource
|
||||
private IPgsProgressPlanDetailService progressPlanDetailService;
|
||||
|
||||
@Resource
|
||||
private DroneManager droneManager;
|
||||
|
||||
/**
|
||||
* 查询无人机大图信息
|
||||
*
|
||||
@ -48,7 +59,19 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
*/
|
||||
@Override
|
||||
public DroDroneBigPictureVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
DroDroneBigPictureVo pictureVo = baseMapper.selectVoById(id);
|
||||
if (pictureVo != null) {
|
||||
String synthesisCompleted = null;
|
||||
try {
|
||||
synthesisCompleted = this.isSynthesisCompleted(pictureVo);
|
||||
if (StringUtils.isNotBlank(synthesisCompleted)) {
|
||||
pictureVo.setStatus(synthesisCompleted);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("查询图片合成进度异常", e);
|
||||
}
|
||||
}
|
||||
return pictureVo;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,6 +85,23 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
public TableDataInfo<DroDroneBigPictureVo> queryPageList(DroDroneBigPictureBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<DroDroneBigPicture> lqw = buildQueryWrapper(bo);
|
||||
Page<DroDroneBigPictureVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
List<DroDroneBigPictureVo> records = result.getRecords();
|
||||
if (CollUtil.isNotEmpty(records)) {
|
||||
// 处理数据,判断合成中的图片是否完成合成
|
||||
for (DroDroneBigPictureVo pictureVo : records) {
|
||||
try {
|
||||
String synthesisCompleted = this.isSynthesisCompleted(pictureVo);
|
||||
if (StringUtils.isNotBlank(synthesisCompleted)) {
|
||||
pictureVo.setStatus(synthesisCompleted);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
pictureVo.setStatus("4");
|
||||
pictureVo.setRemark(e.getMessage());
|
||||
log.error("查询图片合成进度异常", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.setRecords(records);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@ -133,11 +173,32 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
if (bigPicture == null) {
|
||||
throw new ServiceException("无人机大图数据不存在");
|
||||
}
|
||||
// todo 创建识别进度
|
||||
// 判断当前状态是否可以进行识别
|
||||
String status = bigPicture.getStatus();
|
||||
if (!"3".equals(status) && !"7".equals(status)) {
|
||||
throw new ServiceException("当前状态无法进行识别");
|
||||
}
|
||||
String fileUrl;
|
||||
String tifUrl;
|
||||
String taskId = bigPicture.getTaskId();
|
||||
// 获取识别图片地址
|
||||
if (StringUtils.isNotBlank(taskId)) {
|
||||
DroneImgMergeUrlVo mergeUrlVo = droneManager.getMergedFileUrl(taskId);
|
||||
fileUrl = mergeUrlVo.getPngUrl();
|
||||
tifUrl = mergeUrlVo.getTifUrl();
|
||||
} else {
|
||||
fileUrl = bigPicture.getBigPic();
|
||||
tifUrl = bigPicture.getTifFile();
|
||||
}
|
||||
// 创建进度识别
|
||||
PgsProgressPlanDetailAINumberReq ai = new PgsProgressPlanDetailAINumberReq();
|
||||
ai.setFileUrl(bigPicture.getBigPic());
|
||||
ai.setTifUrl(bigPicture.getTifFile());
|
||||
Boolean b = progressPlanDetailService.insertNumberDetailByAI(ai);
|
||||
ai.setFileUrl(fileUrl);
|
||||
ai.setTifUrl(tifUrl);
|
||||
ai.setProjectId(bigPicture.getProjectId());
|
||||
Boolean b = progressPlanDetailService.insertNumberDetailByAI(ai, bigPicture);
|
||||
if (!b) {
|
||||
throw new ServiceException("创建识别进度失败");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -162,4 +223,54 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否合成完成
|
||||
*
|
||||
* @param picture 大图信息
|
||||
*/
|
||||
@Override
|
||||
public String isSynthesisCompleted(DroDroneBigPicture picture) {
|
||||
String newStatus = "";
|
||||
String status = picture.getStatus();
|
||||
String taskId = picture.getTaskId();
|
||||
if (taskId == null) {
|
||||
return newStatus;
|
||||
}
|
||||
if (!status.equals("2")) {
|
||||
return newStatus;
|
||||
}
|
||||
DroneImgMergeProgressVo progress = droneManager.getImgMergeProgress(taskId);
|
||||
if (progress == null) {
|
||||
return newStatus;
|
||||
}
|
||||
BigDecimal msg = progress.getMsg();
|
||||
if (msg != null && msg.compareTo(BigDecimal.ONE) == 0) {
|
||||
newStatus = "3";
|
||||
picture.setStatus(newStatus);
|
||||
} else if (msg != null && msg.compareTo(BigDecimal.ZERO) >= 0 && msg.compareTo(BigDecimal.ONE) < 0) {
|
||||
return newStatus;
|
||||
} else {
|
||||
newStatus = "4";
|
||||
picture.setStatus(newStatus);
|
||||
}
|
||||
// 修改状态
|
||||
boolean b = this.updateById(picture);
|
||||
if (!b) {
|
||||
log.error("修改无人机大图信息状态失败");
|
||||
}
|
||||
return newStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否合成完成
|
||||
*
|
||||
* @param pictureVo 大图信息
|
||||
*/
|
||||
@Override
|
||||
public String isSynthesisCompleted(DroDroneBigPictureVo pictureVo) {
|
||||
DroDroneBigPicture picture = new DroDroneBigPicture();
|
||||
BeanUtils.copyProperties(pictureVo, picture);
|
||||
return this.isSynthesisCompleted(picture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,6 @@ import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -825,7 +824,6 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan
|
||||
* @param coordinateList 识别结果
|
||||
* @param type 类型
|
||||
*/
|
||||
@Async
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateFinishNumberByCoordinate(List<Long> projectIds,
|
||||
|
||||
@ -50,7 +50,6 @@ import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -764,7 +763,6 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
|
||||
* @param coordinateList 坐标列表
|
||||
* @param type 类型
|
||||
*/
|
||||
@Async
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateFinishNumberByCoordinate(List<Long> projectIds,
|
||||
@ -791,17 +789,18 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(finishPanelList)) {
|
||||
LocalDate now = LocalDate.now();
|
||||
// 更新完成状态
|
||||
boolean update = this.lambdaUpdate()
|
||||
.in(FacPhotovoltaicPanel::getId, finishPanelList.stream().map(FacPhotovoltaicPanel::getId).toList())
|
||||
.set(FacPhotovoltaicPanel::getStatus, FacFinishStatusEnum.FINISH.getValue())
|
||||
.set(FacPhotovoltaicPanel::getFinishType, FacFinishTypeEnum.AI.getValue())
|
||||
.set(FacPhotovoltaicPanel::getFinishDate, now)
|
||||
.update();
|
||||
if (update) {
|
||||
Map<Long, List<FacPhotovoltaicPanel>> mapByCategory = finishPanelList.stream()
|
||||
.collect(Collectors.groupingBy(FacPhotovoltaicPanel::getProgressCategoryId));
|
||||
// 判断当天是否有存在的计划
|
||||
LocalDate now = LocalDate.now();
|
||||
for (Map.Entry<Long, List<FacPhotovoltaicPanel>> entry : mapByCategory.entrySet()) {
|
||||
Long categoryId = entry.getKey();
|
||||
PgsProgressCategory category = progressCategoryService.getById(categoryId);
|
||||
@ -836,9 +835,10 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
|
||||
}
|
||||
// 更新计划数量
|
||||
Long planId = planDetail.getProgressPlanId();
|
||||
PgsProgressPlan oldPlan = progressPlanService.getById(planId);
|
||||
PgsProgressPlan plan = new PgsProgressPlan();
|
||||
plan.setId(planId);
|
||||
plan.setFinishedNumber(plan.getFinishedNumber().add(size));
|
||||
plan.setFinishedNumber(oldPlan.getFinishedNumber().add(size));
|
||||
boolean result2 = progressPlanService.updateById(plan);
|
||||
if (!result2) {
|
||||
throw new ServiceException("更新进度计划失败,数据库操作失败", HttpStatus.ERROR);
|
||||
|
||||
@ -18,15 +18,15 @@ public interface DroneConstant {
|
||||
String CREATE_IMG_MERGE_TASK = "/pure/image/synthesis/createTask";
|
||||
|
||||
/**
|
||||
* 下载图片合成结果 GET
|
||||
* 获取图片合成结果 GET
|
||||
*
|
||||
*/
|
||||
String DOWNLOAD_MERGED_FILE = "/pure/image/synthesis/download";
|
||||
String GET_MERGED_FILE_URL = "/pure/image/synthesis/getResultUrls";
|
||||
|
||||
/**
|
||||
* 查询图片合成进度 GET
|
||||
*
|
||||
*/
|
||||
String GET_IMG_MERGE_PROGRESS = "/pure/image/synthesis/queryProgress";
|
||||
String GET_IMG_MERGE_PROGRESS = "/pure/image/synthesis/queryGeneralTaskProgress";
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@ package org.dromara.manager.dronemanager;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.manager.dronemanager.vo.DroneImgMergeProgressVo;
|
||||
import org.dromara.manager.dronemanager.vo.DroneImgMergeUrlVo;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
@ -33,18 +35,8 @@ public class DroneManager {
|
||||
* @param businessName 业务名称
|
||||
* @param imageUrls 图片URL列表
|
||||
*/
|
||||
public void createImageMergeTask(String businessName, List<String> imageUrls) {
|
||||
DroneRequestUtils.createImgMergeTask(droneProperties.getUrl(), businessName, imageUrls);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图片合成结果
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
* @param fileType 文件类型(png/tif)
|
||||
*/
|
||||
public void downloadMergedFile(String taskId, String fileType) {
|
||||
DroneRequestUtils.downloadMergedFile(droneProperties.getUrl(), taskId, fileType);
|
||||
public String createImageMergeTask(String businessName, List<String> imageUrls) {
|
||||
return DroneRequestUtils.createImgMergeTask(droneProperties.getUrl(), businessName, imageUrls);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,8 +44,17 @@ public class DroneManager {
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
*/
|
||||
public void getImgMergeProgress(String taskId) {
|
||||
DroneRequestUtils.getImgMergeProgress(droneProperties.getUrl(), taskId);
|
||||
public DroneImgMergeUrlVo getMergedFileUrl(String taskId) {
|
||||
return DroneRequestUtils.getMergedFileUrl(droneProperties.getUrl(), taskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图片合成结果
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
*/
|
||||
public DroneImgMergeProgressVo getImgMergeProgress(String taskId) {
|
||||
return DroneRequestUtils.getImgMergeProgress(droneProperties.getUrl(), taskId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@ 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.manager.dronemanager.vo.DroneImgMergeProgressVo;
|
||||
import org.dromara.manager.dronemanager.vo.DroneImgMergeUrlVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -66,7 +68,7 @@ public class DroneRequestUtils {
|
||||
* @param businessName 业务名称
|
||||
* @param imageUrls 图片URL列表
|
||||
*/
|
||||
public static void createImgMergeTask(String url, String businessName, List<String> imageUrls) {
|
||||
public static String createImgMergeTask(String url, String businessName, List<String> imageUrls) {
|
||||
if (StringUtils.isBlank(businessName) || CollUtil.isEmpty(imageUrls)) {
|
||||
throw new ServiceException("创建图片合成任务请求参数错误", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
@ -89,28 +91,24 @@ public class DroneRequestUtils {
|
||||
log.error("{},状态码:{},错误信息:{}", errorMsg, obj.get("code"), obj.get("msg"));
|
||||
throw new ServiceException(errorMsg + obj.get("msg"));
|
||||
}
|
||||
log.info("创建图片合成任务请求成功");
|
||||
log.info("创建图片合成任务请求成功:taskId => {}", obj.get("data"));
|
||||
return obj.getStr("data");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载图片合成结果
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
* @param fileType 文件类型(png/tif)
|
||||
* @param taskId 任务ID
|
||||
*/
|
||||
public static void downloadMergedFile(String url, String taskId, String fileType) {
|
||||
if (StringUtils.isAnyBlank(taskId, fileType)) {
|
||||
public static DroneImgMergeUrlVo getMergedFileUrl(String url, String taskId) {
|
||||
if (StringUtils.isAnyBlank(taskId)) {
|
||||
throw new ServiceException("下载图片合成结果请求参数错误", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (!fileType.equals("png") && !fileType.equals("tif")) {
|
||||
throw new ServiceException("无此文件类型", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
// 完整 URL
|
||||
String fullUrl = url + DroneConstant.DOWNLOAD_MERGED_FILE + "/" + taskId + "/" + fileType;
|
||||
String fullUrl = url + DroneConstant.GET_MERGED_FILE_URL + "/" + taskId;
|
||||
String errorMsg = "下载图片合成结果请求失败";
|
||||
try (HttpResponse response = HttpRequest.get(fullUrl)
|
||||
.execute()) {
|
||||
try (HttpResponse response = HttpRequest.get(fullUrl).execute()) {
|
||||
if (!response.isOk()) {
|
||||
log.error("{}:{}", errorMsg, response.getStatus());
|
||||
throw new ServiceException(errorMsg + response.getStatus());
|
||||
@ -121,7 +119,10 @@ public class DroneRequestUtils {
|
||||
log.error("{},状态码:{},错误信息:{}", errorMsg, obj.get("code"), obj.get("msg"));
|
||||
throw new ServiceException(errorMsg + obj.get("msg"));
|
||||
}
|
||||
log.info("下载图片合成结果请求成功");
|
||||
String data = obj.getStr("data");
|
||||
DroneImgMergeUrlVo mergeUrlVo = JSONUtil.toBean(data, DroneImgMergeUrlVo.class);
|
||||
log.info("下载图片合成结果请求成功:{}", mergeUrlVo);
|
||||
return mergeUrlVo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +131,7 @@ public class DroneRequestUtils {
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
*/
|
||||
public static void getImgMergeProgress(String url, String taskId) {
|
||||
public static DroneImgMergeProgressVo getImgMergeProgress(String url, String taskId) {
|
||||
if (StringUtils.isBlank(taskId)) {
|
||||
throw new ServiceException("查询图片合成进度请求参数错误", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
@ -141,15 +142,20 @@ public class DroneRequestUtils {
|
||||
.execute()) {
|
||||
if (!response.isOk()) {
|
||||
log.error("{}:{}", errorMsg, response.getStatus());
|
||||
throw new ServiceException(errorMsg + response.getStatus());
|
||||
throw new ServiceException(errorMsg + ":" + response.getStatus());
|
||||
}
|
||||
String body = response.body();
|
||||
JSONObject obj = JSONUtil.parseObj(body);
|
||||
if (!obj.getStr("code").equals("200")) {
|
||||
log.error("{},状态码:{},错误信息:{}", errorMsg, obj.get("code"), obj.get("msg"));
|
||||
throw new ServiceException(errorMsg + obj.get("msg"));
|
||||
throw new ServiceException(errorMsg + ":" + obj.get("msg"));
|
||||
}
|
||||
log.info("查询图片合成进度请求成功");
|
||||
DroneImgMergeProgressVo progress = JSONUtil.toBean(obj, DroneImgMergeProgressVo.class);
|
||||
if (progress == null) {
|
||||
throw new ServiceException(errorMsg);
|
||||
}
|
||||
log.info("查询图片合成进度请求成功:{}", progress);
|
||||
return progress;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package org.dromara.manager.dronemanager.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-11-17 14:41
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DroneImgMergeProgressVo {
|
||||
|
||||
/**
|
||||
* 进度
|
||||
*/
|
||||
private BigDecimal msg;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private String code;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package org.dromara.manager.dronemanager.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-11-17 17:13
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DroneImgMergeUrlVo {
|
||||
|
||||
/**
|
||||
* png url
|
||||
*/
|
||||
private String pngUrl;
|
||||
|
||||
/**
|
||||
* tif url
|
||||
*/
|
||||
private String tifUrl;
|
||||
}
|
||||
@ -64,7 +64,7 @@ public class PgsProgressPlanDetailController extends BaseController {
|
||||
*/
|
||||
@PostMapping("/insert/numberAI")
|
||||
public R<Void> insertNumberDetailByAI(@Validated @RequestBody PgsProgressPlanDetailAINumberReq req) {
|
||||
return toAjax(pgsProgressPlanDetailService.insertNumberDetailByAI(req));
|
||||
return toAjax(pgsProgressPlanDetailService.insertNumberDetailByAI(req, null));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package org.dromara.progress.domain.dto.progressplandetail;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@ -20,7 +19,6 @@ public class PgsProgressPlanDetailAINumberReq implements Serializable {
|
||||
/**
|
||||
* 大图
|
||||
*/
|
||||
@NotBlank(message = "大图不能为空")
|
||||
private String file;
|
||||
|
||||
/**
|
||||
@ -31,7 +29,6 @@ public class PgsProgressPlanDetailAINumberReq implements Serializable {
|
||||
/**
|
||||
* tif文件
|
||||
*/
|
||||
@NotBlank(message = "tif文件不能为空")
|
||||
private String tif;
|
||||
|
||||
/**
|
||||
|
||||
@ -54,4 +54,9 @@ public class PgsProgressCategoryByDayVo {
|
||||
* 总数
|
||||
*/
|
||||
private Integer size;
|
||||
|
||||
/**
|
||||
* 下日计划
|
||||
*/
|
||||
private String nextPlanStr;
|
||||
}
|
||||
|
||||
@ -54,4 +54,9 @@ public class PgsProgressCategoryDetailByDayVo {
|
||||
* 施工完成
|
||||
*/
|
||||
private BigDecimal constructionCompleted;
|
||||
|
||||
/**
|
||||
* 下日计划
|
||||
*/
|
||||
private BigDecimal nextDayPlan;
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.drone.domain.DroDroneBigPicture;
|
||||
import org.dromara.progress.domain.PgsProgressPlanDetail;
|
||||
import org.dromara.progress.domain.dto.progressplandetail.*;
|
||||
import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailFinishedVo;
|
||||
@ -14,6 +15,7 @@ import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailVo
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* 进度计划详情Service接口
|
||||
@ -132,8 +134,20 @@ public interface IPgsProgressPlanDetailService extends IService<PgsProgressPlanD
|
||||
/**
|
||||
* 使用AI识别计划详情设施数量
|
||||
*
|
||||
* @param req AI识别计划详情设施数量参数
|
||||
* @param req AI识别计划详情设施数量参数
|
||||
* @param bigPicture 大图对象
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean insertNumberDetailByAI(PgsProgressPlanDetailAINumberReq req);
|
||||
Boolean insertNumberDetailByAI(PgsProgressPlanDetailAINumberReq req, DroDroneBigPicture bigPicture);
|
||||
|
||||
/**
|
||||
* 使用AI识别计划详情设施数量
|
||||
*
|
||||
* @param bigPictureId 大图id
|
||||
* @param fileUrl 文件url
|
||||
* @param tifUrl tif文件url
|
||||
* @param projectIds 项目id列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
CompletableFuture<Boolean> recognizeAsync(Long bigPictureId, String fileUrl, String tifUrl, List<Long> projectIds);
|
||||
}
|
||||
|
||||
@ -2296,6 +2296,11 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
.in(PgsProgressPlanDetail::getProjectId, allProjectIds)
|
||||
.eq(PgsProgressPlanDetail::getDate, date)
|
||||
.list();
|
||||
// 获取指定日期后一天的计划详情
|
||||
List<PgsProgressPlanDetail> nextDayDetailList = progressPlanDetailService.lambdaQuery()
|
||||
.in(PgsProgressPlanDetail::getProjectId, allProjectIds)
|
||||
.eq(PgsProgressPlanDetail::getDate, date.plusDays(1))
|
||||
.list();
|
||||
// 根据项目id进行分类
|
||||
Map<Long, String> projectMap = projects.stream()
|
||||
.collect(Collectors.toMap(BusProject::getId, BusProject::getProjectName));
|
||||
@ -2328,8 +2333,18 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
List<PgsProgressPlanDetail> planDetailList = detailList.stream()
|
||||
.filter(detail -> childIds.contains(detail.getProgressCategoryId()))
|
||||
.toList();
|
||||
List<PgsProgressPlanDetail> nextPlanDetailList = nextDayDetailList.stream()
|
||||
.filter(detail -> childIds.contains(detail.getProgressCategoryId()))
|
||||
.toList();
|
||||
// 将子类根据名称进行分类
|
||||
List<PgsProgressCategoryDetailByDayVo> detail = this.getChildrenDetailByName(children, planDetailList);
|
||||
List<PgsProgressCategoryDetailByDayVo> detail = this.getChildrenDetailByName(children, planDetailList, nextPlanDetailList);
|
||||
String nextDayPlanStr = "";
|
||||
if (CollUtil.isNotEmpty(detail)) {
|
||||
nextDayPlanStr = detail.stream()
|
||||
.map(item -> item.getName() + item.getNextDayPlan().stripTrailingZeros().toPlainString() + item.getUnit())
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
vo.setNextPlanStr(nextDayPlanStr);
|
||||
vo.setSize(detail.size());
|
||||
switch (PgsProgressCategoryTypeEnum.fromText(nameKey)) {
|
||||
case BOOSTER_STATION:
|
||||
@ -2998,12 +3013,14 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
/**
|
||||
* 根据子级名称分类并统计数据
|
||||
*
|
||||
* @param children 子级
|
||||
* @param planList 计划
|
||||
* @param children 子级
|
||||
* @param planList 计划
|
||||
* @param nextPlanList 后一天计划
|
||||
* @return 分类后的数据
|
||||
*/
|
||||
private List<PgsProgressCategoryDetailByDayVo> getChildrenDetailByName(List<PgsProgressCategory> children,
|
||||
List<PgsProgressPlanDetail> planList) {
|
||||
List<PgsProgressPlanDetail> planList,
|
||||
List<PgsProgressPlanDetail> nextPlanList) {
|
||||
// 将子类根据名称进行分类
|
||||
Map<String, List<PgsProgressCategory>> childrenMap = children.stream()
|
||||
.collect(Collectors.groupingBy(PgsProgressCategory::getName));
|
||||
@ -3013,6 +3030,12 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
.collect(Collectors.groupingBy(PgsProgressPlanDetail::getProgressCategoryId));
|
||||
}
|
||||
Map<Long, List<PgsProgressPlanDetail>> finalDetailMap = detailMap;
|
||||
Map<Long, List<PgsProgressPlanDetail>> nextDetailMap = new HashMap<>();
|
||||
if (CollUtil.isNotEmpty(nextPlanList)) {
|
||||
nextDetailMap = nextPlanList.stream()
|
||||
.collect(Collectors.groupingBy(PgsProgressPlanDetail::getProgressCategoryId));
|
||||
}
|
||||
Map<Long, List<PgsProgressPlanDetail>> finalNextDetailMap = detailMap;
|
||||
return childrenMap.entrySet().stream()
|
||||
.map(c -> {
|
||||
String name = c.getKey();
|
||||
@ -3034,12 +3057,15 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
.map(PgsProgressCategory::getUnit)
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst().orElse(null);
|
||||
// 获取ids
|
||||
List<Long> ids = list.stream()
|
||||
.map(PgsProgressCategory::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
// 获取施工计划数量
|
||||
BigDecimal constructionPlan = BigDecimal.ZERO;
|
||||
if (CollUtil.isNotEmpty(finalDetailMap)) {
|
||||
constructionPlan = list.stream()
|
||||
.map(PgsProgressCategory::getId)
|
||||
.filter(Objects::nonNull)
|
||||
constructionPlan = ids.stream()
|
||||
.map(finalDetailMap::get)
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(Collection::stream)
|
||||
@ -3050,9 +3076,7 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
// 获取施工完成数量
|
||||
BigDecimal constructionCompleted = BigDecimal.ZERO;
|
||||
if (CollUtil.isNotEmpty(finalDetailMap)) {
|
||||
constructionPlan = list.stream()
|
||||
.map(PgsProgressCategory::getId)
|
||||
.filter(Objects::nonNull)
|
||||
constructionPlan = ids.stream()
|
||||
.map(finalDetailMap::get)
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(Collection::stream)
|
||||
@ -3060,6 +3084,17 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
// 获取后一天的计划
|
||||
BigDecimal nextDayPlan = BigDecimal.ZERO;
|
||||
if (CollUtil.isNotEmpty(finalNextDetailMap)) {
|
||||
nextDayPlan = ids.stream()
|
||||
.map(finalNextDetailMap::get)
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(List::stream)
|
||||
.map(PgsProgressPlanDetail::getPlanNumber)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
// 封装结果
|
||||
PgsProgressCategoryDetailByDayVo vo = new PgsProgressCategoryDetailByDayVo();
|
||||
vo.setConstructionPlan(constructionPlan);
|
||||
@ -3070,6 +3105,7 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
vo.setTotal(total);
|
||||
vo.setCompleted(completed);
|
||||
vo.setCompletedPercentage(BigDecimalUtil.toPercentage(completed, total));
|
||||
vo.setNextDayPlan(nextDayPlan);
|
||||
return vo;
|
||||
}).filter(Objects::nonNull)
|
||||
.sorted(Comparator.comparing(PgsProgressCategoryDetailByDayVo::getId)).toList();
|
||||
|
||||
@ -3,6 +3,7 @@ package org.dromara.progress.service.impl;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.file.FileNameUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
@ -59,6 +60,7 @@ import org.dromara.system.domain.vo.SysOssVo;
|
||||
import org.dromara.system.service.ISysOssService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -71,6 +73,7 @@ import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@ -136,6 +139,10 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
@Resource
|
||||
private IOutConstructionValueRangeService constructionValueRangeService;
|
||||
|
||||
@Lazy
|
||||
@Resource
|
||||
private IPgsProgressPlanDetailService self;
|
||||
|
||||
/**
|
||||
* 分页查询进度计划详情列表
|
||||
*
|
||||
@ -1131,11 +1138,12 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
/**
|
||||
* 使用AI识别计划详情设施数量
|
||||
*
|
||||
* @param req AI识别计划详情设施数量参数
|
||||
* @param req AI识别计划详情设施数量参数
|
||||
* @param bigPicture 大图对象
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertNumberDetailByAI(PgsProgressPlanDetailAINumberReq req) {
|
||||
public Boolean insertNumberDetailByAI(PgsProgressPlanDetailAINumberReq req, DroDroneBigPicture bigPicture) {
|
||||
String fileUrl;
|
||||
String tifUrl;
|
||||
String file = req.getFile();
|
||||
@ -1150,15 +1158,69 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
} else {
|
||||
tifUrl = req.getTifUrl();
|
||||
}
|
||||
if (StringUtils.isAnyBlank(fileUrl, tifUrl)) {
|
||||
throw new ServiceException("请上传图片", HttpStatus.ERROR);
|
||||
}
|
||||
Long projectId = req.getProjectId();
|
||||
// 获取所有子项
|
||||
List<BusProject> projects = projectService.lambdaQuery()
|
||||
.eq(BusProject::getPId, projectId)
|
||||
.list();
|
||||
if (CollUtil.isEmpty(projects)) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
List<Long> projectIds = projects.stream().map(BusProject::getId).distinct().toList();
|
||||
// 保存识别数据
|
||||
Long id;
|
||||
if (bigPicture != null) {
|
||||
bigPicture.setBigPic(fileUrl);
|
||||
bigPicture.setTifFile(tifUrl);
|
||||
bigPicture.setStatus("5");
|
||||
boolean update = droDroneBigPictureService.updateById(bigPicture);
|
||||
if (!update) {
|
||||
throw new ServiceException("保存识别数据失败,数据库异常", HttpStatus.ERROR);
|
||||
}
|
||||
id = bigPicture.getId();
|
||||
} else {
|
||||
DroDroneBigPicture droDroneBigPicture = new DroDroneBigPicture();
|
||||
droDroneBigPicture.setTaskName("无人机任务 - " + RandomUtil.randomString(12));
|
||||
droDroneBigPicture.setProjectId(projectId);
|
||||
droDroneBigPicture.setBigPic(fileUrl);
|
||||
droDroneBigPicture.setTifFile(tifUrl);
|
||||
droDroneBigPicture.setStatus("5");
|
||||
boolean save = droDroneBigPictureService.save(droDroneBigPicture);
|
||||
if (!save) {
|
||||
throw new ServiceException("保存识别数据失败,数据库异常", HttpStatus.ERROR);
|
||||
}
|
||||
id = droDroneBigPicture.getId();
|
||||
}
|
||||
// 异步执行数据同步
|
||||
self.recognizeAsync(id, fileUrl, tifUrl, projectIds)
|
||||
.thenAccept(result -> log.info("识别数据[{}]异步执行成功", id))
|
||||
.exceptionally(ex -> {
|
||||
log.error("识别数据[{}]异步执行失败", id, ex);
|
||||
// 修改状态
|
||||
droDroneBigPictureService.lambdaUpdate()
|
||||
.eq(DroDroneBigPicture::getId, id)
|
||||
.set(DroDroneBigPicture::getStatus, "7")
|
||||
.update();
|
||||
return null;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用AI识别计划详情设施数量
|
||||
*
|
||||
* @param bigPictureId 大图id
|
||||
* @param fileUrl 文件url
|
||||
* @param tifUrl tif文件url
|
||||
* @param projectIds 项目id列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Async
|
||||
@Override
|
||||
public CompletableFuture<Boolean> recognizeAsync(Long bigPictureId, String fileUrl, String tifUrl, List<Long> projectIds) {
|
||||
// 调用识别算法
|
||||
RecognizeVo recognizeVo = null;
|
||||
try {
|
||||
@ -1167,11 +1229,11 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
log.error("识别失败:{}", e.getMessage());
|
||||
}
|
||||
if (recognizeVo == null) {
|
||||
return false;
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
if (recognizeVo.getHasTarget().equals(RecognizerHasTargetEnum.NO.getValue())) {
|
||||
log.info("没有识别到设施");
|
||||
return true;
|
||||
return CompletableFuture.completedFuture(true);
|
||||
}
|
||||
String fileName = FileNameUtil.getName(fileUrl);
|
||||
List<RecognizeTargetVo> targets = recognizeVo.getTargets();
|
||||
@ -1182,7 +1244,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
String type = entry.getKey();
|
||||
List<RecognizeTargetVo> value = entry.getValue();
|
||||
// 调用工具获取经纬度
|
||||
List<RecognizeConvertCoordinateResult> coordinateList = new ArrayList<>();
|
||||
List<RecognizeConvertCoordinateResult> coordinateList;
|
||||
try {
|
||||
coordinateList = recognizerManager.convertCoordinate(tifUrl, targets);
|
||||
if (CollUtil.isEmpty(coordinateList)) {
|
||||
@ -1190,6 +1252,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("转换坐标失败:{}", e.getMessage());
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
log.info("类型:{},识别到的设施:{},转换坐标:{}", type, value, coordinateList);
|
||||
// 处理对应设施
|
||||
@ -1217,14 +1280,16 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
throw new ServiceException("将识别数据同步到图片上失败", HttpStatus.ERROR);
|
||||
}
|
||||
// 保存识别数据
|
||||
DroDroneBigPicture droDroneBigPicture = new DroDroneBigPicture();
|
||||
droDroneBigPicture.setProjectId(projectId);
|
||||
droDroneBigPicture.setBigPic(fileUrl);
|
||||
droDroneBigPicture.setTifFile(tifUrl);
|
||||
droDroneBigPicture.setRecognizePic(recognizePic);
|
||||
droDroneBigPictureService.save(droDroneBigPicture);
|
||||
return true;
|
||||
// 更新数据和状态
|
||||
boolean update = droDroneBigPictureService.lambdaUpdate()
|
||||
.eq(DroDroneBigPicture::getId, bigPictureId)
|
||||
.set(DroDroneBigPicture::getStatus, "6")
|
||||
.set(DroDroneBigPicture::getRecognizePic, recognizePic)
|
||||
.update();
|
||||
if (!update) {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
return CompletableFuture.completedFuture(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user