feat(qc): 优化质量评审审批流程,改为创建时预填内容领导仅确认

1.  调整审批接口为路径参数传递评审单ID,移除审批BO参数
2.  待审批页面改为只读展示已填写的审批意见和钢卷改判状态
3.  审批通过时直接执行改判,无需额外操作
4.  重构编辑弹窗和详情页的布局与展示逻辑
5.  移除独立的品质部意见编辑,整合到表单中
This commit is contained in:
王文昊
2026-07-04 14:35:20 +08:00
parent ec40ab90ba
commit 0f054c189d
6 changed files with 198 additions and 195 deletions

View File

@@ -10,7 +10,6 @@ import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import com.klp.common.enums.BusinessType;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.mes.qc.domain.bo.QcQualityReviewApproveBo;
import com.klp.mes.qc.domain.bo.QcQualityReviewBo;
import com.klp.mes.qc.domain.vo.QcQualityReviewCoilVo;
import com.klp.mes.qc.domain.vo.QcQualityReviewLogVo;
@@ -110,12 +109,13 @@ public class QcQualityReviewController extends BaseController {
}
/**
* 审批通过
* 审批通过(创建时已填好领导意见和改判等级,领导仅确认)
*/
@Log(title = "质量评审单", businessType = BusinessType.UPDATE)
@PostMapping("/approve")
public R<Void> approve(@Validated @RequestBody QcQualityReviewApproveBo bo) {
return toAjax(iQcQualityReviewService.approve(bo));
@PostMapping("/approve/{reviewId}")
public R<Void> approve(@NotNull(message = "主键不能为空")
@PathVariable Long reviewId) {
return toAjax(iQcQualityReviewService.approve(reviewId));
}
/**

View File

@@ -2,7 +2,6 @@ package com.klp.mes.qc.service;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.mes.qc.domain.bo.QcQualityReviewApproveBo;
import com.klp.mes.qc.domain.bo.QcQualityReviewBo;
import com.klp.mes.qc.domain.vo.QcQualityReviewVo;
import com.klp.mes.qc.domain.vo.QcQualityReviewCoilVo;
@@ -55,9 +54,9 @@ public interface IQcQualityReviewService {
Boolean submit(Long reviewId);
/**
* 审批通过flowStatus: 2→3
* 审批通过flowStatus: 2→3,所有填写内容已在创建时完成,领导仅确认
*/
Boolean approve(QcQualityReviewApproveBo bo);
Boolean approve(Long reviewId);
/**
* 驳回flowStatus: 2→4

View File

@@ -16,7 +16,6 @@ import com.klp.service.IWmsMaterialCoilService;
import com.klp.mes.qc.domain.QcQualityReview;
import com.klp.mes.qc.domain.QcQualityReviewCoil;
import com.klp.mes.qc.domain.QcQualityReviewLog;
import com.klp.mes.qc.domain.bo.QcQualityReviewApproveBo;
import com.klp.mes.qc.domain.bo.QcQualityReviewBo;
import com.klp.mes.qc.domain.bo.QcQualityReviewCoilBo;
import com.klp.mes.qc.domain.vo.QcQualityReviewCoilVo;
@@ -32,7 +31,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
/**
* 质量评审单Service业务层处理
@@ -189,6 +187,10 @@ public class QcQualityReviewServiceImpl implements IQcQualityReviewService {
if (StringUtils.isBlank(review.getDeptOpinion())) {
throw new RuntimeException("请先填写品质部评审意见");
}
// 校验:必须有领导审批意见
if (StringUtils.isBlank(review.getLeaderOpinion())) {
throw new RuntimeException("请先填写领导审批意见");
}
// 校验:至少有一个钢卷
Long coilCount = coilMapper.selectCount(
Wrappers.<QcQualityReviewCoil>lambdaQuery()
@@ -197,6 +199,18 @@ public class QcQualityReviewServiceImpl implements IQcQualityReviewService {
if (coilCount == null || coilCount == 0) {
throw new RuntimeException("请至少添加一个钢卷");
}
// 校验:每个钢卷必须指定改判后质量等级
List<QcQualityReviewCoil> submitCoilList = coilMapper.selectList(
Wrappers.<QcQualityReviewCoil>lambdaQuery()
.eq(QcQualityReviewCoil::getReviewId, reviewId)
.eq(QcQualityReviewCoil::getDelFlag, 0));
for (QcQualityReviewCoil coil : submitCoilList) {
if (StringUtils.isBlank(coil.getRegradeQuality())) {
String coilNo = StringUtils.isNotBlank(coil.getCurrentCoilNo())
? coil.getCurrentCoilNo() : "ID:" + coil.getDetailId();
throw new RuntimeException("钢卷【" + coilNo + "】未指定改判后质量状态");
}
}
// 更新流程状态为待审批,清除驳回原因
baseMapper.update(null, Wrappers.<QcQualityReview>lambdaUpdate()
@@ -210,53 +224,30 @@ public class QcQualityReviewServiceImpl implements IQcQualityReviewService {
}
/**
* 审批通过
* 审批通过并直接执行改判(创建时已填好所有内容,领导确认后立即生效)
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean approve(QcQualityReviewApproveBo bo) {
QcQualityReview review = baseMapper.selectById(bo.getReviewId());
public Boolean approve(Long reviewId) {
QcQualityReview review = baseMapper.selectById(reviewId);
if (review == null) {
throw new RuntimeException("评审单不存在");
}
if (!Long.valueOf(2L).equals(review.getFlowStatus())) {
throw new RuntimeException("只有待审批状态的评审单才能审批");
}
if (CollUtil.isEmpty(bo.getCoilRegradeList())) {
throw new RuntimeException("请为每个钢卷指定改判后质量状态");
}
// 校验coilRegradeList 是否覆盖了评审单中的所有有效钢卷
List<QcQualityReviewCoil> dbCoils = coilMapper.selectList(
Wrappers.<QcQualityReviewCoil>lambdaQuery()
.eq(QcQualityReviewCoil::getReviewId, bo.getReviewId())
.eq(QcQualityReviewCoil::getDelFlag, 0));
Set<Long> regradedIds = bo.getCoilRegradeList().stream()
.map(QcQualityReviewApproveBo.CoilRegradeBo::getDetailId)
.collect(Collectors.toSet());
for (QcQualityReviewCoil coil : dbCoils) {
if (!regradedIds.contains(coil.getDetailId())) {
throw new RuntimeException("钢卷【" + coil.getCurrentCoilNo() + "】未指定改判后质量状态");
}
}
// 1. 更新主表流程状态
// 1. 更新主表流程状态为已通过
baseMapper.update(null, Wrappers.<QcQualityReview>lambdaUpdate()
.eq(QcQualityReview::getReviewId, bo.getReviewId())
.set(QcQualityReview::getFlowStatus, 3L)
.set(QcQualityReview::getLeaderOpinion, bo.getLeaderOpinion())
.set(QcQualityReview::getLeaderSign, bo.getLeaderSign())
.set(QcQualityReview::getLeaderSignDate, new java.sql.Date(System.currentTimeMillis())));
.eq(QcQualityReview::getReviewId, reviewId)
.set(QcQualityReview::getFlowStatus, 3L));
// 2. 更新每个钢卷的改判状态
for (QcQualityReviewApproveBo.CoilRegradeBo regrade : bo.getCoilRegradeList()) {
coilMapper.update(null, Wrappers.<QcQualityReviewCoil>lambdaUpdate()
.eq(QcQualityReviewCoil::getDetailId, regrade.getDetailId())
.set(QcQualityReviewCoil::getRegradeQuality, regrade.getRegradeQuality()));
}
// 2. 记录审批日志
addLog(reviewId, "approve", review.getLeaderOpinion());
// 3. 直接执行改判(无需单独点击执行改判按钮)
execute(reviewId);
// 3. 记录审批日志
addLog(bo.getReviewId(), "approve", bo.getLeaderOpinion());
return true;
}