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());