reactor:【INFRA】文件上传 api,增加 directory 参数,去除 path 参数,并支持按照日期分目录、文件名不再使用 sha256 而是时间戳

This commit is contained in:
YunaiV
2025-05-02 20:45:53 +08:00
parent 103685269e
commit 8c7331873e
25 changed files with 421 additions and 205 deletions

View File

@@ -23,14 +23,11 @@ import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_IS_EMPTY;
@Tag(name = "管理后台 - 用户个人中心")
@RestController
@@ -79,16 +76,4 @@ public class UserProfileController {
return success(true);
}
@Deprecated // TODO @芋艿:逐步替换到 updateUserProfile 接口
@RequestMapping(value = "/update-avatar",
method = {RequestMethod.POST, RequestMethod.PUT}) // 解决 uni-app 不支持 Put 上传文件的问题
@Operation(summary = "上传用户个人头像")
public CommonResult<String> updateUserAvatar(@RequestParam("avatarFile") MultipartFile file) throws Exception {
if (file.isEmpty()) {
throw exception(FILE_IS_EMPTY);
}
String avatar = userService.updateUserAvatar(getLoginUserId(), file.getInputStream());
return success(avatar);
}
}

View File

@@ -13,7 +13,6 @@ import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqV
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import jakarta.validation.Valid;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -73,14 +72,6 @@ public interface AdminUserService {
*/
void updateUserPassword(Long id, @Valid UserProfileUpdatePasswordReqVO reqVO);
/**
* 更新用户头像
*
* @param id 用户 id
* @param avatarFile 头像文件
*/
String updateUserAvatar(Long id, InputStream avatarFile) throws Exception;
/**
* 修改密码
*

View File

@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.system.service.user;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
@@ -13,7 +12,6 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
import cn.iocoder.yudao.module.infra.api.config.ConfigApi;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthRegisterReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
@@ -42,7 +40,6 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;
@@ -82,8 +79,6 @@ public class AdminUserServiceImpl implements AdminUserService {
@Resource
private UserPostMapper userPostMapper;
@Resource
private FileApi fileApi;
@Resource
private ConfigApi configApi;
@@ -121,7 +116,7 @@ public class AdminUserServiceImpl implements AdminUserService {
@Override
public Long registerUser(AuthRegisterReqVO registerReqVO) {
// 1.1 校验是否开启注册
if (ObjUtil.notEqual(configApi.getConfigValueByKey(USER_REGISTER_ENABLED_KEY).getCheckedData(), "true")) {
if (ObjUtil.notEqual(configApi.getConfigValueByKey(USER_REGISTER_ENABLED_KEY), "true")) {
throw exception(USER_REGISTER_DISABLED);
}
// 1.2 校验账户配合
@@ -205,19 +200,6 @@ public class AdminUserServiceImpl implements AdminUserService {
userMapper.updateById(updateObj);
}
@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;
}
@Override
@LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_UPDATE_PASSWORD_SUB_TYPE, bizNo = "{{#id}}",
success = SYSTEM_USER_UPDATE_PASSWORD_SUCCESS)

View File

@@ -186,7 +186,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
public void testSendSmsCode() {
// 准备参数
String mobile = randomString();
Integer scene = randomEle(SmsSceneEnum.values()).getScene();
Integer scene = SmsSceneEnum.ADMIN_MEMBER_LOGIN.getScene();
AuthSmsSendReqVO reqVO = new AuthSmsSendReqVO(mobile, scene);
// mock 方法(用户信息)
AdminUserDO user = randomPojo(AdminUserDO.class);

View File

@@ -11,7 +11,10 @@ import cn.iocoder.yudao.module.infra.api.config.ConfigApi;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportExcelVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
@@ -24,6 +27,7 @@ import cn.iocoder.yudao.module.system.service.dept.DeptService;
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 jakarta.annotation.Resource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.stubbing.Answer;
@@ -31,14 +35,11 @@ import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.security.crypto.password.PasswordEncoder;
import jakarta.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import static cn.hutool.core.util.RandomUtil.randomBytes;
import static cn.hutool.core.util.RandomUtil.randomEle;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
@@ -246,26 +247,6 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
assertEquals("encode:yuanma", user.getPassword());
}
@Test
public void testUpdateUserAvatar_success() throws Exception {
// mock 数据
AdminUserDO dbUser = randomAdminUserDO();
userMapper.insert(dbUser);
// 准备参数
Long userId = dbUser.getId();
byte[] avatarFileBytes = randomBytes(10);
ByteArrayInputStream avatarFile = new ByteArrayInputStream(avatarFileBytes);
// mock 方法
String avatar = randomString();
when(fileApi.createFile(eq( avatarFileBytes))).thenReturn(avatar);
// 调用
userService.updateUserAvatar(userId, avatarFile);
// 断言
AdminUserDO user = userMapper.selectById(userId);
assertEquals(avatar, user.getAvatar());
}
@Test
public void testUpdateUserPassword02_success() {
// mock 数据