feat(image): add image upload functionality
- Created FileUploadResponse DTO for image upload responses - Implemented ImageController with upload endpoint - Defined ImageService interface for image operations - Added ImageServiceImpl with placeholder upload logic - Updated pom.xml to include chaos_api_domain dependency
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
package cn.nopj.chaos_api.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FileUploadResponse {
|
||||||
|
private String fileName;
|
||||||
|
private String fileDownloadUri;
|
||||||
|
private String ossBucket;
|
||||||
|
private String fileOSSUri;
|
||||||
|
private String fileType;
|
||||||
|
private long size;
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
<artifactId>chaos_api_domain</artifactId>
|
<artifactId>chaos_api_domain</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package cn.nopj.chaos_api.service;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public interface ImageService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传图片
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @param content 文件内容
|
||||||
|
* @return 文件路径
|
||||||
|
*/
|
||||||
|
String uploadImage(String fileName, InputStream content);
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package cn.nopj.chaos_api.service.impl;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.service.ImageService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class ImageServiceImpl implements ImageService {
|
||||||
|
@Override
|
||||||
|
public String uploadImage(String fileName, InputStream content) {
|
||||||
|
//todo 完成上传图片功能
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
@@ -17,6 +18,7 @@ import org.springframework.stereotype.Component;
|
|||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JWT 登录授权过滤器
|
* JWT 登录授权过滤器
|
||||||
@@ -25,8 +27,6 @@ import java.io.IOException;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserDetailsService userDetailsService;
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private JwtTokenUtil jwtTokenUtil;
|
private JwtTokenUtil jwtTokenUtil;
|
||||||
@Value("${jwt.tokenHeader}")
|
@Value("${jwt.tokenHeader}")
|
||||||
@@ -49,11 +49,19 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
|||||||
log.info("username={}", username);
|
log.info("username={}", username);
|
||||||
// 如果 Token 中有用户名但上下文中没有,说明是首次登录
|
// 如果 Token 中有用户名但上下文中没有,说明是首次登录
|
||||||
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||||
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
|
|
||||||
// 验证 Token 是否有效
|
// 验证 Token 是否有效
|
||||||
if (jwtTokenUtil.validateToken(authToken, userDetails)) {
|
if (jwtTokenUtil.validateToken(authToken)) {
|
||||||
|
|
||||||
|
List<String> authorityStrings = jwtTokenUtil.getAuthoritiesFromToken(authToken);
|
||||||
|
|
||||||
|
List<SimpleGrantedAuthority> authorities = authorityStrings.stream()
|
||||||
|
.map(SimpleGrantedAuthority::new)
|
||||||
|
.toList();
|
||||||
|
log.info("authorities: {}", authorities);
|
||||||
UsernamePasswordAuthenticationToken authentication =
|
UsernamePasswordAuthenticationToken authentication =
|
||||||
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
|
new UsernamePasswordAuthenticationToken(username, null, authorities);
|
||||||
|
|
||||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package cn.nopj.chaos_api.controller;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.model.ApiResult;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/hls")
|
||||||
|
public class HLSController {
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('admin')")
|
||||||
|
@GetMapping("/")
|
||||||
|
ApiResult<String> getHLS(){
|
||||||
|
return ApiResult.success("HLS is radar");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package cn.nopj.chaos_api.controller;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.model.ApiResult;
|
||||||
|
import cn.nopj.chaos_api.service.ImageService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/image")
|
||||||
|
public class ImageController {
|
||||||
|
@Autowired
|
||||||
|
private ImageService imageService;
|
||||||
|
|
||||||
|
@RequestMapping("/upload")
|
||||||
|
ApiResult<String> uploadImage(@RequestParam("file") MultipartFile file) {
|
||||||
|
log.info("上传图片");
|
||||||
|
return ApiResult.success("上传成功");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package cn.nopj.chaos_api.service.impl;
|
|||||||
import cn.nopj.chaos_api.domain.entity.User;
|
import cn.nopj.chaos_api.domain.entity.User;
|
||||||
import cn.nopj.chaos_api.mapper.UserMapper;
|
import cn.nopj.chaos_api.mapper.UserMapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
@@ -15,6 +16,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class UserDetailsServiceImpl implements UserDetailsService {
|
public class UserDetailsServiceImpl implements UserDetailsService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -30,6 +32,7 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
|||||||
// 2. 查询该用户的权限信息 (角色 + 权限)
|
// 2. 查询该用户的权限信息 (角色 + 权限)
|
||||||
List<String> authorities = userMapper.findAuthoritiesByUsername(username);
|
List<String> authorities = userMapper.findAuthoritiesByUsername(username);
|
||||||
|
|
||||||
|
log.info("用户权限列表: {}", authorities);
|
||||||
// 3. 将权限字符串列表转换为 GrantedAuthority 集合
|
// 3. 将权限字符串列表转换为 GrantedAuthority 集合
|
||||||
List<GrantedAuthority> grantedAuthorities = authorities.stream()
|
List<GrantedAuthority> grantedAuthorities = authorities.stream()
|
||||||
.map(SimpleGrantedAuthority::new)
|
.map(SimpleGrantedAuthority::new)
|
||||||
|
|||||||
@@ -6,12 +6,15 @@ import com.auth0.jwt.algorithms.Algorithm;
|
|||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -53,10 +56,9 @@ public class JwtTokenUtil {
|
|||||||
/**
|
/**
|
||||||
* 验证 Token 是否有效
|
* 验证 Token 是否有效
|
||||||
*/
|
*/
|
||||||
public boolean validateToken(String token, UserDetails userDetails) {
|
public boolean validateToken(String token) {
|
||||||
try {
|
try {
|
||||||
String username = getUsernameFromToken(token);
|
return decodeToken(token) != null;
|
||||||
return username != null && username.equals(userDetails.getUsername()) && !isTokenExpired(token);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -69,10 +71,17 @@ public class JwtTokenUtil {
|
|||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date expiryDate = new Date(now.getTime() + expiration * 1000);
|
Date expiryDate = new Date(now.getTime() + expiration * 1000);
|
||||||
|
|
||||||
|
List<String> authorities = userDetails.getAuthorities()
|
||||||
|
.stream()
|
||||||
|
.map(GrantedAuthority::getAuthority)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
|
||||||
return JWT.create()
|
return JWT.create()
|
||||||
.withSubject(userDetails.getUsername())
|
.withSubject(userDetails.getUsername())
|
||||||
.withIssuedAt(now)
|
.withIssuedAt(now)
|
||||||
.withExpiresAt(expiryDate)
|
.withExpiresAt(expiryDate)
|
||||||
|
.withClaim("authorities", authorities)
|
||||||
.sign(algorithm);
|
.sign(algorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,4 +95,34 @@ public class JwtTokenUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析 Token
|
||||||
|
* @param token Token
|
||||||
|
* @return 解析后的 Token
|
||||||
|
*/
|
||||||
|
private DecodedJWT decodeToken(String token) {
|
||||||
|
try {
|
||||||
|
return JWT.decode(token);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 Token 中获取权限列表
|
||||||
|
* @param token Token
|
||||||
|
* @return 权限列表
|
||||||
|
*/
|
||||||
|
public List<String> getAuthoritiesFromToken(String token){
|
||||||
|
DecodedJWT decodedJWT = decodeToken(token);
|
||||||
|
if (decodedJWT == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return decodedJWT.getClaim("authorities")
|
||||||
|
.asList(String.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user