feat:物料验收流程接口

This commit is contained in:
shusir
2026-01-30 17:16:02 +08:00
parent 3302a2ee7c
commit 58ab9961c4
11 changed files with 172 additions and 45 deletions

View File

@@ -98,6 +98,13 @@ public class MaterialBatchController implements BusinessControllerMarker {
return success(pageResult);
}
@GetMapping("/gong-page")
@Operation(summary = "获得批次工段分页")
public CommonResult<PageResult<MaterialBatchRespVO>> getMaterialBatchGongPage(@Valid MaterialBatchPageReqVO pageReqVO) {
PageResult<MaterialBatchRespVO> pageResult = materialBatchService.getMaterialBatchGongPageWithPdtInfo(pageReqVO);
return success(pageResult);
}
@GetMapping("/export-excel")
@Operation(summary = "导出物料批次 Excel")
@PreAuthorize("@ss.hasPermission('qms:material-batch:export')")

View File

@@ -11,10 +11,9 @@ import com.zt.plat.framework.common.pojo.vo.BatchDeleteReqVO;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.datapermission.core.annotation.DeptDataPermissionIgnore;
import com.zt.plat.framework.excel.core.util.ExcelUtils;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialLifecyclePageReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialLifecycleRespVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialLifecycleSaveReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.*;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialLifecycleDO;
import com.zt.plat.module.qms.resource.material.service.MaterialBatchService;
import com.zt.plat.module.qms.resource.material.service.MaterialLifecycleService;
import com.zt.plat.module.qms.resource.material.valid.AddGroup;
import com.zt.plat.module.qms.resource.material.valid.UpdateGroup;
@@ -24,6 +23,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -36,9 +36,9 @@ import static com.zt.plat.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 物料通用流程,物料验收、退换货")
@RestController
@RequestMapping("/t/material-lifecycle")
@RequestMapping("/qms/resource/material-lifecycle")
@Validated
@FileUploadController(source = "t.materiallifecycle")
@FileUploadController(source = "resource.materiallifecycle")
@DeptDataPermissionIgnore(enable = "true")
public class MaterialLifecycleController extends AbstractFileUploadController implements BusinessControllerMarker{
@@ -68,7 +68,7 @@ public class MaterialLifecycleController extends AbstractFileUploadController im
}
@DeleteMapping("/delete")
@Operation(summary = "删除物料通用流程,物料验收、退换货")
@Operation(summary = "删除物料流程")
@Parameter(name = "id", description = "编号", required = true)
// @PreAuthorize("@ss.hasPermission('t:material-lifecycle:delete')")
public CommonResult<Boolean> deleteMaterialLifecycle(@RequestParam("id") Long id) {
@@ -78,7 +78,7 @@ public class MaterialLifecycleController extends AbstractFileUploadController im
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除物料通用流程,物料验收、退换货")
@Operation(summary = "批量删除物料流程")
@PreAuthorize("@ss.hasPermission('t:material-lifecycle:delete')")
public CommonResult<Boolean> deleteMaterialLifecycleList(@RequestBody BatchDeleteReqVO req) {
materialLifecycleService.deleteMaterialLifecycleListByIds(req.getIds());
@@ -86,9 +86,9 @@ public class MaterialLifecycleController extends AbstractFileUploadController im
}
@GetMapping("/get")
@Operation(summary = "获得物料通用流程,物料验收、退换货")
@Operation(summary = "获得物料通用流程")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('t:material-lifecycle:query')")
// @PreAuthorize("@ss.hasPermission('t:material-lifecycle:query')")
public CommonResult<MaterialLifecycleRespVO> getMaterialLifecycle(@RequestParam("id") Long id) {
MaterialLifecycleDO materialLifecycle = materialLifecycleService.getMaterialLifecycle(id);
return success(BeanUtils.toBean(materialLifecycle, MaterialLifecycleRespVO.class));

View File

@@ -54,7 +54,7 @@ public class MaterialBatchPageReqVO extends PageParam {
@Schema(description = "是否检化验,1-是0-否")
private Integer assayFlag;
@Schema(description = "检化验状态,NOT_STARTED-未开始IN_PROGRESS-进行中PASSED-通过NOT_PASSED-未通过", example = "2")
@Schema(description = "检化验状态,未开始,进行中,通过,未通过", example = "2")
private String assayStatus;
// @Schema(description = "检化验结果")

View File

@@ -20,18 +20,39 @@ public class MaterialLifecycleDetailRespVO {
@ExcelProperty("父id")
private Long lifecycleId;
@Schema(description = "物料大类id", example = "31283")
@ExcelProperty("物料大类id")
private Long productId;
@Schema(description = "物料大类名称")
@ExcelProperty("物料大类名称")
private String productName;
@Schema(description = "物料大类编码")
@ExcelProperty("物料大类编码")
private String productCode;
@Schema(description = "物料大类型号")
@ExcelProperty("物料大类型号")
private String productModelNo;
@Schema(description = "物料批次id", example = "12948")
@ExcelProperty("物料批次id")
private Long batchId;
@Schema(description = "物料批次号")
@ExcelProperty("物料批次号")
private String batchNo;
@Schema(description = "批次工段id", example = "21334")
@ExcelProperty("批次工段id")
private Long batchGongduanId;
@Schema(description = "批次工段-部门名称")
@ExcelProperty("批次工段-部门名称")
private String assignDepartmentName;
@Schema(description = "物料实例id", example = "968")
@ExcelProperty("物料实例id")
private Long infomationId;

View File

@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 物料通用流程,物料验收、退换货 Response VO")
@Data
@@ -76,4 +77,8 @@ public class MaterialLifecycleRespVO {
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "流程明细")
@ExcelProperty("流程明细")
private List<MaterialLifecycleDetailRespVO> detailList;
}

View File

@@ -36,20 +36,24 @@ public interface MaterialBatchMapper extends BaseMapperX<MaterialBatchDO> {
.eqIfPresent(MaterialBatchDO::getAcceptanceStatus, reqVO.getAcceptanceStatus())
.eqIfPresent(MaterialBatchDO::getAssayFlag, reqVO.getAssayFlag())
.eqIfPresent(MaterialBatchDO::getAssayStatus, reqVO.getAssayStatus())
//.eqIfPresent(MaterialBatchDO::getAssayResult, reqVO.getAssayResult())
.eqIfPresent(MaterialBatchDO::getSystemDepartmentCode, reqVO.getSystemDepartmentCode())
.eqIfPresent(MaterialBatchDO::getRemark, reqVO.getRemark())
.betweenIfPresent(MaterialBatchDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MaterialBatchDO::getId));
}
default PageResult<MaterialBatchRespVO> selectPage(MaterialBatchPageReqVO reqVO, List<Long> pdtIds) {
// onlyGong 是否只查询工段
default PageResult<MaterialBatchRespVO> selectPage(MaterialBatchPageReqVO reqVO, List<Long> pdtIds, Boolean onlyGong) {
MPJLambdaWrapper<MaterialBatchDO> wrapper = new MPJLambdaWrapperX<MaterialBatchDO>()
.selectAll(MaterialBatchDO.class)
.selectAs(MaterialProductDO::getName, MaterialBatchRespVO::getProductName)
.selectAs(MaterialProductDO::getCode, MaterialBatchRespVO::getProductCode)
.selectAs(MaterialProductDO::getModelNo, MaterialBatchRespVO::getProductModelNo)
.leftJoin(MaterialProductDO.class, MaterialProductDO::getId, MaterialBatchDO::getProductId)
// 只查询批次,不查询工段
.eq(onlyGong != null && !onlyGong, MaterialBatchDO::getParentId, 0)
// 只查询工段
.ne(onlyGong != null && onlyGong, MaterialBatchDO::getParentId, 0)
.in(CollUtil.isNotEmpty(pdtIds), MaterialBatchDO::getProductId, pdtIds)
.eq(CollUtil.isEmpty(pdtIds) && reqVO.getProductId() != null, MaterialBatchDO::getProductId, reqVO.getProductId())
.likeIfExists(MaterialBatchDO::getBatchNo, reqVO.getBatchNo())

View File

@@ -116,4 +116,12 @@ public interface MaterialBatchService {
* @return 工段列表
*/
List<MaterialBatchDO> getGongduanListByGongIds(List<Long> gongIds);
/**
* 获得批次工段分页 - 需要可以层级穿透查询及返回物料信息
*
* @param pageReqVO 分页请求参数
* @return 分页数据
*/
PageResult<MaterialBatchRespVO> getMaterialBatchGongPageWithPdtInfo(@Valid MaterialBatchPageReqVO pageReqVO);
}

View File

@@ -137,20 +137,20 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
@Override
public PageResult<MaterialBatchRespVO> getMaterialBatchPageWithPdtInfo(MaterialBatchPageReqVO pageReqVO) {
Long pdtId = pageReqVO.getProductId();
PageResult<MaterialBatchRespVO> pageResult;
if (pdtId == null) {
pageResult = materialBatchMapper.selectPage(pageReqVO, List.of());
} else {
List<MaterialProductDO> mtrlDos = materialProductService.getMaterialProductsByLikeIdPath(pdtId);
if (CollUtil.isEmpty(mtrlDos)) {
pageResult = materialBatchMapper.selectPage(pageReqVO, List.of());
} else {
List<Long> pdtIds = mtrlDos.stream().map(MaterialProductDO::getId).toList();
pageResult = materialBatchMapper.selectPage(pageReqVO, pdtIds);
// 先分页查询批次
PageResult<MaterialBatchRespVO> pageResult = getMaterialBatchRespVOPageWithPdtInfo(pageReqVO, false);
// 再获取工段
List<MaterialBatchRespVO> batches = pageResult.getList();
if (CollUtil.isNotEmpty(batches)) {
List<Long> batIds = batches.stream().map(MaterialBatchRespVO::getId).toList();
List<MaterialBatchDO> gongs = materialBatchMapper.selectList(Wrappers.lambdaQuery(MaterialBatchDO.class)
.in(MaterialBatchDO::getParentId, batIds));
if (CollUtil.isNotEmpty(gongs)) {
List<MaterialBatchRespVO> gongRespVOs = gongs.stream().map(gong -> BeanUtils.toBean(gong, MaterialBatchRespVO.class)).toList();
batches.addAll(gongRespVOs);
pageResult.setList(batches);
}
}
if (!pageReqVO.getChildren()) return pageResult;
List<MaterialBatchRespVO> voList = pageResult.getList();
if (CollUtil.isNotEmpty(voList)) {
@@ -198,7 +198,7 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
// 3. 保存工段
List<MaterialBatchDO> gongEts = createReqVOs.stream().map(batAsn -> {
MaterialBatchDO bean = BeanUtils.toBean(batAsn, MaterialBatchDO.class);
bean.setProductId(mtrlBat.getProductId());
bean.setProductId(mtrlBat.getProductId()).setBatchNo(mtrlBat.getBatchNo());
return bean;
}).toList();
materialBatchMapper.insertBatch(gongEts);
@@ -256,6 +256,30 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
.ne(MaterialBatchDO::getParentId, 0));
}
@Override
public PageResult<MaterialBatchRespVO> getMaterialBatchGongPageWithPdtInfo(MaterialBatchPageReqVO pageReqVO) {
return getMaterialBatchRespVOPageWithPdtInfo(pageReqVO, true);
}
private PageResult<MaterialBatchRespVO> getMaterialBatchRespVOPageWithPdtInfo(MaterialBatchPageReqVO pageReqVO, boolean onlyGong) {
Long pdtId = pageReqVO.getProductId();
PageResult<MaterialBatchRespVO> pageResult;
if (pdtId == null) {
pageResult = materialBatchMapper.selectPage(pageReqVO, List.of(), onlyGong);
} else {
List<MaterialProductDO> mtrlDos = materialProductService.getMaterialProductsByLikeIdPath(pdtId);
if (CollUtil.isEmpty(mtrlDos)) {
pageResult = materialBatchMapper.selectPage(pageReqVO, List.of(), onlyGong);
} else {
List<Long> pdtIds = mtrlDos.stream().map(MaterialProductDO::getId).toList();
pageResult = materialBatchMapper.selectPage(pageReqVO, pdtIds, onlyGong);
}
}
return pageResult;
}
/**
* 组装物料批次树
*

View File

@@ -65,7 +65,20 @@ public interface MaterialLifecycleDetailService {
* 批量保存
*
* @param detailDOS 需要保存的列表
* @return 成功与否
*/
Boolean saveBatch(List<MaterialLifecycleDetailDO> detailDOS);
void saveBatch(List<MaterialLifecycleDetailDO> detailDOS);
/**
* 根据流程id 删除流程明细数据
*
* @param lfcId 流程id
*/
void deleteLifecycleDetailListByLfcId(Long lfcId);
/**
* 根据流程ids 删除流程明细数据
*
* @param ids 流程ids
*/
void deleteLifecycleDetailListByLfcIds(List<Long> ids);
}

View File

@@ -1,6 +1,7 @@
package com.zt.plat.module.qms.resource.material.service;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialLifecycleDetailPageReqVO;
@@ -87,10 +88,22 @@ public class MaterialLifecycleDetailServiceImpl implements MaterialLifecycleDeta
}
@Override
public Boolean saveBatch(List<MaterialLifecycleDetailDO> detailDOS) {
if (CollUtil.isEmpty(detailDOS)) return false;
public void saveBatch(List<MaterialLifecycleDetailDO> detailDOS) {
if (CollUtil.isEmpty(detailDOS)) return;
materialLifecycleDetailMapper.insertBatch(detailDOS);
return true;
}
@Override
public void deleteLifecycleDetailListByLfcId(Long lfcId) {
materialLifecycleDetailMapper.delete(Wrappers.lambdaQuery(MaterialLifecycleDetailDO.class)
.eq(MaterialLifecycleDetailDO::getLifecycleId, lfcId));
}
@Override
public void deleteLifecycleDetailListByLfcIds(List<Long> ids) {
materialLifecycleDetailMapper.delete(Wrappers.lambdaQuery(MaterialLifecycleDetailDO.class)
.in(MaterialLifecycleDetailDO::getLifecycleId, ids));
}
}

View File

@@ -1,6 +1,7 @@
package com.zt.plat.module.qms.resource.material.service;
import cn.hutool.core.collection.CollUtil;
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;
@@ -12,6 +13,7 @@ import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialLifecycle
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialLifecycleDetailDO;
import com.zt.plat.module.qms.resource.material.dal.mapper.MaterialLifecycleMapper;
import jakarta.annotation.Resource;
import org.jspecify.annotations.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -26,7 +28,7 @@ import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.e
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.MATERIAL_LIFECYCLE_NOT_EXISTS;
/**
* 物料通用流程,物料验收、退换货 Service 实现类
* 物料通用流程,物料验收、退换货 Service 实现类
*
* @author 后台管理
*/
@@ -57,8 +59,18 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService {
List<MaterialBatchDO> gongs = materialBatchService.getGongduanListByGongIds(gongIds);
if (CollUtil.isEmpty(gongs) || gongs.size() != gongIds.size())
throw new ServiceException(1_032_160_000, "工段不存在或与传入的工段数量不匹配");
List<MaterialLifecycleDetailDO> detailDOS = getLifecycleDetailDOsByGongs(gongs, gongIds, mtrlLfc);
materialLifecycleDetailService.saveBatch(detailDOS);
return BeanUtils.toBean(mtrlLfc, MaterialLifecycleRespVO.class);
}
/**
* 工段列表转流程明细列表
*
*/
private List<MaterialLifecycleDetailDO> getLifecycleDetailDOsByGongs(List<MaterialBatchDO> gongs, List<Long> gongIds, MaterialLifecycleDO mtrlLfc) {
Map<Long, MaterialBatchDO> gongsMap = gongs.stream().collect(Collectors.toMap(MaterialBatchDO::getId, Function.identity()));
List<MaterialLifecycleDetailDO> detailDOS = gongIds.stream().map(id -> {
return gongIds.stream().map(id -> {
MaterialBatchDO gong = gongsMap.get(id);
MaterialLifecycleDetailDO detailDO = new MaterialLifecycleDetailDO();
detailDO.setLifecycleId(mtrlLfc.getId())
@@ -67,40 +79,60 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService {
.setTreatmentStatus(0);
return detailDO;
}).toList();
materialLifecycleDetailService.saveBatch(detailDOS);
return BeanUtils.toBean(mtrlLfc, MaterialLifecycleRespVO.class);
}
@Transactional
@Override
public void updateMaterialLifecycle(MaterialLifecycleSaveReqVO updateReqVO) {
MaterialLifecycleDO lifecycleDO = materialLifecycleMapper.selectById(updateReqVO.getId());
Long reqId = updateReqVO.getId();
MaterialLifecycleDO lifecycleDO = materialLifecycleMapper.selectById(reqId);
if (lifecycleDO == null) throw exception(MATERIAL_LIFECYCLE_NOT_EXISTS);
if (lifecycleDO.getSubmitStatus() == 1) throw new ServiceException(1_032_160_000, "流程已提交,不可修改");
List<Long> gongIds = updateReqVO.getGongIds();
// 更新
MaterialLifecycleDO updateObj = BeanUtils.toBean(updateReqVO, MaterialLifecycleDO.class);
MaterialLifecycleDO mtrlLfc = BeanUtils.toBean(updateReqVO, MaterialLifecycleDO.class);
if (CollUtil.isEmpty(gongIds)) {
materialLifecycleMapper.updateById(updateObj);
materialLifecycleMapper.updateById(mtrlLfc);
return;
}
// 明细
// 删除原来的明细
materialLifecycleDetailService.deleteLifecycleDetailListByLfcId(reqId);
List<MaterialBatchDO> gongs = materialBatchService.getGongduanListByGongIds(gongIds);
if (CollUtil.isEmpty(gongs) || gongs.size() != gongIds.size())
throw new ServiceException(1_032_160_000, "工段不存在或与传入的工段数量不匹配");
// 保存新的明细
List<MaterialLifecycleDetailDO> detailDOS = getLifecycleDetailDOsByGongs(gongs, gongIds, mtrlLfc);
materialLifecycleDetailService.saveBatch(detailDOS);
}
@Transactional
@Override
public void deleteMaterialLifecycle(Long id) {
// 校验存在
validateMaterialLifecycleExists(id);
// 删除
MaterialLifecycleDO lifecycleDO = materialLifecycleMapper.selectById(id);
if (lifecycleDO == null) throw exception(MATERIAL_LIFECYCLE_NOT_EXISTS);
// 已提交的流程不允许删除
if (lifecycleDO.getSubmitStatus() == 1) throw new ServiceException(1_032_160_000, "流程已提交,不可删除");
// 删除明细
materialLifecycleDetailService.deleteLifecycleDetailListByLfcId(id);
// 删除流程
materialLifecycleMapper.deleteById(id);
}
@Transactional
@Override
public void deleteMaterialLifecycleListByIds(List<Long> ids) {
// 校验存在
validateMaterialLifecycleExists(ids);
// 删除
List<MaterialLifecycleDO> list = materialLifecycleMapper.selectByIds(ids);
if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
throw exception(MATERIAL_LIFECYCLE_NOT_EXISTS);
}
// 存在已提交的流程不允许删除
for (MaterialLifecycleDO lifecycle : list) {
if (lifecycle.getSubmitStatus() == 1)
throw new ServiceException(1_032_160_000, "存在已提交的流程,不可删除");
}
// 删除明细
materialLifecycleDetailService.deleteLifecycleDetailListByLfcIds(ids);
// 删除流程
materialLifecycleMapper.deleteByIds(ids);
}