优化用户修改头像方法【小程序,web端修改头文件保存至business_file中,且不会添加新的file_content记录,而是在原来的记录中修改数据,bussiness_instance_id用于保存用户ID】

This commit is contained in:
Echo 2024-04-19 09:50:39 +08:00
parent 77a5ce35c8
commit ef7016bd8f
10 changed files with 157 additions and 23 deletions

View File

@ -65,4 +65,15 @@ public interface FileApi {
@Operation(summary = "获取用户的签名图片地址")
CommonResult<String> 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) ;
}

View File

@ -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<String> getUserSignImgPath(@RequestParam Long userId){
public CommonResult<String> 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) ;
}
}

View File

@ -18,8 +18,14 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BusinessFileMapper extends BaseMapperX<BusinessFileDO> {
default BusinessFileDO selectOneByBusinessInstanceId(String businessInstanceId) {
default BusinessFileDO selectOneByUrl(String url) {
//url地址是唯一的
return selectOne(new LambdaQueryWrapperX<BusinessFileDO>()
.eq(BusinessFileDO:: getUrl, url));
}
default BusinessFileDO selectOneByBusinessInstanceId(Long businessType, String businessInstanceId) {
return selectOne(new LambdaQueryWrapperX<BusinessFileDO>()
.eq(BusinessFileDO:: getBusinessType, businessType)
.eq(BusinessFileDO:: getBusinessInstanceId, businessInstanceId));
}

View File

@ -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<FileContentDO> {
default void updateOneContent(String path, byte[] content) {
//path地址是唯一的
update(new FileContentDO().setContent(content),
new LambdaQueryWrapperX<FileContentDO>().eq(FileContentDO::getPath,path));
}
}

View File

@ -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) ;
}

View File

@ -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<FileDO> 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 ;
}
}

View File

@ -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<String> geSignImgPath(@RequestParam("userId") Long userId) {
String path = userService.geSignImgPath(userId) ;
public CommonResult<String> getSignImgPath(@RequestParam("userId") Long userId) {
String path = userService.getSignImgPath(userId) ;
return success(path);
}
}

View File

@ -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) ;
}

View File

@ -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 ;
}

View File

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