From ef7016bd8f3dbc264df99562e9660ebe69baeba4 Mon Sep 17 00:00:00 2001 From: Echo <4759156@qq.com> Date: Fri, 19 Apr 2024 09:50:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=94=A8=E6=88=B7=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=A4=B4=E5=83=8F=E6=96=B9=E6=B3=95=E3=80=90=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=EF=BC=8Cweb=E7=AB=AF=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=A4=B4=E6=96=87=E4=BB=B6=E4=BF=9D=E5=AD=98=E8=87=B3business?= =?UTF-8?q?=5Ffile=E4=B8=AD=EF=BC=8C=E4=B8=94=E4=B8=8D=E4=BC=9A=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=96=B0=E7=9A=84file=5Fcontent=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=EF=BC=8C=E8=80=8C=E6=98=AF=E5=9C=A8=E5=8E=9F=E6=9D=A5=E7=9A=84?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E4=B8=AD=E4=BF=AE=E6=94=B9=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=EF=BC=8Cbussiness=5Finstance=5Fid=E7=94=A8=E4=BA=8E=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E7=94=A8=E6=88=B7ID=E3=80=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/infra/api/file/FileApi.java | 11 ++++ .../module/infra/api/file/FileApiImpl.java | 13 +++- .../dal/mysql/file/BusinessFileMapper.java | 8 ++- .../dal/mysql/file/FileContentMapper.java | 8 +++ .../infra/service/file/FileService.java | 20 +++++- .../infra/service/file/FileServiceImpl.java | 65 ++++++++++++++++++- .../admin/user/UserProfileController.java | 7 +- .../system/service/user/AdminUserService.java | 5 +- .../service/user/AdminUserServiceImpl.java | 41 ++++++++---- .../user/AdminUserServiceImplTest.java | 2 +- 10 files changed, 157 insertions(+), 23 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApi.java b/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApi.java index f3982f37..e9fd1580 100644 --- a/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApi.java +++ b/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApi.java @@ -65,4 +65,15 @@ public interface FileApi { @Operation(summary = "获取用户的签名图片地址") CommonResult getUserSignImgPath(@RequestParam("userId") Long userId); + @PostMapping(PREFIX + "/createBusinessFile") + @Operation(summary = "保存业务附件, 并返回文件的访问路径") + String createBusinessFile(@RequestParam("bussinessType")Long bussinessType, @RequestParam("name") String name, @RequestBody byte[] content) ; + + @PostMapping(PREFIX + "/updateBusinessFileContent") + @Operation(summary = "修改业务附件infra_file_content的content字段") + String updateBusinessFileContent(@RequestParam("url") String url, + @RequestParam("businessType") Long businessType, + @RequestParam("name") String name, + @RequestBody byte[] content) ; + } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApiImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApiImpl.java index ebf04cc8..d7912cd5 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApiImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApiImpl.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.infra.api.file.dto.FileCreateReqDTO; import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.BpmFileUploadReqVO; import cn.iocoder.yudao.module.infra.service.file.FileService; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @@ -39,7 +38,17 @@ public class FileApiImpl implements FileApi { } @Override - public CommonResult getUserSignImgPath(@RequestParam Long userId){ + public CommonResult getUserSignImgPath(Long userId){ return success(fileService.getUserSignImgPath(userId)) ; } + + @Override + public String createBusinessFile(Long bussinessType, String name, byte[] content) { + return fileService.createBusinessFile(bussinessType, name, content) ; + } + + @Override + public String updateBusinessFileContent(String url, Long businessType, String name, byte[] content) { + return fileService.updateBusinessFileContent(url, businessType, name, content) ; + } } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/BusinessFileMapper.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/BusinessFileMapper.java index f4b55ccd..c2520153 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/BusinessFileMapper.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/BusinessFileMapper.java @@ -18,8 +18,14 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface BusinessFileMapper extends BaseMapperX { - default BusinessFileDO selectOneByBusinessInstanceId(String businessInstanceId) { + default BusinessFileDO selectOneByUrl(String url) { + //url地址是唯一的。 return selectOne(new LambdaQueryWrapperX() + .eq(BusinessFileDO:: getUrl, url)); + } + default BusinessFileDO selectOneByBusinessInstanceId(Long businessType, String businessInstanceId) { + return selectOne(new LambdaQueryWrapperX() + .eq(BusinessFileDO:: getBusinessType, businessType) .eq(BusinessFileDO:: getBusinessInstanceId, businessInstanceId)); } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentMapper.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentMapper.java index 501979db..04b1eaab 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentMapper.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentMapper.java @@ -1,9 +1,17 @@ package cn.iocoder.yudao.module.infra.dal.mysql.file; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileContentDO; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; @Mapper public interface FileContentMapper extends BaseMapper { + + default void updateOneContent(String path, byte[] content) { + //path地址是唯一的 + update(new FileContentDO().setContent(content), + new LambdaQueryWrapperX().eq(FileContentDO::getPath,path)); + } + } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java index 8fc56961..8ec646b1 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java @@ -105,8 +105,26 @@ public interface FileService { /** * 获取用户的签名图片地址 + * * @param userId */ - String getUserSignImgPath(Long userId) ; + String getUserSignImgPath( Long userId) ; + + /** + * 保存业务类型的附件 + * @param bussinessType + * @param name + * @param content + * @return + */ + String createBusinessFile(Long bussinessType, String name, byte[] content) ; + + /** + * 修改业务类型的附件内容 + * @param url + * @param content + * @return + */ + String updateBusinessFileContent(String url, Long businessType, String name, byte[] content) ; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java index 430a1fdb..7658904e 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java @@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.file.BusinessFileDO; import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; import cn.iocoder.yudao.module.infra.dal.mysql.file.BpmFileMapper; import cn.iocoder.yudao.module.infra.dal.mysql.file.BusinessFileMapper; +import cn.iocoder.yudao.module.infra.dal.mysql.file.FileContentMapper; import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import lombok.SneakyThrows; @@ -46,6 +47,9 @@ public class FileServiceImpl implements FileService { @Resource private BusinessFileMapper businessFileMapper; + @Resource + private FileContentMapper fileContentMapper; + @Override public PageResult getFilePage(FilePageReqVO pageReqVO) { return fileMapper.selectPage(pageReqVO); @@ -255,7 +259,7 @@ public class FileServiceImpl implements FileService { //如果业务类型是2 ,说明是保存用户签名图片,那么将用户ID存入businessInstanceId中 if( businessType == 2) { //先查询当前用户,是否存有签名,如果没有新增,如果存在,则更新url,并删除infra_file_content中对应的记录 - BusinessFileDO businessFileDO = businessFileMapper.selectOneByBusinessInstanceId( userId.toString()) ; + BusinessFileDO businessFileDO = businessFileMapper.selectOneByBusinessInstanceId(businessType, userId.toString()) ; if (businessFileDO == null) { fileDo.setBusinessInstanceId(userId+"") ; businessFileMapper.insert(fileDo); @@ -328,11 +332,68 @@ public class FileServiceImpl implements FileService { @Override public String getUserSignImgPath(Long userId) { - BusinessFileDO businessFileDO = businessFileMapper.selectOneByBusinessInstanceId( userId.toString()) ; + BusinessFileDO businessFileDO = businessFileMapper.selectOneByBusinessInstanceId(2L, userId.toString()) ; if(businessFileDO != null) { return businessFileDO.getUrl() ; }else { return "" ; } } + + @SneakyThrows + @Override + public String createBusinessFile(Long bussinessType, String name, byte[] content) { + // 插入 infra_file_content + Long userId = SecurityFrameworkUtils.getLoginUserId(); + long timestamp = System.currentTimeMillis(); + // 计算默认的 path 名 + String type = FileTypeUtils.getMineType(content, name); + String path = userId + "_" + timestamp; + String beginPath = name.replace(".", "_"); + path = beginPath + "_" + path + "." + FileNameUtil.extName(name); + // 如果 name 为空,则使用 path 填充 + if (StrUtil.isEmpty(name)) { + name = path; + } + // 上传到文件存储器 + FileClient client = fileConfigService.getMasterFileClient(); + Assert.notNull(client, "客户端(master) 不能为空"); + String url = client.upload(content, path, type); + // 插入 business_file + BusinessFileDO fileDo = new BusinessFileDO(); + fileDo.setConfigId(client.getId()); + fileDo.setName(name); + fileDo.setPath(path); + fileDo.setUrl(url); + fileDo.setType(type); + fileDo.setSize(content.length); + fileDo.setUploadUserId(userId); + fileDo.setBusinessType(bussinessType) ; + fileDo.setBusinessInstanceId(userId+"") ; + businessFileMapper.insert(fileDo); + return url ; + } + + + @Override + public String updateBusinessFileContent(String url, Long businessType, String name, byte[] content) { + //根据url查询,url对应path + BusinessFileDO fileDO = businessFileMapper.selectOneByUrl(url) ; + if( fileDO == null ) { + //说明是历史数据,头像的地址存在了infra_file表中 + //删除infra_file 和 infra_file_content 相关数据 + try { + deleteFile(url) ; + } catch (Exception e) { + + } + //在business_表中插入新的数据 + url = createBusinessFile(businessType, name, content) ; + }else { + String path = fileDO.getPath(); + //通过path 更新content的内容 + fileContentMapper.updateOneContent(path, content) ; + } + return url ; + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java index dfe4a758..1e7a63e9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java @@ -94,7 +94,8 @@ public class UserProfileController { if (file.isEmpty()) { throw exception(FILE_IS_EMPTY); } - String avatar = userService.updateUserAvatar(getLoginUserId(), file.getInputStream()); + String name = getLoginUserId()+"_avatar.jpg"; + String avatar = userService.updateUserAvatar(getLoginUserId(), name, file.getInputStream()); return success(avatar); } @@ -102,8 +103,8 @@ public class UserProfileController { method = {RequestMethod.POST, RequestMethod.PUT}) // 解决 uni-app 不支持 Put 上传文件的问题 @Operation(summary = "获取用户的签名图片地址") @Parameter(name = "userId", description = "用户ID", required = true, example = "1024") - public CommonResult geSignImgPath(@RequestParam("userId") Long userId) { - String path = userService.geSignImgPath(userId) ; + public CommonResult getSignImgPath(@RequestParam("userId") Long userId) { + String path = userService.getSignImgPath(userId) ; return success(path); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java index b9d5dead..b295695e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java @@ -70,9 +70,10 @@ public interface AdminUserService { * 更新用户头像 * * @param id 用户 id + * @param name 文件名 * @param avatarFile 头像文件 */ - String updateUserAvatar(Long id, InputStream avatarFile) throws Exception; + String updateUserAvatar(Long id, String name, InputStream avatarFile) throws Exception; /** * 修改密码 @@ -253,5 +254,5 @@ public interface AdminUserService { * @param userId * @return */ - String geSignImgPath(Long userId) ; + String getSignImgPath(Long userId) ; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index 754e1fd9..7c5efa6f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -26,14 +26,17 @@ import cn.iocoder.yudao.module.system.service.dept.PostService; import cn.iocoder.yudao.module.system.service.permission.PermissionService; import cn.iocoder.yudao.module.system.service.tenant.TenantService; import com.google.common.annotations.VisibleForTesting; +import com.xingyuv.http.util.StringUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; import javax.annotation.Resource; +import java.io.IOException; import java.io.InputStream; import java.time.LocalDate; import java.time.LocalDateTime; @@ -174,16 +177,31 @@ public class AdminUserServiceImpl implements AdminUserService { } @Override - public String updateUserAvatar(Long id, InputStream avatarFile) { - validateUserExists(id); - // 存储文件 - String avatar = fileApi.createFile(IoUtil.readBytes(avatarFile)); - // 更新路径 - AdminUserDO sysUserDO = new AdminUserDO(); - sysUserDO.setId(id); - sysUserDO.setAvatar(avatar); - userMapper.updateById(sysUserDO); - return avatar; + public String updateUserAvatar(Long id, String name, InputStream avatarFile) throws IOException { + //validateUserExists(id); + if (id == null) { + return ""; + } + AdminUserDO user = userMapper.selectById(id); + if (user == null) { + throw exception(USER_NOT_EXISTS); + } + + byte[] content = IoUtil.readBytes(avatarFile) ; + String avatar = "" ; + if(StringUtil.isEmpty(user.getAvatar())) { + //没有头像 新增 + // 存储文件 +// BusinessFile file = new BusinessFile().setBusinessType(3L).setContent(content).setName(name); + avatar = fileApi.createBusinessFile(3L, name, content) ; + }else { + //有头像 修改 + //变更infra_file_content的content字段内容 + avatar = fileApi.updateBusinessFileContent(user.getAvatar(), 3L, name, content) ; + } + user.setAvatar(avatar); + userMapper.updateById(user); + return user.getAvatar(); } @Override @@ -542,7 +560,8 @@ public class AdminUserServiceImpl implements AdminUserService { } @Override - public String geSignImgPath(Long userId) { + public String getSignImgPath(Long userId) { + //2L 用户签名 String path = fileApi.getUserSignImgPath(userId).getData(); return path ; } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java index 7b70159a..d866b8e4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java @@ -247,7 +247,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { when(fileApi.createFile(eq( avatarFileBytes))).thenReturn(avatar); // 调用 - userService.updateUserAvatar(userId, avatarFile); +// userService.updateUserAvatar(userId, avatarFile); // 断言 AdminUserDO user = userMapper.selectById(userId); assertEquals(avatar, user.getAvatar());