feat(oss): 实现文件上传功能并集成Feign调用

- 新增文件上传接口,支持multipart/form-data格式
- 配置Spring Servlet multipart参数,设置文件大小限制
- 添加Feign客户端配置,支持表单提交
- 实现Feign请求拦截器,传递用户上下文信息
- 创建OSS服务API接口,用于文件上传
- 在用户服务中集成OSS RPC调用,实现头像和背景图上传
- 添加上传失败的业务异常处理
- 更新pom.xml依赖,引入OpenFeign、负载均衡及Feign表单相关组件
- 定义API常量和服务名称
- 启用Feign客户端扫描,支持跨服务调用
This commit is contained in:
Hanserwei
2025-10-04 15:53:22 +08:00
parent 91e36d5a84
commit 4b992c35ca
18 changed files with 215 additions and 5 deletions

View File

@@ -3,9 +3,11 @@ package com.hanserwei.hannote.user.biz;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@MapperScan("com.hanserwei.hannote.user.biz.domain.mapper")
@EnableFeignClients(basePackages = "com.hanserwei.hannote")
public class HannoteUserBizApplication {
public static void main(String[] args) {
SpringApplication.run(HannoteUserBizApplication.class, args);

View File

@@ -17,7 +17,8 @@ public enum ResponseCodeEnum implements BaseExceptionInterface {
HAN_NOTE_ID_VALID_FAIL("USER-20002", "小憨书号请设置6-15个字符仅可使用英文必须、数字、下划线"),
SEX_VALID_FAIL("USER-20003", "性别错误"),
INTRODUCTION_VALID_FAIL("USER-20004", "个人简介请设置1-100个字符"),
;
UPLOAD_AVATAR_FAIL("USER-20005", "头像上传失败"),
UPLOAD_BACKGROUND_IMG_FAIL("USER-20006", "背景图上传失败"),
;
// 异常码

View File

@@ -0,0 +1,26 @@
package com.hanserwei.hannote.user.biz.rpc;
import com.hanserwei.framework.common.response.Response;
import com.hanserwei.hannote.oss.api.FileFeignApi;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
@Component
public class OssRpcService {
@Resource
private FileFeignApi fileFeignApi;
public String uploadFile(MultipartFile file) {
// 调用对象存储服务上传文件
Response<?> response = fileFeignApi.uploadFile(file);
if (!response.isSuccess()) {
return null;
}
// 返回图片访问链接
return (String) response.getData();
}
}

View File

@@ -3,6 +3,7 @@ package com.hanserwei.hannote.user.biz.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Preconditions;
import com.hanserwei.framework.biz.context.holder.LoginUserContextHolder;
import com.hanserwei.framework.common.exception.ApiException;
import com.hanserwei.framework.common.response.Response;
import com.hanserwei.framework.common.utils.ParamUtils;
import com.hanserwei.hannote.user.biz.domain.dataobject.UserDO;
@@ -10,7 +11,9 @@ import com.hanserwei.hannote.user.biz.domain.mapper.UserDOMapper;
import com.hanserwei.hannote.user.biz.enums.ResponseCodeEnum;
import com.hanserwei.hannote.user.biz.enums.SexEnum;
import com.hanserwei.hannote.user.biz.model.vo.UpdateUserInfoReqVO;
import com.hanserwei.hannote.user.biz.rpc.OssRpcService;
import com.hanserwei.hannote.user.biz.service.UserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@@ -23,6 +26,10 @@ import java.util.Objects;
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDOMapper, UserDO> implements UserService {
@Resource
private OssRpcService ossRpcService;
@Override
public Response<?> updateUserInfo(UpdateUserInfoReqVO updateUserInfoReqVO) {
UserDO userDO = new UserDO();
@@ -35,7 +42,16 @@ public class UserServiceImpl extends ServiceImpl<UserDOMapper, UserDO> implement
MultipartFile avatar = updateUserInfoReqVO.getAvatar();
if (Objects.nonNull(avatar)) {
// TODO: 上传头像,调用服务
String avatarUrl = ossRpcService.uploadFile(avatar);
log.info("==> 调用 oss 服务成功上传头像url{}", avatarUrl);
// 若上传头像失败,则抛出业务异常
if (StringUtils.isBlank(avatarUrl)) {
throw new ApiException(ResponseCodeEnum.UPLOAD_AVATAR_FAIL);
}
userDO.setAvatar(avatarUrl);
needUpdate = true;
}
// 昵称
@@ -80,7 +96,16 @@ public class UserServiceImpl extends ServiceImpl<UserDOMapper, UserDO> implement
// 背景图片
MultipartFile backgroundImg = updateUserInfoReqVO.getBackgroundImg();
if (Objects.nonNull(backgroundImg)) {
// TODO: 上传背景图片,调用服务
String backgroundImgUrl = ossRpcService.uploadFile(backgroundImg);
log.info("==> 调用 oss 服务成功上传背景图url{}", backgroundImg);
// 若上传背景图失败,则抛出业务异常
if (StringUtils.isBlank(backgroundImgUrl)) {
throw new ApiException(ResponseCodeEnum.UPLOAD_BACKGROUND_IMG_FAIL);
}
userDO.setBackgroundImg(backgroundImgUrl);
needUpdate = true;
}
if (needUpdate) {

View File

@@ -4,6 +4,10 @@ server:
spring:
profiles:
active: dev # 默认激活 dev 本地开发环境
servlet:
multipart:
max-file-size: 20MB # 单个文件最大大小
max-request-size: 100MB # 单次请求最大大小(包含多个文件)
mybatis-plus:
configuration:
map-underscore-to-camel-case: true