diff --git a/src/main/java/com/youlai/boot/common/exception/MsgException.java b/src/main/java/com/youlai/boot/common/exception/MsgException.java new file mode 100644 index 0000000..b0bcaf2 --- /dev/null +++ b/src/main/java/com/youlai/boot/common/exception/MsgException.java @@ -0,0 +1,42 @@ +package com.youlai.boot.common.exception; + +import com.youlai.boot.common.result.IResultCode; +import lombok.Getter; +import org.slf4j.helpers.MessageFormatter; + +/** + * 需反馈给用户端的提示 + */ +@Getter +public class MsgException extends RuntimeException { + + public IResultCode resultCode; + + public MsgException(IResultCode errorCode) { + super(errorCode.getMsg()); + this.resultCode = errorCode; + } + + + public MsgException(IResultCode errorCode, String message) { + super(message); + this.resultCode = errorCode; + } + + + public MsgException(String message, Throwable cause) { + super(message, cause); + } + + public MsgException(Throwable cause) { + super(cause); + } + + public MsgException(String message, Object... args) { + super(formatMessage(message, args)); + } + + private static String formatMessage(String message, Object... args) { + return MessageFormatter.arrayFormat(message, args).getMessage(); + } +} diff --git a/src/main/java/com/youlai/boot/common/result/ResultCode.java b/src/main/java/com/youlai/boot/common/result/ResultCode.java index a0833d1..189e7bc 100644 --- a/src/main/java/com/youlai/boot/common/result/ResultCode.java +++ b/src/main/java/com/youlai/boot/common/result/ResultCode.java @@ -53,10 +53,11 @@ import java.io.Serializable; public enum ResultCode implements IResultCode, Serializable { SUCCESS("00000", "成功"), - + /** 一级宏观错误码:用户端错误(由客户端输入/认证/权限/请求方式等引起,需客户端配合修正) */ USER_ERROR("A0001", "用户端错误"), - + MSG_ERROR("A0002", "需反馈给用户端的提示"), + /** 二级宏观错误码:用户端具体错误(按号段细分,便于定位是注册/登录/令牌/参数/防重等问题) */ @@ -98,7 +99,7 @@ public enum ResultCode implements IResultCode, Serializable { /** A07xx:文件处理异常 */ UPLOAD_FILE_EXCEPTION("A0700", "上传文件异常"), DELETE_FILE_EXCEPTION("A0710", "删除文件异常"), - + /** 一级宏观错误码:系统端错误(服务端内部异常/超时/不可用等,需后端排查修复) */ SYSTEM_ERROR("B0001", "系统执行出错"), diff --git a/src/main/java/com/youlai/boot/file/service/FileService.java b/src/main/java/com/youlai/boot/file/service/FileService.java index b8cbaba..bd4238d 100644 --- a/src/main/java/com/youlai/boot/file/service/FileService.java +++ b/src/main/java/com/youlai/boot/file/service/FileService.java @@ -29,7 +29,4 @@ public interface FileService { boolean deleteFile(String filePath); - String uploadFile(String objectName, InputStream inputStream); - - } diff --git a/src/main/java/com/youlai/boot/file/service/impl/AliyunFileService.java b/src/main/java/com/youlai/boot/file/service/impl/AliyunFileService.java index 2688f0d..baba791 100644 --- a/src/main/java/com/youlai/boot/file/service/impl/AliyunFileService.java +++ b/src/main/java/com/youlai/boot/file/service/impl/AliyunFileService.java @@ -6,6 +6,8 @@ import cn.hutool.core.lang.Assert; import cn.hutool.core.util.IdUtil; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.model.DeleteObjectsRequest; +import com.aliyun.oss.model.DeleteObjectsResult; import com.aliyun.oss.model.ObjectMetadata; import com.aliyun.oss.model.PutObjectRequest; import com.youlai.boot.file.service.FileService; @@ -14,6 +16,7 @@ import jakarta.annotation.PostConstruct; import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -21,6 +24,7 @@ import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; import java.time.LocalDateTime; +import java.util.List; /** * Aliyun 对象存储服务类 @@ -33,6 +37,7 @@ import java.time.LocalDateTime; @ConfigurationProperties(prefix = "oss.aliyun") @RequiredArgsConstructor @Data +@Slf4j public class AliyunFileService implements FileService { /** * 服务Endpoint @@ -109,4 +114,17 @@ public class AliyunFileService implements FileService { aliyunOssClient.deleteObject(bucketName, fileName); return true; } + + public void deleteMultiFile(List objectNames) { + + DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest(bucketName).withKeys(objectNames); + DeleteObjectsResult deleteResult = aliyunOssClient.deleteObjects(deleteRequest); + + List deletedObjects = deleteResult.getDeletedObjects(); + + deletedObjects.forEach(key -> log.info(" - {}", key)); + + log.info("aliyun oss files delete successfully......."); + + } } diff --git a/src/main/java/com/youlai/boot/file/service/impl/LocalFileService.java b/src/main/java/com/youlai/boot/file/service/impl/LocalFileService.java index e9a293f..4a9e927 100644 --- a/src/main/java/com/youlai/boot/file/service/impl/LocalFileService.java +++ b/src/main/java/com/youlai/boot/file/service/impl/LocalFileService.java @@ -90,8 +90,4 @@ public class LocalFileService implements FileService { return FileUtil.del(storagePath + filePath); } - @Override - public String uploadFile(String objectName, InputStream inputStream) { - return ""; - } } diff --git a/src/main/java/com/youlai/boot/file/service/impl/MinioFileService.java b/src/main/java/com/youlai/boot/file/service/impl/MinioFileService.java index 5516795..03e5a32 100644 --- a/src/main/java/com/youlai/boot/file/service/impl/MinioFileService.java +++ b/src/main/java/com/youlai/boot/file/service/impl/MinioFileService.java @@ -165,11 +165,6 @@ public class MinioFileService implements FileService { } } - @Override - public String uploadFile(String objectName, InputStream inputStream) { - return ""; - } - /** * PUBLIC桶策略 diff --git a/src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java b/src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java index fb0e25d..131578f 100644 --- a/src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java +++ b/src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java @@ -1,6 +1,7 @@ package com.youlai.boot.framework.web.advice; import cn.hutool.core.util.StrUtil; +import com.youlai.boot.common.exception.MsgException; import tools.jackson.core.JacksonException; import com.youlai.boot.common.exception.BusinessException; import com.youlai.boot.common.result.Result; @@ -239,6 +240,13 @@ public class GlobalExceptionHandler { return Result.failed(e.getMessage()); } + @ExceptionHandler(MsgException.class) + @ResponseStatus(HttpStatus.OK) + public Result handleMsgException(MsgException e) { + log.error("msg exception", e); + return Result.failed(ResultCode.MSG_ERROR, e.getMessage()); + } + /** * 处理所有未捕获的异常 *

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 804e758..0897d1d 100644 --- a/src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java +++ b/src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java @@ -6,15 +6,21 @@ import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; import com.youlai.boot.common.model.Option; import com.youlai.boot.common.result.Result; +import com.youlai.boot.mini.model.dto.DeleteStrayAnimalDTO; +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.service.StrayAnimalService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -32,7 +38,7 @@ public class StrayAnimalController { private final StrayAnimalService strayAnimalService; @Operation(summary = "添加动物信息") - @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(value = "save", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @RepeatSubmit @Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.INSERT) public Result saveStrayAnimal( @@ -44,4 +50,65 @@ public class StrayAnimalController { return Result.success(uuid); } + + @Operation(summary = "编辑动物信息(不包含图片/视频媒体资源)") + @PostMapping(value = "/update/{animalUuid}") + @RepeatSubmit + @Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.UPDATE) + public Result updateStrayAnimal( + @PathVariable String animalUuid, + @Validated @RequestBody StrayAnimalForm formData + ) { + strayAnimalService.updateStrayAnimal(animalUuid, formData); + return Result.success(); + } + + @Operation(summary = "编辑动物信息时,删除流浪动物信息媒体资源") + @PostMapping(value = "/update/deleteMediaSource") + @Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.UPDATE) + public Result deleteMediaSource( + @RequestBody @Validated DeleteStrayAnimalNoteMediaDTO deleteStrayAnimalNoteMediaDTO + ){ + strayAnimalService.deleteMediaSource(deleteStrayAnimalNoteMediaDTO); + return Result.success(); + } + + + @Operation(summary = "编辑动物信息时,添加流浪动物信息媒体资源", description = "比如补充图片、补充视频") + @PostMapping(value = "/update/saveMediaSource/{noteUuid}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @RepeatSubmit + @Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.UPDATE) + public Result saveMediaSource( + @PathVariable String noteUuid, + @RequestPart(name = "images", required = false) List images, + @RequestPart(name = "videos", required = false) List videos + ) { + strayAnimalService.saveMediaSource(noteUuid, images, videos); + return Result.success(); + } + + + @Operation(summary = "编辑动物信息可见范围") + @PostMapping(value = "/update/visibility/{animalUuid}") + @RepeatSubmit + @Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.UPDATE) + public Result updateVisibility( + @PathVariable String animalUuid, + @RequestBody @Validated EditVisibilityDTO editVisibilityDTO + ) { + strayAnimalService.updateVisibility(animalUuid, editVisibilityDTO); + return Result.success(); + } + + @Operation(summary = "删除动物信息") + @PostMapping(value = "/delete") + @RepeatSubmit + @Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.DELETE) + public Result delete( + @RequestBody @Validated DeleteStrayAnimalDTO deleteStrayAnimalDTO + ) { + strayAnimalService.delete(deleteStrayAnimalDTO); + return Result.success(); + } + } diff --git a/src/main/java/com/youlai/boot/mini/converter/MiniStrayAnimalConverter.java b/src/main/java/com/youlai/boot/mini/converter/MiniStrayAnimalConverter.java index bcf6b4d..670e00e 100644 --- a/src/main/java/com/youlai/boot/mini/converter/MiniStrayAnimalConverter.java +++ b/src/main/java/com/youlai/boot/mini/converter/MiniStrayAnimalConverter.java @@ -2,9 +2,6 @@ package com.youlai.boot.mini.converter; import com.youlai.boot.mini.model.entity.MiniStrayAnimal; import com.youlai.boot.mini.model.form.StrayAnimalForm; -import com.youlai.boot.system.model.entity.Dept; -import com.youlai.boot.system.model.form.DeptForm; -import com.youlai.boot.system.model.vo.DeptVO; import org.mapstruct.Mapper; /** diff --git a/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalMapper.java b/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalMapper.java index 0ff5576..72946ec 100644 --- a/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalMapper.java +++ b/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalMapper.java @@ -13,4 +13,6 @@ public interface MiniStrayAnimalMapper extends BaseMapper { boolean insertStrayAnimal(MiniStrayAnimal entity); + void updateStrayAnimal(MiniStrayAnimal miniStrayAnimal); + } diff --git a/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalNoteMediaMapper.java b/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalNoteMediaMapper.java index 4f60da1..c326c67 100644 --- a/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalNoteMediaMapper.java +++ b/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalNoteMediaMapper.java @@ -3,6 +3,8 @@ package com.youlai.boot.mini.mapper; import com.youlai.boot.mini.model.entity.MiniStrayAnimalNoteMedia; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import java.util.Map; + /** * 流浪信息资源表 Mapper 接口 * @@ -11,4 +13,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; */ public interface MiniStrayAnimalNoteMediaMapper extends BaseMapper { + int getMediaCountByNoteIdAndType(Map param); } diff --git a/src/main/java/com/youlai/boot/mini/model/dto/DeleteStrayAnimalDTO.java b/src/main/java/com/youlai/boot/mini/model/dto/DeleteStrayAnimalDTO.java new file mode 100644 index 0000000..61e54a9 --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/dto/DeleteStrayAnimalDTO.java @@ -0,0 +1,29 @@ +package com.youlai.boot.mini.model.dto; + +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; +import org.bytedeco.opencv.presets.opencv_core; + +import java.util.List; + +@Data +public class DeleteStrayAnimalDTO { + + @NotEmpty(message = "uuid不能为空") + @ArraySchema( + arraySchema = @Schema( + description = "流浪动物信息uuid列表", + example = "[\"uuid1\",\"uuid2\"]", + requiredMode = Schema.RequiredMode.REQUIRED + ), + schema = @Schema( + description = "动物信息uuid", + example = "uuid1" + ) + ) + private List<@NotBlank(message = "uuid不能为空") String> animalUuidList; + +} diff --git a/src/main/java/com/youlai/boot/mini/model/dto/DeleteStrayAnimalNoteMediaDTO.java b/src/main/java/com/youlai/boot/mini/model/dto/DeleteStrayAnimalNoteMediaDTO.java new file mode 100644 index 0000000..3010dbb --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/dto/DeleteStrayAnimalNoteMediaDTO.java @@ -0,0 +1,36 @@ +package com.youlai.boot.mini.model.dto; + +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +@Data +public class DeleteStrayAnimalNoteMediaDTO { + + @NotEmpty(message = "媒体资源uuid不能为空") + @ArraySchema( + arraySchema = @Schema( + description = "流浪动物信息媒体资源uuid列表", + example = "[\"uuid1\",\"uuid2\"]", + requiredMode = Schema.RequiredMode.REQUIRED + ), + schema = @Schema( + description = "媒体资源uuid", + example = "uuid1" + ) + ) + private List<@NotBlank(message = "uuid不能为空") String> noteMediaUuidList; + + @NotBlank(message = "笔记uuid不能为空") + @Schema( + description = "流浪动物信息笔记uuid", + example = "2d7890db8a6e47016ccef2d679d5a2c8", + requiredMode = Schema.RequiredMode.REQUIRED + ) + private String noteUuid; +} diff --git a/src/main/java/com/youlai/boot/mini/model/dto/EditVisibilityDTO.java b/src/main/java/com/youlai/boot/mini/model/dto/EditVisibilityDTO.java new file mode 100644 index 0000000..0076b80 --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/dto/EditVisibilityDTO.java @@ -0,0 +1,18 @@ +package com.youlai.boot.mini.model.dto; + +import com.youlai.boot.common.annotation.EnumValid; +import com.youlai.boot.mini.model.enums.VisibilityEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class EditVisibilityDTO { + + @NotBlank(message = "可见性范围不能为空") + @EnumValid(enumClass = VisibilityEnum.class, message = "可见性范围不合法") + @Schema(description = "可见性范围:public-公开,private-仅自己,friends-仅好友", example = "public") + private String visibility="public"; + +} diff --git a/src/main/java/com/youlai/boot/mini/model/entity/MiniStrayAnimalNoteMedia.java b/src/main/java/com/youlai/boot/mini/model/entity/MiniStrayAnimalNoteMedia.java index 9cd53ed..5760a35 100644 --- a/src/main/java/com/youlai/boot/mini/model/entity/MiniStrayAnimalNoteMedia.java +++ b/src/main/java/com/youlai/boot/mini/model/entity/MiniStrayAnimalNoteMedia.java @@ -62,7 +62,7 @@ public class MiniStrayAnimalNoteMedia implements Serializable { @TableField("sort_order") @Schema(description = "排序顺序") - private Integer sortOrder; + private Long sortOrder; @TableField("create_time") @Schema(description = "创建时间") 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 7516fbc..834f336 100644 --- a/src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java +++ b/src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java @@ -1,6 +1,10 @@ package com.youlai.boot.mini.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.youlai.boot.common.result.Result; +import com.youlai.boot.mini.model.dto.DeleteStrayAnimalDTO; +import com.youlai.boot.mini.model.dto.DeleteStrayAnimalNoteMediaDTO; +import com.youlai.boot.mini.model.dto.EditVisibilityDTO; import com.youlai.boot.mini.model.entity.MiniStrayAnimal; import com.youlai.boot.mini.model.form.StrayAnimalForm; import jakarta.validation.Valid; @@ -12,4 +16,14 @@ public interface StrayAnimalService extends IService { String saveStrayAnimal(@Valid StrayAnimalForm formData, List images, List videos); + void updateStrayAnimal(String animalUuid, StrayAnimalForm formData); + + void deleteMediaSource(DeleteStrayAnimalNoteMediaDTO deleteStrayAnimalNoteMediaDTO); + + void saveMediaSource(String noteUuid, List images, List videos); + + void updateVisibility(String animalUuid, EditVisibilityDTO editVisibilityDTO); + + void delete(DeleteStrayAnimalDTO deleteStrayAnimalDTO); } + 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 457563c..6fc83b1 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 @@ -3,18 +3,24 @@ package com.youlai.boot.mini.service.impl; import ch.hsr.geohash.GeoHash; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.youlai.boot.common.constant.CommonConstants; +import com.youlai.boot.common.exception.MsgException; import com.youlai.boot.common.util.CoordinateTransformUtils; import com.youlai.boot.common.util.FileUtils; import com.youlai.boot.common.util.JavaVCUtils; import com.youlai.boot.common.util.RandomNumberUtils; -import com.youlai.boot.file.service.FileService; +import com.youlai.boot.file.service.impl.AliyunFileService; import com.youlai.boot.framework.security.util.SecurityUtils; import com.youlai.boot.mini.converter.MiniStrayAnimalConverter; import com.youlai.boot.mini.mapper.MiniStrayAnimalMapper; import com.youlai.boot.mini.mapper.MiniStrayAnimalNoteMapper; import com.youlai.boot.mini.mapper.MiniStrayAnimalNoteMediaMapper; +import com.youlai.boot.mini.model.dto.DeleteStrayAnimalDTO; +import com.youlai.boot.mini.model.dto.DeleteStrayAnimalNoteMediaDTO; +import com.youlai.boot.mini.model.dto.EditVisibilityDTO; import com.youlai.boot.mini.model.enums.AnimalNoteMediaTypeEnum; import com.youlai.boot.mini.model.entity.MiniStrayAnimal; import com.youlai.boot.mini.model.entity.MiniStrayAnimalNote; @@ -23,6 +29,7 @@ import com.youlai.boot.mini.model.form.StrayAnimalForm; import com.youlai.boot.mini.service.StrayAnimalService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.FilenameUtils; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.GeometryFactory; @@ -34,9 +41,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; -import java.util.Date; -import java.util.List; -import java.util.UUID; +import java.util.*; /** * 流浪动物业务实现类 @@ -46,7 +51,7 @@ import java.util.UUID; @Slf4j public class StrayAnimalServiceImpl extends ServiceImpl implements StrayAnimalService { - private final FileService fileService; + private final AliyunFileService aliyunFileService; private final MiniStrayAnimalNoteMapper miniStrayAnimalNoteMapper; private final MiniStrayAnimalNoteMediaMapper miniStrayAnimalNoteMediaMapper; @@ -59,7 +64,7 @@ public class StrayAnimalServiceImpl extends ServiceImpl images, List videos) { // 1. 参数校验 - validateInput(formData, images, videos); + validateInput(images, videos); // 2. 保存流浪动物基本信息 MiniStrayAnimal miniStrayAnimal = saveAnimalInfo(formData); @@ -68,23 +73,25 @@ public class StrayAnimalServiceImpl extends ServiceImpl images, List videos) { - int sortOrder = 0; + private void saveMediaFiles(MiniStrayAnimalNote note, List images, List videos, long currentTimestamp) { + long sortOrder = currentTimestamp; // 处理图片 if (images != null) { for (MultipartFile image : images) { try { String objectName = "animal_note/" + note.getId() + "/" - + note.getCreateTimestamp() + RandomNumberUtils.createRandomLowerLetterAndNumber(8) + + currentTimestamp + RandomNumberUtils.createRandomLowerLetterAndNumber(8) + "." + FilenameUtils.getExtension(image.getOriginalFilename()); - String url = fileService.uploadFile(objectName, image.getInputStream()); + String url = aliyunFileService.uploadFile(objectName, image.getInputStream()); MiniStrayAnimalNoteMedia miniStrayAnimalNoteMedia = new MiniStrayAnimalNoteMedia(); miniStrayAnimalNoteMedia.setUuid(UUID.randomUUID().toString()); miniStrayAnimalNoteMedia.setNoteId(note.getId()); @@ -95,8 +102,8 @@ public class StrayAnimalServiceImpl extends ServiceImpl images, List videos) { + private void validateInput(List images, List videos) { // 验证必填图片 - Assert.notEmpty(images, "需要上传图片"); + if (images == null || images.isEmpty()) { + throw new MsgException("需要上传图片"); + } // 验证图片数量 - Assert.isTrue( - images.size() <= CommonConstants.STRAY_ANIMAL_IMAGE_NUM_LIMIT, - "最多只能上传" + CommonConstants.STRAY_ANIMAL_IMAGE_NUM_LIMIT + "张图片"); + if (images.size() > CommonConstants.STRAY_ANIMAL_IMAGE_NUM_LIMIT) { + throw new MsgException( + "最多只能上传" + CommonConstants.STRAY_ANIMAL_IMAGE_NUM_LIMIT + "张图片" + ); + } + // 验证视频数量 - Assert.isTrue( - CollUtil.isEmpty(videos) || videos.size() <= CommonConstants.STRAY_ANIMAL_VIDEO_NUM_LIMIT, - "最多只能上传" + CommonConstants.STRAY_ANIMAL_VIDEO_NUM_LIMIT + "个视频"); + if (!CollUtil.isEmpty(videos) && videos.size() > CommonConstants.STRAY_ANIMAL_VIDEO_NUM_LIMIT) { + throw new MsgException( + "最多只能上传" + CommonConstants.STRAY_ANIMAL_VIDEO_NUM_LIMIT + "个视频" + ); + } + } + + + @Override + public void updateStrayAnimal(String animalUuid, StrayAnimalForm formData) { + // 校验动物是否存在 + MiniStrayAnimal animal = getValidAnimal(animalUuid); + + // 校验审核状态 + checkNotAuditing(animal); + + long currentTimestamp = System.currentTimeMillis(); + + // 1. 更新流浪动物基本信息 + updateAnimalInfo(animal.getId(), formData, currentTimestamp); + // 3. 更新笔记信息` + updateNoteInfo(animal.getId(), formData, currentTimestamp); + // 4. 提交审核 + + } + + private MiniStrayAnimal getValidAnimal(String animalUuid) { + MiniStrayAnimal animal = miniStrayAnimalMapper.selectOne( + new LambdaQueryWrapper() + .eq(MiniStrayAnimal::getUuid, animalUuid) + .eq(MiniStrayAnimal::getDeleted, 0) + ); + + if (animal == null) { + throw new MsgException("动物不存在"); + } + + return animal; + } + + private void checkNotAuditing(MiniStrayAnimal animal) { + if (1 == animal.getAuditStatus()) { + throw new MsgException("审核中无法更改"); + } + } + + private void updateNoteInfo(Long animalId, StrayAnimalForm formData, long currentTimestamp) { + //处理笔记 + MiniStrayAnimalNote miniStrayAnimalNote = miniStrayAnimalNoteMapper.selectOne(new LambdaQueryWrapper() + .eq(MiniStrayAnimalNote::getStrayAnimalId, animalId)); + if (null != miniStrayAnimalNote){ + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(MiniStrayAnimalNote::getId, miniStrayAnimalNote.getId()) + .set(MiniStrayAnimalNote::getTitle, formData.getTitle()) + .set(MiniStrayAnimalNote::getContent, formData.getContent()) + .set(MiniStrayAnimalNote::getVisibility, formData.getVisibility()) + .set(MiniStrayAnimalNote::getUpdateTimestamp, currentTimestamp) + .set(MiniStrayAnimalNote::getUpdateBy, SecurityUtils.getUserId()) + .set(MiniStrayAnimalNote::getUpdateTime, new Date(currentTimestamp)); + + miniStrayAnimalNoteMapper.update(null, updateWrapper); + + } + } + + private void updateAnimalInfo(Long animalId, StrayAnimalForm formData, long currentTimestamp) { + MiniStrayAnimal miniStrayAnimal = miniStrayAnimalConverter.toEntity(formData); + + miniStrayAnimal.setId(animalId); + miniStrayAnimal.setUpdateTimestamp(currentTimestamp); + miniStrayAnimal.setUpdateTime(new Date(currentTimestamp)); + miniStrayAnimal.setUpdateBy(SecurityUtils.getUserId()); + handleLngLat(miniStrayAnimal, formData.getLng(), formData.getLat()); + + miniStrayAnimalMapper.updateStrayAnimal(miniStrayAnimal); + } + + @Override + public void deleteMediaSource(DeleteStrayAnimalNoteMediaDTO deleteStrayAnimalNoteMediaDTO) { + List noteMediaUuidList = deleteStrayAnimalNoteMediaDTO.getNoteMediaUuidList(); + + MiniStrayAnimalNote note = miniStrayAnimalNoteMapper.selectOne(new LambdaQueryWrapper() + .eq(MiniStrayAnimalNote::getUuid, deleteStrayAnimalNoteMediaDTO.getNoteUuid())); + if (note == null) { + throw new MsgException("笔记不存在"); + } + + LambdaQueryWrapper queryWrapper = + new LambdaQueryWrapper() + .in(MiniStrayAnimalNoteMedia::getUuid, noteMediaUuidList) + .eq(MiniStrayAnimalNoteMedia::getNoteId, note.getId()) + .eq(MiniStrayAnimalNoteMedia::getDeleted, 0); + + List mediaList = + miniStrayAnimalNoteMediaMapper.selectList(queryWrapper); + + if (CollectionUtils.isNotEmpty(mediaList)) { + + // 删除源文件 + List storageKeyList = mediaList.stream() + .map(MiniStrayAnimalNoteMedia::getStorageKey) + .toList(); + aliyunFileService.deleteMultiFile(storageKeyList); + + long currentTimestamp = System.currentTimeMillis(); + + // 逻辑删除 + miniStrayAnimalNoteMediaMapper.update( + null, + new LambdaUpdateWrapper() + .in(MiniStrayAnimalNoteMedia::getUuid, noteMediaUuidList) + .eq(MiniStrayAnimalNoteMedia::getNoteId, note.getId()) + .set(MiniStrayAnimalNoteMedia::getDeleted, 1) + .set(MiniStrayAnimalNoteMedia::getUpdateTimestamp, currentTimestamp) + .set(MiniStrayAnimalNoteMedia::getUpdateTime, new Date(currentTimestamp)) + .set(MiniStrayAnimalNoteMedia::getUpdateBy, SecurityUtils.getUserId()) + ); + } + } + + private MiniStrayAnimalNote getValidNote(String noteUuid) { + MiniStrayAnimalNote note = miniStrayAnimalNoteMapper.selectOne( + new LambdaQueryWrapper() + .eq(MiniStrayAnimalNote::getUuid, noteUuid) + .eq(MiniStrayAnimalNote::getDeleted, 0) + ); + + if (note == null) { + throw new MsgException("笔记不存在"); + } + + return note; + } + + @Override + public void saveMediaSource(String noteUuid, List images, List videos) { + if ((images == null || images.isEmpty()) && (videos == null || videos.isEmpty())) { + throw new MsgException("需要上传媒体资源"); + } + // 获取笔记 + MiniStrayAnimalNote note = getValidNote(noteUuid); + + Long animalId = note.getStrayAnimalId(); + MiniStrayAnimal miniStrayAnimal = miniStrayAnimalMapper.selectById(animalId); + if (miniStrayAnimal == null) { + throw new MsgException("动物信息不存在"); + } + if (1 == miniStrayAnimal.getAuditStatus()){ + throw new MsgException("审核中"); + } + + //校验数量有没有超出 + Map param = new HashMap<>(); + param.put("noteId", note.getId()); + + if (CollectionUtils.isNotEmpty(images)){ + param.put("mediaType", AnimalNoteMediaTypeEnum.IMAGE.name().toLowerCase()); + int imagesExist = miniStrayAnimalNoteMediaMapper.getMediaCountByNoteIdAndType(param); + if (imagesExist+images.size() > CommonConstants.STRAY_ANIMAL_IMAGE_NUM_LIMIT) { + throw new MsgException("图片总数不能超过" + CommonConstants.STRAY_ANIMAL_IMAGE_NUM_LIMIT + "张"); + } + } + if (CollectionUtils.isNotEmpty(videos)){ + param.put("mediaType", AnimalNoteMediaTypeEnum.VIDEO.name().toLowerCase()); + int videosExist = miniStrayAnimalNoteMediaMapper.getMediaCountByNoteIdAndType(param); + if(videosExist+videos.size() > CommonConstants.STRAY_ANIMAL_VIDEO_NUM_LIMIT){ + throw new MsgException("视频总数不能超过" + CommonConstants.STRAY_ANIMAL_VIDEO_NUM_LIMIT + "个"); + } + } + + saveMediaFiles(note, images, videos, System.currentTimeMillis()); + + } + + @Override + public void updateVisibility(String animalUuid, EditVisibilityDTO editVisibilityDTO) { + // 校验动物是否存在 + MiniStrayAnimal animal = getValidAnimal(animalUuid); + + MiniStrayAnimalNote miniStrayAnimalNote = miniStrayAnimalNoteMapper.selectOne(new LambdaQueryWrapper() + .eq(MiniStrayAnimalNote::getStrayAnimalId, animal.getId()) + .eq(MiniStrayAnimalNote::getDeleted, 0)); + if (null != miniStrayAnimalNote) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(MiniStrayAnimalNote::getId, miniStrayAnimalNote.getId()) + .set(MiniStrayAnimalNote::getVisibility, editVisibilityDTO.getVisibility()); + + miniStrayAnimalNoteMapper.update(null, updateWrapper); + } + } + + @Override + public void delete(DeleteStrayAnimalDTO deleteStrayAnimalDTO) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.in(MiniStrayAnimal::getUuid, deleteStrayAnimalDTO.getAnimalUuidList()) + .set(MiniStrayAnimal::getDeleted, 1); + + miniStrayAnimalMapper.update(null, updateWrapper); } } diff --git a/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml b/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml index 1b699c0..aaeab58 100644 --- a/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml +++ b/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml @@ -80,4 +80,40 @@ + + + UPDATE mini_stray_animal + + uuid = #{uuid}, + mini_user_id = #{miniUserId}, + animal_type = #{animalType}, + color = #{color}, + size = #{size}, + status = #{status}, + adopted_by = #{adoptedBy}, + adopted_at = #{adoptedAt}, + audit_status = #{auditStatus}, + province = #{province}, + city = #{city}, + district = #{district}, + address = #{address}, + + + gd_location_point = + ST_GeomFromWKB(#{gdLocationPoint, typeHandler=com.youlai.boot.common.handler.PointTypeHandler}, 4326), + + + + wgs84_location_point = + ST_GeomFromWKB(#{wgs84LocationPoint, typeHandler=com.youlai.boot.common.handler.PointTypeHandler}, 4326), + + + wgs84_geohash = #{wgs84Geohash}, + update_time = #{updateTime}, + update_timestamp = #{updateTimestamp}, + update_by = #{updateBy}, + + WHERE id = #{id} + + diff --git a/src/main/resources/mapper/mini/MiniStrayAnimalNoteMediaMapper.xml b/src/main/resources/mapper/mini/MiniStrayAnimalNoteMediaMapper.xml index 4ff3cf4..e7dbb62 100644 --- a/src/main/resources/mapper/mini/MiniStrayAnimalNoteMediaMapper.xml +++ b/src/main/resources/mapper/mini/MiniStrayAnimalNoteMediaMapper.xml @@ -5,5 +5,13 @@ +