1.图片信息增加预处理路径、预处理状态、项目id

2.增加预处理job,开发环境默认禁用
This commit is contained in:
cuizhibin 2025-07-24 14:57:21 +08:00
parent 3c7f8a22d7
commit 55238c157c
12 changed files with 139 additions and 53 deletions

View File

@ -14,6 +14,8 @@ import org.springframework.context.annotation.Configuration;
@ConfigurationProperties(prefix = "util")
public class ExtUtilConfig {
@ApiModelProperty("是否开启预处理job")
private Boolean enableImagePreTreatment;
@ApiModelProperty("图片预处理工具路径")
private String imagePreTreatmentPath;
@ApiModelProperty("报告生成工具路径")

View File

@ -0,0 +1,68 @@
package com.dite.znpt.config;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.BooleanUtil;
import com.dite.znpt.domain.entity.ImageEntity;
import com.dite.znpt.domain.vo.PartResp;
import com.dite.znpt.enums.FilePathEnum;
import com.dite.znpt.service.ImageService;
import com.dite.znpt.service.PartService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
@Component
@RequiredArgsConstructor
public class Schedule {
private final ImageService imageService;
private final PartService partService;
private final ExtUtilConfig extUtilConfig;
/**
* 功能描述图像预处理持续运行
*
* @author cuizhibin
* @date 2025/07/24 14:23
**/
@Scheduled(fixedRate = 10_000)
public void imagePreTreatment() {
if (BooleanUtil.isFalse(extUtilConfig.getEnableImagePreTreatment())) {
return;
}
List<ImageEntity> list = imageService.lambdaQuery().eq(ImageEntity::getPreTreatment, "0")
.isNotNull(ImageEntity::getPartId)
.isNotNull(ImageEntity::getProjectId).list();
List<String> partIds = list.stream().map(ImageEntity::getPartId).toList();
Map<String, PartResp> partRespMap = partService.listInfos(partIds).stream().collect(Collectors.toMap(PartResp::getPartId, Function.identity()));
// 预处理
List<ImageEntity> successList = new ArrayList<>();
for (ImageEntity image : list) {
PartResp partResp = partRespMap.get(image.getPartId());
FilePathEnum pathEnum = image.getImagePath().contains("temp") ? FilePathEnum.IMAGE_TEMP : FilePathEnum.IMAGE;
String inputFile = pathEnum.getFileAbsolutePath(image.getImagePath());
String outputDir = FilePathEnum.IMAGE.getFileAbsolutePathPrefix().concat(partResp.getProjectName())
.concat(FileUtil.FILE_SEPARATOR).concat(partResp.getTurbineName())
.concat(FileUtil.FILE_SEPARATOR).concat(partResp.getPartName());
extUtilConfig.imagePreTreatment(inputFile, outputDir);
String outputFile = outputDir.concat(FileUtil.FILE_SEPARATOR).concat(FileUtil.getName(inputFile));
boolean preSuccess = FileUtil.exist(outputFile);
if(!preSuccess) {
log.warn("图片预处理失败图片id:{},路径:{}", image.getImageId(), inputFile);
continue;
}
image.setPreTreatment(true);
image.setPreImagePath(FilePathEnum.IMAGE.getFileDownPath(outputFile));
successList.add(image);
}
imageService.updateBatchById(successList);
}
}

View File

@ -1,23 +0,0 @@
package com.dite.znpt.domain.bo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableField;
import com.dite.znpt.domain.entity.PartEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class PartFullInfoBo extends PartEntity {
@ApiModelProperty("机组名称")
private String turbineName;
@ApiModelProperty("项目id")
private String projectId;
@ApiModelProperty("机组名称")
private String projectName;
}

View File

@ -120,8 +120,20 @@ public class ImageEntity extends AuditableEntity implements Serializable {
@TableField("image_path")
private String imagePath;
@ApiModelProperty("预处理后的图片路径")
@TableField("pre_image_path")
private String preImagePath;
@ApiModelProperty("是否已审核0未审核1已审核")
@TableField("review_state")
private Boolean reviewState;
@ApiModelProperty("是否已预处理0未审核1已审核")
@TableField("pre_treatment")
private Boolean preTreatment;
@ApiModelProperty("项目id")
@TableField("project_id")
private String projectId;
}

View File

@ -97,4 +97,13 @@ public class ImageListResp implements Serializable {
@ApiModelProperty("关联图像的音频列表")
private List<AudioFileInfoResp> audioList;
@ApiModelProperty("预处理后的图片路径")
private String preImagePath;
@ApiModelProperty("是否已预处理0未审核1已审核")
private Boolean preTreatment;
@ApiModelProperty("项目id")
private String projectId;
}

View File

@ -52,4 +52,12 @@ public class ImageResp implements Serializable {
@ApiModelProperty("影像类型描述")
private String imageTypeLabel;
@ApiModelProperty("预处理后的图片路径")
private String preImagePath;
@ApiModelProperty("是否已预处理0未审核1已审核")
private Boolean preTreatment;
@ApiModelProperty("项目id")
private String projectId;
}

View File

@ -1,7 +1,6 @@
package com.dite.znpt.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dite.znpt.domain.bo.PartFullInfoBo;
import com.dite.znpt.domain.entity.PartEntity;
import com.dite.znpt.domain.vo.PartListReq;
import com.dite.znpt.domain.vo.PartListResp;
@ -86,8 +85,8 @@ public interface PartService extends IService<PartEntity> {
/**
* 查询完整部件信息包含机组项目
* @param partIds
* @return {@link List }<{@link PartFullInfoBo }>
* @return {@link List }<{@link PartResp }>
*/
List<PartFullInfoBo> listInfos(List<String> partIds);
List<PartResp> listInfos(List<String> partIds);
}

View File

@ -12,7 +12,6 @@ import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dite.znpt.constant.Message;
import com.dite.znpt.domain.bo.PartFullInfoBo;
import com.dite.znpt.domain.entity.ImageCollectEntity;
import com.dite.znpt.domain.entity.ImageEntity;
import com.dite.znpt.domain.entity.PartEntity;
@ -114,7 +113,7 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, ImageEntity> impl
}
}
});
this.saveBatch(imageList);
baseMapper.insert(imageList);
return imageList;
}
@ -139,9 +138,7 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, ImageEntity> impl
if (StrUtil.isEmpty(imageSource) || Objects.isNull(ImageSourceEnum.getByCode(imageSource))) {
throw new ServiceException(Message.IMAGE_SOURCE_IS_NOT_EXIST);
}
if(null == partService.getById(partId)){
throw new ServiceException(Message.PART_ID_IS_NOT_EXIST);
}
PartResp partResp = partService.detail(partId);
if(null == files || files.length == 0){
throw new ServiceException(Message.IMAGE_IS_EMPTY);
}
@ -168,6 +165,7 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, ImageEntity> impl
list.add(imageReq);
imageEntity.setImagePath(FilePathEnum.IMAGE_TEMP.getFileDownPath(path));
imageEntity.setPartId(partId);
imageEntity.setProjectId(partResp.getProjectId());
imageEntity.setCollectId(imageCollect.getCollectId());
imageEntity.setImageType(collectReq.getImageType());
imageEntity.setImageTypeLabel(collectReq.getImageTypeLabel());
@ -211,10 +209,7 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, ImageEntity> impl
ImageCollectEntity imageCollect = new ImageCollectEntity();
imageCollect.setCollectId(IdUtil.simpleUUID());
imageCollect.setCollectorName(imageWorkReq.getUploadUser());
PartEntity part = partService.getById(partId);
if (Objects.isNull(part)) {
throw new ServiceException(Message.PART_ID_IS_NOT_EXIST);
}
PartResp part = partService.detail(partId);
List<ImageEntity> imageList = new ArrayList<>();
result.forEach(path -> {
ImageEntity imageEntity = new ImageEntity();
@ -233,6 +228,7 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, ImageEntity> impl
imageEntity.setAltitude(imageWorkReq.getAltitude());
imageEntity.setImagePath(path);
imageEntity.setPartId(partId);
imageEntity.setProjectId(part.getProjectId());
imageEntity.setCollectId(imageCollect.getCollectId());
imageList.add(imageEntity);
});
@ -254,10 +250,9 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, ImageEntity> impl
if(CollUtil.isEmpty(imageList)){
imageCollectService.removeById(image.getCollectId());
}
File file = new File(image.getImagePath());
if (file.exists()) {
FileUtil.del(file);
}
FilePathEnum pathEnum = image.getImagePath().contains("temp") ? FilePathEnum.IMAGE_TEMP : FilePathEnum.IMAGE;
FileUtil.del(pathEnum.getFileAbsolutePath(image.getImagePath()));
FileUtil.del(FilePathEnum.IMAGE.getFileAbsolutePath(image.getPreImagePath()));
}
private ImageReq imageRespBuilder(String path) throws Exception {
@ -349,11 +344,11 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, ImageEntity> impl
.collect(Collectors.toMap(ImageEntity::getImagePath, Function.identity(), (a, b) -> a));
// 查询部件信息
Map<String, PartFullInfoBo> partInfoMap = new HashMap<>();
Map<String, PartResp> partInfoMap = new HashMap<>();
CollUtil.split(imageList, 1000).forEach(images -> {
List<String> partIds = images.stream().map(ImageEntity::getPartId).collect(Collectors.toList());
List<PartFullInfoBo> partList = partService.listInfos(partIds);
partInfoMap.putAll(partList.stream().collect(Collectors.toMap(PartFullInfoBo::getPartId, Function.identity())));
List<PartResp> partList = partService.listInfos(partIds);
partInfoMap.putAll(partList.stream().collect(Collectors.toMap(PartResp::getPartId, Function.identity())));
});
// 将信息写入返回实体
@ -367,7 +362,7 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, ImageEntity> impl
ImageEntity image = imageMap.get(filePath);
if (image != null) {
BeanUtil.copyProperties(image, resp);
PartFullInfoBo part = partInfoMap.get(image.getPartId());
PartResp part = partInfoMap.get(image.getPartId());
if (part != null) {
resp.setPartId(part.getPartId());
resp.setPartName(part.getPartName());

View File

@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dite.znpt.constant.Message;
import com.dite.znpt.converts.Converts;
import com.dite.znpt.domain.bo.PartFullInfoBo;
import com.dite.znpt.domain.entity.PartEntity;
import com.dite.znpt.domain.entity.ProjectEntity;
import com.dite.znpt.domain.entity.TurbineEntity;
@ -89,6 +88,9 @@ public class PartServiceImpl extends ServiceImpl<PartMapper, PartEntity> impleme
@Override
public PartResp detail(String partId) {
PartEntity entity = this.baseMapper.selectById(partId);
if(null == entity){
throw new ServiceException(Message.PART_ID_IS_NOT_EXIST);
}
PartResp resp = Converts.INSTANCE.toPartResp(entity);
if(StrUtil.isNotEmpty(resp.getTurbineId())){
TurbineEntity turbine = turbineService.getById(resp.getTurbineId());
@ -97,6 +99,7 @@ public class PartServiceImpl extends ServiceImpl<PartMapper, PartEntity> impleme
if(StrUtil.isNotEmpty(turbine.getProjectId())){
ProjectEntity project = projectService.getById(turbine.getProjectId());
if(null != project){
resp.setProjectId(resp.getProjectId());
resp.setProjectName(project.getProjectName());
}
}
@ -166,18 +169,18 @@ public class PartServiceImpl extends ServiceImpl<PartMapper, PartEntity> impleme
}
@Override
public List<PartFullInfoBo> listInfos(List<String> partIds) {
public List<PartResp> listInfos(List<String> partIds) {
List<PartEntity> list = lambdaQuery().in(PartEntity::getPartId, partIds).list();
List<TurbineEntity> turbineList = turbineService.lambdaQuery().in(TurbineEntity::getTurbineId, list.stream().map(PartEntity::getTurbineId).collect(Collectors.toList())).list();
Map<String, TurbineEntity> turbineMap = turbineList.stream().collect(Collectors.toMap(TurbineEntity::getTurbineId, Function.identity()));
Map<String, ProjectEntity> projectMap = projectService.lambdaQuery().in(ProjectEntity::getProjectId, turbineList.stream().map(TurbineEntity::getProjectId).collect(Collectors.toList())).list()
.stream().collect(Collectors.toMap(ProjectEntity::getProjectId, Function.identity()));
return BeanUtil.copyToList(list, PartFullInfoBo.class).stream().peek(partBo -> {
TurbineEntity turbineEntity = turbineMap.get(partBo.getTurbineId());
return BeanUtil.copyToList(list, PartResp.class).stream().peek(resp -> {
TurbineEntity turbineEntity = turbineMap.get(resp.getTurbineId());
ProjectEntity projectEntity = projectMap.get(turbineEntity.getProjectId());
partBo.setTurbineName(turbineEntity.getTurbineName());
partBo.setProjectId(projectEntity.getProjectId());
partBo.setProjectName(projectEntity.getProjectName());
resp.setTurbineName(turbineEntity.getTurbineName());
resp.setProjectId(projectEntity.getProjectId());
resp.setProjectName(projectEntity.getProjectName());
}).collect(Collectors.toList());
}
}

View File

@ -5,7 +5,8 @@
SELECT
i.image_id, i.image_name, i.part_id, p.part_name, i.image_resolution, i.focal_distance, i.shooting_time, i.camera_manufacturer,
i.camera_model, i.GPS, ic.weather, ic.humidness, CONCAT(ic.temperature_min, '℃', '~',temperature_max, '℃') AS temperature, ic.wind_level,
ic.shooting_method, ic.shooting_distance,ic.collector_name, i.image_type, i.image_path, ic.image_source, i.review_state, i.image_type_label
ic.shooting_method, ic.shooting_distance,ic.collector_name, i.image_type, i.image_path, ic.image_source, i.review_state, i.image_type_label,
i.pre_image_path, i.project_id, i.pre_treatment
FROM image i
LEFT JOIN image_collect ic ON i.collect_id = ic.collect_id
LEFT JOIN part p ON i.part_id = p.part_id
@ -32,6 +33,9 @@
<id property="imageId" column="image_id"></id>
<result property="imageName" column="image_name"></result>
<result property="imagePath" column="image_path"></result>
<result property="preImagePath" column="pre_image_path"></result>
<result property="preTreatment" column="pre_treatment"></result>
<result property="projectId" column="project_id"></result>
<result property="imageSize" column="image_size"></result>
<result property="imageResolution" column="image_resolution"></result>
<result property="reviewState" column="review_state"></result>
@ -67,10 +71,11 @@
</resultMap>
<select id="detail" resultMap="imageRespMap">
SELECT i.image_id, i.image_name, i.image_path, i.image_height, i.image_resolution, i.image_width, i.image_height, i.focal_distance,
SELECT i.image_id, i.image_name, i.image_path, i.pre_image_path, i.image_height, i.image_resolution, i.image_width, i.image_height, i.focal_distance,
i.focal_distance35, i.x_resolution, i.y_resolution, i.resolution_units, i.shooting_time, i.camera_manufacturer, i.camera_model,
i.latitude, i.latitude, i.altitude, ic.collect_id, ic.weather, CONCAT(ic.temperature_min, '℃', '~',temperature_max, '℃') AS temperature,
ic.wind_level, ic.shooting_method, ic.shooting_distance, ic.collector_name, ic.image_source, i.review_state, i.image_type, i.image_type_label
ic.wind_level, ic.shooting_method, ic.shooting_distance, ic.collector_name, ic.image_source, i.review_state, i.image_type, i.image_type_label,
i.pre_treatment, i.project_id
FROM image i
LEFT JOIN image_collect ic ON i.collect_id = ic.collect_id
WHERE i.image_id = #{imageId}

View File

@ -5,11 +5,13 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@MapperScan("com.dite.**.mapper")
@ComponentScan(basePackages = {"com.dite"})
@EnableSpringUtil
@EnableScheduling
public class DiteApplication {
public static void main(String[] args) {

View File

@ -142,3 +142,9 @@ deploy:
secret: cRc5888KAo4TxRS4y5iv35GM
build-dir: /home/dtyx/znpt-backend/build
# 工具路径
util:
enableImagePreTreatment: false
imagePreTreatmentPath: d:\
reportGeneratorPath: D:\blade_report_generator.exe
reportGeneratorTemplatePath: D:\muban