云
4 天以前 bd961491fb449a92e7c357376073e138f99c5a29
refactor(seal): 重构用印管理与申请模块并优化交互体验

- 移除用印下载时对审批人必须为他人的限制
- 补充申请人自身审批通过即可下载后端的单元测试
- 重构用印管理页面并增加图片预览与文件校验功能
- 完善用印管理页面的加载错误处理与状态切换交互
- 抽取项目跟踪表用印申请逻辑为独立的弹窗组件
- 优化用印申请弹窗的表单校验与审批记录展示交互
已修改2个文件
19 ■■■■■ 文件已修改
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/seal/PdSealService.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/pd/seal/PdSealServiceTest.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/seal/PdSealService.java
@@ -80,11 +80,11 @@
        if (instance == null || instance.isBlank()) throw fail("审批记录不完整,无法下载");
        boolean humanApproval = taskService.getTaskListByProcessInstanceId(instance, true).stream().anyMatch(task -> {
            var vars = task.getTaskLocalVariables();
            if (vars == null || !Integer.valueOf(2).equals(vars.get("TASK_STATUS")) || task.getAssignee() == null || task.getAssignee().equals(String.valueOf(userId))) return false;
            if (vars == null || !Integer.valueOf(2).equals(vars.get("TASK_STATUS")) || task.getAssignee() == null) return false;
            Object reason = vars.get("TASK_REASON");
            return Arrays.stream(cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum.values()).noneMatch(item -> Objects.equals(item.getReason(), reason));
        });
        if (!humanApproval) throw fail("未找到其他审批人的人工通过记录,无法下载");
        if (!humanApproval) throw fail("未找到人工审批通过记录,无法下载");
        byte[] snapshot=(byte[])rows.get(0).get("document_snapshot"), image=(byte[])rows.get(0).get("seal_image");
        var out=new ByteArrayOutputStream(); boolean found=false;
        try(var zin=new ZipInputStream(new ByteArrayInputStream(snapshot)); var zout=new ZipOutputStream(out)) { ZipEntry entry; while((entry=zin.getNextEntry())!=null){byte[] bytes=zin.readAllBytes(); if(entry.getName().equals("word/media/seal.png")){bytes=image;found=true;} zout.putNextEntry(new ZipEntry(entry.getName())); zout.write(bytes); zout.closeEntry();} }
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/pd/seal/PdSealServiceTest.java
@@ -34,6 +34,21 @@
        when(tasks.getTaskListByProcessInstanceId("p",true)).thenReturn(List.of(task));
        assertThrows(ServiceException.class, () -> service.download(1,7));
    }
    @Test void allowsManualApprovalByApplicant() throws Exception {
        var buffer = new ByteArrayOutputStream();
        try (var zip = new ZipOutputStream(buffer)) {
            zip.putNextEntry(new ZipEntry("word/media/seal.png"));
            zip.write(new byte[]{1});
            zip.closeEntry();
        }
        when(jdbc.queryForList(anyString(), any(Object[].class))).thenReturn(List.of(Map.of(
                "process_instance_id", "p", "document_snapshot", buffer.toByteArray(), "seal_image", new byte[]{2})));
        HistoricTaskInstance task = mock(HistoricTaskInstance.class);
        when(task.getAssignee()).thenReturn("7");
        when(task.getTaskLocalVariables()).thenReturn(Map.of("TASK_STATUS", 2, "TASK_REASON", ""));
        when(tasks.getTaskListByProcessInstanceId("p", true)).thenReturn(List.of(task));
        assertNotNull(service.download(1, 7));
    }
    @Test void approvedDownloadEmbedsSelectedImage() throws Exception {
        var buffer=new ByteArrayOutputStream();
        try(var zip=new ZipOutputStream(buffer)){zip.putNextEntry(new ZipEntry("word/media/seal.png"));zip.write(new byte[]{1});zip.closeEntry();}