|
|
@@ -41,8 +41,10 @@ import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.LinkedHashMap;
|
|
|
+import java.util.LinkedHashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
|
|
|
/** 气密泄露点位统计 Controller。 */
|
|
|
@Controller
|
|
|
@@ -92,56 +94,51 @@ public class MesProductLeakagePointStatController extends BaseController {
|
|
|
@ResponseBody
|
|
|
public Map<String, Object> chartData(String leakagePoint, String sn, String dataType, Date startDate, Date endDate) {
|
|
|
List<MesProductHf> records = findRecords(sn, startDate, endDate, dataType);
|
|
|
- Map<String, Integer> pointCounts = new HashMap<>();
|
|
|
- for (MesProductHf record : records) {
|
|
|
- if (StringUtils.isBlank(record.getHfFlag())) continue;
|
|
|
- for (String item : record.getHfFlag().split(",")) {
|
|
|
- String point = normalizeLeakPoint(item);
|
|
|
- if (StringUtils.isNotBlank(point)) pointCounts.put(point, pointCounts.getOrDefault(point, 0) + 1);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
+ Map<String, Object> qualityData = buildQualityData(records, startDate, endDate, dataType);
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ List<Map<String, Object>> occurrences = (List<Map<String, Object>>) qualityData.remove("defectOccurrences");
|
|
|
List<Map<String, Object>> points = new ArrayList<>();
|
|
|
- for (Map.Entry<String, Integer> entry : pointCounts.entrySet()) {
|
|
|
+ Map<String, Integer> pointCounts = new LinkedHashMap<>();
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ List<Map<String, Object>> defectCategories = (List<Map<String, Object>>) qualityData.get("defectCategories");
|
|
|
+ for (Map<String, Object> category : defectCategories) {
|
|
|
+ String point = (String) category.get("label");
|
|
|
+ Integer count = (Integer) category.get("count");
|
|
|
+ if ("找不到漏点".equals(point) && count == 0) continue;
|
|
|
Map<String, Object> row = new LinkedHashMap<>();
|
|
|
- row.put("point", entry.getKey());
|
|
|
- row.put("count", entry.getValue());
|
|
|
+ row.put("point", point);
|
|
|
+ row.put("count", count);
|
|
|
points.add(row);
|
|
|
+ pointCounts.put(point, count);
|
|
|
}
|
|
|
- points.sort((a, b) -> Integer.compare((Integer) b.get("count"), (Integer) a.get("count")));
|
|
|
String selectedPoint = StringUtils.isNotBlank(leakagePoint) ? leakagePoint.trim()
|
|
|
: (points.isEmpty() ? "" : (String) points.get(0).get("point"));
|
|
|
|
|
|
Map<String, MesProductLeakagePointStat> detailsBySn = new LinkedHashMap<>();
|
|
|
Map<String, Integer> dailyCounts = new LinkedHashMap<>();
|
|
|
SimpleDateFormat dayFormat = new SimpleDateFormat("MM-dd");
|
|
|
- for (MesProductHf record : records) {
|
|
|
- if (StringUtils.isBlank(record.getSn()) || StringUtils.isBlank(record.getHfFlag())) continue;
|
|
|
- boolean containsSelectedPoint = false;
|
|
|
- for (String item : record.getHfFlag().split(",")) {
|
|
|
- if (selectedPoint.equals(normalizeLeakPoint(item))) {
|
|
|
- containsSelectedPoint = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (!containsSelectedPoint) continue;
|
|
|
- MesProductLeakagePointStat detail = detailsBySn.get(record.getSn());
|
|
|
+ for (Map<String, Object> occurrence : occurrences) {
|
|
|
+ if (!selectedPoint.equals(occurrence.get("point"))) continue;
|
|
|
+ String occurrenceSn = (String) occurrence.get("sn");
|
|
|
+ if (StringUtils.isBlank(occurrenceSn)) continue;
|
|
|
+ Date occurrenceTime = (Date) occurrence.get("time");
|
|
|
+ MesProductLeakagePointStat detail = detailsBySn.get(occurrenceSn);
|
|
|
if (detail == null) {
|
|
|
detail = new MesProductLeakagePointStat();
|
|
|
detail.setLeakagePoint(selectedPoint);
|
|
|
- detail.setSn(record.getSn());
|
|
|
- detail.setFirstOccurrenceTime(record.getCreateDate());
|
|
|
- detailsBySn.put(record.getSn(), detail);
|
|
|
+ detail.setSn(occurrenceSn);
|
|
|
+ detail.setFirstOccurrenceTime(occurrenceTime);
|
|
|
+ detailsBySn.put(occurrenceSn, detail);
|
|
|
}
|
|
|
detail.setOccurrenceCount(detail.getOccurrenceCount() + 1);
|
|
|
- if (record.getCreateDate() != null && (detail.getFirstOccurrenceTime() == null || record.getCreateDate().before(detail.getFirstOccurrenceTime()))) {
|
|
|
- detail.setFirstOccurrenceTime(record.getCreateDate());
|
|
|
+ if (occurrenceTime != null && (detail.getFirstOccurrenceTime() == null || occurrenceTime.before(detail.getFirstOccurrenceTime()))) {
|
|
|
+ detail.setFirstOccurrenceTime(occurrenceTime);
|
|
|
}
|
|
|
- if (record.getCreateDate() != null && (detail.getLastOccurrenceTime() == null || record.getCreateDate().after(detail.getLastOccurrenceTime()))) {
|
|
|
- detail.setLastOccurrenceTime(record.getCreateDate());
|
|
|
+ if (occurrenceTime != null && (detail.getLastOccurrenceTime() == null || occurrenceTime.after(detail.getLastOccurrenceTime()))) {
|
|
|
+ detail.setLastOccurrenceTime(occurrenceTime);
|
|
|
}
|
|
|
- if (record.getCreateDate() != null) {
|
|
|
- String day = dayFormat.format(record.getCreateDate());
|
|
|
+ if (occurrenceTime != null) {
|
|
|
+ String day = dayFormat.format(occurrenceTime);
|
|
|
dailyCounts.put(day, dailyCounts.getOrDefault(day, 0) + 1);
|
|
|
}
|
|
|
}
|
|
|
@@ -165,7 +162,7 @@ public class MesProductLeakagePointStatController extends BaseController {
|
|
|
result.put("trend", trend);
|
|
|
result.put("totalCount", pointCounts.getOrDefault(selectedPoint, 0));
|
|
|
result.put("workpieceCount", details.size());
|
|
|
- result.putAll(buildQualityData(records, startDate, endDate, dataType));
|
|
|
+ result.putAll(qualityData);
|
|
|
result.put("rawRecordCount", result.get("qualityTotal"));
|
|
|
return result;
|
|
|
}
|
|
|
@@ -178,28 +175,34 @@ public class MesProductLeakagePointStatController extends BaseController {
|
|
|
int defective = 0;
|
|
|
int noPoint = 0;
|
|
|
Map<String, Integer> pointCounts = new LinkedHashMap<>();
|
|
|
+ List<Map<String, Object>> occurrences = new ArrayList<>();
|
|
|
+ Map<String, Set<String>> leakagePointsByProduct = buildLeakagePointsByProduct(hfRecords);
|
|
|
for (MesProductQm record : mesProductQmService.findList(query)) {
|
|
|
if (!matchesDataType(record.getOprno(), dataType)) continue;
|
|
|
if ("OK".equalsIgnoreCase(record.getTestResult())) qualified++;
|
|
|
- else { defective++; noPoint++; }
|
|
|
+ else {
|
|
|
+ defective++;
|
|
|
+ Set<String> points = leakagePointsByProduct.get(leakagePointKey(record.getComponentNum(), record.getOprno()));
|
|
|
+ if (!addLeakagePoints(points, pointCounts)) noPoint++;
|
|
|
+ else addDefectOccurrences(occurrences, record.getComponentNum(), record.getTestTime(), points);
|
|
|
+ }
|
|
|
}
|
|
|
for (MesProductRecord record : findProductRecords(startDate, endDate)) {
|
|
|
if (!matchesDataType(record.getOprno(), dataType)) continue;
|
|
|
if ("OK".equalsIgnoreCase(record.getContent())) qualified++;
|
|
|
- else { defective++; noPoint++; }
|
|
|
+ else {
|
|
|
+ defective++;
|
|
|
+ Set<String> points = leakagePointsByProduct.get(leakagePointKey(record.getSn(), record.getOprno()));
|
|
|
+ if (!addLeakagePoints(points, pointCounts)) noPoint++;
|
|
|
+ else addDefectOccurrences(occurrences, record.getSn(), record.getUpdateDate(), points);
|
|
|
+ }
|
|
|
}
|
|
|
for (MesProductHf record : hfRecords) {
|
|
|
if ("OK".equalsIgnoreCase(record.getResult())) { qualified++; continue; }
|
|
|
defective++;
|
|
|
- boolean found = false;
|
|
|
- for (String item : (record.getHfFlag() == null ? "" : record.getHfFlag()).split(",")) {
|
|
|
- String point = normalizeLeakPoint(item);
|
|
|
- if (StringUtils.isNotBlank(point)) {
|
|
|
- found = true;
|
|
|
- pointCounts.put(point, pointCounts.getOrDefault(point, 0) + 1);
|
|
|
- }
|
|
|
- }
|
|
|
- if (!found) noPoint++;
|
|
|
+ Set<String> points = parseLeakagePoints(record.getHfFlag());
|
|
|
+ if (!addLeakagePoints(points, pointCounts)) noPoint++;
|
|
|
+ else addDefectOccurrences(occurrences, record.getSn(), record.getCreateDate(), points);
|
|
|
}
|
|
|
List<Map<String, Object>> quality = new ArrayList<>();
|
|
|
Map<String, Object> ok = new LinkedHashMap<>(); ok.put("label", "合格数量"); ok.put("count", qualified); ok.put("color", "#2b8c70"); quality.add(ok);
|
|
|
@@ -216,9 +219,50 @@ public class MesProductLeakagePointStatController extends BaseController {
|
|
|
Map<String, Object> result = new LinkedHashMap<>();
|
|
|
result.put("qualifiedCount", qualified); result.put("defectiveCount", defective); result.put("noPointCount", noPoint);
|
|
|
result.put("qualityCategories", quality); result.put("defectCategories", defects); result.put("qualityTotal", qualified + defective);
|
|
|
+ result.put("defectOccurrences", occurrences);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+ /** Matches the leakage-point enrichment used by the gas-tightness record page. */
|
|
|
+ private Map<String, Set<String>> buildLeakagePointsByProduct(List<MesProductHf> records) {
|
|
|
+ Map<String, Set<String>> pointsByProduct = new HashMap<>();
|
|
|
+ for (MesProductHf record : records) {
|
|
|
+ Set<String> points = pointsByProduct.computeIfAbsent(
|
|
|
+ leakagePointKey(record.getSn(), record.getOprno()), key -> new LinkedHashSet<>());
|
|
|
+ points.addAll(parseLeakagePoints(record.getHfFlag()));
|
|
|
+ }
|
|
|
+ return pointsByProduct;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean addLeakagePoints(Set<String> points, Map<String, Integer> pointCounts) {
|
|
|
+ if (points == null || points.isEmpty()) return false;
|
|
|
+ for (String point : points) pointCounts.put(point, pointCounts.getOrDefault(point, 0) + 1);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Set<String> parseLeakagePoints(String value) {
|
|
|
+ Set<String> points = new LinkedHashSet<>();
|
|
|
+ for (String item : (value == null ? "" : value).split(",")) {
|
|
|
+ String point = normalizeLeakPoint(item);
|
|
|
+ if (StringUtils.isNotBlank(point)) points.add(point);
|
|
|
+ }
|
|
|
+ return points;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void addDefectOccurrences(List<Map<String, Object>> occurrences, String sn, Date time, Set<String> points) {
|
|
|
+ for (String point : points) {
|
|
|
+ Map<String, Object> occurrence = new LinkedHashMap<>();
|
|
|
+ occurrence.put("point", point);
|
|
|
+ occurrence.put("sn", sn);
|
|
|
+ occurrence.put("time", time);
|
|
|
+ occurrences.add(occurrence);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String leakagePointKey(String sn, String oprno) {
|
|
|
+ return StringUtils.defaultString(sn) + "|" + StringUtils.defaultString(oprno);
|
|
|
+ }
|
|
|
+
|
|
|
/** Overall air-tightness results from INSP030A/B are stored in the production-record table. */
|
|
|
private List<MesProductRecord> findProductRecords(Date startDate, Date endDate) {
|
|
|
MesProductRecord query = new MesProductRecord();
|