方法验证后端恢复为本地版本:移除合并进来的 Word 表单字段(标准名称/标准编号/验证项目/验证内容JSON)、getCurrentWorkFiles 接口、字段校验与程序化导出,恢复本地 poi-tl 模板导出实现;数据库多出的 4 列保留不再使用
已修改7个文件
181 ■■■■■ 文件已修改
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessMethodVerifyController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/mapper/ProcessMethodVerifyWorkFileMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/pojo/ProcessMethodVerify.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/service/ProcessMethodVerifyService.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/service/impl/ProcessMethodVerifyServiceImpl.java 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/resources/mapper/ProcessMethodVerifyMapper.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/resources/mapper/ProcessMethodVerifyWorkFileMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessMethodVerifyController.java
@@ -7,7 +7,6 @@
import com.ruoyi.process.dto.ProcessMethodVerifyDto;
import com.ruoyi.process.pojo.ProcessMethodVerify;
import com.ruoyi.process.pojo.ProcessMethodVerifyMethodFile;
import com.ruoyi.process.pojo.ProcessMethodVerifyWorkFile;
import com.ruoyi.process.service.ProcessMethodVerifyMethodFileService;
import com.ruoyi.process.service.ProcessMethodVerifyService;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -73,12 +72,6 @@
    @GetMapping("/getMethodVerifyOne")
    public Result<ProcessMethodVerifyDto> getMethodVerifyOne(Integer methodVerifyId) {
        return Result.success(processMethodVerifyService.getMethodVerifyOne(methodVerifyId));
    }
    @Operation(summary = "实时查看检测人员上岗证")
    @GetMapping("/getCurrentWorkFiles")
    public Result<List<ProcessMethodVerifyWorkFile>> getCurrentWorkFiles(String userIds) {
        return Result.success(processMethodVerifyService.getCurrentWorkFiles(userIds));
    }
cnas-process/src/main/java/com/ruoyi/process/mapper/ProcessMethodVerifyWorkFileMapper.java
@@ -20,8 +20,5 @@
     * @return
     */
    String selectWorkFile(@Param("userId") Integer userId);
    /** 读取人员最新的任职授权记录,供方法验证实时查看证书。 */
    ProcessMethodVerifyWorkFile selectLatestAuthorization(@Param("userId") Integer userId);
}
cnas-process/src/main/java/com/ruoyi/process/pojo/ProcessMethodVerify.java
@@ -27,18 +27,6 @@
    @Schema(description = "标准方法")
    private String methodName;
    @Schema(description = "方法验证的标准名称")
    private String standardName;
    @Schema(description = "方法验证的标准编号")
    private String standardCode;
    @Schema(description = "方法验证的验证项目")
    private String verifyItem;
    @Schema(description = "方法验证表格内容,JSON")
    private String verificationContent;
    @Schema(description = "验证原因")
    private String verifyReason;
cnas-process/src/main/java/com/ruoyi/process/service/ProcessMethodVerifyService.java
@@ -6,7 +6,6 @@
import com.ruoyi.process.dto.ProcessMethodVerifyDto;
import com.ruoyi.process.pojo.ProcessMethodVerify;
import com.ruoyi.process.pojo.ProcessMethodVerifyMethodFile;
import com.ruoyi.process.pojo.ProcessMethodVerifyWorkFile;
import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.http.HttpServletResponse;
@@ -41,9 +40,6 @@
     * @return
     */
    ProcessMethodVerifyDto getMethodVerifyOne(Integer methodVerifyId);
    /** 实时读取所选检测人员的任职授权证书。 */
    List<ProcessMethodVerifyWorkFile> getCurrentWorkFiles(String userIds);
    /**
     * 修改标准方法验证
cnas-process/src/main/java/com/ruoyi/process/service/impl/ProcessMethodVerifyServiceImpl.java
@@ -2,9 +2,6 @@
import  cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@@ -32,11 +29,6 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
@@ -49,9 +41,6 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
/**
 * 标准方法验证
@@ -114,7 +103,6 @@
        if (methodVerifyDto.getOperationType() == null) {
            throw new ErrorException("请选择是变更还是验证");
        }
        validateWordVerification(methodVerifyDto);
        // 新增
        baseMapper.insert(methodVerifyDto);
@@ -160,37 +148,6 @@
        return processMethodVerifyDto;
    }
    @Override
    public List<ProcessMethodVerifyWorkFile> getCurrentWorkFiles(String userIds) {
        List<ProcessMethodVerifyWorkFile> files = new ArrayList<>();
        if (StringUtils.isBlank(userIds)) return files;
        Set<Integer> ids = new LinkedHashSet<>();
        for (String value : StrUtil.split(userIds, ",")) {
            try {
                ids.add(Integer.valueOf(value.trim()));
            } catch (NumberFormatException e) {
                throw new ErrorException("检测人员ID无效");
            }
        }
        if (ids.size() > 5) throw new ErrorException("最多选择5名检测人员");
        for (Integer userId : ids) {
            ProcessMethodVerifyWorkFile file = processMethodVerifyWorkFileMapper.selectLatestAuthorization(userId);
            if (file == null) continue;
            file.setUserId(userId);
            if (StringUtils.isBlank(file.getFileUrl())) {
                file.setFileName("未上传上岗证书");
                file.setType(0);
            } else {
                file.setFileName(file.getFileUrl());
                file.setType(file.getFileUrl().matches("(?i).*\\.(png|jpe?g|gif|bmp|webp)$") ? 1 : 2);
            }
            files.add(file);
        }
        return files;
    }
    /**
     * 修改标准方法验证
     *
@@ -199,7 +156,6 @@
     */
    @Override
    public boolean updateMethodVerify(ProcessMethodVerifyDto methodVerifyDto) {
        validateWordVerification(methodVerifyDto);
        baseMapper.updateById(methodVerifyDto);
        // 删除上岗证
@@ -332,14 +288,6 @@
    public void exportMethodVerify(Integer methodVerifyId, HttpServletResponse response) {
        // 获取标准方法更新验证数据
        ProcessMethodVerify processMethodVerify = baseMapper.selectById(methodVerifyId);
        if (processMethodVerify == null) {
            throw new ErrorException("方法验证记录不存在");
        }
        if (Objects.equals(processMethodVerify.getOperationType(), 1)
                && StringUtils.isNotBlank(processMethodVerify.getVerificationContent())) {
            exportWordVerification(processMethodVerify, response);
            return;
        }
        // 将内部字段转换成展示到word中的对象
        ProcessMethodVerifyExportWordDto exportWordTemplate = getExportWordTemplate(processMethodVerify);
@@ -402,91 +350,6 @@
            e.printStackTrace();
            throw new RuntimeException("导出失败");
        }
    }
    /** 新版方法验证主表导出;原始记录和验证结果仍作为附件保存。 */
    private void exportWordVerification(ProcessMethodVerify verify, HttpServletResponse response) {
        JSONObject content = JSONUtil.parseObj(verify.getVerificationContent());
        String[][] checks = {
                {"personnel", "1. 人员能力"}, {"equipment", "2. 检测设备"},
                {"reagents", "3. 试剂要求"}, {"conditions", "4. 试验条件"},
                {"sample", "5. 样品处置"}, {"steps", "6. 试验步骤"},
                {"processing", "7. 数据处理"}, {"qualityControl", "质量控制方法"},
                {"result", "方法验证结果"}
        };
        try (XWPFDocument document = new XWPFDocument()) {
            XWPFParagraph title = document.createParagraph();
            title.setAlignment(ParagraphAlignment.CENTER);
            title.createRun().setText("方法验证记录");
            XWPFTable basic = document.createTable(2, 4);
            setCells(basic, 0, "标准名称", verify.getStandardName(), "标准编号", verify.getStandardCode());
            setCells(basic, 1, "验证项目", verify.getVerifyItem(), "", "");
            XWPFTable table = document.createTable(checks.length + 1, 4);
            setCells(table, 0, "验证内容", "方法要求", "实验室能力", "是否满足");
            JSONArray entries = content.getJSONArray("checks");
            for (int i = 0; i < checks.length; i++) {
                JSONObject entry = findCheck(entries, checks[i][0]);
                Integer satisfied = entry == null ? null : entry.getInt("satisfied");
                setCells(table, i + 1, checks[i][1], field(entry, "requirement"),
                        field(entry, "capability"), satisfied == null ? "" : satisfied == 1 ? "是" : "否");
            }
            XWPFTable conclusion = document.createTable(1, 2);
            setCells(conclusion, 0, "验证结论", field(content, "conclusion"));
            XWPFTable decisions = document.createTable(2, 4);
            setCells(decisions, 0, "评审意见", field(content, "reviewDecision"),
                    "评审人员:" + field(content, "reviewer"), field(content, "reviewDate"));
            setCells(decisions, 1, "审批意见", field(content, "approvalDecision"),
                    "技术负责人:" + field(content, "approver"), field(content, "approvalDate"));
            document.createParagraph().createRun().setText("附件1 原始记录;附件2 验证结果(附件在系统中查看)");
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            String fileName = URLEncoder.encode("方法验证记录", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".docx");
            document.write(response.getOutputStream());
        } catch (Exception e) {
            throw new RuntimeException("导出方法验证记录失败", e);
        }
    }
    private JSONObject findCheck(JSONArray entries, String key) {
        if (entries == null) return null;
        for (Object value : entries) {
            JSONObject check = JSONUtil.parseObj(value);
            if (key.equals(check.getStr("key"))) return check;
        }
        return null;
    }
    private String field(JSONObject object, String key) {
        return object == null ? "" : StrUtil.nullToEmpty(object.getStr(key));
    }
    private void setCells(XWPFTable table, int row, String... values) {
        for (int i = 0; i < values.length; i++) {
            XWPFTableCell cell = table.getRow(row).getCell(i);
            cell.setText(StrUtil.nullToEmpty(values[i]));
        }
    }
    private void validateWordVerification(ProcessMethodVerifyDto verify) {
        // 没有 verificationContent 的旧记录继续由旧表单维护。
        if (!Objects.equals(verify.getOperationType(), 1)
                || StringUtils.isBlank(verify.getVerificationContent())) return;
        if (StringUtils.isBlank(verify.getStandardName())
                || StringUtils.isBlank(verify.getStandardCode())
                || StringUtils.isBlank(verify.getVerifyItem())) {
            throw new ErrorException("请填写标准名称、标准编号和验证项目");
        }
        try {
            JSONUtil.parseObj(verify.getVerificationContent());
        } catch (Exception e) {
            throw new ErrorException("方法验证内容格式错误");
        }
        // 保留旧列供现有依赖 method_name 的查询使用。
        verify.setMethodName(verify.getStandardName());
    }
    private ProcessMethodVerifyExportWordDto getExportWordTemplate(ProcessMethodVerify processMethodVerify) {
@@ -561,7 +424,7 @@
                User user = userMapper.selectById(userId);
                ProcessMethodVerifyWorkFile workFile = new ProcessMethodVerifyWorkFile();
                workFile.setMethodVerifyId(methodVerifyDto.getMethodVerifyId());
                workFile.setType(workName.matches("(?i).*\\.(png|jpe?g|gif|bmp|webp)$") ? 1 : 2);
                workFile.setType(1);
                workFile.setFileUrl(workName);
                workFile.setFileName(workName);
                workFile.setUserId(user.getId());
cnas-process/src/main/resources/mapper/ProcessMethodVerifyMapper.xml
@@ -7,9 +7,6 @@
        select * from (
        select method_verify_id,
        method_name,
        coalesce(standard_name, method_name) as standard_name,
        standard_code,
        verify_item,
        verify_reason,
        technology_change,
        confirm_date,
cnas-process/src/main/resources/mapper/ProcessMethodVerifyWorkFileMapper.xml
@@ -7,20 +7,7 @@
        select system_file_name
        from cnas_person_post_authorization_record
        where user_id = #{userId}
          and system_file_name is not null
          and system_file_name != ''
        order by create_time desc
        limit 1
    </select>
    <select id="selectLatestAuthorization" resultType="com.ruoyi.process.pojo.ProcessMethodVerifyWorkFile">
        select p.system_file_name as file_url,
               u.id as user_id,
               u.name as user_name
        from cnas_person_post_authorization_record p
        join user u on u.id = p.user_id
        where p.user_id = #{userId}
        order by p.create_time desc, p.id desc
        limit 1
    </select>
</mapper>