feat(character): 新增未登录人设列表及详情接口

支持未登录用户按 rank、标签查看人设列表及详情,同步放行新接口并添加请求体缓存过滤器
This commit is contained in:
2025-12-04 20:56:32 +08:00
parent db178a66fb
commit dc855ac33d
6 changed files with 128 additions and 5 deletions

View File

@@ -68,19 +68,18 @@ public class SaTokenConfigure implements WebMvcConfigurer {
"/file/upload", "/file/upload",
"/user/logout", "/user/logout",
"/tag/list", "/tag/list",
"/character/list",
"/character/detail", "/character/detail",
"/character/listByTag",
"/user/login", "/user/login",
"/character/listByUser", "/character/listByUser",
"/user/updateInfo",
"/user/detail", "/user/detail",
"/user/register", "/user/register",
"/character/updateUserCharacterSort", "/character/updateUserCharacterSort",
"/character/addUserCharacter",
"/character/delUserCharacter", "/character/delUserCharacter",
"/user/sendVerifyMail", "/user/sendVerifyMail",
"/user/verifyMailCode" "/user/verifyMailCode",
"/character/listWithNotLogin",
"/character/listByTagWithNotLogin",
"/character/detailWithNotLogin"
}; };
} }
@Bean @Bean

View File

@@ -85,4 +85,23 @@ public class CharacterController {
characterService.removeUserCharacter(id); characterService.removeUserCharacter(id);
return ResultUtils.success(true); return ResultUtils.success(true);
} }
@GetMapping("/listWithNotLogin")
@Operation(summary = "未登录用户人设列表", description = "未登录用户人设列表接口按 rank 排名")
public BaseResponse<List<KeyboardCharacterRespVO>> listWithNotLogin() {
return ResultUtils.success(characterService.selectListWithNotLoginRank());
}
@GetMapping("/detailWithNotLogin")
@Operation(summary = "未登录用户人设详情", description = "未登录用户人设详情接口")
public BaseResponse<KeyboardCharacterRespVO> detailWithNotLogin(@RequestParam("id") Long id) {
KeyboardCharacter character = characterService.getById(id);
return ResultUtils.success(BeanUtil.copyProperties(character, KeyboardCharacterRespVO.class));
}
@GetMapping("/listByTagWithNotLogin")
@Operation(summary = "未登录用户按标签查询人设列表", description = "未登录用户按标签查询人设列表接口")
public BaseResponse<List<KeyboardCharacterRespVO>> listByTagWithNotLogin(@RequestParam("tagId") Long tagId) {
return ResultUtils.success(characterService.selectListByTagWithNotLogin(tagId));
}
} }

View File

@@ -0,0 +1,52 @@
package com.yolo.keyborad.filter;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.springframework.util.StreamUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper {
private byte[] cachedBody;
public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {
super(request);
InputStream requestInputStream = request.getInputStream();
this.cachedBody = StreamUtils.copyToByteArray(requestInputStream);
}
@Override
public ServletInputStream getInputStream() {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cachedBody);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return byteArrayInputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
@Override
public BufferedReader getReader() {
return new BufferedReader(
new InputStreamReader(this.getInputStream(), StandardCharsets.UTF_8));
}
}

View File

@@ -0,0 +1,32 @@
package com.yolo.keyborad.filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@Component
public class RequestBodyCacheFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
// 只缓存一次
if (!(request instanceof CachedBodyHttpServletRequest)) {
CachedBodyHttpServletRequest cachedRequest = new CachedBodyHttpServletRequest(request);
filterChain.doFilter(cachedRequest, response);
return;
}
filterChain.doFilter(request, response);
}
}

View File

@@ -29,4 +29,8 @@ public interface KeyboardCharacterService extends IService<KeyboardCharacter>{
void addUserCharacter(KeyboardUserCharacterAddDTO addDTO); void addUserCharacter(KeyboardUserCharacterAddDTO addDTO);
void removeUserCharacter(Long id); void removeUserCharacter(Long id);
List<KeyboardCharacterRespVO> selectListWithNotLoginRank();
List<KeyboardCharacterRespVO> selectListByTagWithNotLogin(Long tagId);
} }

View File

@@ -148,4 +148,21 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl<KeyboardCharacterM
//只能删除自己的人设 //只能删除自己的人设
keyboardUserCharacterMapper.deleteByIdAndUserId(id, userId); keyboardUserCharacterMapper.deleteByIdAndUserId(id, userId);
} }
@Override
public List<KeyboardCharacterRespVO> selectListWithNotLoginRank() {
List<KeyboardCharacter> keyboardCharacters = keyboardCharacterMapper.selectList(new LambdaQueryWrapper<KeyboardCharacter>()
.eq(KeyboardCharacter::getDeleted, false)
.orderByAsc(KeyboardCharacter::getRank));
return BeanUtil.copyToList(keyboardCharacters, KeyboardCharacterRespVO.class);
}
@Override
public List<KeyboardCharacterRespVO> selectListByTagWithNotLogin(Long tagId) {
List<KeyboardCharacter> keyboardCharacters = keyboardCharacterMapper.selectList(new LambdaQueryWrapper<KeyboardCharacter>()
.eq(KeyboardCharacter::getDeleted, false)
.eq(KeyboardCharacter::getTag, tagId)
.orderByDesc(KeyboardCharacter::getRank));
return BeanUtil.copyToList(keyboardCharacters, KeyboardCharacterRespVO.class);
}
} }