ruoyi-common/src/main/java/com/ruoyi/common/filter/CustomRequestWrapper.java
@@ -9,67 +9,75 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; /** * 解决服务器字符集问题 * * @author 文敏杰 * @date 2026/06/25 */ public class CustomRequestWrapper extends HttpServletRequestWrapper { private final String body; /** * 构造函数,用于创建自定义请求包装器。 * * @param request 原始 HTTP 请求对象 * @param body 新的请求体内容 * @throws IOException 如果读取或处理请求体时发生错误 */ public CustomRequestWrapper(HttpServletRequest request, String body) throws IOException { private final byte[] body; public CustomRequestWrapper(HttpServletRequest request, String body) { super(request); this.body = body; this.body = body.getBytes(StandardCharsets.UTF_8); } /** * 重写 getInputStream 方法,返回一个新的 ServletInputStream, * 其中包含修改后的请求体内容。 * * @return 包含修改后请求体内容的 ServletInputStream * @throws IOException 如果读取输入流时发生错误 */ @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); public ServletInputStream getInputStream() { ByteArrayInputStream bis = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() { return bis.read(); } @Override public boolean isFinished() { // 返回是否已经完成读取 return false; return bis.available() == 0; } @Override public boolean isReady() { // 返回是否准备好读取数据 return false; return true; } @Override public void setReadListener(ReadListener readListener) { // 设置读监听器,这里不需要实现 } @Override public int read() throws IOException { // 从字节数组输入流中读取下一个字节 return byteArrayInputStream.read(); } }; } /** * 重写 getReader 方法,返回一个新的 BufferedReader, * 其中包含修改后的请求体内容。 * * @return 包含修改后请求体内容的 BufferedReader * @throws IOException 如果读取输入流时发生错误 */ @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(this.getInputStream())); public BufferedReader getReader() { return new BufferedReader( new InputStreamReader( getInputStream(), StandardCharsets.UTF_8 ) ); } @Override public String getCharacterEncoding() { return StandardCharsets.UTF_8.name(); } @Override public int getContentLength() { return body.length; } @Override public long getContentLengthLong() { return body.length; } } ruoyi-common/src/main/java/com/ruoyi/common/filter/SmCryptoFilter.java
@@ -12,6 +12,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.rmi.ServerException; public class SmCryptoFilter implements Filter { @@ -24,6 +25,12 @@ HttpServletResponse httpResponse = (HttpServletResponse) response; try { // 设置请求和响应的编码为 UTF-8 request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=UTF-8"); // 对请求进行解密 String decryptedRequestBody = decryptRequest(httpRequest); // 处理解密后的请求体 CustomRequestWrapper为自定义请求包装器,请看下面实现 @@ -35,7 +42,8 @@ // 获取并加密响应内容 byte[] content = responseWrapper.getContentAsByteArray(); String originalResponseBody = new String(content); String originalResponseBody = new String(content, StandardCharsets.UTF_8); // 关键修改 // String originalResponseBody = new String(content); String encryptedResponseBody = encryptResponse(originalResponseBody); responseWrapper.setContentType("application/json"); JSONObject result = new JSONObject(); @@ -66,12 +74,18 @@ * @throws IOException 如果读取或解密过程中发生错误 */ private String decryptRequest(HttpServletRequest request) throws IOException { // 先设置编码 request.setCharacterEncoding("UTF-8"); StringBuilder jb = new StringBuilder(); String line; BufferedReader reader = request.getReader(); while ((line = reader.readLine()) != null) { jb.append(line); // 直接使用getReader(),此时应该使用UTF-8 try (BufferedReader reader = request.getReader()) { while ((line = reader.readLine()) != null) { jb.append(line); } } try { return Sm4Utils.sm4DecryptUtil(jb.toString()); } catch (Exception e) { ruoyi-system/src/main/java/com/ruoyi/system/mapper/TTrainLibraryMapper.java
@@ -25,6 +25,9 @@ List<TTrainLibraryVO> pageList(@Param("query")TTrainLibraryQuery query, @Param("pageInfo")PageInfo<TTrainLibraryVO> pageInfo); // 新增:查询所有数据(不分页) List<TTrainLibraryVO> listAll(@Param("query") TTrainLibraryQuery query); List<TTrainLibraryWarehousingVO> getDetailById(@Param("query")TTrainLibraryDetailQuery query, @Param("pageInfo")PageInfo<TTrainLibraryWarehousingVO> pageInfo); } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTrainLibraryServiceImpl.java
@@ -35,24 +35,42 @@ @Override public PageInfo<TTrainLibraryVO> pageList(TTrainLibraryQuery query, String roleType) { PageInfo<TTrainLibraryVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<TTrainLibraryVO> list = this.baseMapper.pageList(query,pageInfo); // 1. 查询所有符合条件的数据(不分页) List<TTrainLibraryVO> allList = this.baseMapper.listAll(query); List<TTrainLibraryVO> resultList = new ArrayList<>(); for (TTrainLibraryVO tTrainLibraryVO : list) { if (StringUtils.isNotEmpty(tTrainLibraryVO.getProjectId())) { TProjectTeam byId = projectTeamService.getById(tTrainLibraryVO.getProjectId()); //未封存的数据 if (byId != null && ("2".equals(roleType) || byId.getStatus() == 1)) { // 只处理status为1的数据 tTrainLibraryVO.setProjectName(byId.getTeamName()); resultList.add(tTrainLibraryVO); // 2. 在内存中过滤 + 补充 projectName List<TTrainLibraryVO> filteredList = new ArrayList<>(); for (TTrainLibraryVO vo : allList) { if (StringUtils.isNotEmpty(vo.getProjectId())) { TProjectTeam byId = projectTeamService.getById(vo.getProjectId()); // 未封存的数据:roleType=2 或 status=1 if (byId != null && ("2".equals(roleType) || byId.getStatus() == 1)) { vo.setProjectName(byId.getTeamName()); filteredList.add(vo); } } } pageInfo.setRecords(resultList); pageInfo.setTotal(resultList.size()); // 重新设置总记录数 // 3. 手动分页(在内存中截取) int total = filteredList.size(); int pageNum = query.getPageNum(); int pageSize = query.getPageSize(); int start = (pageNum - 1) * pageSize; int end = Math.min(start + pageSize, total); // 处理边界情况 List<TTrainLibraryVO> pageList = new ArrayList<>(); if (start < total) { pageList = filteredList.subList(start, end); } // 4. 构建 PageInfo 返回 PageInfo<TTrainLibraryVO> pageInfo = new PageInfo<>(); pageInfo.setRecords(pageList); pageInfo.setTotal(total); pageInfo.setPages((int) Math.ceil((double) total / pageSize)); pageInfo.setHasNextPage(pageNum < (int) Math.ceil((double) total / pageSize)); return pageInfo; } ruoyi-system/src/main/resources/mapper/system/TTrainLibraryMapper.xml
@@ -68,5 +68,43 @@ order by create_time desc </select> <!-- 新增:查询所有数据(不分页) --> <select id="listAll" resultType="com.ruoyi.system.vo.TTrainLibraryVO"> select <include refid="Base_Column_List"/> from t_train_library <where> <if test="query.strainCode != null and query.strainCode != ''"> and strain_code like concat('%', #{query.strainCode}, '%') </if> <if test="query.strainName != null and query.strainName != ''"> and strain_name like concat('%', #{query.strainName}, '%') </if> <if test="query.status != null"> and status = #{query.status} </if> <if test="query.type != null"> and `type` = #{query.type} </if> <if test="query.isDraft != null"> and is_draft = #{query.isDraft} </if> <if test="query.projectIds != null and query.projectIds.size() > 0"> and project_id in <foreach item="item" collection="query.projectIds" separator="," open="(" close=")" index=""> #{item} </foreach> </if> <!-- 时间范围查询 --> <if test="query.startTime != null and query.startTime != ''"> and create_time >= #{query.startTime} </if> <if test="query.endTime != null and query.endTime != ''"> and create_time <= #{query.endTime} </if> AND disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} </where> order by strain_code desc </select> </mapper> ruoyi-system/target/classes/mapper/system/TTrainLibraryMapper.xml
@@ -68,5 +68,43 @@ order by create_time desc </select> <!-- 新增:查询所有数据(不分页) --> <select id="listAll" resultType="com.ruoyi.system.vo.TTrainLibraryVO"> select <include refid="Base_Column_List"/> from t_train_library <where> <if test="query.strainCode != null and query.strainCode != ''"> and strain_code like concat('%', #{query.strainCode}, '%') </if> <if test="query.strainName != null and query.strainName != ''"> and strain_name like concat('%', #{query.strainName}, '%') </if> <if test="query.status != null"> and status = #{query.status} </if> <if test="query.type != null"> and `type` = #{query.type} </if> <if test="query.isDraft != null"> and is_draft = #{query.isDraft} </if> <if test="query.projectIds != null and query.projectIds.size() > 0"> and project_id in <foreach item="item" collection="query.projectIds" separator="," open="(" close=")" index=""> #{item} </foreach> </if> <!-- 时间范围查询 --> <if test="query.startTime != null and query.startTime != ''"> and create_time >= #{query.startTime} </if> <if test="query.endTime != null and query.endTime != ''"> and create_time <= #{query.endTime} </if> AND disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} </where> order by strain_code desc </select> </mapper>