云
2 天以前 616a6b2e9a7824da8d11a4e11730fd2f9b615299
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package cn.iocoder.yudao.module.mes.controller.admin.qc.attachment;
 
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;
import cn.iocoder.yudao.module.mes.service.qc.rqc.MesQcRqcService;
import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
import cn.iocoder.yudao.module.system.api.storage.dto.StorageBlobRespDTO;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Data;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
/** 质检附件独立于检验结论,上传附件不自动将产品判为合格。 */
@RestController
@RequestMapping("/mes/qc/attachment")
@Validated
public class MesQcAttachmentController {
    @Resource private MesQcIqcService iqcService;
    @Resource private MesQcIpqcService ipqcService;
    @Resource private MesQcOqcService oqcService;
    @Resource private MesQcRqcService rqcService;
    @Resource private StorageAttachmentApi storageApi;
    @Resource private org.springframework.jdbc.core.JdbcTemplate jdbcTemplate;
 
    @GetMapping("/list")
    @PreAuthorize("@ss.hasPermission('mes:qc-' + #type.toLowerCase() + ':query')")
    public CommonResult<List<StorageBlobRespDTO>> list(
            @RequestParam @Pattern(regexp = "iqc|ipqc|oqc|rqc|patrol") String type,
            @RequestParam @NotNull Long id) {
        validateDocument(type, id);
        var files = storageApi.listAttachments(recordType(type), id);
        return success(files == null ? List.of() : files);
    }
 
    @PutMapping("/save")
    @PreAuthorize("@ss.hasPermission('mes:qc-' + #req.type.toLowerCase() + ':update')")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> save(@Valid @RequestBody SaveReq req) {
        lockDocument(req.getType(), req.getId());
        validateDocument(req.getType(), req.getId());
        // bindAttachments 仅替换关联,不删除共享文件本体。
        storageApi.bindAttachments("file", recordType(req.getType()), req.getId(), req.getBlobIds().stream().distinct().toList());
        return success(true);
    }
 
    @PostMapping("/append")
    @PreAuthorize("@ss.hasPermission('mes:qc-' + #req.type.toLowerCase() + ':update')")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> append(@Valid @RequestBody AppendReq req) {
        lockDocument(req.getType(), req.getId());
        validateDocument(req.getType(), req.getId());
        var existing = storageApi.listAttachments(recordType(req.getType()), req.getId());
        var ids = new java.util.LinkedHashSet<Long>();
        if (existing != null) existing.forEach(blob -> ids.add(blob.getId()));
        ids.add(req.getBlobId());
        if (ids.size() > 50) throw new ServiceException(400, "每张质检单最多上传50份附件");
        storageApi.bindAttachments("file", recordType(req.getType()), req.getId(), List.copyOf(ids));
        return success(true);
    }
 
    @DeleteMapping("/remove")
    @PreAuthorize("@ss.hasPermission('mes:qc-' + #type.toLowerCase() + ':update')")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> remove(
            @RequestParam @Pattern(regexp = "iqc|ipqc|oqc|rqc|patrol") String type,
            @RequestParam @NotNull Long id, @RequestParam @NotNull Long blobId) {
        lockDocument(type, id);
        validateDocument(type, id);
        storageApi.removeReference("file", recordType(type), id, blobId);
        return success(true);
    }
 
    private String recordType(String type) {
        return switch (type) {
            case "iqc", "ipqc", "oqc", "rqc", "patrol" -> "mes_qc_" + type + "_attachment";
            default -> throw new ServiceException(400, "质检类型无效");
        };
    }
 
    private void lockDocument(String type, Long id) {
        String table = switch (type) {
            case "iqc" -> "mes_qc_iqc";
            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);
        if (ids.isEmpty()) throw new ServiceException(400, "质检单不存在");
    }
 
    private Integer validateDocument(String type, Long id) {
        return switch (type) {
            case "iqc" -> iqcService.validateIqcExists(id).getStatus();
            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|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|patrol") private String type;
        @NotNull private Long id;
        @NotNull private Long blobId;
    }
}