refactor(issue-ticket): 优化质量问题工单管理及审核功能

- 替换来料检验任务完成事件发布逻辑为调用质量问题工单发起方法
- 修改来料检验任务AQL规则查询,调整检验标准关联及查询条件
- 移除质量问题工单相关查询条件和VO中检测项相关字段,新增检验标准版本字段
- 在来料检验任务数据中新增采购组字段并完善相应VO属性
- 添加质量问题工单实体逻辑删除字段,实现软删除功能
- 在质量问题工单Controller新增审核和批量删除接口
- 实现质量问题工单审核方法,校验数据并更新审批及状态信息
- 新增审核参数QO,完善参数校验,包括审批状态和事故类型限制
- 新增待办事项生成逻辑,基于采购组分配任务给相关用户
- 优化质量问题工单详情查询接口命名,明确接口用途
This commit is contained in:
曹鹏飞 2026-04-28 11:25:14 +08:00
parent bb80178e2b
commit 70baa07783
10 changed files with 153 additions and 30 deletions

View File

@ -4,6 +4,7 @@ import com.nflg.qms.admin.service.QmsIssueTicketControllerService;
import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData; import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.qo.QmsIssueTicketAddQO; import com.nflg.wms.common.pojo.qo.QmsIssueTicketAddQO;
import com.nflg.wms.common.pojo.qo.QmsIssueTicketAuditQO;
import com.nflg.wms.common.pojo.qo.QmsIssueTicketSearchQO; import com.nflg.wms.common.pojo.qo.QmsIssueTicketSearchQO;
import com.nflg.wms.common.pojo.vo.QmsIssueTicketDetailVO; import com.nflg.wms.common.pojo.vo.QmsIssueTicketDetailVO;
import com.nflg.wms.common.pojo.vo.QmsIssueTicketVO; import com.nflg.wms.common.pojo.vo.QmsIssueTicketVO;
@ -11,11 +12,14 @@ import com.nflg.wms.repository.service.IQmsIssueTicketService;
import com.nflg.wms.starter.BaseController; import com.nflg.wms.starter.BaseController;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/** /**
* 质量问题工单管理 * 质量问题工单管理
*/ */
@ -39,13 +43,32 @@ public class QmsIssueTicketController extends BaseController {
return ApiResult.success(); return ApiResult.success();
} }
/**
* 审核质量问题工单
* 更新审批状态审批意见审批人信息并根据审批结果更新工单状态
*/
@PostMapping("audit")
public ApiResult<Void> audit(@Valid @RequestBody QmsIssueTicketAuditQO request) {
issueTicketControllerService.audit(request);
return ApiResult.success();
}
/** /**
* 查询来料检测任务质量问题工单详情 * 查询来料检测任务质量问题工单详情
* 含来料检测任务详情及来料检验任务检验记录子项样本列表 * 含来料检测任务详情及来料检验任务检验记录子项样本列表
*/ */
@GetMapping("detail") @GetMapping("detail/incoming-inspection-task")
public ApiResult<QmsIssueTicketDetailVO> detail(@NotNull(message = "ID不能为空") Long id) { public ApiResult<QmsIssueTicketDetailVO> detailIncomingInspectionTask(@NotNull(message = "ID不能为空") Long id) {
return ApiResult.success(issueTicketControllerService.getDetail(id)); return ApiResult.success(issueTicketControllerService.getIncomingInspectionTaskDetail(id));
}
/**
* 批量删除质量问题工单
*/
@PostMapping("delete")
public ApiResult<Void> delete(@RequestBody @NotEmpty(message = "ID列表不能为空") List<Long> ids) {
issueTicketService.removeByIds(ids);
return ApiResult.success();
} }
/** /**

View File

@ -106,7 +106,7 @@ public class IncomingInspectionTaskControllerService {
private IFileUploadRecordService fileUploadRecordService; private IFileUploadRecordService fileUploadRecordService;
@Resource @Resource
private TicketEventPublisher publisher; private QmsIssueTicketControllerService issueTicketControllerService;
/** /**
* 来料检验申请对外接口 * 来料检验申请对外接口
@ -952,7 +952,7 @@ public class IncomingInspectionTaskControllerService {
updateWrapper.update(); updateWrapper.update();
publisher.publishIncomingInspectionTaskFinishEvent(task.getId(), request.getQualified()); issueTicketControllerService.initiate(task.getId());
} }
/** /**

View File

@ -6,14 +6,12 @@ import cn.hutool.core.util.StrUtil;
import com.nflg.wms.common.constant.STATE; import com.nflg.wms.common.constant.STATE;
import com.nflg.wms.common.exception.NflgException; import com.nflg.wms.common.exception.NflgException;
import com.nflg.wms.common.pojo.qo.QmsIssueTicketAddQO; import com.nflg.wms.common.pojo.qo.QmsIssueTicketAddQO;
import com.nflg.wms.common.pojo.qo.QmsIssueTicketAuditQO;
import com.nflg.wms.common.pojo.vo.*; import com.nflg.wms.common.pojo.vo.*;
import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.common.util.VUtil; import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.FileUploadRecord; import com.nflg.wms.repository.entity.*;
import com.nflg.wms.repository.entity.QmsIssueTicket; import com.nflg.wms.repository.service.*;
import com.nflg.wms.repository.entity.VUser;
import com.nflg.wms.repository.service.IFileUploadRecordService;
import com.nflg.wms.repository.service.IQmsIssueTicketService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import jakarta.validation.Valid; import jakarta.validation.Valid;
@ -24,6 +22,7 @@ import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* 质量问题工单 ControllerService * 质量问题工单 ControllerService
@ -45,6 +44,48 @@ public class QmsIssueTicketControllerService {
@Resource @Resource
private IncomingInspectionTaskControllerService incomingInspectionTaskControllerService; private IncomingInspectionTaskControllerService incomingInspectionTaskControllerService;
@Resource
private IUserService userService;
@Resource
private IQmsTodoItemService todoItemService;
@Resource
private IDictionaryItemService dictionaryItemService;
/**
* 审核质量问题工单
* 更新审批状态审批意见审批人信息事故类型并更新工单状态
*/
@Transactional(rollbackFor = Exception.class)
public void audit(@Valid QmsIssueTicketAuditQO request) {
// 校验工单存在
QmsIssueTicket entity = issueTicketService.getById(request.getId());
VUtil.trueThrowBusinessError(Objects.isNull(entity))
.throwMessage("质量问题工单不存在");
VUtil.trueThrowBusinessError(Objects.nonNull(entity.getApprovalStatus())).throwMessage("请勿重复审批");
// 校验审批状态合法性
Set<Short> validApprovalStatus = Stream.of((short) 0, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6)
.collect(Collectors.toSet());
VUtil.trueThrowBusinessError(!validApprovalStatus.contains(request.getApprovalStatus()))
.throwMessage("审批状态不合法");
Long userId = UserUtil.getUserId();
String userName = UserUtil.getUserName();
LocalDateTime now = LocalDateTime.now();
entity.setApprovalStatus(request.getApprovalStatus())
.setStatus((short) 2)
.setApprovalOpinion(request.getApprovalOpinion())
.setIncidentType(request.getIncidentType())
.setApprovalUserId(userId)
.setApprovalUserName(userName)
.setApprovalTime(now);
issueTicketService.updateById(entity);
}
/** /**
* 新增质量问题工单 * 新增质量问题工单
* 工单编号自动生成来源类型固定为2巡检状态默认为0待流转 * 工单编号自动生成来源类型固定为2巡检状态默认为0待流转
@ -133,6 +174,26 @@ public class QmsIssueTicketControllerService {
}); });
issueTicketService.save(entity); issueTicketService.save(entity);
// 添加待办
if (detail.getInspectionType() == 0) {
if (StrUtil.isNotBlank(detail.getPurchaseGroup())) {
List<User> users = userService.lambdaQuery()
.eq(User::getPurchasingGroup, detail.getPurchaseGroup())
.list();
List<QmsTodoItem> todoItems = users.stream().map(user -> new QmsTodoItem()
.setCode(basdeSerialNumberControllerService.generateSerialNumber(32))
.setSourceTypeId(dictionaryItemService.getIdByCode("MessageType","IncomingMaterialInspectionApproval"))
.setSourceId(entity.getId())
.setCreateUserId(user.getId())
.setCreateUserName(user.getUserName())
.setCreateTime(LocalDateTime.now())
).toList();
if (CollectionUtil.isNotEmpty(todoItems)){
todoItemService.saveBatch(todoItems);
}
}
}
} }
private String generateTicketTitle(Object... args) { private String generateTicketTitle(Object... args) {
@ -143,7 +204,7 @@ public class QmsIssueTicketControllerService {
* 查询来料检测任务质量问题工单详情 * 查询来料检测任务质量问题工单详情
* 包含图片文件信息来料检测任务详情检验记录含子项和样本数据 * 包含图片文件信息来料检测任务详情检验记录含子项和样本数据
*/ */
public QmsIssueTicketDetailVO getDetail(Long id) { public QmsIssueTicketDetailVO getIncomingInspectionTaskDetail(Long id) {
QmsIssueTicket entity = issueTicketService.getById(id); QmsIssueTicket entity = issueTicketService.getById(id);
if (Objects.isNull(entity)) { if (Objects.isNull(entity)) {
throw new NflgException(STATE.BusinessError, "质量问题工单不存在"); throw new NflgException(STATE.BusinessError, "质量问题工单不存在");

View File

@ -24,9 +24,4 @@ public class QmsIncomingInspectionTaskAqlRuleSearchQO extends PageQO {
* 物料编码模糊匹配 * 物料编码模糊匹配
*/ */
private String materialNo; private String materialNo;
/**
* 检测项id精确匹配
*/
private Long inspectionItemId;
} }

View File

@ -0,0 +1,40 @@
package com.nflg.wms.common.pojo.qo;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 质量问题工单 审核参数
*/
@Data
@Accessors(chain = true)
public class QmsIssueTicketAuditQO {
/**
* 工单ID
*/
@NotNull(message = "工单ID不能为空")
private Long id;
/**
* 审批状态0=通过1=驳回2=重检3=报废4=维修5=挑选使用6=让渡使用
*/
@NotNull(message = "审批状态不能为空")
private Short approvalStatus;
/**
* 审批意见
*/
private String approvalOpinion;
/**
* 事故类型0=一般1=较严重2=严重
*/
@NotNull(message = "事故类型不能为空")
@Min(value = 0, message = "事故类型不能小于0")
@Min(value = 2, message = "事故类型不能大于2")
private Short incidentType;
}

View File

@ -41,14 +41,9 @@ public class QmsIncomingInspectionTaskAqlRuleVO {
private String materialDesc; private String materialDesc;
/** /**
* 检测项id关联检验标准项表 * 检测标准版本号
*/ */
private Long inspectionItemId; private String version;
/**
* 检测项名称
*/
private String inspectionItemName;
/** /**
* 计算的AQL类型字典项id * 计算的AQL类型字典项id

View File

@ -162,6 +162,11 @@ public class QmsIncomingInspectionTaskVO {
*/ */
private Long relatedTaskNo; private Long relatedTaskNo;
/**
* 采购组
*/
private String purchaseGroup;
/** /**
* 最近更新人id * 最近更新人id
*/ */

View File

@ -2,6 +2,7 @@ package com.nflg.wms.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -157,4 +158,10 @@ public class QmsIssueTicket implements Serializable {
* 更新时间 * 更新时间
*/ */
private LocalDateTime updateTime; private LocalDateTime updateTime;
/**
* 逻辑删除0=未删除1=已删除
*/
@TableLogic
private Integer deleted;
} }

View File

@ -10,8 +10,7 @@
m.material_no, m.material_no,
m.material_name, m.material_name,
m.material_desc, m.material_desc,
r.inspection_item_id, s.version,
si.name AS inspection_item_name,
r.calculated_aql_type, r.calculated_aql_type,
r.used_aql_type, r.used_aql_type,
r.trigger_category, r.trigger_category,
@ -26,7 +25,7 @@
FROM qms_incoming_inspection_task_aql_rule r FROM qms_incoming_inspection_task_aql_rule r
INNER JOIN qms_incoming_inspection_task t ON r.task_id = t.id INNER JOIN qms_incoming_inspection_task t ON r.task_id = t.id
INNER JOIN qms_qc_material m ON t.material_id = m.id INNER JOIN qms_qc_material m ON t.material_id = m.id
LEFT JOIN qms_inspection_standard_item si ON r.inspection_item_id = si.id LEFT JOIN qms_inspection_standard s ON r.inspection_standard_id = s.id
<where> <where>
t.inspection_status IN (0, 1) t.inspection_status IN (0, 1)
<if test="request.supplierCode != null and request.supplierCode != ''"> <if test="request.supplierCode != null and request.supplierCode != ''">
@ -38,9 +37,6 @@
<if test="request.materialNo != null and request.materialNo != ''"> <if test="request.materialNo != null and request.materialNo != ''">
AND m.material_no ilike concat('%', #{request.materialNo}, '%') AND m.material_no ilike concat('%', #{request.materialNo}, '%')
</if> </if>
<if test="request.inspectionItemId != null">
AND r.inspection_item_id = #{request.inspectionItemId}
</if>
</where> </where>
ORDER BY t.id ASC, r.id ASC ORDER BY t.id ASC, r.id ASC
</select> </select>

View File

@ -205,7 +205,8 @@
t2.task_no as related_task_no, t2.task_no as related_task_no,
t.update_user_id, t.update_user_id,
t.update_user_name, t.update_user_name,
t.update_time t.update_time,
t.purchase_group
FROM qms_incoming_inspection_task t FROM qms_incoming_inspection_task t
LEFT JOIN qms_qc_material m ON t.material_id = m.id LEFT JOIN qms_qc_material m ON t.material_id = m.id
LEFT JOIN qms_inspection_standard s ON t.inspection_standard_id = s.id LEFT JOIN qms_inspection_standard s ON t.inspection_standard_id = s.id