Merge branch 'test' of https://git.will-way.cn/zgty/zt-qms into test

This commit is contained in:
2026-03-09 18:27:22 +08:00
9 changed files with 160 additions and 30 deletions

View File

@@ -31,7 +31,7 @@ import static com.zt.plat.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 物料通用流程明细")
@RestController
@RequestMapping("/t/material-lifecycle-detail")
@RequestMapping("/qms/resource/material-lifecycle-detail")
@Validated
public class MaterialLifecycleDetailController implements BusinessControllerMarker {
@@ -46,14 +46,22 @@ public class MaterialLifecycleDetailController implements BusinessControllerMark
return success(materialLifecycleDetailService.createMaterialLifecycleDetail(createReqVO));
}
// @PutMapping("/update")
@PutMapping("/update")
@Operation(summary = "更新物料通用流程明细")
@PreAuthorize("@ss.hasPermission('t:material-lifecycle-detail:update')")
// @PreAuthorize("@ss.hasPermission('t:material-lifecycle-detail:update')")
public CommonResult<Boolean> updateMaterialLifecycleDetail(@Valid @RequestBody MaterialLifecycleDetailSaveReqVO updateReqVO) {
materialLifecycleDetailService.updateMaterialLifecycleDetail(updateReqVO);
return success(true);
}
@PutMapping("/update-batch")
@Operation(summary = "批量更新物料通用流程明细")
// @PreAuthorize("@ss.hasPermission('t:material-lifecycle-detail:update')")
public CommonResult<Boolean> updateBatchMaterialLifecycleDetail(@Valid @RequestBody List<MaterialLifecycleDetailSaveReqVO> updateReqVOS) {
materialLifecycleDetailService.updateBatchMaterialLifecycleDetail(updateReqVOS);
return success(true);
}
// @DeleteMapping("/delete")
@Operation(summary = "删除物料通用流程明细")
@Parameter(name = "id", description = "编号", required = true)

View File

@@ -11,7 +11,9 @@ public enum MaterialInfomationOrigin {
standard_solution_make("标液配置"),
hazardous_material_make("危化品配置")
hazardous_material_make("危化品配置"),
verify_calibrate("检定校准"),
;
private final String name;

View File

@@ -182,4 +182,11 @@ public interface MaterialBatchService {
* @param adjustType 调整类型
*/
void updateBatchVerifyCalibrateCount(List<MaterialLifecycleDetailDO> batches, AdjustType adjustType);
/**
* 创建批次检定拆分工段
*
* @param id 流程id
*/
void createVerifyBatchAssignsByLfcId(Long id);
}

View File

@@ -4,8 +4,12 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zt.plat.framework.common.exception.ServiceException;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.module.bpm.api.task.BpmProcessInstanceApi;
import com.zt.plat.module.bpm.api.task.dto.BpmProcessInstanceRespDTO;
import com.zt.plat.module.bpm.api.task.dto.UserSimpleDTO;
import com.zt.plat.module.qms.core.code.SequenceUtil;
import com.zt.plat.module.qms.enums.AdjustType;
import com.zt.plat.module.qms.enums.LockType;
@@ -14,6 +18,7 @@ import com.zt.plat.module.qms.resource.material.controller.vo.MaterialBatchPageR
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialBatchRespVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialBatchSaveReqVO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialBatchDO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialLifecycleDO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialLifecycleDetailDO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialProductDO;
import com.zt.plat.module.qms.resource.material.dal.mapper.MaterialBatchMapper;
@@ -22,6 +27,7 @@ import com.zt.plat.module.qms.resource.material.enums.MaterialBatchGongType;
import com.zt.plat.module.qms.resource.material.enums.MaterialFlowType;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -54,9 +60,11 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
@Autowired
private MaterialProductService materialProductService;
@Lazy
@Autowired
private MaterialLifecycleDetailService materialLifecycleDetailService;
private MaterialLifecycleService materialLifecycleService;
@Autowired
private BpmProcessInstanceApi bpmProcessInstanceApi;
@Override
public MaterialBatchRespVO createMaterialBatch(MaterialBatchSaveReqVO createReqVO) {
@@ -246,7 +254,7 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
@Override
public void updateMaterialBatchAcceptStatusByLfcId(Long lfcId, String status) {
List<MaterialLifecycleDetailDO> detailList = materialLifecycleDetailService.getDetailListByLfcId(lfcId);
List<MaterialLifecycleDetailDO> detailList = materialLifecycleService.getDetailListByLfcId(lfcId);
if (CollUtil.isEmpty(detailList)) return;
List<Long> gongIds = detailList.stream().map(MaterialLifecycleDetailDO::getBatchGongduanId).toList();
if (CollUtil.isEmpty(gongIds)) return;
@@ -434,6 +442,38 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
materialBatchMapper.updateBatch(batchDOS);
}
@Override
public void createVerifyBatchAssignsByLfcId(Long id) {
MaterialLifecycleDO lifecycleDO = materialLifecycleService.getMaterialLifecycle(id);
if (lifecycleDO == null) return;
List<MaterialLifecycleDetailDO> lifecycleDetailDOs = materialLifecycleService.getDetailListByLfcId(id);
if (CollUtil.isEmpty(lifecycleDetailDOs)) return;
String flowInstanceId = lifecycleDO.getFlowInstanceId();
if (StrUtil.isEmpty(flowInstanceId)) return;
CommonResult<BpmProcessInstanceRespDTO> processInstance = bpmProcessInstanceApi.getProcessInstance(flowInstanceId);
BpmProcessInstanceRespDTO instanceData = processInstance.getData();
UserSimpleDTO startUser = instanceData.getStartUser();
List<Long> batIds = lifecycleDetailDOs.stream().map(MaterialLifecycleDetailDO::getBatchId).toList();
List<MaterialBatchDO> batchDOS = this.getBatchListByBatchIds(batIds);
Map<Long, MaterialBatchDO> batchDOMap = batchDOS.stream().collect(Collectors.toMap(MaterialBatchDO::getId, Function.identity()));
List<MaterialBatchDO> gongs = lifecycleDetailDOs.stream().map(detailDO -> {
MaterialBatchDO batchDO = batchDOMap.get(detailDO.getBatchId());
// TODO 此批次此部门下可能已经创建过
Long deptId = startUser.getDeptId();
MaterialBatchDO gong = new MaterialBatchDO()
.setParentId(detailDO.getBatchId())
.setProductId(batchDO.getProductId())
.setAssignDepartmentId(deptId)
.setAssignDepartmentName(startUser.getDeptName())
.setInboundQuantity(detailDO.getQualifiedCount())
.setBatchNo(batchDO.getBatchNo())
.setRemaineQuantity(detailDO.getQualifiedCount())
.setAcceptanceStatus(MaterialAcceptStatus.accepted.name());
return gong;
}).toList();
materialBatchMapper.insertBatch(gongs);
}
private void lockBatchOrGongReturnExchangeCount(LockType lockType, List<MaterialBatchDO> batchOrGongDOS, Map<Long, MaterialLifecycleDetailDO> lifecycleDetailDOMapByBatOrGongId) {
for (MaterialBatchDO batOrGong : batchOrGongDOS) {
MaterialLifecycleDetailDO detailDO = lifecycleDetailDOMapByBatOrGongId.get(batOrGong.getId());

View File

@@ -7,6 +7,7 @@ import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryI
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialInventoryInboundDO;
import jakarta.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -61,4 +62,10 @@ public interface MaterialInventoryInboundService {
*/
PageResult<MaterialInventoryInboundDO> getMaterialInventoryInboundPage(MaterialInventoryInboundPageReqVO pageReqVO);
/**
* 入库数量限制
*
* @param reqQuantity 入库数量
*/
void inboundQtyLimit(BigDecimal reqQuantity);
}

View File

@@ -64,19 +64,8 @@ public class MaterialInventoryInboundServiceImpl implements MaterialInventoryInb
Long gongduanId = createReqVO.getGongduanId();
BigDecimal reqQuantity = createReqVO.getQuantity();
if (reqQuantity.compareTo(BigDecimal.ZERO) <= 0) throw new ServiceException(1_032_160_000, "入库数量不能小于等于0");
CommonResult<DictionaryBusinessRespVO> inboundQuantityLimitResult = dictionaryBusinessService.getDataByDataKey(MaterialConstants.DICT_MATERIAL_INBOUND_QUANTITY_LIMIT);
DictionaryBusinessRespVO inboundQuantityLimit = inboundQuantityLimitResult.getData();
if (reqQuantity.compareTo(CommonConstant.MAX_GENERATE_QUANTITY) > 0
|| reqQuantity.compareTo(CommonConstant.MAX_RESPONSE_QUANTITY) > 0)
throw new ServiceException(1_032_160_000,
String.format("入库数量不能超过系统限制数量:%s", Math.min(CommonConstant.MAX_GENERATE_QUANTITY.doubleValue(), CommonConstant.MAX_RESPONSE_QUANTITY.doubleValue())));
if (inboundQuantityLimit != null) {
BigDecimal inbQtyLimit = new BigDecimal(inboundQuantityLimit.getValue());
if (reqQuantity.compareTo(inbQtyLimit) > 0) {
throw new ServiceException(1_032_160_000,
String.format("入库数量超出配置限制:%s当前请求数量%s", inbQtyLimit, reqQuantity));
}
}
// 入库数量限制
inboundQtyLimit(reqQuantity);
MaterialBatchDO gongDO = materialBatchService.getMaterialBatch(gongduanId);
if (gongDO == null) throw exception(MATERIAL_BATCH_GONG_NOT_EXISTS);
// 1.检查工段是否已经验收
@@ -121,6 +110,23 @@ public class MaterialInventoryInboundServiceImpl implements MaterialInventoryInb
return respVO;
}
@Override
public void inboundQtyLimit(BigDecimal reqQuantity) {
CommonResult<DictionaryBusinessRespVO> inboundQuantityLimitResult = dictionaryBusinessService.getDataByDataKey(MaterialConstants.DICT_MATERIAL_INBOUND_QUANTITY_LIMIT);
DictionaryBusinessRespVO inboundQuantityLimit = inboundQuantityLimitResult.getData();
if (reqQuantity.compareTo(CommonConstant.MAX_GENERATE_QUANTITY) > 0
|| reqQuantity.compareTo(CommonConstant.MAX_RESPONSE_QUANTITY) > 0)
throw new ServiceException(1_032_160_000,
String.format("入库数量不能超过系统限制数量:%s", Math.min(CommonConstant.MAX_GENERATE_QUANTITY.doubleValue(), CommonConstant.MAX_RESPONSE_QUANTITY.doubleValue())));
if (inboundQuantityLimit != null) {
BigDecimal inbQtyLimit = new BigDecimal(inboundQuantityLimit.getValue());
if (reqQuantity.compareTo(inbQtyLimit) > 0) {
throw new ServiceException(1_032_160_000,
String.format("入库数量超出配置限制:%s当前请求数量%s", inbQtyLimit, reqQuantity));
}
}
}
private MaterialInventoryInboundDO getInbound(MaterialInventoryInboundSaveReqVO createReqVO, MaterialBatchDO gongDO) {
MaterialInventoryInboundDO inbound = BeanUtils.toBean(createReqVO, MaterialInventoryInboundDO.class);
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();

View File

@@ -146,4 +146,11 @@ public interface MaterialLifecycleDetailService {
* @return 明细列表
*/
List<MaterialLifecycleDetailDO> getDetailListByLfcIds(List<Long> lfcIds);
/**
* 批量更新
*
* @param updateReqVO 批量更新信息
*/
void updateBatchMaterialLifecycleDetail(@Valid List<MaterialLifecycleDetailSaveReqVO> updateReqVO);
}

View File

@@ -3,16 +3,19 @@ package com.zt.plat.module.qms.resource.material.service;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zt.plat.framework.common.exception.ServiceException;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.module.qms.enums.QmsBpmConstant;
import com.zt.plat.module.qms.enums.QmsCommonConstant;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryInboundSaveReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialLifecycleDetailPageReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialLifecycleDetailRespVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialLifecycleDetailSaveReqVO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.*;
import com.zt.plat.module.qms.resource.material.dal.mapper.MaterialLifecycleDetailMapper;
import com.zt.plat.module.qms.resource.material.enums.MaterialFlowType;
import com.zt.plat.module.qms.resource.material.enums.MaterialInfomationOrigin;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@@ -46,6 +49,9 @@ public class MaterialLifecycleDetailServiceImpl implements MaterialLifecycleDeta
@Autowired
private MaterialProductService materialProductService;
@Autowired
private MaterialInventoryInboundService materialInventoryInboundService;
@Override
public MaterialLifecycleDetailRespVO createMaterialLifecycleDetail(MaterialLifecycleDetailSaveReqVO createReqVO) {
// 插入
@@ -57,11 +63,20 @@ public class MaterialLifecycleDetailServiceImpl implements MaterialLifecycleDeta
@Override
public void updateMaterialLifecycleDetail(MaterialLifecycleDetailSaveReqVO updateReqVO) {
// 校验存在
validateMaterialLifecycleDetailExists(updateReqVO.getId());
MaterialLifecycleDetailDO detailDO = materialLifecycleDetailMapper.selectById(updateReqVO.getId());
if (detailDO == null) throw exception(MATERIAL_LIFECYCLE_DETAIL_NOT_EXISTS);
// 更新
MaterialLifecycleDetailDO updateObj = BeanUtils.toBean(updateReqVO, MaterialLifecycleDetailDO.class);
materialLifecycleDetailMapper.updateById(updateObj);
MaterialFlowType flowType = MaterialFlowType.fromName(detailDO.getBusinessType());
if (MaterialFlowType.verify_calibrate.equals(flowType)) {
// 合格数量不大于总数量
BigDecimal qualifiedCount = updateReqVO.getQualifiedCount();
if (qualifiedCount == null) throw new ServiceException(1_032_160_000, "请填写合格数量");
if (qualifiedCount.compareTo(detailDO.getInfluenceCount()) > 0)
throw new ServiceException(1_032_160_000, "合格数量不能大于总数量");
detailDO.setQualifiedCount(qualifiedCount);
detailDO.setUnqualifiedCount(detailDO.getInfluenceCount().subtract(detailDO.getQualifiedCount()));
}
materialLifecycleDetailMapper.updateById(detailDO);
}
@Override
@@ -213,4 +228,34 @@ public class MaterialLifecycleDetailServiceImpl implements MaterialLifecycleDeta
.in(MaterialLifecycleDetailDO::getLifecycleId, lfcIds));
}
@Override
public void updateBatchMaterialLifecycleDetail(List<MaterialLifecycleDetailSaveReqVO> updateReqVOS) {
List<MaterialLifecycleDetailDO> reqDetailDOS = BeanUtils.toBean(updateReqVOS, MaterialLifecycleDetailDO.class);
List<Long> dtlIds = reqDetailDOS.stream().map(MaterialLifecycleDetailDO::getId).filter(Objects::nonNull).toList();
if (CollUtil.isEmpty(dtlIds) || dtlIds.size() != updateReqVOS.size())
throw new ServiceException(1_032_160_000, "存在id为空的请求数据");
List<MaterialLifecycleDetailDO> detailDOS = materialLifecycleDetailMapper.selectByIds(dtlIds);
if (CollUtil.isEmpty(detailDOS) || detailDOS.size() != dtlIds.size())
throw exception(MATERIAL_LIFECYCLE_DETAIL_NOT_EXISTS);
Map<String, List<MaterialLifecycleDetailDO>> detailGroupByBusinessType = detailDOS.stream().collect(Collectors.groupingBy(MaterialLifecycleDetailDO::getBusinessType));
List<MaterialLifecycleDetailDO> verifyDetailDOS = detailGroupByBusinessType.get(MaterialFlowType.verify_calibrate.getName());
// 检定校准
if (CollUtil.isNotEmpty(verifyDetailDOS)) {
Map<Long, MaterialLifecycleDetailDO> verifyDetailDOMapById = verifyDetailDOS.stream().collect(Collectors.toMap(MaterialLifecycleDetailDO::getId, Function.identity()));
Map<Long, MaterialLifecycleDetailDO> reqDOMapById = reqDetailDOS.stream().collect(Collectors.toMap(MaterialLifecycleDetailDO::getId, Function.identity()));
for (MaterialLifecycleDetailDO detailDO : reqDetailDOS) {
BigDecimal qualifiedCount = reqDOMapById.get(detailDO.getId()).getQualifiedCount();
MaterialLifecycleDetailDO verifyDetailDO = verifyDetailDOMapById.get(detailDO.getId());
if (qualifiedCount == null) throw new ServiceException(1_032_160_000, "请填写合格数量");
BigDecimal influenceCount = verifyDetailDO.getInfluenceCount();
if (qualifiedCount.compareTo(influenceCount) > 0)
throw new ServiceException(1_032_160_000, "合格数量不能大于总数量");
detailDO.setQualifiedCount(qualifiedCount);
detailDO.setUnqualifiedCount(influenceCount.subtract(detailDO.getQualifiedCount()));
}
materialLifecycleDetailMapper.updateBatch(reqDetailDOS);
}
}
}

View File

@@ -11,11 +11,14 @@ import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.bpm.api.event.BpmProcessInstanceStatusEvent;
import com.zt.plat.module.bpm.api.event.BpmProcessInstanceStatusEventListener;
import com.zt.plat.module.bpm.api.task.BpmProcessInstanceApi;
import com.zt.plat.module.bpm.api.task.BpmTaskApi;
import com.zt.plat.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import com.zt.plat.module.bpm.api.task.dto.BpmTaskApproveReqDTO;
import com.zt.plat.module.bpm.api.task.dto.BpmTaskRespDTO;
import com.zt.plat.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
import com.zt.plat.module.infra.api.businessfile.dto.BusinessFileWithUrlRespDTO;
import com.zt.plat.module.qms.api.task.BMPCallbackInterface;
import com.zt.plat.module.qms.api.task.dto.QmsBpmDTO;
@@ -668,10 +671,10 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService ,
*/
@Override
public CommonResult<JSONObject> callback(QmsBpmDTO reqDTO) {
log.debug("物料流程回调信息:{}", reqDTO.toString());
log.info("物料流程回调信息:{}", reqDTO.toString());
JSONObject variables = reqDTO.getVariables();
log.debug("流程变量:{}", variables.toString());
log.info("流程变量:{}", variables.toString());
String processInsId = reqDTO.getProcessInstanceId();
String currentActivityInsId = variables.getString(QmsBpmConstant.BPM_CUR_ACTIVITY_INS_ID);
String returnFlag = variables.getString(QmsBpmConstant.BPM_REJECT_TO_FIRST_FLAG);
@@ -710,8 +713,8 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService ,
}
}
}
// 走到检化验节点时需要发起检化验流程
// TODO 走到检化验节点时需要发起检化验流程
MaterialFlowType flowType = MaterialFlowType.fromName(entity.getBusinessType());
// 根据流程状态处理业务数据
if(("1").equals(returnFlag)){
// 驳回。流程需要配置退回到发起节点
@@ -735,8 +738,13 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService ,
entity.setFlowStatus(QmsCommonConstant.COMPLETED);
// 更新明细处理状态
materialLifecycleDetailService.updateDetailTreatStatusByLfcId(entity.getId(), true);
if (MaterialFlowType.acceptance.equals(flowType))
// 更新批次工段验收状态
materialBatchService.updateMaterialBatchAcceptStatusByLfcId(entity.getId(), MaterialAcceptStatus.accepted.name());
if (MaterialFlowType.verify_calibrate.equals(flowType))
// 批次检定完成后生成批次拆分
materialBatchService.createVerifyBatchAssignsByLfcId(entity.getId());
}
}