diff --git a/src/main/java/com/guaiguailang/harmony/config/LoggingInterceptor.java b/src/main/java/com/guaiguailang/harmony/config/LoggingInterceptor.java index b82a786..adff03d 100644 --- a/src/main/java/com/guaiguailang/harmony/config/LoggingInterceptor.java +++ b/src/main/java/com/guaiguailang/harmony/config/LoggingInterceptor.java @@ -38,6 +38,7 @@ public class LoggingInterceptor implements HandlerInterceptor { // 记录请求头 request.getHeaderNames().asIterator().forEachRemaining(name -> { String value = request.getHeader(name); + log.info("Header {}: {}", name, value); }); @@ -69,4 +70,4 @@ public class LoggingInterceptor implements HandlerInterceptor { public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 可以在这里记录异常信息 } -} \ No newline at end of file +} diff --git a/src/main/java/com/guaiguailang/harmony/config/SaTokenConfigure.java b/src/main/java/com/guaiguailang/harmony/config/SaTokenConfigure.java index af77b7c..4b41b4e 100644 --- a/src/main/java/com/guaiguailang/harmony/config/SaTokenConfigure.java +++ b/src/main/java/com/guaiguailang/harmony/config/SaTokenConfigure.java @@ -3,8 +3,10 @@ package com.guaiguailang.harmony.config; import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.stp.StpUtil; import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.system.ApplicationHome; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** @@ -32,7 +34,37 @@ public class SaTokenConfigure implements WebMvcConfigurer { "/swagger-ui.html", "/swagger-ui.html/**", "/webjars/**", - "/v3/api-docs/**" + "/v3/api-docs/**", + "/static/**" ); + } + + // 静态资源映射 + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + /** + * 资源映射路径 + * addResourceHandler:访问映射路径 + * addResourceLocations:资源绝对路径 + */ + String osName=System.getProperty("os.name"); + String fileUploadResources="/static/**"; + String win="win"; + if(osName.toLowerCase().startsWith(win)){ + ApplicationHome applicationHome=new ApplicationHome(this.getClass()); + String pre="file:"+applicationHome.getDir().getParentFile().getParentFile()+ "\\src\\main\\resources\\static\\"; + + registry.addResourceHandler(fileUploadResources) + .addResourceLocations(pre); + }else { + ApplicationHome applicationHome=new ApplicationHome(this.getClass()); + String pre="file:"+applicationHome.getDir().getParentFile().getParentFile()+ "/src/main/resources/static/"; + registry.addResourceHandler(fileUploadResources) + .addResourceLocations(pre); + } + + } + + } diff --git a/src/main/java/com/guaiguailang/harmony/constant/FileUploadFolder.java b/src/main/java/com/guaiguailang/harmony/constant/FileUploadFolder.java new file mode 100644 index 0000000..3b0c7c2 --- /dev/null +++ b/src/main/java/com/guaiguailang/harmony/constant/FileUploadFolder.java @@ -0,0 +1,6 @@ +package com.guaiguailang.harmony.constant; + +public class FileUploadFolder { + public static final String USER_AVATER_FOLDER = "usera_vatar"; + public static final String ACTIVITY_FOLDER = "activity"; +} diff --git a/src/main/java/com/guaiguailang/harmony/controller/UploadController.java b/src/main/java/com/guaiguailang/harmony/controller/UploadController.java new file mode 100644 index 0000000..66ea975 --- /dev/null +++ b/src/main/java/com/guaiguailang/harmony/controller/UploadController.java @@ -0,0 +1,44 @@ +package com.guaiguailang.harmony.controller; + +import cn.dev33.satoken.stp.StpUtil; +import com.guaiguailang.harmony.domain.vo.ResponseResult; +import com.guaiguailang.harmony.service.UserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +@Tag(name="文件上传接口") +@RestController +@RequestMapping("/upload") +@Slf4j +public class UploadController { + + @Autowired + private UserService userService; + + + /** + * 修改用户头像 + * @param file + * @return + */ + @Operation(summary = "修改用户头像") + @PostMapping("/uploadUserAvater") + public ResponseResult uploadUserAvater(@RequestParam("file") MultipartFile file){ + if(file.isEmpty()){ + return ResponseResult.error("头像为空,请重新选择"); + } + String imgUrl = userService.uploadUserAvater(file); + if(imgUrl==null){ + return ResponseResult.error("头像上传失败"); + } + return ResponseResult.success(imgUrl); + } + +} diff --git a/src/main/java/com/guaiguailang/harmony/service/UserService.java b/src/main/java/com/guaiguailang/harmony/service/UserService.java index 3513b8c..9d61353 100644 --- a/src/main/java/com/guaiguailang/harmony/service/UserService.java +++ b/src/main/java/com/guaiguailang/harmony/service/UserService.java @@ -4,6 +4,7 @@ import com.guaiguailang.harmony.domain.dto.ParamUserAdd; import com.guaiguailang.harmony.domain.dto.ParamUserList; import com.guaiguailang.harmony.domain.vo.ResponseResult; import org.springframework.http.ResponseEntity; +import org.springframework.web.multipart.MultipartFile; public interface UserService { ResponseResult getUserInfo(); @@ -25,4 +26,6 @@ public interface UserService { ResponseResult deleteUserReay(ParamUserAdd userAddParam); ResponseResult selfUpdateUserInfo(ParamUserAdd userAddParam); + + String uploadUserAvater(MultipartFile file); } diff --git a/src/main/java/com/guaiguailang/harmony/service/impl/UserServiceImpl.java b/src/main/java/com/guaiguailang/harmony/service/impl/UserServiceImpl.java index 576c3f2..6b415b1 100644 --- a/src/main/java/com/guaiguailang/harmony/service/impl/UserServiceImpl.java +++ b/src/main/java/com/guaiguailang/harmony/service/impl/UserServiceImpl.java @@ -3,6 +3,7 @@ package com.guaiguailang.harmony.service.impl; import cn.dev33.satoken.stp.StpUtil; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.github.yitter.idgen.YitIdHelper; +import com.guaiguailang.harmony.constant.FileUploadFolder; import com.guaiguailang.harmony.domain.dto.ParamUserAdd; import com.guaiguailang.harmony.domain.dto.ParamUserList; import com.guaiguailang.harmony.domain.entity.*; @@ -11,14 +12,19 @@ import com.guaiguailang.harmony.mapper.AuthMapper; import com.guaiguailang.harmony.mapper.LogCaptchaMapper; import com.guaiguailang.harmony.mapper.UserMapper; import com.guaiguailang.harmony.service.UserService; +import com.guaiguailang.harmony.utils.FileUpload; import com.guaiguailang.harmony.utils.PasswordEncryptor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.system.ApplicationHome; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.time.LocalDateTime; import java.util.*; @@ -33,6 +39,8 @@ public class UserServiceImpl implements UserService { private final AuthMapper authMapper; @Autowired private LogCaptchaMapper logCaptchaMapper; + @Autowired + private FileUpload fileUpload; public UserServiceImpl(UserMapper userMapper, AuthMapper authMapper) { this.userMapper = userMapper; @@ -294,6 +302,30 @@ return ResponseResult.error("删除失败"); } } + /** + * 修改用户头像 + * @param file + * @return + */ + @Override + public String uploadUserAvater(MultipartFile file) { + // 获取用户获取用户信息 + Long uid = Long.parseLong(StpUtil.getLoginId().toString()); + UserInfo userInfo = userMapper.getUserById(uid); + // 调用文件上传工具类,传入:文件,保存到的文件夹,文件名 + //设置文件名是为了替换旧的头像文件 + String imgUrl= fileUpload.uploadFile(file, FileUploadFolder.USER_AVATER_FOLDER,userInfo.getUsername()); + if(imgUrl!=null) { + userInfo.setAvatar(imgUrl); + userMapper.updateById(userInfo); + log.info("头像上传成功:" + imgUrl); + return imgUrl; + } + return null; + } + + + // 方法 public UserInfo getUserByAccount(String username){ return userMapper.getUserByAccount(username); diff --git a/src/main/java/com/guaiguailang/harmony/utils/FileUpload.java b/src/main/java/com/guaiguailang/harmony/utils/FileUpload.java new file mode 100644 index 0000000..e25bbdd --- /dev/null +++ b/src/main/java/com/guaiguailang/harmony/utils/FileUpload.java @@ -0,0 +1,126 @@ +package com.guaiguailang.harmony.utils; + + +import jakarta.servlet.ServletContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +/** + * 文件上传工具类 + */ +@Component +public class FileUpload { + + @Value("${server.servlet.context-path}") + private String contextPath; + + @Value("${server.port}") + private String serverPort; + + @Value("${server.address}") + private String serverAddress; + + @Autowired + private ServletContext servletContext; + + + public String uploadFile(MultipartFile file, String folder) { + // 获取图片的原始名字 + String originalFilename = file.getOriginalFilename(); + + if (originalFilename == null || originalFilename.isEmpty()) { + throw new IllegalArgumentException("文件名不能为空"); + } + + // 获取文件的后缀和新文件名 + String ext = "." + originalFilename.substring(originalFilename.lastIndexOf('.') + 1); + String uuid = UUID.randomUUID().toString().replace("-", ""); + String fileName = uuid + ext; + + // 构建目标文件路径 + String pre = getResourcePath(folder); + String filePath = pre + fileName; + + + // 上传图片 + try { + file.transferTo(new File(filePath)); + // 返回访问链接 + return getAccessPath(folder, fileName); + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } + + public String uploadFile(MultipartFile file, String folder, String fileName) { + // 获取图片的原始名字 + String originalFilename = file.getOriginalFilename(); + + if (originalFilename == null || originalFilename.isEmpty()) { + throw new IllegalArgumentException("文件名不能为空"); + } + + // 获取文件的后缀和新文件名 + String ext = "." + originalFilename.substring(originalFilename.lastIndexOf('.') + 1); + fileName = fileName + ext; + + // 构建目标文件路径 + String pre = getResourcePath(folder); + String filePath = pre + fileName; + + // 上传图片 + try { + file.transferTo(new File(filePath)); + // 返回访问链接 + return getAccessPath(folder, fileName); + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + private String getResourcePath(String folder) { + // 获取操作系统的名称 + String osName = System.getProperty("os.name"); + String win = "win"; + + // 获取项目的根目录 + String projectRoot = System.getProperty("user.dir"); + + // 根据操作系统生成正确的路径 + String staticPath; + if (osName.toLowerCase().startsWith(win)) { + staticPath = projectRoot + "\\src\\main\\resources\\static\\" + folder + "\\"; + } else { + staticPath = projectRoot + "/src/main/resources/static/" + folder + "/"; + } + + System.out.println("路径: " + staticPath); + + // 如果目录不存在,就创建目录 + File dir = new File(staticPath); + if (!dir.exists()) { + dir.mkdirs(); + } + + return staticPath; + } + + + + private String getAccessPath(String folder, String fileName) { + // 构建访问路径 + return "http://" + serverAddress + ":" + serverPort + contextPath + "static/" + folder + "/" + fileName; + } + + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6ca368b..5a86cf1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -5,12 +5,15 @@ spring.application.version=1.0.0 logging.config=classpath:logback-spring.xml # Server Info Setting server.port=8080 +server.address=localhost server.servlet.context-path=/ server.servlet.session.timeout=3600 # Spring Boot Info Setting spring.main.banner-mode=log spring.banner.charset=utf-8 spring.banner.location=classpath:banner.txt +spring.servlet.multipart.max-file-size=5MB +spring.servlet.multipart.max-request-size=5MB # MySQL Setting #spring.datasource.url=jdbc:mysql://localhost:3306/harmonylife?serverTimezone=UTC&useSSL=false spring.datasource.url=jdbc:mysql://212.64.14.96:3306/harmonylife?serverTimezone=UTC&useSSL=false @@ -28,8 +31,8 @@ mybatis.configuration.map-underscore-to-camel-case=true # Redis Configuration spring.data.redis.host=localhost spring.data.redis.port=6379 -spring.data.redis.database=0 -spring.data.redis.password= +spring.data.redis.database=10 +spring.data.redis.password=123456 spring.data.redis.lettuce.pool.max-active= 8 spring.data.redis.lettuce.pool.max-wait=-1 spring.data.redis.lettuce.pool.max-idle=8 @@ -110,4 +113,4 @@ server.tomcat.uri-encoding=UTF-8 server.servlet.encoding.charset=UTF-8 server.servlet.encoding.enabled=true server.servlet.encoding.force=true -spring.messages.encoding=UTF-8 \ No newline at end of file +spring.messages.encoding=UTF-8 diff --git a/src/main/resources/static/user_avatar/test.txt b/src/main/resources/static/user_avatar/test.txt new file mode 100644 index 0000000..58c9bdf --- /dev/null +++ b/src/main/resources/static/user_avatar/test.txt @@ -0,0 +1 @@ +111 diff --git a/src/main/resources/static/user_avatar/xrilang.jpg b/src/main/resources/static/user_avatar/xrilang.jpg new file mode 100644 index 0000000..f4f0dfe Binary files /dev/null and b/src/main/resources/static/user_avatar/xrilang.jpg differ diff --git a/src/main/resources/static/usera_vatar/xrilang.jpg b/src/main/resources/static/usera_vatar/xrilang.jpg new file mode 100644 index 0000000..0354a1b Binary files /dev/null and b/src/main/resources/static/usera_vatar/xrilang.jpg differ