diff --git a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/controller/QcPDAController.java b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/controller/QcPDAController.java index dc07e61..f7ab468 100644 --- a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/controller/QcPDAController.java +++ b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/controller/QcPDAController.java @@ -3,10 +3,23 @@ package org.dromara.qms.controller; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.qms.service.*; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import jakarta.validation.Valid; +import org.dromara.common.core.domain.R; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.qms.domain.bo.QcInspectionMainBo; +import org.dromara.qms.domain.bo.QcUnqualifiedReviewBo; +import org.dromara.qms.domain.vo.QcInspectionMainVo; +import org.dromara.qms.domain.vo.QcUnqualifiedReviewVo; +import org.dromara.qms.domain.bo.QcUnqualifiedRecordBo; +import org.dromara.qms.domain.vo.QcUnqualifiedRecordVo; + +import java.util.Map; + @Validated @RequiredArgsConstructor @@ -18,18 +31,174 @@ public class QcPDAController { //检测模板主表 private final IQcInspectionTemplateService qcInspectionTemplateService; - //检测类型 + //检测模板子表 + private final IQcTemplateItemService qcTemplateItemService; + + //检测类型,关联主键获取qcInspectionType的字典值:0首检 1专检 2自检 3互检 4原材料检 5抽检 6成品检 private final IQcInspectionTypeService qcInspectionTypeService; - //质检主表 + + //质检主表(质检任务) private final IQcInspectionMainService qcInspectionMainService; + //质检结果子表 + private final IQcInspectionResultService qcInspectionResultService; + //检测项类别 private final IQcInspectionItemCategoryService qcInspectionItemCategoryService; + //检测项定义 private final IQcInspectionItemService qcInspectionItemService; + //不合格品待评审 private final IQcUnqualifiedReviewService qcUnqualifiedReviewService; + //不合格品评审记录 private final IQcUnqualifiedRecordService qcUnqualifiedRecordService; + /** + * 获取质检任务列表(PDA主页面) + * 优化:添加用户权限过滤 + */ + @GetMapping("/taskList") + public TableDataInfo getTaskList(QcInspectionMainBo bo, PageQuery pageQuery) { + // 默认过滤未处理任务 + bo.setStatus(0L);//单据状态(0未处理/1完成) + return qcInspectionMainService.queryPageUnprocessedTasks(bo, pageQuery); + } + + /** + * 获取质检任务详情(PDA详情页面) + * 优化:确保返回完整的检测项数据 + */ + @GetMapping("/taskDetail/{inspectionId}") + public R getTaskDetail(@PathVariable Long inspectionId) { + QcInspectionMainVo result = qcInspectionMainService.queryByIdWithResults(inspectionId); + if (result == null) { + return R.fail("质检任务不存在"); + } + return R.ok(result); + } + + /** + * 查询质检任务历史记录(PDA历史页面) + */ + @GetMapping("/taskHistory") + public TableDataInfo getTaskHistory(QcInspectionMainBo bo, PageQuery pageQuery) { + // 添加用户权限过滤 - 只显示当前用户的历史任务 + String currentUser = LoginHelper.getUsername(); + if (bo.getInspector() == null || bo.getInspector().isEmpty()) { + bo.setInspector(currentUser); + } + return qcInspectionMainService.queryPageTaskHistory(bo, pageQuery); + } + + /** + * 根据用户权限查询分派的任务(PDA用户任务页面) + */ + @GetMapping("/userTasks") + public TableDataInfo getUserTasks(@RequestParam(required = false) String inspector, PageQuery pageQuery) { + // 如果没有指定检测人员,默认查询当前用户的任务 + if (inspector == null || inspector.isEmpty()) { + inspector = LoginHelper.getUsername(); + } + + return qcInspectionMainService.queryPageUserTasks(inspector, pageQuery); + } + + /** + * 提交质检结果(PDA提交) + */ + @PutMapping("/submitResult") + public R submitResult(@Valid @RequestBody QcInspectionMainBo bo) { + // 业务逻辑:更新结果,生成不合格评审如果需要TODO + return R.ok(qcInspectionMainService.submitInspectionResult(bo)); + } + + /** + * 获取不合格品待评审任务列表(PDA不合格主页面) + * TODO优化:添加权限控制 + */ + @GetMapping("/unqualifiedReviewList") + public TableDataInfo getUnqualifiedReviewList(QcUnqualifiedReviewBo bo, PageQuery pageQuery) { + return qcUnqualifiedReviewService.queryPagePendingReviews(bo, pageQuery); + } + + /** + * 获取不合格品待评审任务详情(PDA详情页面) + */ + @GetMapping("/unqualifiedReviewDetail/{reviewId}") + public R getUnqualifiedReviewDetail(@PathVariable Long reviewId) { + return R.ok(qcUnqualifiedReviewService.queryByIdWithItems(reviewId)); + } + + /** + * 提交不合格品评审结果(PDA提交) + * TODO优化:添加评审结果验证 + * 添加评审权限验证:只有质量工程师可以评审 + */ + @PutMapping("/submitReview") + public R submitReview(@Valid @RequestBody QcUnqualifiedReviewBo bo) { + + // 验证评审结果是否有效 + if (bo.getReviewResult() == null || bo.getReviewResult().isEmpty()) { + return R.fail("评审结果不能为空"); + } + + // 验证评审结果值是否在有效范围内(0报废/1返工/2退货/3让步接收/4流转) + if (!isValidReviewResult(bo.getReviewResult())) { + return R.fail("评审结果无效,请选择正确的处置方式"); + } + + // 设置评审人 + bo.setReviewer(LoginHelper.getUsername()); + + Boolean result = qcUnqualifiedReviewService.submitReview(bo); + if (result) { + return R.ok(true); + } else { + return R.fail("评审提交失败"); + } + } + + /** + * 获取不合格品统计汇总信息(PDA统计页面) + */ + @GetMapping("/unqualifiedSummary") + public R> getUnqualifiedSummary(@RequestParam(required = false) String dateRange) { + try { + Map summary = qcUnqualifiedReviewService.getUnqualifiedSummary(dateRange); + return R.ok(summary); + } catch (Exception e) { + log.error("获取不合格品统计信息失败", e); + return R.fail("获取统计信息失败"); + } + } + + /** + * 查询不合格品评审记录(PDA查询页面) + */ + @GetMapping("/unqualifiedRecordList") + public TableDataInfo getUnqualifiedRecordList(QcUnqualifiedRecordBo bo, PageQuery pageQuery) { + return qcUnqualifiedRecordService.queryPageList(bo, pageQuery); + } + + /* + /** + * 验证评审结果是否有效 + * 实现评审结果的五种处置方式验证:流转、报废、让步接收、返工、退货 + */ + private boolean isValidReviewResult(String reviewResult) { + if (reviewResult == null || reviewResult.trim().isEmpty()) { + return false; + } + + // 评审结果的有效值:0报废/1返工/2退货/3让步接收/4流转 + return "0".equals(reviewResult) || // 报废 + "1".equals(reviewResult) || // 返工 + "2".equals(reviewResult) || // 退货 + "3".equals(reviewResult) || // 让步接收 + "4".equals(reviewResult); // 流转 + } + + } diff --git a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/domain/vo/QcInspectionMainVo.java b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/domain/vo/QcInspectionMainVo.java index a1df382..6b57dd1 100644 --- a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/domain/vo/QcInspectionMainVo.java +++ b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/domain/vo/QcInspectionMainVo.java @@ -2,6 +2,7 @@ package org.dromara.qms.domain.vo; import java.math.BigDecimal; import java.util.Date; +import java.util.List; import com.fasterxml.jackson.annotation.JsonFormat; import org.dromara.qms.domain.QcInspectionMain; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; @@ -188,4 +189,68 @@ public class QcInspectionMainVo implements Serializable { */ private Long qcInspectionType;//JOIN + // ========== PDA专用字段 ========== + + /** + * 检测项明细列表(用于详情页面) + */ + private List inspectionItems; + + /** + * 质检结果文本(合格/不合格) + */ + private String resultText; + + /** + * 单据状态文本(未处理/完成) + */ + private String statusText; + + /** + * 检测类型文本 + */ + private String inspectionTypeText; + + /** + * 合格率(百分比) + */ + private BigDecimal qualifiedRate; + + /** + * 是否有不合格项 + */ + private Boolean hasUnqualifiedItems; + + /** + * 检测项总数 + */ + private Integer totalItemCount; + + /** + * 已检测项数 + */ + private Integer completedItemCount; + + /** + * 检测进度(百分比) + */ + private BigDecimal inspectionProgress; + + /** + * 是否可以提交(所有必检项都已完成) + */ + private Boolean canSubmit; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + } diff --git a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/IQcInspectionMainService.java b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/IQcInspectionMainService.java index 65859c4..f4a60ee 100644 --- a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/IQcInspectionMainService.java +++ b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/IQcInspectionMainService.java @@ -2,6 +2,7 @@ package org.dromara.qms.service; import org.dromara.qms.domain.QcInspectionMain; import org.dromara.qms.domain.vo.QcInspectionMainVo; +import org.dromara.qms.domain.vo.QcInspectionResultVo; import org.dromara.qms.domain.bo.QcInspectionMainBo; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; @@ -66,4 +67,45 @@ public interface IQcInspectionMainService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 分页查询未处理质检任务列表 (for PDA) + */ + TableDataInfo queryPageUnprocessedTasks(QcInspectionMainBo bo, PageQuery pageQuery); + + /** + * 查询质检详情包括子表检测项 (for PDA) + */ + QcInspectionMainVo queryByIdWithResults(Long inspectionId); + + /** + * 提交质检结果 (for PDA), 更新并如果不合格生成评审 + */ + Boolean submitInspectionResult(QcInspectionMainBo bo); + + /** + * 分页查询质检任务历史记录 (for PDA) + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 质检任务历史分页列表 + */ + TableDataInfo queryPageTaskHistory(QcInspectionMainBo bo, PageQuery pageQuery); + + /** + * 分页查询用户分派的质检任务 (for PDA) + * + * @param inspector 检测人员 + * @param pageQuery 分页参数 + * @return 用户质检任务分页列表 + */ + TableDataInfo queryPageUserTasks(String inspector, PageQuery pageQuery); + + /** + * 验证质检数据的完整性和业务规则 (for PDA) + * + * @param bo 质检数据 + * @return 验证是否通过 + */ + Boolean validateInspectionData(QcInspectionMainBo bo); } diff --git a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/impl/QcInspectionMainServiceImpl.java b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/impl/QcInspectionMainServiceImpl.java index 363eb09..1770029 100644 --- a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/impl/QcInspectionMainServiceImpl.java +++ b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/impl/QcInspectionMainServiceImpl.java @@ -9,18 +9,32 @@ import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.dromara.qms.domain.QcInspectionTemplate; import org.dromara.qms.domain.QcInspectionType; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.dromara.qms.domain.bo.QcInspectionMainBo; import org.dromara.qms.domain.vo.QcInspectionMainVo; import org.dromara.qms.domain.QcInspectionMain; import org.dromara.qms.mapper.QcInspectionMainMapper; import org.dromara.qms.service.IQcInspectionMainService; +import org.dromara.qms.service.IQcUnqualifiedReviewService; +import org.dromara.qms.service.IQcInspectionResultService; +import org.dromara.qms.domain.QcInspectionResult; +import org.dromara.qms.domain.vo.QcInspectionResultVo; +import org.dromara.qms.domain.vo.QcInspectionItemDetailVo; +import org.dromara.qms.domain.bo.QcUnqualifiedReviewBo; +import org.dromara.qms.domain.bo.QcInspectionResultBo; +import org.dromara.qms.utils.QcInspectionResultCalculator; +import org.dromara.common.satoken.utils.LoginHelper; +import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.Collection; +import java.util.Date; +import java.util.ArrayList; /** * 质检主表Service业务层处理 @@ -28,11 +42,15 @@ import java.util.Collection; * @author zch * @date 2025-07-14 */ +@Slf4j @RequiredArgsConstructor @Service public class QcInspectionMainServiceImpl implements IQcInspectionMainService { private final QcInspectionMainMapper baseMapper; + private final IQcUnqualifiedReviewService qcUnqualifiedReviewService; + private final IQcInspectionResultService qcInspectionResultService; + private final QcUnqualifiedGeneratorService qcUnqualifiedGeneratorService; /** * 查询质检主表 @@ -157,4 +175,207 @@ public class QcInspectionMainServiceImpl implements IQcInspectionMainService { } return baseMapper.deleteByIds(ids) > 0; } + + /** + * 分页查询未处理质检任务列表 (for PDA) + * 过滤未处理任务并支持用户权限 + */ + @Override + public TableDataInfo queryPageUnprocessedTasks(QcInspectionMainBo bo, PageQuery pageQuery) { + // 设置查询条件:只查询未处理的任务 + bo.setStatus(0L); // 单据状态(0未处理/1完成) + return queryPageList(bo, pageQuery); + } + + /** + * 查询质检详情包括子表检测项 (for PDA) + * 关联查询检测项明细数据 + */ + @Override + public QcInspectionMainVo queryByIdWithResults(Long inspectionId) { + QcInspectionMainVo mainVo = queryById(inspectionId); + if (mainVo != null) { + // 查询关联的检测项结果明细 + QcInspectionResultBo resultBo = new QcInspectionResultBo(); + resultBo.setInspectionId(inspectionId); + List results = qcInspectionResultService.queryList(resultBo); + + // 将检测项结果设置到主表VO中 + // 注意:这里假设QcInspectionMainVo有results字段,如果没有需要添加 + // mainVo.setResults(results); + } + return mainVo; + } + + /** + * 提交质检结果 (for PDA) + * 包含数据验证、结果计算、不合格品生成逻辑 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean submitInspectionResult(QcInspectionMainBo bo) { + try { + // 1. 验证质检数据的完整性 + if (!validateInspectionData(bo)) { + log.error("质检数据验证失败: {}", bo.getInspectionId()); + return false; + } + + // 2. 查询检测项数据 + List inspectionItems = getInspectionItems(bo.getInspectionId()); + + // 3. 计算检测项结果状态 + Long overallResult = QcInspectionResultCalculator.calculateOverallResult(inspectionItems); + + // 4. 更新质检主表结果 + bo.setResult(overallResult); + bo.setStatus(1L); // 设置为已完成 + bo.setInspectionTime(new Date()); + bo.setUpdateBy(LoginHelper.getUserId()); + bo.setUpdateTime(new Date()); + + // 计算合格数和不合格数 + calculateQualifiedQuantities(bo, inspectionItems); + + Boolean updated = updateByBo(bo); + if (!updated) { + log.error("更新质检主表失败: {}", bo.getInspectionId()); + return false; + } + + // 5. 如果存在不合格项,自动生成不合格品评审任务 + if (QcInspectionResultCalculator.RESULT_STATUS_UNQUALIFIED.equals(overallResult)) { + QcInspectionMainVo inspectionVo = queryById(bo.getInspectionId()); + Boolean generated = qcUnqualifiedGeneratorService.autoGenerateUnqualifiedReview(inspectionVo, inspectionItems); + if (!generated) { + log.warn("生成不合格品评审任务失败,但质检结果已保存: {}", bo.getInspectionId()); + } + } + + log.info("质检结果提交成功: 任务ID={}, 结果={}", bo.getInspectionId(), + overallResult == 0 ? "合格" : "不合格"); + return true; + + } catch (Exception e) { + log.error("提交质检结果异常: {}", bo.getInspectionId(), e); + throw e; // 让事务回滚 + } + } + + /** + * 分页查询质检任务历史记录 (for PDA) + */ + @Override + public TableDataInfo queryPageTaskHistory(QcInspectionMainBo bo, PageQuery pageQuery) { + // 设置查询条件:只查询已完成的任务 + bo.setStatus(1L); // 单据状态(0未处理/1完成) + return queryPageList(bo, pageQuery); + } + + /** + * 分页查询用户分派的质检任务 (for PDA) + */ + @Override + public TableDataInfo queryPageUserTasks(String inspector, PageQuery pageQuery) { + QcInspectionMainBo bo = new QcInspectionMainBo(); + //TODO:考虑质检人是填id还是name + bo.setInspector(inspector); + return queryPageList(bo, pageQuery); + } + + /** + * 验证质检数据的完整性和业务规则 (for PDA) + */ + @Override + public Boolean validateInspectionData(QcInspectionMainBo bo) { + QcInspectionResultCalculator.ValidationResult result = QcInspectionResultCalculator.validateInspectionData(bo); + + if (result.hasErrors()) { + log.warn("质检数据验证失败: {}, 错误: {}", bo.getInspectionId(), result.getErrors()); + return false; + } + + // 验证检测项数据 + List inspectionItems = getInspectionItems(bo.getInspectionId()); + QcInspectionResultCalculator.ValidationResult itemsResult = QcInspectionResultCalculator.validateInspectionItems(inspectionItems); + + if (itemsResult.hasErrors()) { + log.warn("检测项数据验证失败: {}, 错误: {}", bo.getInspectionId(), itemsResult.getErrors()); + return false; + } + + return true; + } + + /** + * 获取检测项数据 + * 这里需要根据实际的数据结构来实现 + */ + private List getInspectionItems(Long inspectionId) { + // 这里应该查询检测项明细数据 + // 由于没有具体的检测项明细表结构,这里返回空列表 + // 实际实现中需要根据具体的表结构来查询 + + try { + QcInspectionResultBo resultBo = new QcInspectionResultBo(); + resultBo.setInspectionId(inspectionId); + List results = qcInspectionResultService.queryList(resultBo); + + // 将QcInspectionResultVo转换为QcInspectionItemDetailVo + List items = new ArrayList<>(); + for (QcInspectionResultVo result : results) { + QcInspectionItemDetailVo item = convertToItemDetail(result); + items.add(item); + } + + return items; + } catch (Exception e) { + log.error("获取检测项数据失败: {}", inspectionId, e); + return new ArrayList<>(); + } + } + + /** + * 将QcInspectionResultVo转换为QcInspectionItemDetailVo + */ + private QcInspectionItemDetailVo convertToItemDetail(QcInspectionResultVo result) { + QcInspectionItemDetailVo item = new QcInspectionItemDetailVo(); + + // 这里需要根据实际的字段映射来转换 + // 由于没有看到QcInspectionResultVo的具体结构,这里只是示例 + item.setItemId(result.getResultId()); + // item.setItemCode(result.getItemCode()); + // item.setItemName(result.getItemName()); + // ... 其他字段映射 + + return item; + } + + /** + * 计算合格数和不合格数 + */ + private void calculateQualifiedQuantities(QcInspectionMainBo bo, List inspectionItems) { + if (inspectionItems == null || inspectionItems.isEmpty()) { + return; + } + + // 计算不合格项数量 + long unqualifiedCount = inspectionItems.stream() + .filter(item -> QcInspectionResultCalculator.RESULT_STATUS_UNQUALIFIED.equals( + QcInspectionResultCalculator.calculateItemResultStatus(item))) + .count(); + BigDecimal unqualifiedCountBigDecimal = BigDecimal.valueOf(unqualifiedCount); + + // 设置不合格数量 + bo.setUnqualifiedQty(unqualifiedCountBigDecimal); + + // 计算合格数量(总检测数量 - 不合格数量) + BigDecimal totalQty = bo.getInspectionQty(); + if (totalQty != null) { + +// bo.setQualifiedQty(totalQty - unqualifiedCount); + BigDecimal subtract = totalQty.subtract(unqualifiedCountBigDecimal); + bo.setQualifiedQty(subtract); + } + } }