diff --git a/core/pom.xml b/core/pom.xml index cba752e..08bc1a5 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -140,6 +140,17 @@ metadata-extractor 2.15.0 + + + org.mapstruct + mapstruct + 1.4.1.Final + + + org.mapstruct + mapstruct-processor + 1.4.1.Final + diff --git a/core/src/main/java/com/dite/znpt/converts/Converts.java b/core/src/main/java/com/dite/znpt/converts/Converts.java new file mode 100644 index 0000000..971f8b8 --- /dev/null +++ b/core/src/main/java/com/dite/znpt/converts/Converts.java @@ -0,0 +1,25 @@ +package com.dite.znpt.converts; + +import com.dite.znpt.domain.entity.ImageCollectEntity; +import com.dite.znpt.domain.entity.ImageEntity; +import com.dite.znpt.domain.vo.ImageCollectReq; +import com.dite.znpt.domain.vo.ImageReq; +import org.mapstruct.Mapper; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * @Author: gaoxiong + * @Date: 2025/4/26 1:32 + * @Description: + */ +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +public interface Converts { + Converts INSTANCE = Mappers.getMapper(Converts.class); + + List toImageEntity(List list); + + ImageCollectEntity toImageCollectEntity(ImageCollectReq req); +} diff --git a/core/src/main/java/com/dite/znpt/domain/AuditableEntity.java b/core/src/main/java/com/dite/znpt/domain/AuditableEntity.java index a36c17e..befb37a 100644 --- a/core/src/main/java/com/dite/znpt/domain/AuditableEntity.java +++ b/core/src/main/java/com/dite/znpt/domain/AuditableEntity.java @@ -20,7 +20,6 @@ import java.util.List; @AllArgsConstructor @NoArgsConstructor @Data -@SuperBuilder(toBuilder = true) public class AuditableEntity implements Serializable { private static final long serialVersionUID = 141481953116476081L; diff --git a/core/src/main/java/com/dite/znpt/domain/entity/ImageCollectEntity.java b/core/src/main/java/com/dite/znpt/domain/entity/ImageCollectEntity.java index 4980ae9..d6bb148 100644 --- a/core/src/main/java/com/dite/znpt/domain/entity/ImageCollectEntity.java +++ b/core/src/main/java/com/dite/znpt/domain/entity/ImageCollectEntity.java @@ -29,9 +29,13 @@ public class ImageCollectEntity extends AuditableEntity implements Serializable private static final long serialVersionUID = -2957687117182827156L; @ApiModelProperty("图像采集id") - @TableId(value = "collect", type = IdType.ASSIGN_UUID) + @TableId(value = "collect_id", type = IdType.ASSIGN_UUID) private String collectId; + @ApiModelProperty("部件id") + @TableField("part_id") + private String partId; + @ApiModelProperty("拍摄时间-起") @TableField("shooting_time_begin") private LocalDateTime shootingTimeBegin; @@ -64,10 +68,14 @@ public class ImageCollectEntity extends AuditableEntity implements Serializable @TableField("shooting_method") private String shootingMethod; - @ApiModelProperty("拍摄方式,枚举ShootingDistanceEnum") + @ApiModelProperty("拍摄距离") @TableField("shooting_distance") private Integer shootingDistance; + @ApiModelProperty("采集员id") + @TableField("collector_id") + private String collectorId; + @ApiModelProperty("采集员姓名") @TableField("collector_name") private String collectorName; diff --git a/core/src/main/java/com/dite/znpt/domain/entity/ImageEntity.java b/core/src/main/java/com/dite/znpt/domain/entity/ImageEntity.java index d4bab7a..0a66e39 100644 --- a/core/src/main/java/com/dite/znpt/domain/entity/ImageEntity.java +++ b/core/src/main/java/com/dite/znpt/domain/entity/ImageEntity.java @@ -36,18 +36,6 @@ public class ImageEntity extends AuditableEntity implements Serializable { @TableField("collect_id") private String collectId; - @ApiModelProperty("部件id") - @TableField("part_id") - private String partId; - - @ApiModelProperty("项目id") - @TableField("project_id") - private String projectId; - - @ApiModelProperty("机组id") - @TableField("turbine_id") - private String turbineId; - @ApiModelProperty("图像名称") @TableField("image_name") private String imageName; diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ImageCollectReq.java b/core/src/main/java/com/dite/znpt/domain/vo/ImageCollectReq.java new file mode 100644 index 0000000..2f0dbf1 --- /dev/null +++ b/core/src/main/java/com/dite/znpt/domain/vo/ImageCollectReq.java @@ -0,0 +1,60 @@ +package com.dite.znpt.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.List; + +/** + * @Author: gaoxiong + * @Date: 2025/4/26 1:11 + * @Description: + */ +@Data +@ApiModel("图像采集信息请求实体") +public class ImageCollectReq implements Serializable { + + @Serial + private static final long serialVersionUID = 8937301872925896770L; + + @ApiModelProperty("拍摄时间-起") + private LocalDateTime shootingTimeBegin; + + @ApiModelProperty("拍摄时间-讫") + private LocalDateTime shootingTimeEnd; + + @ApiModelProperty("天气,枚举:WeatherEnum") + private String weather; + + @ApiModelProperty("湿度(百分比)") + private Integer humidness; + + @ApiModelProperty("温度-低") + private Double temperatureMin; + + @ApiModelProperty("温度-高") + private Double temperatureMax; + + @ApiModelProperty("风力等级") + private Integer windLevel; + + @ApiModelProperty("拍摄方式,枚举ShootingMethodEnum") + private String shootingMethod; + + @ApiModelProperty("拍摄距离") + private Integer shootingDistance; + + @ApiModelProperty("采集员id") + private String collectorId; + + @ApiModelProperty("采集员姓名") + private String collectorName; + + @ApiModelProperty("图像信息") + private List imageList; +} diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ImageCollectResp.java b/core/src/main/java/com/dite/znpt/domain/vo/ImageCollectResp.java index 6ce9002..9a4a1e0 100644 --- a/core/src/main/java/com/dite/znpt/domain/vo/ImageCollectResp.java +++ b/core/src/main/java/com/dite/znpt/domain/vo/ImageCollectResp.java @@ -1,9 +1,19 @@ package com.dite.znpt.domain.vo; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + /** * @Author: gaoxiong * @Date: 2025/4/24 21:16 * @Description: */ -public class ImageCollectResp { +@Data +@ApiModel("图像采集信息响应实体") +public class ImageCollectResp implements Serializable { + @Serial + private static final long serialVersionUID = 6594307991137605975L; } diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ImageListReq.java b/core/src/main/java/com/dite/znpt/domain/vo/ImageListReq.java index c0b8473..070bb14 100644 --- a/core/src/main/java/com/dite/znpt/domain/vo/ImageListReq.java +++ b/core/src/main/java/com/dite/znpt/domain/vo/ImageListReq.java @@ -12,7 +12,7 @@ import java.io.Serializable; * @description */ @Data -@ApiModel("图像信息列表查询实体") +@ApiModel("图像采集信息列表查询实体") public class ImageListReq implements Serializable { @Serial private static final long serialVersionUID = 671014582625089979L; diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ImageReq.java b/core/src/main/java/com/dite/znpt/domain/vo/ImageReq.java new file mode 100644 index 0000000..4628b60 --- /dev/null +++ b/core/src/main/java/com/dite/znpt/domain/vo/ImageReq.java @@ -0,0 +1,59 @@ +package com.dite.znpt.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * @Author: gaoxiong + * @Date: 2025/4/26 1:18 + * @Description: + */ +@Data +@ApiModel("图像信息请求实体") +public class ImageReq implements Serializable { + + @Serial + private static final long serialVersionUID = -1726859254176864573L; + + @ApiModelProperty("图像id") + private String imageId; + + @ApiModelProperty("图像名称") + @TableField("image_name") + private String imageName; + + @ApiModelProperty("图像尺寸") + private String imageSize; + + @ApiModelProperty("焦距") + private String focalDistance; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("拍摄时间") + private LocalDateTime shootingTime; + + @ApiModelProperty("相机制造商") + private String cameraManufacturer; + + @ApiModelProperty("相机型号") + private String cameraModel; + + @ApiModelProperty("经度") + private String longitude; + + @ApiModelProperty("纬度") + private String latitude; + + @ApiModelProperty("海拔") + private String altitude; + + @ApiModelProperty("图片路径") + private String imagePath; +} diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ImageResp.java b/core/src/main/java/com/dite/znpt/domain/vo/ImageResp.java index cce541b..dd7e001 100644 --- a/core/src/main/java/com/dite/znpt/domain/vo/ImageResp.java +++ b/core/src/main/java/com/dite/znpt/domain/vo/ImageResp.java @@ -1,10 +1,14 @@ package com.dite.znpt.domain.vo; +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serial; import java.io.Serializable; +import java.time.LocalDateTime; /** * @author Bear.G @@ -13,7 +17,10 @@ import java.io.Serializable; */ @Data @ApiModel("图像信息响应实体") -public class ImageResp implements Serializable { +public class ImageResp extends ImageReq implements Serializable { @Serial private static final long serialVersionUID = -5215414858454232077L; + + @ApiModelProperty("影像类型,枚举ImageTypeEnum") + private String imageType; } diff --git a/core/src/main/java/com/dite/znpt/service/ImageCollectService.java b/core/src/main/java/com/dite/znpt/service/ImageCollectService.java index c1c3754..9c6819c 100644 --- a/core/src/main/java/com/dite/znpt/service/ImageCollectService.java +++ b/core/src/main/java/com/dite/znpt/service/ImageCollectService.java @@ -2,6 +2,7 @@ package com.dite.znpt.service; import com.baomidou.mybatisplus.extension.service.IService; import com.dite.znpt.domain.entity.ImageCollectEntity; +import com.dite.znpt.domain.vo.ImageCollectReq; /** * @Author: gaoxiong @@ -9,4 +10,5 @@ import com.dite.znpt.domain.entity.ImageCollectEntity; * @Description: */ public interface ImageCollectService extends IService { + void save(String departId, ImageCollectReq req); } diff --git a/core/src/main/java/com/dite/znpt/service/ImageService.java b/core/src/main/java/com/dite/znpt/service/ImageService.java index b956e32..284a3d8 100644 --- a/core/src/main/java/com/dite/znpt/service/ImageService.java +++ b/core/src/main/java/com/dite/znpt/service/ImageService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.dite.znpt.domain.entity.ImageEntity; import com.dite.znpt.domain.vo.ImageListReq; import com.dite.znpt.domain.vo.ImageResp; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -15,4 +16,6 @@ import java.util.List; public interface ImageService extends IService { List selectList(ImageListReq req); + + List batchUpload(String departId, MultipartFile[] files); } diff --git a/core/src/main/java/com/dite/znpt/service/impl/ImageCollectServiceImpl.java b/core/src/main/java/com/dite/znpt/service/impl/ImageCollectServiceImpl.java index c10efeb..4e9b308 100644 --- a/core/src/main/java/com/dite/znpt/service/impl/ImageCollectServiceImpl.java +++ b/core/src/main/java/com/dite/znpt/service/impl/ImageCollectServiceImpl.java @@ -1,10 +1,22 @@ package com.dite.znpt.service.impl; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.dite.znpt.converts.Converts; import com.dite.znpt.domain.entity.ImageCollectEntity; +import com.dite.znpt.domain.entity.ImageEntity; +import com.dite.znpt.domain.vo.ImageCollectReq; import com.dite.znpt.mapper.ImageCollectMapper; import com.dite.znpt.service.ImageCollectService; +import com.dite.znpt.service.ImageService; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.io.File; +import java.util.List; /** * @Author: gaoxiong @@ -14,4 +26,33 @@ import org.springframework.stereotype.Service; @Service public class ImageCollectServiceImpl extends ServiceImpl implements ImageCollectService { + @Value("${upload.perm-path}") + private String permPath; + + @Resource + private ImageService imageService; + + @Transactional(rollbackFor = Exception.class) + @Override + public void save(String partId, ImageCollectReq req) { + ImageCollectEntity imageCollect = Converts.INSTANCE.toImageCollectEntity(req); + imageCollect.setPartId(partId); + this.save(imageCollect); + List imageList = Converts.INSTANCE.toImageEntity(req.getImageList()); + String path_prefix = permPath.concat(StrUtil.BACKSLASH).concat(partId).concat(StrUtil.BACKSLASH); + imageList.stream().forEach(image -> { + image.setCollectId(imageCollect.getCollectId()); + String path = path_prefix + image.getImageName(); + File file = new File(image.getImagePath()); + if (file.exists()) { + byte[] bytes = FileUtil.readBytes(file); + FileUtil.writeBytes(bytes, path); + FileUtil.del(file); + image.setImagePath(path); + }else { + imageList.remove(image); + } + }); + imageService.saveOrUpdateBatch(imageList); + } } diff --git a/core/src/main/java/com/dite/znpt/service/impl/ImageServiceImpl.java b/core/src/main/java/com/dite/znpt/service/impl/ImageServiceImpl.java index 38d5089..c973250 100644 --- a/core/src/main/java/com/dite/znpt/service/impl/ImageServiceImpl.java +++ b/core/src/main/java/com/dite/znpt/service/impl/ImageServiceImpl.java @@ -1,15 +1,32 @@ package com.dite.znpt.service.impl; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.dite.znpt.domain.entity.ImageEntity; import com.dite.znpt.domain.vo.ImageListReq; import com.dite.znpt.domain.vo.ImageResp; import com.dite.znpt.mapper.ImageMapper; import com.dite.znpt.service.ImageService; +import com.dite.znpt.util.EXIFUtil; import com.dite.znpt.util.PageUtil; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author Bear.G @@ -18,6 +35,10 @@ import java.util.List; */ @Service public class ImageServiceImpl extends ServiceImpl implements ImageService { + + @Value("${upload.temp-path}") + private String tempPath; + @Override public List selectList(ImageListReq req) { PageUtil.startPage(); @@ -27,4 +48,65 @@ public class ImageServiceImpl extends ServiceImpl impl }); return imageList; } + + @Transactional(rollbackFor = Exception.class) + @Override + public List batchUpload(String departId, MultipartFile[] files) { + List list = new ArrayList<>(files.length); + String path_prefix = tempPath.concat(StrUtil.BACKSLASH).concat(departId).concat(StrUtil.BACKSLASH); + for (MultipartFile file : files) { + if (!file.isEmpty()) { + try { + String path = path_prefix + file.getOriginalFilename(); + FileUtil.writeBytes(file.getBytes(),path); + list.add(imageRespBuilder(path)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return list; + } + + private ImageResp imageRespBuilder(String path) throws Exception { + ImageResp resp = new ImageResp(); + File file = new File(path); + JSONObject obj = EXIFUtil.printImageTags(file); + resp.setCameraManufacturer(obj.getStr("Make")); + resp.setCameraModel(obj.getStr("Model")); + resp.setImageName(obj.getStr("File Name")); + resp.setImagePath(path); + resp.setImageSize(extractDigit(obj.getStr("Image Width")).concat("*").concat(extractDigit(obj.getStr("Image Height")))); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ss"); + resp.setShootingTime(LocalDateTime.parse( obj.getStr("Date/Time Original"),formatter)); + resp.setFocalDistance(extractDigit(obj.getStr("Focal Length"))); + resp.setLatitude(obj.getStr("GPS Latitude").concat("°").concat(directionTranslator(obj.getStr("GPS Latitude Ref")))); + resp.setLongitude(obj.getStr("GPS Longitude").concat("°").concat(directionTranslator(obj.getStr("GPS Longitude Ref")))); + resp.setAltitude(extractDigit(obj.getStr("GPS Altitude")).concat("m")); + return resp; + } + + private String directionTranslator(String direction){ + if(direction.equalsIgnoreCase("N")){ + return "北"; + } else if (direction.equalsIgnoreCase("S")) { + return "南"; + } else if (direction.equalsIgnoreCase("E")) { + return "东"; + }else if (direction.equalsIgnoreCase("W")) { + return "西"; + }else { + return "未知"; + } + } + + private static String extractDigit(String str) { + Pattern pattern = Pattern.compile("\\d+(\\.\\d+)?"); + Matcher matcher = pattern.matcher(str); + if (matcher.find()) { + return matcher.group(); + } else { + return null; + } + } } diff --git a/web/src/main/java/com/dite/znpt/web/controller/ImageCollectController.java b/web/src/main/java/com/dite/znpt/web/controller/ImageCollectController.java new file mode 100644 index 0000000..d798a88 --- /dev/null +++ b/web/src/main/java/com/dite/znpt/web/controller/ImageCollectController.java @@ -0,0 +1,33 @@ +package com.dite.znpt.web.controller; + +import com.dite.znpt.domain.Result; +import com.dite.znpt.domain.vo.ImageCollectReq; +import com.dite.znpt.domain.vo.ImageResp; +import com.dite.znpt.service.ImageCollectService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.util.List; + +/** + * @Author: gaoxiong + * @Date: 2025/4/26 1:34 + * @Description: + */ +@Api(tags = "图像采集信息") +@RestController +@RequestMapping("/image-collect") +public class ImageCollectController { + + @Resource + private ImageCollectService imageCollectService; + @ApiOperation(value = "保存图像采集信息", httpMethod = "POST") + @PostMapping("/{departId}") + public Result save(@PathVariable String departId, @RequestBody ImageCollectReq req) { + imageCollectService.save(departId, req); + return Result.ok(); + } +} diff --git a/web/src/main/java/com/dite/znpt/web/controller/ImageController.java b/web/src/main/java/com/dite/znpt/web/controller/ImageController.java index 00cb1ec..bde3bf2 100644 --- a/web/src/main/java/com/dite/znpt/web/controller/ImageController.java +++ b/web/src/main/java/com/dite/znpt/web/controller/ImageController.java @@ -2,6 +2,7 @@ package com.dite.znpt.web.controller; import com.dite.znpt.domain.PageResult; +import com.dite.znpt.domain.Result; import com.dite.znpt.domain.vo.ImageListReq; import com.dite.znpt.domain.vo.ImageResp; import com.dite.znpt.service.ImageService; @@ -39,19 +40,7 @@ public class ImageController { @ApiOperation(value = "批量上传图像", httpMethod = "POST") @PostMapping("/upload-batch/{departId}") - public List uploadBatch(@PathVariable String departId, @RequestParam("files") MultipartFile[] files) { - for (MultipartFile file : files) { - if (!file.isEmpty()) { - try { - byte[] bytes = file.getBytes(); - java.nio.file.Path path = Paths.get("G:\\Image/" + file.getOriginalFilename()); - Files.write(path, bytes); - System.out.println("Uploaded: " + file.getOriginalFilename()); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - return null; + public Result> uploadBatch(@PathVariable String departId, @RequestParam("files") MultipartFile[] files) { + return Result.ok(imageService.batchUpload(departId, files)); } } diff --git a/web/src/main/resources/application-dev.yml b/web/src/main/resources/application-dev.yml index f53ac7c..f819151 100644 --- a/web/src/main/resources/application-dev.yml +++ b/web/src/main/resources/application-dev.yml @@ -1,7 +1,7 @@ # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 - port: 8080 + port: 8888 # 数据源配置 spring: @@ -10,7 +10,7 @@ spring: driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://39.99.201.243:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root - password: h67&E98HS8^6 + password: BUw8YW6%@^8q druid: # 初始连接数 initialSize: 5 @@ -59,11 +59,15 @@ spring: max-wait: 3000 host: 39.99.201.243 port: 6379 - password: yfeng@123 + password: diTeZn@123 timeout: 3000 # 0 gaea系统,3 gaea-dev/gaea-test系统,4 znpt开发,5 znpt测试 6 znpt生产 database: 4 - + rabbitmq: + host: 39.99.201.243 + port: 3389 + username: dite + password: diTezN@123 ## MINIO配置 #minio: # url: http://10.20.32.11:9000 @@ -80,7 +84,7 @@ spring: sip-config: name: 信令服务 - ip: 10.17.12.203 + ip: 127.0.0.1 port: 1074 charset: gb2312 domain: 3402000000 @@ -96,7 +100,7 @@ zlm-config: # 公网ip publicHost: # 接口ip - apiHost: 10.17.12.203 + apiHost: 127.0.0.1 # 接口端口 apiPort: 30186 # 密钥 @@ -104,10 +108,15 @@ zlm-config: # 流id前缀 streamPrefix: # rtp ip - rtpHost: 10.17.12.203 + rtpHost: 127.0.0.1 # rtp 端口 rtpPort: 30186 # 动态端口起始值 dynamicPortStart: 30150 # 动态端口结束值 dynamicPortEnd: 30185 + +upload: + temp-path: D:\Upload\Temp + perm-path: D:\Upload\Perm +