wenminjie
2026-07-15 999e0159112d9405bad7fcd839b339e006a3530d
修复了已知的BUG
6个文件已修改
223 ■■■■■ 已修改文件
ruoyi-common/src/main/java/com/ruoyi/common/filter/CustomRequestWrapper.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/filter/SmCryptoFilter.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TTrainLibraryMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTrainLibraryServiceImpl.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/TTrainLibraryMapper.xml 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/target/classes/mapper/system/TTrainLibraryMapper.xml 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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;
public class CustomRequestWrapper extends HttpServletRequestWrapper {
    private final String body;
    /**
     * 构造函数,用于创建自定义请求包装器。
 *  解决服务器字符集问题
     *
     * @param request 原始 HTTP 请求对象
     * @param body    新的请求体内容
     * @throws IOException 如果读取或处理请求体时发生错误
 * @author 文敏杰
 * @date 2026/06/25
     */
    public CustomRequestWrapper(HttpServletRequest request, String body) throws IOException {
public class CustomRequestWrapper extends HttpServletRequestWrapper {
    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();
        // 直接使用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 &lt;= #{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 &lt;= #{query.endTime}
            </if>
            AND disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
        </where>
        order by strain_code desc
    </select>
</mapper>