From 7dd33b86a11e49a6ca226daf5880e029cfc91888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LI-CCONG=5C=E6=9D=8E=E8=81=AA=E8=81=AA?= <1441652193@qq.com> Date: Wed, 6 Mar 2024 11:59:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=BC=80=E5=8F=91v1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cc/yunxi/common/utils/FileUtils.java | 33 ++++++++++ .../cc/yunxi/controller/CommonController.java | 8 ++- .../cc/yunxi/controller/FileController.java | 33 ++++++++++ .../java/cc/yunxi/domain/dto/WxLoginDTO.java | 11 ++-- .../yunxi/domain/vo/client/ClientRespVO.java | 3 +- .../domain/vo/common/FileUploadReqVO.java | 21 ++++++ .../java/cc/yunxi/service/ICommonService.java | 6 +- .../java/cc/yunxi/service/IFileService.java | 24 +++++++ .../cc/yunxi/service/impl/CommonService.java | 3 + .../yunxi/service/impl/FileServiceImpl.java | 64 +++++++++++++++++++ 10 files changed, 195 insertions(+), 11 deletions(-) create mode 100644 nxhs-common/src/main/java/cc/yunxi/common/utils/FileUtils.java create mode 100644 nxhs-service/src/main/java/cc/yunxi/controller/FileController.java create mode 100644 nxhs-service/src/main/java/cc/yunxi/domain/vo/common/FileUploadReqVO.java create mode 100644 nxhs-service/src/main/java/cc/yunxi/service/IFileService.java create mode 100644 nxhs-service/src/main/java/cc/yunxi/service/impl/FileServiceImpl.java diff --git a/nxhs-common/src/main/java/cc/yunxi/common/utils/FileUtils.java b/nxhs-common/src/main/java/cc/yunxi/common/utils/FileUtils.java new file mode 100644 index 0000000..320bc98 --- /dev/null +++ b/nxhs-common/src/main/java/cc/yunxi/common/utils/FileUtils.java @@ -0,0 +1,33 @@ +package cc.yunxi.common.utils; + +import cn.hutool.core.io.FileTypeUtil; +import cn.hutool.core.io.file.FileNameUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.DigestUtil; + +import java.io.ByteArrayInputStream; + +/** + * 文件工具 + */ +public class FileUtils { + + /** + * 生成文件路径 + * + * @param content 文件内容 + * @param originalName 原始文件名 + * @return path,唯一不可重复 + */ + public static String generatePath(byte[] content, String originalName) { + String sha256Hex = DigestUtil.sha256Hex(content); + // 情况一:如果存在 name,则优先使用 name 的后缀 + if (StrUtil.isNotBlank(originalName)) { + String extName = FileNameUtil.extName(originalName); + return StrUtil.isBlank(extName) ? sha256Hex : sha256Hex + "." + extName; + } + // 情况二:基于 content 计算 + return sha256Hex + '.' + FileTypeUtil.getType(new ByteArrayInputStream(content)); + } + +} diff --git a/nxhs-service/src/main/java/cc/yunxi/controller/CommonController.java b/nxhs-service/src/main/java/cc/yunxi/controller/CommonController.java index 41fd3e5..9307944 100644 --- a/nxhs-service/src/main/java/cc/yunxi/controller/CommonController.java +++ b/nxhs-service/src/main/java/cc/yunxi/controller/CommonController.java @@ -6,6 +6,7 @@ import cc.yunxi.config.WxHsyProperties; import cc.yunxi.domain.dto.UserDTO; import cc.yunxi.domain.dto.WxLoginDTO; import cc.yunxi.domain.po.Recycler; +import cc.yunxi.domain.vo.common.FileUploadReqVO; import cc.yunxi.enums.UserTypeEnum; import cc.yunxi.service.IRecyclerService; import cc.yunxi.service.impl.CommonService; @@ -20,8 +21,10 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.validation.Valid; @@ -31,6 +34,7 @@ import javax.validation.Valid; @RequestMapping("/common") @RequiredArgsConstructor @Slf4j + public class CommonController { private final CommonService commonService; @@ -38,14 +42,14 @@ public class CommonController { @ApiOperation("回收员登录") @PostMapping("/hsylogin") - public CommonResult hsyLogin(@Valid @RequestBody WxLoginDTO wxLoginDTO) { + public CommonResult hsyLogin(@RequestBody WxLoginDTO wxLoginDTO) { UserDTO userDTO = commonService.loginByRecycler(wxLoginDTO); return CommonResult.success(userDTO); } @ApiOperation("散户登录") @PostMapping("/shlogin") - public CommonResult shLogin(@Valid @RequestBody WxLoginDTO wxLoginDTO) { + public CommonResult shLogin(@RequestBody WxLoginDTO wxLoginDTO) { // 散户端登录业务 UserDTO userDTO = commonService.loginByClient(wxLoginDTO); return CommonResult.success(userDTO); diff --git a/nxhs-service/src/main/java/cc/yunxi/controller/FileController.java b/nxhs-service/src/main/java/cc/yunxi/controller/FileController.java new file mode 100644 index 0000000..03900b3 --- /dev/null +++ b/nxhs-service/src/main/java/cc/yunxi/controller/FileController.java @@ -0,0 +1,33 @@ +package cc.yunxi.controller; + +import cc.yunxi.common.domain.CommonResult; +import cc.yunxi.domain.vo.common.FileUploadReqVO; +import cc.yunxi.service.IFileService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +@Api(tags = "文件接口") +@RestController +@RequestMapping("/file") +@RequiredArgsConstructor +@Slf4j +public class FileController { + + private final IFileService fileService; + + @ApiOperation("文件上传") + @PostMapping(value ="/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public CommonResult upload(FileUploadReqVO uploadReqVO) { + fileService.uploadFile(uploadReqVO); + return CommonResult.success("ok"); + } + +} diff --git a/nxhs-service/src/main/java/cc/yunxi/domain/dto/WxLoginDTO.java b/nxhs-service/src/main/java/cc/yunxi/domain/dto/WxLoginDTO.java index 7f58849..6d339fc 100644 --- a/nxhs-service/src/main/java/cc/yunxi/domain/dto/WxLoginDTO.java +++ b/nxhs-service/src/main/java/cc/yunxi/domain/dto/WxLoginDTO.java @@ -4,25 +4,26 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import javax.validation.constraints.NotNull; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; @Data @ApiModel(description = "小程序认证实体") public class WxLoginDTO { @ApiModelProperty(value = "code", required = true) - @NotNull + @NotBlank(message = "code缺失") private String code; @ApiModelProperty(value = "encryptedData", required = true) - @NotNull + @NotBlank(message = "登录参数缺失") private String encryptedData; @ApiModelProperty(value = "iv", required = true) - @NotNull + @NotBlank(message = "登录参数缺失") private String iv; @ApiModelProperty(value = "userType (1散户 2回收员)", required = true, example = "1") - @NotNull(message = "用户类型缺失") + @NotBlank(message = "用户类型缺失") private String userType; } diff --git a/nxhs-service/src/main/java/cc/yunxi/domain/vo/client/ClientRespVO.java b/nxhs-service/src/main/java/cc/yunxi/domain/vo/client/ClientRespVO.java index dbc2e40..e27cea8 100644 --- a/nxhs-service/src/main/java/cc/yunxi/domain/vo/client/ClientRespVO.java +++ b/nxhs-service/src/main/java/cc/yunxi/domain/vo/client/ClientRespVO.java @@ -21,8 +21,7 @@ import java.util.Date; @ApiModel(description = "散户 Response VO") public class ClientRespVO { - @ApiModelProperty("自然主键") - @TableId("id") + @ApiModelProperty("主键id") private String id; @ApiModelProperty("微信openid") diff --git a/nxhs-service/src/main/java/cc/yunxi/domain/vo/common/FileUploadReqVO.java b/nxhs-service/src/main/java/cc/yunxi/domain/vo/common/FileUploadReqVO.java new file mode 100644 index 0000000..e72de48 --- /dev/null +++ b/nxhs-service/src/main/java/cc/yunxi/domain/vo/common/FileUploadReqVO.java @@ -0,0 +1,21 @@ +package cc.yunxi.domain.vo.common; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Data +@ApiModel(description = "文件上传 request VO") +public class FileUploadReqVO { + @ApiModelProperty(value = "文件附件", required = true) + @NotNull(message = "文件附件不能为空") + private MultipartFile file; + + @ApiModelProperty(value = "自定义文件路径", required = false, example = "bbj.png") + @NotEmpty(message = "文件路径不能为空") + private String path; +} diff --git a/nxhs-service/src/main/java/cc/yunxi/service/ICommonService.java b/nxhs-service/src/main/java/cc/yunxi/service/ICommonService.java index d287cb1..d1fd514 100644 --- a/nxhs-service/src/main/java/cc/yunxi/service/ICommonService.java +++ b/nxhs-service/src/main/java/cc/yunxi/service/ICommonService.java @@ -4,6 +4,8 @@ package cc.yunxi.service; import cc.yunxi.domain.dto.UserDTO; import cc.yunxi.domain.dto.WxLoginDTO; +import javax.validation.Valid; + /** * 统一业务接口 */ @@ -15,7 +17,7 @@ public interface ICommonService { * @return UserDTO * @return */ - UserDTO loginByRecycler(WxLoginDTO wxLoginDTO); + UserDTO loginByRecycler(@Valid WxLoginDTO wxLoginDTO); /** @@ -23,7 +25,7 @@ public interface ICommonService { * @param wxLoginDTO * @return UserDTO */ - UserDTO loginByClient(WxLoginDTO wxLoginDTO); + UserDTO loginByClient(@Valid WxLoginDTO wxLoginDTO); /** diff --git a/nxhs-service/src/main/java/cc/yunxi/service/IFileService.java b/nxhs-service/src/main/java/cc/yunxi/service/IFileService.java new file mode 100644 index 0000000..be5a2fe --- /dev/null +++ b/nxhs-service/src/main/java/cc/yunxi/service/IFileService.java @@ -0,0 +1,24 @@ +package cc.yunxi.service; + +import cc.yunxi.domain.po.Client; +import cc.yunxi.domain.query.ClientQuery; +import cc.yunxi.domain.vo.client.ClientUpdateVO; +import cc.yunxi.domain.vo.common.FileUploadReqVO; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; + +import javax.validation.Valid; +import java.io.IOException; + +/** + *

+ * 文件信息 服务类 + *

+ * + * @author ccongli + * @since 2024-02-28 06:08:09 + */ +public interface IFileService { + + void uploadFile(@Valid FileUploadReqVO uploadReqVO); +} diff --git a/nxhs-service/src/main/java/cc/yunxi/service/impl/CommonService.java b/nxhs-service/src/main/java/cc/yunxi/service/impl/CommonService.java index 609834d..b8cea35 100644 --- a/nxhs-service/src/main/java/cc/yunxi/service/impl/CommonService.java +++ b/nxhs-service/src/main/java/cc/yunxi/service/impl/CommonService.java @@ -21,8 +21,10 @@ import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import javax.validation.Valid; import java.time.LocalDateTime; import java.util.Date; @@ -31,6 +33,7 @@ import java.util.Date; */ @Service @Slf4j +@Validated //@CacheConfig(cacheNames = "AUTH_TOKEN") public class CommonService implements ICommonService { diff --git a/nxhs-service/src/main/java/cc/yunxi/service/impl/FileServiceImpl.java b/nxhs-service/src/main/java/cc/yunxi/service/impl/FileServiceImpl.java new file mode 100644 index 0000000..c46e7ff --- /dev/null +++ b/nxhs-service/src/main/java/cc/yunxi/service/impl/FileServiceImpl.java @@ -0,0 +1,64 @@ +package cc.yunxi.service.impl; + +import cc.yunxi.common.exception.BizIllegalException; +import cc.yunxi.common.utils.FileUtils; +import cc.yunxi.domain.vo.common.FileUploadReqVO; +import cc.yunxi.service.IFileService; +import cn.hutool.core.io.FileTypeUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.StrUtil; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.Valid; +import java.io.IOException; +import java.io.InputStream; + +/** + *

+ * 散户信息 服务类 + *

+ * + * @author ccongli + * @since 2024-02-28 06:08:09 + */ +@Service +@Validated +public class FileServiceImpl implements IFileService { + + @Override + public void uploadFile(FileUploadReqVO uploadReqVO) { + MultipartFile file = uploadReqVO.getFile(); + String path = uploadReqVO.getPath(); + + // 获取文件源名称 + String name = file.getOriginalFilename(); + try (InputStream inputStream = file.getInputStream()){ + // 获取文件二进制内容 + byte[] content = IoUtil.readBytes(inputStream, false); + // 获取文件类型 + String fileType = FileTypeUtil.getType(inputStream); + // 文件类型、大小校验 todo + long fileSize = file.getSize(); + + if (StrUtil.isEmpty(path)) { // 不自定义path时 + path = FileUtils.generatePath(content, name); + } + + // 源文件name为空时,则使用 path 填充 + if (StrUtil.isEmpty(name)) { + name = path; + } + + // 上传到文件存储位置 todo + FileUtil.writeBytes(content, path); + + // 入库操作 todo + + } catch (IOException exception) { + throw new BizIllegalException("文件上传失败"); + } + } +}