From d9a42cdedd00a231ce43a10c714995f3b5fd2e22 Mon Sep 17 00:00:00 2001 From: "review512jwy@163.com" <“review512jwy@163.com”> Date: Wed, 22 Apr 2026 16:24:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=88=E4=BC=A0=E6=96=87=E4=BB=B6=E5=86=8D?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E7=AC=94=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/StrayAnimalController.java | 27 ++-- .../boot/mini/model/form/StrayAnimalForm.java | 5 + .../boot/mini/model/vo/SaveStrayAnimalVO.java | 15 +++ .../boot/mini/service/StrayAnimalService.java | 5 +- .../service/impl/StrayAnimalServiceImpl.java | 119 +++++++++++++++--- 5 files changed, 149 insertions(+), 22 deletions(-) create mode 100644 src/main/java/com/youlai/boot/mini/model/vo/SaveStrayAnimalVO.java diff --git a/src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java b/src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java index 15d0d04..b20bbe2 100644 --- a/src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java +++ b/src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java @@ -12,6 +12,7 @@ import com.youlai.boot.mini.model.dto.DeleteStrayAnimalNoteMediaDTO; import com.youlai.boot.mini.model.dto.EditVisibilityDTO; import com.youlai.boot.mini.model.form.StrayAnimalForm; import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery; +import com.youlai.boot.mini.model.vo.SaveStrayAnimalVO; import com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO; import com.youlai.boot.mini.model.vo.StrayAnimalShortVO; import com.youlai.boot.mini.service.StrayAnimalService; @@ -40,20 +41,32 @@ public class StrayAnimalController { private final StrayAnimalService strayAnimalService; + + @Operation(summary = "添加动物信息时先保存文件") + @PostMapping(value = "save/file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @RepeatSubmit + @Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.INSERT) + public Result saveFile( + @RequestPart(name = "images", required = false) List images, + @RequestPart(name = "videos", required = false) List videos + ) { + List urlList = strayAnimalService.saveFile(images, videos); + return Result.success(urlList); + } + @Operation(summary = "添加动物信息") - @PostMapping(value = "save", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(value = "save") @RepeatSubmit @Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.INSERT) public Result saveStrayAnimal( - @Valid StrayAnimalForm formData, - @RequestPart(name = "images") List images, - @RequestPart(name = "videos", required = false) List videos + @Valid @RequestBody StrayAnimalForm formData +// @RequestPart(name = "images", required = false) List images, +// @RequestPart(name = "videos", required = false) List videos ) { - String uuid = strayAnimalService.saveStrayAnimal(formData, images, videos); - return Result.success(uuid); + SaveStrayAnimalVO vo = strayAnimalService.saveStrayAnimal(formData); + return Result.success(vo); } - @Operation(summary = "编辑动物信息(不包含图片/视频媒体资源)") @PostMapping(value = "/update/{animalUuid}") @RepeatSubmit diff --git a/src/main/java/com/youlai/boot/mini/model/form/StrayAnimalForm.java b/src/main/java/com/youlai/boot/mini/model/form/StrayAnimalForm.java index 85e1235..d4441ea 100644 --- a/src/main/java/com/youlai/boot/mini/model/form/StrayAnimalForm.java +++ b/src/main/java/com/youlai/boot/mini/model/form/StrayAnimalForm.java @@ -12,6 +12,8 @@ import lombok.Getter; import lombok.Setter; import org.hibernate.validator.constraints.Length; +import java.util.List; + @Schema(description = "动物信息表单对象") @Getter @Setter @@ -72,4 +74,7 @@ public class StrayAnimalForm { @Schema(description = "完整详细地址,含省市区(县)", example = "福建省厦门市集美区侨英街道莲花尚院2号院") private String address; + @Schema(description = "笔记的文件url集合", example = "[]") + private List mediaUrlList; + } diff --git a/src/main/java/com/youlai/boot/mini/model/vo/SaveStrayAnimalVO.java b/src/main/java/com/youlai/boot/mini/model/vo/SaveStrayAnimalVO.java new file mode 100644 index 0000000..4178c75 --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/vo/SaveStrayAnimalVO.java @@ -0,0 +1,15 @@ +package com.youlai.boot.mini.model.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class SaveStrayAnimalVO { + + @Schema(type = "string", description = "动物信息UUID", example = "0677d62d63ec693bf1bd6dab8a877dc1", requiredMode = Schema.RequiredMode.REQUIRED) + private String animalUuid; + + @Schema(type = "string", description = "笔记UUID", example = "0677d62d63ec693bf1bd6dab8a877dc1", requiredMode = Schema.RequiredMode.REQUIRED) + private String animalNoteUuid; + +} diff --git a/src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java b/src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java index 9629cbd..23e49e5 100644 --- a/src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java +++ b/src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java @@ -9,6 +9,7 @@ import com.youlai.boot.mini.model.dto.MapSearchDTO; import com.youlai.boot.mini.model.entity.MiniStrayAnimal; import com.youlai.boot.mini.model.form.StrayAnimalForm; import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery; +import com.youlai.boot.mini.model.vo.SaveStrayAnimalVO; import com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO; import com.youlai.boot.mini.model.vo.StrayAnimalNearbyVO; import com.youlai.boot.mini.model.vo.StrayAnimalShortVO; @@ -19,7 +20,9 @@ import java.util.List; public interface StrayAnimalService extends IService { - String saveStrayAnimal(@Valid StrayAnimalForm formData, List images, List videos); + List saveFile(List images, List videos); + + SaveStrayAnimalVO saveStrayAnimal(@Valid StrayAnimalForm formData); void updateStrayAnimal(String animalUuid, StrayAnimalForm formData); diff --git a/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java b/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java index 3ef88db..ecd244c 100644 --- a/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java +++ b/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java @@ -31,10 +31,7 @@ import com.youlai.boot.mini.model.entity.MiniStrayAnimalNote; import com.youlai.boot.mini.model.entity.MiniStrayAnimalNoteMedia; import com.youlai.boot.mini.model.form.StrayAnimalForm; import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery; -import com.youlai.boot.mini.model.vo.MiniStrayAnimalNoteMediaVO; -import com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO; -import com.youlai.boot.mini.model.vo.StrayAnimalNearbyVO; -import com.youlai.boot.mini.model.vo.StrayAnimalShortVO; +import com.youlai.boot.mini.model.vo.*; import com.youlai.boot.mini.service.MiniPointRecordService; import com.youlai.boot.mini.service.StrayAnimalService; import com.youlai.boot.system.mapper.UserMapper; @@ -86,11 +83,97 @@ public class StrayAnimalServiceImpl extends ServiceImpl saveFile(List images, List videos) { + long currentTimestamp = System.currentTimeMillis(); + List urlList = new ArrayList<>(); + // 处理图片 + if (images != null) { + for (MultipartFile image : images) { + try { + String objectName = "animal_note/image/" + + currentTimestamp + RandomNumberUtils.createRandomLowerLetterAndNumber(8) + + "." + + FilenameUtils.getExtension(image.getOriginalFilename()); + String url = aliyunFileService.uploadFile(objectName, image.getInputStream()); + MiniStrayAnimalNoteMedia miniStrayAnimalNoteMedia = new MiniStrayAnimalNoteMedia(); + miniStrayAnimalNoteMedia.setUuid(UUID.randomUUID().toString()); + miniStrayAnimalNoteMedia.setMediaType(AnimalNoteMediaTypeEnum.IMAGE.name().toLowerCase()); + miniStrayAnimalNoteMedia.setSourceUrl(url); + miniStrayAnimalNoteMedia.setStorageKey(objectName); + BufferedImage imageInfo = ImageIO.read(image.getInputStream()); + miniStrayAnimalNoteMedia.setWidth(imageInfo.getWidth()); + miniStrayAnimalNoteMedia.setHeight(imageInfo.getHeight()); + miniStrayAnimalNoteMedia.setCreateTimestamp(currentTimestamp); + miniStrayAnimalNoteMedia.setCreateTime(new Date(currentTimestamp)); + miniStrayAnimalNoteMedia.setCreateBy(SecurityUtils.getUserId()); + + int result = miniStrayAnimalNoteMediaMapper.insert(miniStrayAnimalNoteMedia); + + if (result > 0) { + urlList.add(url); + } + } catch (Exception e) { + log.error("image upload failed", e); + } + } + } + + // 处理视频 (如果有) + if (videos != null) { + String tmpPath = System.getProperty("user.dir") + "/tmp"; + for (MultipartFile video : videos) { + try { + String fileName = currentTimestamp + RandomNumberUtils.createRandomLowerLetterAndNumber(8); + String objectName = "animal_note/video/" + + fileName + + "." + + FilenameUtils.getExtension(video.getOriginalFilename()); + String url = aliyunFileService.uploadFile(objectName, video.getInputStream()); + MiniStrayAnimalNoteMedia miniStrayAnimalNoteMedia = new MiniStrayAnimalNoteMedia(); + miniStrayAnimalNoteMedia.setUuid(UUID.randomUUID().toString()); + miniStrayAnimalNoteMedia.setMediaType(AnimalNoteMediaTypeEnum.VIDEO.name().toLowerCase()); + miniStrayAnimalNoteMedia.setSourceUrl(url); + miniStrayAnimalNoteMedia.setStorageKey(objectName); + miniStrayAnimalNoteMedia.setCreateTimestamp(currentTimestamp); + miniStrayAnimalNoteMedia.setCreateTime(new Date(currentTimestamp)); + miniStrayAnimalNoteMedia.setCreateBy(SecurityUtils.getUserId()); + //时长 + FileUtils.saveFile(video, tmpPath, fileName); + String videoPath = tmpPath + File.separator + fileName; + double duration = JavaVCUtils.getVideoDuration(videoPath); + miniStrayAnimalNoteMedia.setDuration((int) Math.ceil(duration)); + //缩略图 + BufferedImage thumbnail = JavaVCUtils.getVideoThumbnail(videoPath, 1); + String thumbnailFileName = currentTimestamp + RandomNumberUtils.createRandomLowerLetterAndNumber(8); + String thumbnailObjectName = "animal_note/thumbnail/" + + thumbnailFileName + + ".png"; + String thumbnailUrl = aliyunFileService.uploadFile(thumbnailObjectName, + FileUtils.bufferedImageToInputStream(thumbnail, "png")); + miniStrayAnimalNoteMedia.setThumbnailUrl(thumbnailUrl); + + int result = miniStrayAnimalNoteMediaMapper.insert(miniStrayAnimalNoteMedia); + if (result > 0) { + urlList.add(url); + } + + FileUtils.delete(videoPath); + + } catch (Exception e) { + log.error("video upload failed", e); + } + } + } + + return urlList; + } + @Override @Transactional(rollbackFor = Exception.class) - public String saveStrayAnimal(StrayAnimalForm formData, List images, List videos) { + public SaveStrayAnimalVO saveStrayAnimal(StrayAnimalForm formData) { // 1. 参数校验 - validateInput(images, videos); +// validateInput(images, videos); // 2. 保存流浪动物基本信息 MiniStrayAnimal miniStrayAnimal = saveAnimalInfo(formData); @@ -99,14 +182,26 @@ public class StrayAnimalServiceImpl extends ServiceImpl wrapper = new LambdaUpdateWrapper<>(); + wrapper.in(MiniStrayAnimalNoteMedia::getSourceUrl, formData.getMediaUrlList()) + .set(MiniStrayAnimalNoteMedia::getNoteId, note.getId()); + miniStrayAnimalNoteMediaMapper.update(wrapper); + } } private void saveMediaFiles(MiniStrayAnimalNote note, List images, List videos, long currentTimestamp) { @@ -236,12 +331,8 @@ public class StrayAnimalServiceImpl extends ServiceImpl images, List videos) { - // 验证必填图片 - if (images == null || images.isEmpty()) { - throw new MsgException("需要上传图片"); - } // 验证图片数量 - if (images.size() > CommonConstants.STRAY_ANIMAL_IMAGE_NUM_LIMIT) { + if (!CollUtil.isEmpty(images) && images.size() > CommonConstants.STRAY_ANIMAL_IMAGE_NUM_LIMIT) { throw new MsgException( "最多只能上传" + CommonConstants.STRAY_ANIMAL_IMAGE_NUM_LIMIT + "张图片" );