feat(qms): 新增PQC工单分派及详情查看功能
- 增加接口支持发起PQC工单,更新工单状态为处理中并分配处理人推送待办 - 实现按处理人分组合并不合格项并创建处理记录及待办消息 - 新增查询本人相关PQC工单详情接口,仅返回本人相关处理记录和措施 - 完善PQC工单处理流程,支持处理人提交审批及措施填写校验 - 添加PQC工单结束处理判断,最后一人提交时更新工单状态为已完成 - 新增文件及措施信息的解析和转换辅助方法,丰富详情数据展示 - 新增PQC任务及任务详情相关实体、接口及实现,支持任务管理功能 - 新增PQC任务相关Controller接口,包括查询、暂存和提交功能 - 优化PQC工单流程中的权限校验和异常处理,保障业务流程合理性
This commit is contained in:
parent
4f78cbe83b
commit
3b782f471f
|
|
@ -46,6 +46,22 @@ public class QmsReportController extends BaseController {
|
|||
return ApiResult.success(reportControllerService.getTicketReport(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* PQC报表数据
|
||||
*/
|
||||
@PostMapping("pqc")
|
||||
public ApiResult<QmsPqcReportVO> getPqcReport(@Valid @RequestBody QmsReportQueryQO request) {
|
||||
return ApiResult.success(reportControllerService.getPqcReport(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* PQC待复核统计数据
|
||||
*/
|
||||
@PostMapping("pqc/pending-review")
|
||||
public ApiResult<QmsPqcPendingReviewVO> getPqcPendingReviewStats() {
|
||||
return ApiResult.success(reportControllerService.getPqcPendingReviewStats());
|
||||
}
|
||||
|
||||
/**
|
||||
* IQC超时统计数据
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1428,4 +1428,439 @@ public class QmsReportControllerService {
|
|||
double avgHours = totalHours / durations.size();
|
||||
return String.format("%.2f小时", avgHours);
|
||||
}
|
||||
|
||||
// ===== PQC报表 =====
|
||||
|
||||
@Resource
|
||||
private IQmsPqcTaskRecordService pqcTaskRecordService;
|
||||
|
||||
@Resource
|
||||
private IQmsPqcInspectionPointService pqcInspectionPointService;
|
||||
|
||||
/**
|
||||
* PQC报表数据
|
||||
*/
|
||||
public QmsPqcReportVO getPqcReport(QmsReportQueryQO request) {
|
||||
QmsPqcReportVO vo = new QmsPqcReportVO();
|
||||
|
||||
// 计算时间范围
|
||||
LocalDateTime currentStart = request.getStartTime();
|
||||
LocalDateTime currentEnd = request.getEndTime();
|
||||
boolean hasTimeRange = currentStart != null || currentEnd != null;
|
||||
|
||||
if (!hasTimeRange) {
|
||||
currentStart = LocalDateTime.now().minusYears(1);
|
||||
currentEnd = LocalDateTime.now();
|
||||
} else {
|
||||
if (currentStart == null) currentStart = LocalDateTime.now().minusYears(1);
|
||||
if (currentEnd == null) currentEnd = LocalDateTime.now();
|
||||
}
|
||||
|
||||
// 计算上周期
|
||||
long daysBetween = java.time.temporal.ChronoUnit.DAYS.between(currentStart, currentEnd);
|
||||
LocalDateTime previousStart = currentStart.minusDays(daysBetween);
|
||||
LocalDateTime previousEnd = currentStart;
|
||||
|
||||
// 1. 总工单数
|
||||
Long currentTotal = pqcTaskRecordService.lambdaQuery()
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, currentStart)
|
||||
.le(QmsPqcTaskRecord::getCreateTime, currentEnd)
|
||||
.count();
|
||||
Long previousTotal = pqcTaskRecordService.lambdaQuery()
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, previousStart)
|
||||
.lt(QmsPqcTaskRecord::getCreateTime, previousEnd)
|
||||
.count();
|
||||
|
||||
vo.setTotalTickets(currentTotal.intValue());
|
||||
vo.setTotalChange((int) (currentTotal - previousTotal));
|
||||
vo.setTotalChangeRate(calculateChangeRate(currentTotal, previousTotal));
|
||||
|
||||
// 2. 已完成数(状态=3)
|
||||
Long currentCompleted = pqcTaskRecordService.lambdaQuery()
|
||||
.eq(QmsPqcTaskRecord::getStatus, (short) 3)
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, currentStart)
|
||||
.le(QmsPqcTaskRecord::getCreateTime, currentEnd)
|
||||
.count();
|
||||
Long previousCompleted = pqcTaskRecordService.lambdaQuery()
|
||||
.eq(QmsPqcTaskRecord::getStatus, (short) 3)
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, previousStart)
|
||||
.lt(QmsPqcTaskRecord::getCreateTime, previousEnd)
|
||||
.count();
|
||||
|
||||
vo.setCompletedTickets(currentCompleted.intValue());
|
||||
double currentCompletionRate = currentTotal > 0 ? (currentCompleted * 100.0 / currentTotal) : 0;
|
||||
double previousCompletionRate = previousTotal > 0 ? (previousCompleted * 100.0 / previousTotal) : 0;
|
||||
vo.setCompletionRate(String.format("%.2f%%", currentCompletionRate));
|
||||
vo.setCompletionRateChange(calculateChangeRate(currentCompletionRate, previousCompletionRate));
|
||||
|
||||
// 3. 待处理数(状态≠3)
|
||||
vo.setPendingTickets((int) (currentTotal - currentCompleted));
|
||||
|
||||
// 4. 平均耗时
|
||||
String avgTime = calculatePqcAvgProcessingTime(currentStart, currentEnd);
|
||||
String previousAvgTime = calculatePqcAvgProcessingTime(previousStart, previousEnd);
|
||||
vo.setAvgProcessingTime(avgTime);
|
||||
|
||||
// 解析平均耗时(小时)用于计算增减率
|
||||
double currentAvgHours = parseHoursFromTimeStr(avgTime);
|
||||
double previousAvgHours = parseHoursFromTimeStr(previousAvgTime);
|
||||
vo.setAvgTimeChangeRate(calculateChangeRate(currentAvgHours, previousAvgHours));
|
||||
|
||||
// 5. 一次合格率(无关联任务)
|
||||
calculateFirstPassRate(vo, currentStart, currentEnd, previousStart, previousEnd);
|
||||
|
||||
// 6. 人效统计
|
||||
vo.setEfficiencyStats(calculateEfficiencyStats(currentStart, currentEnd));
|
||||
|
||||
// 7. 步装合格率
|
||||
vo.setStepAssemblyRates(calculateStepAssemblyRates(currentStart, currentEnd));
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算一次合格率
|
||||
*/
|
||||
private void calculateFirstPassRate(QmsPqcReportVO vo, LocalDateTime currentStart, LocalDateTime currentEnd,
|
||||
LocalDateTime previousStart, LocalDateTime previousEnd) {
|
||||
// 当前周期
|
||||
Long currentTotalNoRelated = pqcTaskRecordService.lambdaQuery()
|
||||
.isNull(QmsPqcTaskRecord::getRelatedTaskId)
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, currentStart)
|
||||
.le(QmsPqcTaskRecord::getCreateTime, currentEnd)
|
||||
.count();
|
||||
Long currentPassed = pqcTaskRecordService.lambdaQuery()
|
||||
.isNull(QmsPqcTaskRecord::getRelatedTaskId)
|
||||
.eq(QmsPqcTaskRecord::getEnable, true)
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, currentStart)
|
||||
.le(QmsPqcTaskRecord::getCreateTime, currentEnd)
|
||||
.count();
|
||||
|
||||
double currentRate = currentTotalNoRelated > 0 ? (currentPassed * 100.0 / currentTotalNoRelated) : 0;
|
||||
|
||||
// 上周期
|
||||
Long previousTotalNoRelated = pqcTaskRecordService.lambdaQuery()
|
||||
.isNull(QmsPqcTaskRecord::getRelatedTaskId)
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, previousStart)
|
||||
.lt(QmsPqcTaskRecord::getCreateTime, previousEnd)
|
||||
.count();
|
||||
Long previousPassed = pqcTaskRecordService.lambdaQuery()
|
||||
.isNull(QmsPqcTaskRecord::getRelatedTaskId)
|
||||
.eq(QmsPqcTaskRecord::getEnable, true)
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, previousStart)
|
||||
.lt(QmsPqcTaskRecord::getCreateTime, previousEnd)
|
||||
.count();
|
||||
|
||||
double previousRate = previousTotalNoRelated > 0 ? (previousPassed * 100.0 / previousTotalNoRelated) : 0;
|
||||
|
||||
vo.setFirstPassRate(String.format("%.2f%%", currentRate));
|
||||
vo.setFirstPassRateChange(calculateChangeRate(currentRate, previousRate));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算人效统计
|
||||
*/
|
||||
private List<QmsPqcReportVO.EfficiencyVO> calculateEfficiencyStats(LocalDateTime start, LocalDateTime end) {
|
||||
// 查询所有无关联任务
|
||||
List<QmsPqcTaskRecord> tasks = pqcTaskRecordService.lambdaQuery()
|
||||
.isNull(QmsPqcTaskRecord::getRelatedTaskId)
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, start)
|
||||
.le(QmsPqcTaskRecord::getCreateTime, end)
|
||||
.list();
|
||||
|
||||
if (tasks.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 按自检人分组统计
|
||||
Map<Long, List<QmsPqcTaskRecord>> groupByTester = tasks.stream()
|
||||
.filter(t -> t.getSelfTesterId() != null)
|
||||
.collect(Collectors.groupingBy(QmsPqcTaskRecord::getSelfTesterId));
|
||||
|
||||
List<QmsPqcReportVO.EfficiencyVO> stats = new ArrayList<>();
|
||||
for (Map.Entry<Long, List<QmsPqcTaskRecord>> entry : groupByTester.entrySet()) {
|
||||
Long testerId = entry.getKey();
|
||||
List<QmsPqcTaskRecord> testerTasks = entry.getValue();
|
||||
|
||||
long totalTasks = testerTasks.size();
|
||||
long passedTasks = testerTasks.stream().filter(QmsPqcTaskRecord::getEnable).count();
|
||||
double passRate = totalTasks > 0 ? (passedTasks * 100.0 / totalTasks) : 0;
|
||||
|
||||
QmsPqcReportVO.EfficiencyVO efficiencyVO = new QmsPqcReportVO.EfficiencyVO();
|
||||
efficiencyVO.setSelfTesterId(testerId);
|
||||
efficiencyVO.setSelfTesterName(testerTasks.get(0).getSelfTesterName());
|
||||
efficiencyVO.setPassRate(String.format("%.2f%%", passRate));
|
||||
stats.add(efficiencyVO);
|
||||
}
|
||||
|
||||
// 按合格率降序
|
||||
stats.sort((a, b) -> Double.compare(
|
||||
Double.parseDouble(b.getPassRate().replace("%", "")),
|
||||
Double.parseDouble(a.getPassRate().replace("%", ""))
|
||||
));
|
||||
|
||||
// 截取前10+后10
|
||||
if (stats.size() > 20) {
|
||||
List<QmsPqcReportVO.EfficiencyVO> result = new ArrayList<>();
|
||||
result.addAll(stats.subList(0, 10)); // 前10
|
||||
result.addAll(stats.subList(stats.size() - 10, stats.size())); // 后10
|
||||
return result;
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算步装合格率
|
||||
*/
|
||||
private List<QmsPqcReportVO.StepAssemblyRateVO> calculateStepAssemblyRates(LocalDateTime start, LocalDateTime end) {
|
||||
// 查询所有无关联任务
|
||||
List<QmsPqcTaskRecord> tasks = pqcTaskRecordService.lambdaQuery()
|
||||
.isNull(QmsPqcTaskRecord::getRelatedTaskId)
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, start)
|
||||
.le(QmsPqcTaskRecord::getCreateTime, end)
|
||||
.list();
|
||||
|
||||
if (tasks.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 批量查询检查点信息获取步装名
|
||||
Set<Long> pointIds = tasks.stream()
|
||||
.map(QmsPqcTaskRecord::getInspectionPointId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Map<Long, String> pointStepNameMap = new HashMap<>();
|
||||
if (!pointIds.isEmpty()) {
|
||||
List<QmsPqcInspectionPoint> points = pqcInspectionPointService.listByIds(pointIds);
|
||||
pointStepNameMap = points.stream()
|
||||
.filter(p -> p.getStepName() != null)
|
||||
.collect(Collectors.toMap(QmsPqcInspectionPoint::getId, QmsPqcInspectionPoint::getStepName));
|
||||
}
|
||||
|
||||
// 按 步装+机型 分组
|
||||
Map<String, Map<String, List<QmsPqcTaskRecord>>> groupByStepAndModel = new LinkedHashMap<>();
|
||||
for (QmsPqcTaskRecord task : tasks) {
|
||||
String stepName = pointStepNameMap.get(task.getInspectionPointId());
|
||||
if (stepName == null) continue;
|
||||
|
||||
String modelNo = task.getModelNo();
|
||||
if (modelNo == null) continue;
|
||||
|
||||
groupByStepAndModel.computeIfAbsent(stepName, k -> new LinkedHashMap<>())
|
||||
.computeIfAbsent(modelNo, k -> new ArrayList<>())
|
||||
.add(task);
|
||||
}
|
||||
|
||||
List<QmsPqcReportVO.StepAssemblyRateVO> result = new ArrayList<>();
|
||||
for (Map.Entry<String, Map<String, List<QmsPqcTaskRecord>>> stepEntry : groupByStepAndModel.entrySet()) {
|
||||
String stepName = stepEntry.getKey();
|
||||
Map<String, List<QmsPqcTaskRecord>> modelMap = stepEntry.getValue();
|
||||
|
||||
List<QmsPqcReportVO.StepAssemblyRateVO.ModelRateVO> modelRates = new ArrayList<>();
|
||||
for (Map.Entry<String, List<QmsPqcTaskRecord>> modelEntry : modelMap.entrySet()) {
|
||||
String modelNo = modelEntry.getKey();
|
||||
List<QmsPqcTaskRecord> modelTasks = modelEntry.getValue();
|
||||
|
||||
long totalCheckpoints = modelTasks.size();
|
||||
long passedCheckpoints = modelTasks.stream().filter(QmsPqcTaskRecord::getEnable).count();
|
||||
double passRate = totalCheckpoints > 0 ? (passedCheckpoints * 100.0 / totalCheckpoints) : 0;
|
||||
|
||||
QmsPqcReportVO.StepAssemblyRateVO.ModelRateVO modelRateVO = new QmsPqcReportVO.StepAssemblyRateVO.ModelRateVO();
|
||||
modelRateVO.setModelNo(modelNo);
|
||||
modelRateVO.setPassRate(String.format("%.2f%%", passRate));
|
||||
modelRates.add(modelRateVO);
|
||||
}
|
||||
|
||||
// 按合格率降序
|
||||
modelRates.sort((a, b) -> Double.compare(
|
||||
Double.parseDouble(b.getPassRate().replace("%", "")),
|
||||
Double.parseDouble(a.getPassRate().replace("%", ""))
|
||||
));
|
||||
|
||||
// 截取前5+后5
|
||||
List<QmsPqcReportVO.StepAssemblyRateVO.ModelRateVO> finalModelRates;
|
||||
if (modelRates.size() > 10) {
|
||||
finalModelRates = new ArrayList<>();
|
||||
finalModelRates.addAll(modelRates.subList(0, 5));
|
||||
finalModelRates.addAll(modelRates.subList(modelRates.size() - 5, modelRates.size()));
|
||||
} else {
|
||||
finalModelRates = modelRates;
|
||||
}
|
||||
|
||||
QmsPqcReportVO.StepAssemblyRateVO stepVO = new QmsPqcReportVO.StepAssemblyRateVO();
|
||||
stepVO.setStepAssemblyName(stepName);
|
||||
stepVO.setModelRates(finalModelRates);
|
||||
result.add(stepVO);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算PQC平均处理时间
|
||||
*/
|
||||
private String calculatePqcAvgProcessingTime(LocalDateTime start, LocalDateTime end) {
|
||||
List<QmsPqcTaskRecord> completedTasks = pqcTaskRecordService.lambdaQuery()
|
||||
.eq(QmsPqcTaskRecord::getStatus, (short) 3)
|
||||
.isNotNull(QmsPqcTaskRecord::getCompleteTime)
|
||||
.ge(QmsPqcTaskRecord::getCreateTime, start)
|
||||
.le(QmsPqcTaskRecord::getCreateTime, end)
|
||||
.list();
|
||||
|
||||
if (completedTasks.isEmpty()) {
|
||||
return "0小时";
|
||||
}
|
||||
|
||||
double totalHours = 0;
|
||||
for (QmsPqcTaskRecord task : completedTasks) {
|
||||
if (task.getCompleteTime() != null && task.getCreateTime() != null) {
|
||||
long seconds = java.time.temporal.ChronoUnit.SECONDS.between(task.getCreateTime(), task.getCompleteTime());
|
||||
totalHours += seconds / 3600.0;
|
||||
}
|
||||
}
|
||||
|
||||
double avgHours = totalHours / completedTasks.size();
|
||||
return formatHoursToDaysAndHours(avgHours);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化小时为xx天xx小时
|
||||
*/
|
||||
private String formatHoursToDaysAndHours(double hours) {
|
||||
long days = (long) (hours / 24);
|
||||
long remainingHours = Math.round(hours % 24);
|
||||
|
||||
if (days > 0) {
|
||||
return days + "天" + remainingHours + "小时";
|
||||
} else {
|
||||
return remainingHours + "小时";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从时间字符串解析小时数
|
||||
*/
|
||||
private double parseHoursFromTimeStr(String timeStr) {
|
||||
if (timeStr == null || timeStr.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
if (timeStr.contains("天")) {
|
||||
String[] parts = timeStr.replace("小时", "").split("天");
|
||||
long days = Long.parseLong(parts[0]);
|
||||
long hours = parts.length > 1 ? Long.parseLong(parts[1]) : 0;
|
||||
return days * 24 + hours;
|
||||
} else {
|
||||
return Double.parseDouble(timeStr.replace("小时", ""));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算增减率
|
||||
*/
|
||||
private String calculateChangeRate(double current, double previous) {
|
||||
if (previous == 0) {
|
||||
if (current == 0) {
|
||||
return "0.00%";
|
||||
} else {
|
||||
return "新增";
|
||||
}
|
||||
}
|
||||
|
||||
double rate = ((current - previous) / previous) * 100;
|
||||
return String.format("%.2f%%", rate);
|
||||
}
|
||||
|
||||
// ===== PQC待复核统计 =====
|
||||
|
||||
/**
|
||||
* PQC待复核统计数据
|
||||
*/
|
||||
public QmsPqcPendingReviewVO getPqcPendingReviewStats() {
|
||||
QmsPqcPendingReviewVO vo = new QmsPqcPendingReviewVO();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 1. 查询待复核任务(状态=1)
|
||||
List<QmsPqcTaskRecord> pendingTasks = pqcTaskRecordService.lambdaQuery()
|
||||
.eq(QmsPqcTaskRecord::getStatus, (short) 1)
|
||||
.orderByDesc(QmsPqcTaskRecord::getCreateTime)
|
||||
.list();
|
||||
|
||||
// 2. 待复核任务总数
|
||||
vo.setTotalCount(pendingTasks.size());
|
||||
|
||||
if (pendingTasks.isEmpty()) {
|
||||
vo.setAvgWaitTime("0小时");
|
||||
vo.setTasks(new ArrayList<>());
|
||||
return vo;
|
||||
}
|
||||
|
||||
// 3. 计算平均等待时间
|
||||
long totalWaitSeconds = 0;
|
||||
List<QmsPqcPendingReviewVO.PendingReviewTaskVO> taskVOs = new ArrayList<>();
|
||||
|
||||
for (QmsPqcTaskRecord task : pendingTasks) {
|
||||
// 自检提交时间使用 complete_time
|
||||
LocalDateTime submitTime = task.getCompleteTime();
|
||||
if (submitTime == null) {
|
||||
submitTime = task.getCreateTime();
|
||||
}
|
||||
|
||||
long waitSeconds = java.time.temporal.ChronoUnit.SECONDS.between(submitTime, now);
|
||||
totalWaitSeconds += waitSeconds;
|
||||
|
||||
// 构建任务VO
|
||||
QmsPqcPendingReviewVO.PendingReviewTaskVO taskVO = new QmsPqcPendingReviewVO.PendingReviewTaskVO();
|
||||
taskVO.setTaskId(task.getId());
|
||||
taskVO.setTaskNo(task.getTaskNo());
|
||||
taskVO.setAufnr(task.getAufnr());
|
||||
taskVO.setModelNo(task.getModelNo());
|
||||
taskVO.setNo(task.getNo());
|
||||
taskVO.setSelfTestSubmitTime(submitTime);
|
||||
taskVO.setWaitTime(formatSecondsToDaysAndHours(waitSeconds));
|
||||
taskVOs.add(taskVO);
|
||||
}
|
||||
|
||||
// 平均等待时间(秒)
|
||||
long avgWaitSeconds = totalWaitSeconds / pendingTasks.size();
|
||||
vo.setAvgWaitTime(formatSecondsToDaysAndHoursWithDecimal(avgWaitSeconds));
|
||||
vo.setTasks(taskVOs);
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化秒为xx天xx小时(小时保留两位小数)
|
||||
* 例如:15分钟 = 900秒 = 0.25小时
|
||||
*/
|
||||
private String formatSecondsToDaysAndHoursWithDecimal(long seconds) {
|
||||
long days = seconds / 86400; // 86400秒 = 1天
|
||||
double remainingHours = (seconds % 86400) / 3600.0;
|
||||
|
||||
if (days > 0) {
|
||||
return days + "天" + String.format("%.2f", remainingHours) + "小时";
|
||||
} else {
|
||||
return String.format("%.2f", remainingHours) + "小时";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化秒为xx天xx小时(用于单个任务)
|
||||
*/
|
||||
private String formatSecondsToDaysAndHours(long seconds) {
|
||||
long days = seconds / 86400;
|
||||
double remainingHours = (seconds % 86400) / 3600.0;
|
||||
|
||||
if (days > 0) {
|
||||
return days + "天" + String.format("%.2f", remainingHours) + "小时";
|
||||
} else {
|
||||
return String.format("%.2f", remainingHours) + "小时";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
package com.nflg.wms.common.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PQC待复核统计VO
|
||||
*/
|
||||
@Data
|
||||
public class QmsPqcPendingReviewVO {
|
||||
|
||||
/**
|
||||
* 待复核任务总数
|
||||
*/
|
||||
private Integer totalCount;
|
||||
|
||||
/**
|
||||
* 平均等待时间(格式:xx天xx.xx小时)
|
||||
*/
|
||||
private String avgWaitTime;
|
||||
|
||||
/**
|
||||
* 待复核任务列表
|
||||
*/
|
||||
private List<PendingReviewTaskVO> tasks;
|
||||
|
||||
/**
|
||||
* 待复核任务
|
||||
*/
|
||||
@Data
|
||||
public static class PendingReviewTaskVO {
|
||||
/**
|
||||
* 任务ID
|
||||
*/
|
||||
private Long taskId;
|
||||
|
||||
/**
|
||||
* 任务编号
|
||||
*/
|
||||
private String taskNo;
|
||||
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
private String aufnr;
|
||||
|
||||
/**
|
||||
* 机型编号
|
||||
*/
|
||||
private String modelNo;
|
||||
|
||||
/**
|
||||
* 机台编号
|
||||
*/
|
||||
private String no;
|
||||
|
||||
/**
|
||||
* 自检提交时间
|
||||
*/
|
||||
private LocalDateTime selfTestSubmitTime;
|
||||
|
||||
/**
|
||||
* 等待时长(格式:xx天xx.xx小时)
|
||||
*/
|
||||
private String waitTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package com.nflg.wms.common.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PQC报表VO
|
||||
*/
|
||||
@Data
|
||||
public class QmsPqcReportVO {
|
||||
|
||||
// ===== 总体统计 =====
|
||||
|
||||
/**
|
||||
* 总工单数
|
||||
*/
|
||||
private Integer totalTickets;
|
||||
|
||||
/**
|
||||
* 较上周期增减数
|
||||
*/
|
||||
private Integer totalChange;
|
||||
|
||||
/**
|
||||
* 较上周期增减率
|
||||
*/
|
||||
private String totalChangeRate;
|
||||
|
||||
/**
|
||||
* 已完成数(状态=3)
|
||||
*/
|
||||
private Integer completedTickets;
|
||||
|
||||
/**
|
||||
* 完成率
|
||||
*/
|
||||
private String completionRate;
|
||||
|
||||
/**
|
||||
* 完成率较上周期增减率
|
||||
*/
|
||||
private String completionRateChange;
|
||||
|
||||
/**
|
||||
* 待处理数(状态≠3)
|
||||
*/
|
||||
private Integer pendingTickets;
|
||||
|
||||
/**
|
||||
* 平均耗时(格式:xx天xx小时)
|
||||
*/
|
||||
private String avgProcessingTime;
|
||||
|
||||
/**
|
||||
* 平均耗时较上周期增减率
|
||||
*/
|
||||
private String avgTimeChangeRate;
|
||||
|
||||
/**
|
||||
* 一次合格率
|
||||
*/
|
||||
private String firstPassRate;
|
||||
|
||||
/**
|
||||
* 一次合格率较上周期增减率
|
||||
*/
|
||||
private String firstPassRateChange;
|
||||
|
||||
// ===== 人效统计 =====
|
||||
|
||||
/**
|
||||
* 人效统计列表
|
||||
*/
|
||||
private List<EfficiencyVO> efficiencyStats;
|
||||
|
||||
// ===== 步装合格率 =====
|
||||
|
||||
/**
|
||||
* 步装合格率列表
|
||||
*/
|
||||
private List<StepAssemblyRateVO> stepAssemblyRates;
|
||||
|
||||
// ===== 嵌套类 =====
|
||||
|
||||
/**
|
||||
* 人效统计
|
||||
*/
|
||||
@Data
|
||||
public static class EfficiencyVO {
|
||||
/**
|
||||
* 自检人ID
|
||||
*/
|
||||
private Long selfTesterId;
|
||||
|
||||
/**
|
||||
* 自检人姓名
|
||||
*/
|
||||
private String selfTesterName;
|
||||
|
||||
/**
|
||||
* 合格率
|
||||
*/
|
||||
private String passRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 步装合格率
|
||||
*/
|
||||
@Data
|
||||
public static class StepAssemblyRateVO {
|
||||
/**
|
||||
* 步装名
|
||||
*/
|
||||
private String stepAssemblyName;
|
||||
|
||||
/**
|
||||
* 机型合格率列表(前5+后5)
|
||||
*/
|
||||
private List<ModelRateVO> modelRates;
|
||||
|
||||
/**
|
||||
* 机型合格率
|
||||
*/
|
||||
@Data
|
||||
public static class ModelRateVO {
|
||||
/**
|
||||
* 机型编号
|
||||
*/
|
||||
private String modelNo;
|
||||
|
||||
/**
|
||||
* 合格率
|
||||
*/
|
||||
private String passRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue