gaoluyang
昨天 abd339106ed3a6465293edccd33e5f87bd43bdde
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
package com.ruoyi.process.service;
 
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.exception.ErrorException;
import com.ruoyi.inspect.mapper.InsOrderStateMapper;
import com.ruoyi.inspect.pojo.InsOrder;
import com.ruoyi.inspect.pojo.InsOrderState;
import com.ruoyi.inspect.service.InsOrderPlanService;
import com.ruoyi.inspect.vo.QualityMonitorRawContext;
import com.ruoyi.process.mapper.QualityMonitorDetailsEvaluateMapper;
import com.ruoyi.process.mapper.QualityMonitorDetailsMapper;
import com.ruoyi.process.mapper.QualityMonitorEvaluateResultMapper;
import com.ruoyi.process.mapper.QualityMonitorMapper;
import com.ruoyi.process.pojo.QualityMonitor;
import com.ruoyi.process.pojo.QualityMonitorDetails;
import com.ruoyi.process.pojo.QualityMonitorDetailsEvaluate;
import com.ruoyi.process.pojo.QualityMonitorEvaluateResult;
import com.ruoyi.system.mapper.UserMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
 
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
 
@Service
public class QualityMonitorInspectionEvaluationService {
    @Resource
    private QualityMonitorTaskService taskService;
    @Resource
    private QualityMonitorDetailsMapper detailsMapper;
    @Resource
    private QualityMonitorMapper monitorMapper;
    @Resource
    private QualityMonitorDetailsEvaluateMapper evaluateMapper;
    @Resource
    private QualityMonitorEvaluateResultMapper resultMapper;
    @Resource
    private InsOrderStateMapper stateMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private InsOrderPlanService insOrderPlanService;
 
    public QualityMonitorDetailsEvaluate get(Integer detailId) {
        QualityMonitorDetails detail = requireDetail(detailId);
        QualityMonitorDetailsEvaluate evaluation = evaluateMapper.selectOne(Wrappers.<QualityMonitorDetailsEvaluate>lambdaQuery()
                .eq(QualityMonitorDetailsEvaluate::getQualityMonitorDetailsId, detailId).last("limit 1"));
        InsOrder task = taskService.getTask(detailId);
        if (evaluation == null) {
            evaluation = new QualityMonitorDetailsEvaluate();
            evaluation.setQualityMonitorDetailsId(detailId);
            evaluation.setInspectorUserId(detail.getInspectorUserId());
            evaluation.setSampleName(detail.getSampleName());
            evaluation.setSampleSpec(detail.getSampleSpec());
        }
        // 评价记录里的“监督员”就是计划中指定的“评价人”,未保存过评价时直接反显评价人
        if (evaluation.getSupervisorUserId() == null) {
            evaluation.setSupervisorUserId(detail.getEvaluatorUserId());
        }
        // 历史评价记录可能没有保存被监督人员,回退到计划明细中的检测员
        if (evaluation.getInspectorUserId() == null) {
            evaluation.setInspectorUserId(detail.getInspectorUserId());
        }
        List<QualityMonitorEvaluateResult> rows = evaluation.getDetailsEvaluateId() == null
                ? List.of() : resultMapper.selectList(Wrappers.<QualityMonitorEvaluateResult>lambdaQuery()
                                                      .eq(QualityMonitorEvaluateResult::getDetailsEvaluateId, evaluation.getDetailsEvaluateId())
                                                      .orderByAsc(QualityMonitorEvaluateResult::getSortNo, QualityMonitorEvaluateResult::getId));
        if (task != null && Integer.valueOf(5).equals(task.getInsState())) {
            List<Map<String, String>> rawRows = insOrderPlanService.getQualityMonitorRawResults(task.getId());
            fillRawContext(evaluation, insOrderPlanService.getQualityMonitorRawContext(task.getId()));
            if (!rows.isEmpty() && rows.size() != rawRows.size())
                throw new ErrorException("原始记录检测数据已变化,请重新核对评价记录");
            if (rows.isEmpty()) {
                rows = new java.util.ArrayList<>();
                for (int i = 0; i < rawRows.size(); i++) {
                    QualityMonitorEvaluateResult row = new QualityMonitorEvaluateResult();
                    row.setInspectorUserId(detail.getInspectorUserId());
                    row.setMeasuredValue(rawRows.get(i).get("result"));
                    row.setUnit(rawRows.get(i).get("unit"));
                    row.setSortNo(i);
                    rows.add(row);
                }
            }
            for (int i = 0; i < rows.size(); i++) rows.get(i).setItemName(rawRows.get(i).get("itemName"));
        }
        evaluation.setResultRows(rows);
        evaluation.setInspectionTaskState(task == null ? null : task.getInsState());
        // 监督员、检测员可能不在前端人员下拉列表中(角色或状态被过滤),回传名称保证能正常反显
        if (evaluation.getSupervisorUserId() != null) {
            var supervisor = userMapper.selectById(evaluation.getSupervisorUserId());
            if (supervisor != null) evaluation.setSupervisorName(supervisor.getName());
        }
        if (evaluation.getInspectorUserId() != null) {
            var inspector = userMapper.selectById(evaluation.getInspectorUserId());
            if (inspector != null) evaluation.setInspectorName(inspector.getName());
        }
        if (Integer.valueOf(1).equals(evaluation.getIsFinish())) {
            evaluation.setEvaluationEditReason("评价已批准归档,只能查看");
        } else if (task == null) {
            evaluation.setEvaluationEditReason("质控检验任务尚未下发,暂不能填写评价");
        } else if (!Integer.valueOf(5).equals(task.getInsState())) {
            evaluation.setEvaluationEditReason("原始记录复核通过后,指定评价人才可以填写");
        } else if (detail.getEvaluatorUserId() == null) {
            evaluation.setEvaluationEditReason("计划项目尚未指定评价人");
        } else if (!Integer.valueOf(SecurityUtils.getUserId().intValue()).equals(detail.getEvaluatorUserId())) {
            var evaluator = userMapper.selectById(detail.getEvaluatorUserId());
            evaluation.setEvaluationEditReason("当前账号不是指定评价人("
                    + (evaluator == null ? "用户ID " + detail.getEvaluatorUserId() : evaluator.getName())
                    + "),只能查看");
        } else {
            evaluation.setEvaluationEditable(true);
        }
        return evaluation;
    }
 
    @Transactional(rollbackFor = Exception.class)
    public QualityMonitorDetailsEvaluate submit(QualityMonitorDetailsEvaluate input) {
        if (input == null) throw new ErrorException("评价内容不能为空");
        QualityMonitorDetails detail = requireDetail(input.getQualityMonitorDetailsId());
        InsOrder task = taskService.getTask(detail.getQualityMonitorDetailsId());
        if (task == null || !QualityMonitorTaskService.SOURCE.equals(task.getTaskSource()))
            throw new ErrorException("质量监控检验任务不存在");
        if (!Integer.valueOf(5).equals(task.getInsState()))
            throw new ErrorException("原始记录复核通过后才能评价");
        if (!Integer.valueOf(SecurityUtils.getUserId().intValue()).equals(detail.getEvaluatorUserId()))
            throw new ErrorException("只有指定评价人可以填写评价");
        if (input.getSupervisorUserId() == null
                || input.getSupervisorUserId().equals(detail.getInspectorUserId())
                || userMapper.selectById(input.getSupervisorUserId()) == null)
            throw new ErrorException("请选择监督员(默认为计划评价人,不能与检测员相同)");
        Long pendingCount = stateMapper.selectCount(Wrappers.<InsOrderState>lambdaQuery()
                .eq(InsOrderState::getInsOrderId, task.getId()).ne(InsOrderState::getInsState, 5));
        if (pendingCount > 0) throw new ErrorException("原始记录复核通过后才能评价");
        List<Map<String, String>> rawRows = insOrderPlanService.getQualityMonitorRawResults(task.getId());
        QualityMonitorRawContext rawContext = insOrderPlanService.getQualityMonitorRawContext(task.getId());
        if (rawContext.getDetectionDates().isEmpty() || rawContext.getDevices().isEmpty())
            throw new ErrorException("原始记录缺少检测时间或所用设备,请先补齐并复核");
        if (!StringUtils.hasText(input.getEvaluationConclusion()) || input.getResultRows() == null
                || input.getResultRows().size() != rawRows.size())
            throw new ErrorException("请填写评价内容并核对全部原始记录检测数据");
        if (!Boolean.TRUE.equals(input.getMeasurementConfirmed()))
            throw new ErrorException("请先核对已复核原始记录的检测数据");
        QualityMonitorDetailsEvaluate existing = evaluateMapper.selectOne(Wrappers.<QualityMonitorDetailsEvaluate>lambdaQuery()
                .eq(QualityMonitorDetailsEvaluate::getQualityMonitorDetailsId, detail.getQualityMonitorDetailsId())
                .last("FOR UPDATE"));
        if (existing != null && Integer.valueOf(1).equals(existing.getIsFinish()))
            throw new ErrorException("已批准的评价不可修改");
        QualityMonitor plan = monitorMapper.selectById(detail.getQualityMonitorId());
        QualityMonitorDetailsEvaluate saved = existing == null ? new QualityMonitorDetailsEvaluate() : existing;
        saved.setQualityMonitorDetailsId(detail.getQualityMonitorDetailsId());
        saved.setInsOrderId(task.getId());
        saved.setInspectorUserId(detail.getInspectorUserId());
        saved.setImplementUserId(detail.getEvaluatorUserId());
        saved.setRatifyUserId(plan.getRatifyUserId());
        saved.setSupervisorUserId(input.getSupervisorUserId());
        saved.setSampleName(detail.getSampleName());
        saved.setSampleSpec(detail.getSampleSpec());
        // 时间和设备始终由已复核原始记录读取,评价请求中的同名字段不参与保存。
        saved.setImplementCondition(input.getEvaluationConclusion());
        saved.setImplementResult(input.getImplementResult());
        saved.setEvaluationConclusion(input.getEvaluationConclusion());
        saved.setCorrectiveAction(input.getCorrectiveAction());
        saved.setVerificationResult(input.getVerificationResult());
        saved.setCorrectiveResponsibleUserId(input.getCorrectiveResponsibleUserId());
        saved.setCorrectiveDueDate(input.getCorrectiveDueDate());
        saved.setVerificationResponsibleUserId(input.getVerificationResponsibleUserId());
        saved.setVerificationDate(input.getVerificationDate());
        saved.setReviewPurpose(detail.getMonitorPurpose());
        saved.setReviewUser(userMapper.selectById(detail.getEvaluatorUserId()).getName());
        saved.setReviewTime(LocalDateTime.now().toLocalDate().toString());
        if (!StringUtils.hasText(saved.getImplementResult())) {
            saved.setImplementResult(input.getEvaluationConclusion());
        }
        saved.setIsFinish(0);
        if (existing == null) evaluateMapper.insert(saved);
        else evaluateMapper.updateById(saved);
        resultMapper.delete(Wrappers.<QualityMonitorEvaluateResult>lambdaQuery()
                .eq(QualityMonitorEvaluateResult::getDetailsEvaluateId, saved.getDetailsEvaluateId()));
        int index = 0;
        for (QualityMonitorEvaluateResult row : input.getResultRows()) {
            Map<String, String> rawRow = rawRows.get(index);
            if (!Objects.equals(row.getMeasuredValue(), rawRow.get("result")))
                throw new ErrorException("检测数据与已复核原始记录不一致,请刷新后重新核对");
            if (!StringUtils.hasText(row.getReferenceValue())) throw new ErrorException("请填写盲样值");
            row.setId(null);
            row.setDetailsEvaluateId(saved.getDetailsEvaluateId());
            row.setInspectorUserId(detail.getInspectorUserId());
            row.setMeasuredValue(rawRow.get("result"));
            row.setUnit(rawRow.get("unit"));
            row.setSortNo(index++);
            resultMapper.insert(row);
        }
        return get(detail.getQualityMonitorDetailsId());
    }
 
    @Transactional(rollbackFor = Exception.class)
    public void approve(Integer detailId, boolean approved, String opinion) {
        QualityMonitorDetails detail = requireDetail(detailId);
        QualityMonitor plan = monitorMapper.selectById(detail.getQualityMonitorId());
        int current = SecurityUtils.getUserId().intValue();
        if (plan == null || !Integer.valueOf(current).equals(plan.getRatifyUserId())
                || Integer.valueOf(current).equals(detail.getInspectorUserId()))
            throw new ErrorException("只有指定批准人可以审批评价");
        QualityMonitorDetailsEvaluate evaluation = evaluateMapper.selectOne(Wrappers.<QualityMonitorDetailsEvaluate>lambdaQuery()
                .eq(QualityMonitorDetailsEvaluate::getQualityMonitorDetailsId, detailId).last("FOR UPDATE"));
        if (evaluation == null || Integer.valueOf(1).equals(evaluation.getIsFinish()))
            throw new ErrorException("评价不存在或已批准");
        if (approved && StringUtils.hasText(evaluation.getCorrectiveAction())
                && (!StringUtils.hasText(evaluation.getVerificationResult())
                || evaluation.getCorrectiveResponsibleUserId() == null
                || evaluation.getCorrectiveDueDate() == null
                || evaluation.getVerificationResponsibleUserId() == null
                || evaluation.getVerificationDate() == null))
            throw new ErrorException("请补齐纠正措施责任人、完成日期和验证信息后再批准");
        evaluation.setRatifyOpinion(opinion);
        evaluation.setRatifyTime(LocalDateTime.now());
        evaluation.setIsFinish(approved ? 1 : 0);
        evaluateMapper.updateById(evaluation);
    }
 
    private QualityMonitorDetails requireDetail(Integer detailId) {
        QualityMonitorDetails detail = detailId == null ? null : detailsMapper.selectById(detailId);
        if (detail == null || !"INSPECTION".equals(detail.getItemKind()))
            throw new ErrorException("质量监控检测明细不存在");
        return detail;
    }
 
    private void fillRawContext(QualityMonitorDetailsEvaluate evaluation, QualityMonitorRawContext context) {
        evaluation.setRawInspectionDates(context.getDetectionDates().stream()
                .map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE)).collect(Collectors.toList()));
        List<String> names = new ArrayList<>();
        List<String> specs = new ArrayList<>();
        List<String> codes = new ArrayList<>();
        for (Map<String, String> device : context.getDevices()) {
            names.add(deviceText(device, "device_name", "deviceName"));
            specs.add(deviceText(device, "specification_model", "specificationModel"));
            String managementNumber = deviceText(device, "management_number", "managementNumber");
            codes.add("-".equals(managementNumber)
                    ? deviceText(device, "factory_no", "factoryNo") : managementNumber);
        }
        evaluation.setRawEquipmentDescription(String.join("\n", names));
        evaluation.setRawEquipmentSpec(String.join("\n", specs));
        evaluation.setRawEquipmentCode(String.join("\n", codes));
    }
 
    private String deviceText(Map<String, String> device, String snakeCase, String camelCase) {
        String value = device.get(snakeCase);
        if (!StringUtils.hasText(value)) value = device.get(camelCase);
        return StringUtils.hasText(value) ? value : "-";
    }
}