gaoluyang
4 天以前 eee03bbfea8b15d1a56ab63bd09a35c6c861c4cb
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/attachment/MesQcAttachmentController.java
@@ -2,6 +2,7 @@
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcService;
import cn.iocoder.yudao.module.mes.service.qc.ipqc.MesQcIpqcService;
import cn.iocoder.yudao.module.mes.service.qc.oqc.MesQcOqcService;
@@ -37,7 +38,7 @@
    @GetMapping("/list")
    @PreAuthorize("@ss.hasPermission('mes:qc-' + #type.toLowerCase() + ':query')")
    public CommonResult<List<StorageBlobRespDTO>> list(
            @RequestParam @Pattern(regexp = "iqc|ipqc|oqc|rqc") String type,
            @RequestParam @Pattern(regexp = "iqc|ipqc|oqc|rqc|patrol") String type,
            @RequestParam @NotNull Long id) {
        validateDocument(type, id);
        var files = storageApi.listAttachments(recordType(type), id);
@@ -74,7 +75,7 @@
    @PreAuthorize("@ss.hasPermission('mes:qc-' + #type.toLowerCase() + ':update')")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> remove(
            @RequestParam @Pattern(regexp = "iqc|ipqc|oqc|rqc") String type,
            @RequestParam @Pattern(regexp = "iqc|ipqc|oqc|rqc|patrol") String type,
            @RequestParam @NotNull Long id, @RequestParam @NotNull Long blobId) {
        lockDocument(type, id);
        validateDocument(type, id);
@@ -82,9 +83,60 @@
        return success(true);
    }
    // ==================== 过程检验「检验行」附件 ====================
    /** 过程检验行附件:recordId 为检验结果明细 ID,每行独立上传 */
    @GetMapping("/ipqc-detail/list")
    @PreAuthorize("@ss.hasPermission('mes:qc-ipqc:query')")
    public CommonResult<List<StorageBlobRespDTO>> listIpqcDetail(@RequestParam @NotNull Long detailId) {
        validateIpqcDetail(detailId);
        var files = storageApi.listAttachments(IPQC_DETAIL_RECORD_TYPE, detailId);
        return success(files == null ? List.of() : files);
    }
    @PostMapping("/ipqc-detail/save")
    @PreAuthorize("@ss.hasPermission('mes:qc-ipqc:update')")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> saveIpqcDetail(@Valid @RequestBody IpqcDetailSaveReq req) {
        validateIpqcDetail(req.getDetailId());
        storageApi.bindAttachments("file", IPQC_DETAIL_RECORD_TYPE, req.getDetailId(),
                req.getBlobIds().stream().distinct().toList());
        return success(true);
    }
    @DeleteMapping("/ipqc-detail/remove")
    @PreAuthorize("@ss.hasPermission('mes:qc-ipqc:update')")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> removeIpqcDetail(@RequestParam @NotNull Long detailId,
                                                  @RequestParam @NotNull Long blobId) {
        validateIpqcDetail(detailId);
        storageApi.removeReference("file", IPQC_DETAIL_RECORD_TYPE, detailId, blobId);
        return success(true);
    }
    private static final String IPQC_DETAIL_RECORD_TYPE = "mes_qc_ipqc_detail_attachment";
    /** 校验明细存在且属于过程检验结果 */
    private void validateIpqcDetail(Long detailId) {
        var ids = jdbcTemplate.queryForList(
                "SELECT d.id FROM mes_qc_indicator_result_detail d "
                        + "JOIN mes_qc_indicator_result r ON r.id = d.result_id "
                        + "WHERE d.id = ? AND r.qc_type = ? AND d.deleted = 0 AND r.deleted = 0",
                Long.class, detailId, cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum.IPQC.getType());
        if (ids.isEmpty()) {
            throw new ServiceException(400, "过程检验行不存在或不属于过程检验单,无法上传附件");
        }
    }
    @Data public static class IpqcDetailSaveReq {
        @NotNull private Long detailId;
        /** 允许空列表:表示清空该行附件 */
        @NotNull @Size(max = 50) private List<@NotNull Long> blobIds;
    }
    private String recordType(String type) {
        return switch (type) {
            case "iqc", "ipqc", "oqc", "rqc" -> "mes_qc_" + type + "_attachment";
            case "iqc", "ipqc", "oqc", "rqc", "patrol" -> "mes_qc_" + type + "_attachment";
            default -> throw new ServiceException(400, "质检类型无效");
        };
    }
@@ -95,6 +147,7 @@
            case "ipqc" -> "mes_qc_ipqc";
            case "oqc" -> "mes_qc_oqc";
            case "rqc" -> "mes_qc_rqc";
            case "patrol" -> "mes_qc_patrol";
            default -> throw new ServiceException(400, "质检类型无效");
        };
        var ids = jdbcTemplate.queryForList("SELECT id FROM " + table + " WHERE id = ? AND deleted = 0 FOR UPDATE", Long.class, id);
@@ -107,17 +160,24 @@
            case "ipqc" -> ipqcService.validateIpqcExists(id).getStatus();
            case "oqc" -> oqcService.validateOqcExists(id).getStatus();
            case "rqc" -> rqcService.validateRqcExists(id).getStatus();
            case "patrol" -> {
                var ids = jdbcTemplate.queryForList(
                        "SELECT id FROM mes_qc_patrol WHERE id = ? AND tenant_id = ? AND deleted = 0",
                        Long.class, id, TenantContextHolder.getRequiredTenantId());
                if (ids.isEmpty()) throw new ServiceException(400, "巡检记录不存在");
                yield 0;
            }
            default -> throw new ServiceException(400, "质检类型无效");
        };
    }
    @Data public static class SaveReq {
        @NotNull @Pattern(regexp = "iqc|ipqc|oqc|rqc") private String type;
        @NotNull @Pattern(regexp = "iqc|ipqc|oqc|rqc|patrol") private String type;
        @NotNull private Long id;
        @NotEmpty @Size(max = 50) private List<@NotNull Long> blobIds;
    }
    @Data public static class AppendReq {
        @NotNull @Pattern(regexp = "iqc|ipqc|oqc|rqc") private String type;
        @NotNull @Pattern(regexp = "iqc|ipqc|oqc|rqc|patrol") private String type;
        @NotNull private Long id;
        @NotNull private Long blobId;
    }