Merge branch 'qms/yf' into qms/develop

This commit is contained in:
funny 2026-04-29 11:18:38 +08:00
commit e60b389ffc
13 changed files with 407 additions and 5 deletions

View File

@ -1,8 +1,10 @@
package com.nflg.qms.admin.controller;
import com.nflg.qms.admin.service.QmsIssueTicketProcessControllerService;
import com.nflg.qms.admin.service.QmsIssueTicketProcessMeasureControllerService;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessAddQO;
import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessDraftQO;
import com.nflg.wms.starter.BaseController;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
@ -21,6 +23,9 @@ public class QmsIssueTicketProcessController extends BaseController {
@Resource
private QmsIssueTicketProcessControllerService issueTicketProcessControllerService;
@Resource
private QmsIssueTicketProcessMeasureControllerService issueTicketProcessMeasureControllerService;
/**
* 新增工单处理
*/
@ -29,4 +34,22 @@ public class QmsIssueTicketProcessController extends BaseController {
issueTicketProcessControllerService.add(request);
return ApiResult.success();
}
/**
* 暂存工单处理
*/
@PostMapping("draft")
public ApiResult<Void> draft(@Valid @RequestBody QmsIssueTicketProcessDraftQO request) {
issueTicketProcessMeasureControllerService.draft(request);
return ApiResult.success();
}
/**
* 提交工单处理
*/
@PostMapping("submit")
public ApiResult<Void> submit(@Valid @RequestBody QmsIssueTicketProcessDraftQO request) {
issueTicketProcessControllerService.submit(request);
return ApiResult.success();
}
}

View File

@ -7,8 +7,12 @@ import com.nflg.wms.common.pojo.qo.QmsPdiInspectionResultItemQO;
import com.nflg.wms.common.pojo.qo.QmsPdiInspectionResultsSearchQO;
import com.nflg.wms.common.pojo.qo.QmsPdiInspectionResultsSubmitQO;
import com.nflg.wms.common.pojo.qo.QmsPdiStatusItemsFillQO;
import com.nflg.wms.common.pojo.qo.QmsPdiTaskListQO;
import com.nflg.wms.common.pojo.qo.QmsPdiTaskRecordStatusItemDetailQO;
import com.nflg.wms.repository.entity.QmsPdiInspectionResults;
import com.nflg.wms.common.pojo.vo.QmsPdiInspectionResultsPageVO;
import com.nflg.wms.common.pojo.vo.QmsPdiTaskListVO;
import com.nflg.wms.common.pojo.vo.QmsPdiTaskRecordDetailVO;
import com.nflg.wms.starter.BaseController;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
@ -53,11 +57,30 @@ public class QmsPdiInspectionResultsController extends BaseController {
}
/**
* 分页查询以任务单为主体
* 分页查询以任务单为主体+ 状态统计
*/
@PostMapping("search")
public ApiResult<PageData<QmsPdiInspectionResultsPageVO>> search(
public ApiResult<QmsPdiTaskListVO> search(
@RequestBody QmsPdiInspectionResultsSearchQO request) {
return ApiResult.success(inspectionResultsControllerService.search(request));
}
/**
* 查询检查任务列表平板使用
* 仅支持 taskStatus 筛选分页返回
*/
@PostMapping("searchTaskList")
public ApiResult<PageData<QmsPdiInspectionResultsPageVO>> searchTaskList(@RequestBody QmsPdiTaskListQO request) {
return ApiResult.success(inspectionResultsControllerService.searchTaskList(request));
}
/**
* 检测项详情平板使用不分页
* 根据任务ID + 检测项类型返回对应检测结果及图片URL
*/
@PostMapping("detail")
public ApiResult<List<QmsPdiTaskRecordDetailVO.StatusItemVO>> detail(
@Valid @RequestBody QmsPdiTaskRecordStatusItemDetailQO request) {
return ApiResult.success(inspectionResultsControllerService.detail(request));
}
}

View File

@ -3,13 +3,16 @@ package com.nflg.qms.admin.service;
import com.nflg.wms.common.constant.STATE;
import com.nflg.wms.common.exception.NflgException;
import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessAddQO;
import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessDraftQO;
import com.nflg.wms.repository.entity.QmsIssueTicketProcess;
import com.nflg.wms.repository.entity.User;
import com.nflg.wms.repository.service.IQmsIssueTicketProcessService;
import com.nflg.wms.repository.service.IUserService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@ -26,6 +29,9 @@ public class QmsIssueTicketProcessControllerService {
@Resource
private IUserService userService;
@Resource
private QmsIssueTicketProcessMeasureControllerService issueTicketProcessMeasureControllerService;
/**
* 新增工单处理同步 Controller 直接调用
*/
@ -57,4 +63,13 @@ public class QmsIssueTicketProcessControllerService {
issueTicketProcessService.save(entity);
}
/**
* 提交工单处理更新工单处理记录有措施内容则新增一条措施记录
* TODO: 后续补充推送到下一级的逻辑
*/
@Transactional(rollbackFor = Exception.class)
public void submit(@Valid QmsIssueTicketProcessDraftQO request) {
issueTicketProcessMeasureControllerService.draft(request);
}
}

View File

@ -1,8 +1,18 @@
package com.nflg.qms.admin.service;
import cn.hutool.core.util.StrUtil;
import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessDraftQO;
import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.QmsIssueTicketProcess;
import com.nflg.wms.repository.entity.QmsIssueTicketProcessMeasure;
import com.nflg.wms.repository.service.IQmsIssueTicketProcessMeasureService;
import com.nflg.wms.repository.service.IQmsIssueTicketProcessService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Objects;
/**
* 质量问题工单处理解决措施 ControllerService
@ -12,4 +22,33 @@ public class QmsIssueTicketProcessMeasureControllerService {
@Resource
private IQmsIssueTicketProcessMeasureService issueTicketProcessMeasureService;
@Resource
private IQmsIssueTicketProcessService issueTicketProcessService;
/**
* 暂存工单处理更新工单处理记录有措施内容则新增一条措施记录
*/
@Transactional(rollbackFor = Exception.class)
public void draft(@Valid QmsIssueTicketProcessDraftQO request) {
// 校验工单处理记录存在
QmsIssueTicketProcess process = issueTicketProcessService.getById(request.getId());
VUtil.trueThrowBusinessError(Objects.isNull(process)).throwMessage("工单处理记录不存在");
// 更新工单处理记录
issueTicketProcessService.lambdaUpdate()
.eq(QmsIssueTicketProcess::getId, request.getId())
.set(request.getRootCause() != null, QmsIssueTicketProcess::getRootCause, request.getRootCause())
.set(request.getApprovalStatus() != null, QmsIssueTicketProcess::getApprovalStatus, request.getApprovalStatus())
.set(request.getApprovalOpinion() != null, QmsIssueTicketProcess::getApprovalOpinion, request.getApprovalOpinion())
.update();
// 有措施内容则新增一条措施记录
if (StrUtil.isNotBlank(request.getMeasureContent())) {
QmsIssueTicketProcessMeasure measure = new QmsIssueTicketProcessMeasure()
.setIssueTicketProcessId(request.getId())
.setMeasureContent(request.getMeasureContent());
issueTicketProcessMeasureService.save(measure);
}
}
}

View File

@ -8,7 +8,11 @@ import com.nflg.wms.common.pojo.qo.QmsPdiInspectionResultItemQO;
import com.nflg.wms.common.pojo.qo.QmsPdiInspectionResultsSearchQO;
import com.nflg.wms.common.pojo.qo.QmsPdiInspectionResultsSubmitQO;
import com.nflg.wms.common.pojo.qo.QmsPdiStatusItemsFillQO;
import com.nflg.wms.common.pojo.qo.QmsPdiTaskListQO;
import com.nflg.wms.common.pojo.qo.QmsPdiTaskRecordStatusItemDetailQO;
import com.nflg.wms.common.pojo.vo.QmsPdiInspectionResultsPageVO;
import com.nflg.wms.common.pojo.vo.QmsPdiTaskListVO;
import com.nflg.wms.common.pojo.vo.QmsPdiTaskRecordDetailVO;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.repository.entity.QmsPdiInspectionResults;
import com.nflg.wms.repository.entity.QmsPdiTaskRecord;
@ -20,6 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@ -35,6 +40,9 @@ public class QmsPdiInspectionResultsControllerService {
@Resource
private IQmsPdiTaskRecordService taskRecordService;
@Resource
private QmsPdiTaskRecordControllerService taskRecordControllerService;
// ========================= 动静态检查项填写 =========================
/**
@ -205,14 +213,55 @@ public class QmsPdiInspectionResultsControllerService {
/**
* 分页查询以任务单为主体
* 权限过滤只能查看当前用户是帮办人或质检负责人的任务单
* 返回分页列表 + 状态统计
*/
public PageData<QmsPdiInspectionResultsPageVO> search(QmsPdiInspectionResultsSearchQO request) {
// 设置当前登录用户ID用于权限过滤
request.setUserId(UserUtil.getUserId());
public QmsPdiTaskListVO search(QmsPdiInspectionResultsSearchQO request) {
Long userId = UserUtil.getUserId();
request.setUserId(userId);
Page<QmsPdiInspectionResultsPageVO> page = inspectionResultsService.search(request);
// 统计各状态数量不受筛选条件影响
Map<String, Object> countMap = inspectionResultsService.countByStatus(userId);
QmsPdiTaskListVO vo = new QmsPdiTaskListVO();
vo.setItems(page.getRecords());
vo.setTotal((int) page.getTotal());
vo.setPendingCount(toInt(countMap.get("pendingCount")));
vo.setInProgressCount(toInt(countMap.get("inProgressCount")));
vo.setOverdueCount(toInt(countMap.get("overdueCount")));
vo.setCompletedCount(toInt(countMap.get("completedCount")));
return vo;
}
// ========================= 平板检查任务列表 =========================
/**
* 查询检查任务列表平板使用
* 权限过滤帮办人ID或质检负责人ID=当前登录用户ID
* 仅支持 taskStatus 筛选分页返回
*/
public PageData<QmsPdiInspectionResultsPageVO> searchTaskList(QmsPdiTaskListQO request) {
request.setUserId(UserUtil.getUserId());
Page<QmsPdiInspectionResultsPageVO> page = inspectionResultsService.searchTaskList(request);
PageData<QmsPdiInspectionResultsPageVO> result = new PageData<>();
result.setItems(page.getRecords());
result.setTotal((int) page.getTotal());
return result;
}
private int toInt(Object value) {
if (value == null) return 0;
return ((Number) value).intValue();
}
// ========================= 检测项详情不分页 =========================
/**
* 查询检测项详情平板使用不分页
* 根据任务ID + 检测项类型返回对应结果及图片URL
*/
public List<QmsPdiTaskRecordDetailVO.StatusItemVO> detail(QmsPdiTaskRecordStatusItemDetailQO request) {
return taskRecordControllerService.statusItemList(request.getId(), request.getInspectionItemType());
}
}

View File

@ -198,6 +198,66 @@ public class QmsPdiTaskRecordControllerService {
return pd;
}
/**
* 查询静态/动态/特殊检测项详情不分页返回全部
*/
public List<QmsPdiTaskRecordDetailVO.StatusItemVO> statusItemList(Long taskId, Integer inspectionItemType) {
List<QmsPdiInspectionResults> records = inspectionResultsService.lambdaQuery()
.eq(QmsPdiInspectionResults::getTaskId, taskId)
.eq(QmsPdiInspectionResults::getInspectionItemType, inspectionItemType)
.list();
if (records.isEmpty()) {
return List.of();
}
// 批量查关联的 status_item
Set<Long> statusItemIds = records.stream()
.map(QmsPdiInspectionResults::getInspectionItemId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
Map<Long, QmsPdiDetectionRulesStatusItem> statusItemMap = Map.of();
if (!statusItemIds.isEmpty()) {
List<QmsPdiDetectionRulesStatusItem> statusItems = statusItemService.listByIds(statusItemIds);
statusItemMap = statusItems.stream()
.collect(Collectors.toMap(QmsPdiDetectionRulesStatusItem::getId, si -> si, (a, b) -> a));
}
// 收集所有示例图ID批量查询file_upload_record
Set<Long> exampleImageIds = statusItemMap.values().stream()
.map(QmsPdiDetectionRulesStatusItem::getInspectionImage)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
Map<Long, String> exampleImageUrlMap = Map.of();
if (!exampleImageIds.isEmpty()) {
List<FileUploadRecord> files = fileUploadRecordService.listByIds(exampleImageIds);
exampleImageUrlMap = files.stream()
.collect(Collectors.toMap(FileUploadRecord::getId, FileUploadRecord::getUrl, (a, b) -> a));
}
// 映射
Map<Long, QmsPdiDetectionRulesStatusItem> finalStatusMap = statusItemMap;
Map<Long, String> finalExampleImageUrlMap = exampleImageUrlMap;
return records.stream().map(r -> {
QmsPdiTaskRecordDetailVO.StatusItemVO vo = new QmsPdiTaskRecordDetailVO.StatusItemVO();
vo.setId(r.getId());
QmsPdiDetectionRulesStatusItem si = finalStatusMap.get(r.getInspectionItemId());
if (si != null) {
vo.setComponentsDes(si.getComponentsDes());
vo.setInspectionContent(si.getInspectionContent());
if (si.getInspectionImage() != null) {
vo.setInspectionImage(finalExampleImageUrlMap.get(si.getInspectionImage()));
}
}
vo.setInspectionItemImage(convertImageIdsToVO(r.getInspectionItemImage()));
vo.setInspectionBy(r.getInspectionBy());
vo.setInspectionTime(r.getInspectionTime());
vo.setInspectionItemResults(r.getInspectionItemResults());
vo.setRemark(r.getRemark());
return vo;
}).collect(Collectors.toList());
}
/**
* 构建装车前检测项列表不分页
*/

View File

@ -0,0 +1,37 @@
package com.nflg.wms.common.pojo.qo;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* 质量问题工单处理 暂存/提交参数
*/
@Data
public class QmsIssueTicketProcessDraftQO {
/**
* 工单处理IDQmsIssueTicketProcess.ID
*/
@NotNull(message = "工单处理ID不能为空")
private Long id;
/**
* 根本原因可选
*/
private String rootCause;
/**
* 审批状态可选
*/
private Short approvalStatus;
/**
* 审批意见可选
*/
private String approvalOpinion;
/**
* 措施内容可选有值则新增一条 QmsIssueTicketProcessMeasure 记录
*/
private String measureContent;
}

View File

@ -0,0 +1,30 @@
package com.nflg.wms.common.pojo.qo;
import lombok.Data;
/**
* PDI检查任务列表 查询参数平板使用
*/
@Data
public class QmsPdiTaskListQO {
/**
* 任务状态筛选可选0=待检测1=检测中2=已完成3=已延期
*/
private Integer taskStatus;
/**
* 当前登录用户ID内部使用用于权限过滤
*/
private Long userId;
/**
* 当前页
*/
private Integer page = 1;
/**
* 每页条数
*/
private Integer pageSize = 20;
}

View File

@ -0,0 +1,42 @@
package com.nflg.wms.common.pojo.vo;
import lombok.Data;
import java.util.List;
/**
* PDI检查任务列表 返回VO含状态统计
*/
@Data
public class QmsPdiTaskListVO {
/**
* 分页列表
*/
private List<QmsPdiInspectionResultsPageVO> items;
/**
* 总条数
*/
private int total;
/**
* 待检测数量inspection_enable=0
*/
private int pendingCount;
/**
* 检测中数量inspection_enable=1
*/
private int inProgressCount;
/**
* 已延期数量overdue=true
*/
private int overdueCount;
/**
* 已完成数量inspection_enable=2
*/
private int completedCount;
}

View File

@ -3,11 +3,14 @@ package com.nflg.wms.repository.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nflg.wms.common.pojo.qo.QmsPdiInspectionResultsSearchQO;
import com.nflg.wms.common.pojo.qo.QmsPdiTaskListQO;
import com.nflg.wms.common.pojo.vo.QmsPdiInspectionResultsPageVO;
import com.nflg.wms.repository.entity.QmsPdiInspectionResults;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Map;
/**
* PDI现场检测记录 Mapper
*/
@ -19,4 +22,15 @@ public interface QmsPdiInspectionResultsMapper extends BaseMapper<QmsPdiInspecti
*/
Page<QmsPdiInspectionResultsPageVO> search(Page<QmsPdiInspectionResultsPageVO> page,
@Param("request") QmsPdiInspectionResultsSearchQO request);
/**
* 平板检查任务列表查询分页
*/
Page<QmsPdiInspectionResultsPageVO> searchTaskList(Page<QmsPdiInspectionResultsPageVO> page,
@Param("request") QmsPdiTaskListQO request);
/**
* 平板统计各状态数量
*/
Map<String, Object> countByStatus(@Param("userId") Long userId);
}

View File

@ -3,9 +3,12 @@ package com.nflg.wms.repository.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.nflg.wms.common.pojo.qo.QmsPdiInspectionResultsSearchQO;
import com.nflg.wms.common.pojo.qo.QmsPdiTaskListQO;
import com.nflg.wms.common.pojo.vo.QmsPdiInspectionResultsPageVO;
import com.nflg.wms.repository.entity.QmsPdiInspectionResults;
import java.util.Map;
/**
* PDI现场检测记录 Service
*/
@ -15,4 +18,14 @@ public interface IQmsPdiInspectionResultsService extends IService<QmsPdiInspecti
* 分页查询
*/
Page<QmsPdiInspectionResultsPageVO> search(QmsPdiInspectionResultsSearchQO request);
/**
* 平板检查任务列表查询分页
*/
Page<QmsPdiInspectionResultsPageVO> searchTaskList(QmsPdiTaskListQO request);
/**
* 平板统计各状态数量
*/
Map<String, Object> countByStatus(Long userId);
}

View File

@ -3,12 +3,15 @@ package com.nflg.wms.repository.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.wms.common.pojo.qo.QmsPdiInspectionResultsSearchQO;
import com.nflg.wms.common.pojo.qo.QmsPdiTaskListQO;
import com.nflg.wms.common.pojo.vo.QmsPdiInspectionResultsPageVO;
import com.nflg.wms.repository.entity.QmsPdiInspectionResults;
import com.nflg.wms.repository.mapper.QmsPdiInspectionResultsMapper;
import com.nflg.wms.repository.service.IQmsPdiInspectionResultsService;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* PDI现场检测记录 ServiceImpl
*/
@ -22,4 +25,15 @@ public class QmsPdiInspectionResultsServiceImpl
Page<QmsPdiInspectionResultsPageVO> page = new Page<>(request.getPage(), request.getPageSize());
return baseMapper.search(page, request);
}
@Override
public Page<QmsPdiInspectionResultsPageVO> searchTaskList(QmsPdiTaskListQO request) {
Page<QmsPdiInspectionResultsPageVO> page = new Page<>(request.getPage(), request.getPageSize());
return baseMapper.searchTaskList(page, request);
}
@Override
public Map<String, Object> countByStatus(Long userId) {
return baseMapper.countByStatus(userId);
}
}

View File

@ -36,4 +36,47 @@
ORDER BY t.id DESC
</select>
<!-- 平板:检查任务列表分页查询(仅 taskStatus 筛选) -->
<select id="searchTaskList" resultType="com.nflg.wms.common.pojo.vo.QmsPdiInspectionResultsPageVO">
SELECT DISTINCT
t.id AS taskId,
r.machine_no AS machineNo,
t.order_no AS orderNo,
t.device_no AS deviceNo,
t.task_no AS taskNo,
r.inspection_version AS inspectionVersion,
t.submission_time AS submissionTime,
t.required_completion_time AS requiredCompletionTime
FROM qms_pdi_task_record t
LEFT JOIN qms_pdi_detection_rules r ON r.id = t.detection_rules_id
<where>
<if test="request.userId != null">
AND (t.assistant_id = #{request.userId} OR r.inspector_id = #{request.userId})
</if>
<if test="request.taskStatus != null and request.taskStatus != 3">
AND t.inspection_enable = #{request.taskStatus}
</if>
<if test="request.taskStatus != null and request.taskStatus == 3">
AND t.overdue = true
</if>
</where>
ORDER BY t.id DESC
</select>
<!-- 平板:统计各状态数量(不受筛选条件影响,只受权限过滤) -->
<select id="countByStatus" resultType="map">
SELECT
COUNT(CASE WHEN t.inspection_enable = 0 THEN 1 END) AS "pendingCount",
COUNT(CASE WHEN t.inspection_enable = 1 THEN 1 END) AS "inProgressCount",
COUNT(CASE WHEN t.overdue = true THEN 1 END) AS "overdueCount",
COUNT(CASE WHEN t.inspection_enable = 2 THEN 1 END) AS "completedCount"
FROM qms_pdi_task_record t
LEFT JOIN qms_pdi_detection_rules r ON r.id = t.detection_rules_id
<where>
<if test="userId != null">
AND (t.assistant_id = #{userId} OR r.inspector_id = #{userId})
</if>
</where>
</select>
</mapper>