From 5d314130e6f21bd265388b5210808baeba5f2d0c Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期一, 23 三月 2026 17:57:14 +0800
Subject: [PATCH] feat: 生产报工的工序参数/BOM消耗产品查询返回、新增报工、分页查询
---
src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 348 insertions(+), 0 deletions(-)
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java
new file mode 100644
index 0000000..45d43d1
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java
@@ -0,0 +1,348 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.other.mapper.TempFileMapper;
+import com.ruoyi.other.pojo.TempFile;
+import com.ruoyi.production.dto.ProductionProductRouteItemDto;
+import com.ruoyi.production.dto.ProductionProductRouteItemParamDto;
+import com.ruoyi.production.dto.ProductionRecordDto;
+import com.ruoyi.production.enums.ProductOrderStatusEnum;
+import com.ruoyi.production.pojo.*;
+import com.ruoyi.production.service.*;
+import com.ruoyi.production.vo.ProductionOrderRouteItemParamVo;
+import com.ruoyi.production.vo.ProductionOrderRouteItemVo;
+import com.ruoyi.production.vo.ProductionOrderStructureVo;
+import com.ruoyi.production.vo.ProductionRecordVo;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FilenameUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * <br>
+ * 鐢熶骇鎶ュ伐璁板綍Service瀹炵幇绫�
+ * </br>
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/03/23 10:23
+ */
+@Slf4j
+@Service
+public class ProductionRecordServiceImpl implements ProductionRecordService {
+
+ @Value("${file.upload-dir}")
+ private String uploadDir;
+
+ @Autowired
+ private ProductionProductMainService productionProductMainService;
+
+ @Autowired
+ private ProductionProductInputService productionProductInputService;
+
+ @Autowired
+ private ProductionProductOutputService productionProductOutputService;
+
+ @Autowired
+ private IProductionProductRouteItemService productionProductRouteItemService;
+
+ @Autowired
+ private IProductionProductRouteItemParamService productionProductRouteItemParamService;
+
+ @Autowired
+ private IProductionProductRouteItemFileService productionProductRouteItemFileService;
+
+ @Autowired
+ private ProductOrderService productOrderService;
+
+ @Autowired
+ private IProductionOrderRouteItemService productionOrderRouteItemService;
+
+ @Autowired
+ private IProductionOrderRouteItemParamService productionOrderRouteItemParamService;
+
+ @Autowired
+ private IProductionOrderStructureService productionOrderStructureService;
+
+ @Autowired
+ private ProductProcessService productProcessService;
+
+ @Autowired
+ private ProductMaterialSkuService productMaterialSkuService;
+
+ @Autowired
+ private ProductMaterialService productMaterialService;
+
+ @Autowired
+ private TempFileMapper tempFileMapper;
+
+ @Override
+ public ProductionRecordVo productRouteItem(Long productOrderId) {
+ if (productOrderId == null) {
+ throw new ServiceException("璇烽�夋嫨鐢熶骇璁㈠崟鍐嶆柊澧炴姤宸�");
+ }
+
+ // 鏌ヨ鍑虹敓浜ц鍗曠粦瀹氱殑宸ヨ壓璺嚎
+ ProductOrder productOrder = productOrderService.getById(productOrderId);
+ if (productOrder == null) {
+ throw new ServiceException("鏈煡璇㈠埌璇ョ敓浜ц鍗曠殑淇℃伅");
+ }
+ // 閫氳繃宸ヨ壓璺嚎鏌ヨ鍑虹粦瀹氱殑宸ュ簭鍙婂弬鏁�
+ List<ProductionOrderRouteItem> productionOrderRouteItemList = productionOrderRouteItemService.list(new LambdaQueryWrapper<ProductionOrderRouteItem>()
+ .eq(ProductionOrderRouteItem::getOrderId, productOrderId)
+ .eq(ProductionOrderRouteItem::getRouteId, productOrder.getRouteId()));
+
+ if (productionOrderRouteItemList == null || productionOrderRouteItemList.isEmpty()) {
+ throw new ServiceException("璇ョ敓浜ц鍗曠粦瀹氱殑宸ヨ壓璺嚎鏃犲伐搴�");
+ }
+
+ ProductionRecordVo productionRecordVo = new ProductionRecordVo();
+ productionRecordVo.setProductOrderId(productOrderId);
+ productionRecordVo.setProductRouteId(productOrder.getRouteId());
+
+ List<ProductionOrderRouteItemVo> productionOrderRouteItemVoList = new ArrayList<>();
+
+ // 鏍规嵁缁戝畾鐨勫伐搴忔煡璇㈠嚭宸ュ簭鍙傛暟鍙夿OM闇�瑕佹秷鑰楃殑浜у搧
+ for (ProductionOrderRouteItem orderRouteItem : productionOrderRouteItemList) {
+ ProductionOrderRouteItemVo productionOrderRouteItemVo = new ProductionOrderRouteItemVo();
+ productionOrderRouteItemVo.setProcessId(orderRouteItem.getProcessId());
+
+ if (orderRouteItem.getProcessId() != null) {
+ ProductProcess process = productProcessService.getById(orderRouteItem.getProcessId());
+ if (process != null) {
+ productionOrderRouteItemVo.setProcessName(process.getName());
+ }
+ }
+
+ List<ProductionOrderRouteItemParam> orderRouteItemParamList = productionOrderRouteItemParamService.list(new LambdaQueryWrapper<ProductionOrderRouteItemParam>()
+ .eq(ProductionOrderRouteItemParam::getOrderId, productOrderId)
+ .eq(ProductionOrderRouteItemParam::getRouteItemId, orderRouteItem.getId()));
+
+ if (orderRouteItemParamList != null && !orderRouteItemParamList.isEmpty()) {
+ List<ProductionOrderRouteItemParamVo> paraVoList = orderRouteItemParamList.stream().map(param -> {
+ ProductionOrderRouteItemParamVo paraVo = new ProductionOrderRouteItemParamVo();
+ BeanUtils.copyProperties(param, paraVo);
+ paraVo.setParamFormat(DateUtils.toUpperCasePattern(paraVo.getParamFormat()));
+ return paraVo;
+ }).collect(Collectors.toList());
+ productionOrderRouteItemVo.setOrderRouteItemParaVos(paraVoList);
+ }
+
+ List<ProductionOrderStructure> orderStructureList = productionOrderStructureService.list(new LambdaQueryWrapper<ProductionOrderStructure>()
+ .eq(ProductionOrderStructure::getOrderId, productOrderId)
+ .eq(ProductionOrderStructure::getProcessId, orderRouteItem.getProcessId()));
+
+ if (orderStructureList != null && !orderStructureList.isEmpty()) {
+ List<ProductionOrderStructureVo> structureVoList = orderStructureList.stream().map(struct -> {
+ ProductionOrderStructureVo structureVo = new ProductionOrderStructureVo();
+ BeanUtils.copyProperties(struct, structureVo);
+ // 鏌ヨ鍑轰骇鍝佺殑鍚嶇О/妯″瀷
+ ProductMaterialSku productMaterialSku = productMaterialSkuService.getById(structureVo.getProductModelId());
+ ProductMaterial productMaterial = productMaterialService.getById(productMaterialSku.getProductId());
+ structureVo.setProductName(productMaterial.getProductName());
+ structureVo.setModel(productMaterialSku.getModel());
+ return structureVo;
+ }).collect(Collectors.toList());
+ productionOrderRouteItemVo.setOrderStructureVos(structureVoList);
+ }
+
+ // 姣忎竴涓伐搴忕殑鍙傛暟銆丅OM娑堣�椾骇鍝�
+ productionOrderRouteItemVoList.add(productionOrderRouteItemVo);
+ }
+
+ productionRecordVo.setProductionOrderRouteItemVos(productionOrderRouteItemVoList);
+ return productionRecordVo;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void addProductionRecordService(ProductionRecordDto dto) {
+ if (dto == null) {
+ throw new ServiceException("鎶ュ伐澶辫触,鏁版嵁涓嶈兘涓虹┖");
+ }
+ if (dto.getProductOrderId() == null) {
+ throw new ServiceException("鎶ュ伐澶辫触,鐢熶骇璁㈠崟ID涓嶈兘涓虹┖");
+ }
+ if (dto.getProductId() == null) {
+ throw new ServiceException("鎶ュ伐澶辫触,浜у搧淇℃伅涓嶈兘涓虹┖");
+ }
+ if (StringUtils.isEmpty(dto.getPostName()) || StringUtils.isEmpty(dto.getSchedule())) {
+ throw new ServiceException("鎶ュ伐澶辫触,宀椾綅浜哄憳/鐝淇℃伅涓嶈兘涓虹┖");
+ }
+
+ // 鏇存柊鐢熶骇璁㈠崟鏁版嵁
+ ProductOrder productOrder = productOrderService.getById(dto.getProductOrderId());
+ if (productOrder == null) {
+ throw new ServiceException("鎶ュ伐澶辫触,鐢熶骇璁㈠崟涓嶅瓨鍦�");
+ }
+
+ // 褰撳墠鎶ュ伐鍚堟牸鏁伴噺
+ BigDecimal qualifiedQty = dto.getQualifiedQuantity() == null ? BigDecimal.ZERO : dto.getQualifiedQuantity();
+ // 宸插畬鎴愭暟閲�
+ BigDecimal completeQty = productOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productOrder.getCompleteQuantity();
+ // 绱姞(鍙畻鍚堟牸)
+ BigDecimal newCompleteQty = completeQty.add(qualifiedQty);
+ productOrder.setCompleteQuantity(newCompleteQty);
+ // 闇�姹傛暟閲�
+ BigDecimal totalQty = productOrder.getQuantity() == null ? BigDecimal.ZERO : productOrder.getQuantity();
+ // 鍓╀綑鍙姤宸ユ暟閲�
+ BigDecimal remainQty = totalQty.subtract(completeQty);
+ // 鏈鎶ュ伐涓嶈兘瓒呰繃鍓╀綑鏁伴噺
+ if (qualifiedQty.compareTo(remainQty) > 0) {
+ throw new ServiceException("鎶ュ伐澶辫触锛屾湰娆℃姤宸ユ暟閲忎笉鑳藉ぇ浜庡墿浣欏彲鎶ュ伐鏁伴噺");
+ }
+ // 璁剧疆寮�濮嬫椂闂达紙绗竴娆℃姤宸ワ級
+ if (productOrder.getStartTime() == null) {
+ productOrder.setStartTime(LocalDateTime.now());
+ }
+ // 鐘舵�佸垽鏂�
+ if (newCompleteQty.compareTo(totalQty) >= 0 && totalQty.compareTo(BigDecimal.ZERO) > 0) {
+ productOrder.setStatus(ProductOrderStatusEnum.FINISHED.getCode());
+ productOrder.setEndTime(LocalDateTime.now());
+ } else {
+ productOrder.setStatus(ProductOrderStatusEnum.RUNNING.getCode());
+ }
+ boolean update = productOrderService.updateById(productOrder);
+ if (!update) {
+ throw new ServiceException("鎶ュ伐澶辫触,鐢熶骇璁㈠崟鏇存柊澶辫触");
+ }
+
+ // 瀹屾垚鎶ュ伐涓昏〃-鎶曞叆琛�-浜у嚭琛ㄦ暟鎹�
+ ProductionProductMain productionProductMain = new ProductionProductMain();
+ productionProductMain.setProductNo("BG" + UUID.randomUUID());
+ productionProductMain.setProductOrderId(dto.getProductOrderId());
+ productionProductMain.setSchedule(dto.getSchedule());
+ boolean result = productionProductMainService.save(productionProductMain);
+ if (!result) {
+ throw new ServiceException("鎶ュ伐澶辫触,鏁版嵁瀛樺偍澶辫触");
+ }
+
+ ProductionProductInput productionProductInput = new ProductionProductInput();
+ productionProductInput.setProductMainId(productionProductMain.getId());
+ productionProductInput.setProductModelId(dto.getProductId());
+ productionProductInput.setQuantity(dto.getQuantity());
+ result = productionProductInputService.save(productionProductInput);
+ if (!result) {
+ throw new ServiceException("鎶ュ伐澶辫触,鐢熶骇鎶曞叆瀛樺偍澶辫触");
+ }
+
+ ProductionProductOutput productionProductOutput = new ProductionProductOutput();
+ productionProductOutput.setProductMainId(productionProductMain.getId());
+ productionProductOutput.setProductModelId(dto.getProductId());
+ productionProductOutput.setQuantity(dto.getQualifiedQuantity());
+ productionProductOutput.setScrapQty(dto.getUnqualifiedQuantity());
+ result = productionProductOutputService.save(productionProductOutput);
+ if (!result) {
+ throw new ServiceException("鎶ュ伐澶辫触,鐢熶骇浜у嚭瀛樺偍澶辫触");
+ }
+
+ // 澶勭悊宸ュ簭
+ List<ProductionProductRouteItemDto> productionProductRouteItemDtoList = dto.getProductionProductRouteItemDtoList();
+ if (productionProductRouteItemDtoList == null || productionProductRouteItemDtoList.isEmpty()) {
+ throw new ServiceException("鎶ュ伐澶辫触,宸ュ簭鍙傛暟涓嶈兘涓虹┖");
+ }
+ for (ProductionProductRouteItemDto productRouteItemDto : productionProductRouteItemDtoList) {
+ // 澶勭悊宸ュ簭涓昏〃
+ ProductionProductRouteItem productRouteItemEntity = new ProductionProductRouteItem();
+ BeanUtils.copyProperties(productRouteItemDto, productRouteItemEntity, "id");
+ productRouteItemEntity.setProductMainId(productionProductMain.getId());
+ productionProductRouteItemService.save(productRouteItemEntity);
+
+ // 澶勭悊鍙傛暟鍙婃秷鑰椾骇鍝�
+ List<ProductionProductRouteItemParamDto> productionProductRouteItemParamDtoList = productRouteItemDto.getProductionProductRouteItemParamDtoList();
+ if (productionProductRouteItemParamDtoList != null && !productionProductRouteItemParamDtoList.isEmpty()) {
+ for (ProductionProductRouteItemParamDto productRouteItemParamDto : productionProductRouteItemParamDtoList) {
+ ProductionProductRouteItemParam paramEntity = new ProductionProductRouteItemParam();
+ BeanUtils.copyProperties(productRouteItemParamDto, paramEntity, "id");
+ paramEntity.setProductionProductRouteItemId(productRouteItemEntity.getId());
+ if (paramEntity.getProductId() != null) {
+ } else {
+ ProductionOrderRouteItemParam productionOrderRouteItemParam = productionOrderRouteItemParamService.getById(productRouteItemParamDto.getId());
+ paramEntity.setParamName(productionOrderRouteItemParam.getParamName());
+ paramEntity.setParamType(productionOrderRouteItemParam.getParamType());
+ paramEntity.setParamFormat(productionOrderRouteItemParam.getParamFormat());
+ paramEntity.setValueMode(productionOrderRouteItemParam.getValueMode());
+ }
+
+ productionProductRouteItemParamService.save(paramEntity);
+ }
+ }
+
+ // 澶勭悊宸ュ簭涓婁紶鐨勯檮浠�
+ List<String> files = productRouteItemDto.getFiles();
+ if (files != null && !files.isEmpty()) {
+ for (String tempId : files) {
+ TempFile tempFile = tempFileMapper.selectById(tempId);
+ if (tempFile == null) {
+ log.warn("鏈壘鍒颁复鏃舵枃浠惰褰�: {}", tempId);
+ continue;
+ }
+
+ try {
+ // 姝e紡鐩綍璺緞锛堟寜鏃ユ湡鍒嗙粍锛�
+ String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
+ Path formalDirPath = Paths.get(formalDir);
+ if (!Files.exists(formalDirPath)) {
+ Files.createDirectories(formalDirPath);
+ }
+
+ // 姝e紡鏂囦欢鍚�
+ String originalFilename = tempFile.getOriginalName();
+ String fileExtension = FilenameUtils.getExtension(originalFilename);
+ String formalFilename = productRouteItemEntity.getId() + "_" +
+ System.currentTimeMillis() + "_" +
+ UUID.randomUUID().toString().substring(0, 8) +
+ (StringUtils.hasText(fileExtension) ? "." + fileExtension : "");
+
+ Path formalFilePath = formalDirPath.resolve(formalFilename);
+
+ // 鏂囦欢杩佺Щ (澶嶅埗+鍒犻櫎)
+ Files.copy(Paths.get(tempFile.getTempPath()), formalFilePath, StandardCopyOption.REPLACE_EXISTING);
+ Files.deleteIfExists(Paths.get(tempFile.getTempPath()));
+
+ // 淇濆瓨鎶ュ伐闄勪欢璁板綍
+ ProductionProductRouteItemFile fileEntity = new ProductionProductRouteItemFile();
+ fileEntity.setProductionProductRouteItemId(productRouteItemEntity.getId());
+ fileEntity.setFileName(originalFilename);
+ fileEntity.setFileUrl(formalFilePath.toString());
+ fileEntity.setFileSuffix(fileExtension);
+ fileEntity.setFileSize(Files.size(formalFilePath));
+ fileEntity.setCreateTime(LocalDateTime.now());
+ fileEntity.setTenantId(SecurityUtils.getLoginUser().getTenantId());
+ productionProductRouteItemFileService.save(fileEntity);
+
+ // 鍒犻櫎涓存椂鏂囦欢璁板綍
+ tempFileMapper.deleteById(tempId);
+ log.info("宸ュ簭闄勪欢杩佺Щ鎴愬姛: {} -> {}", tempFile.getTempPath(), formalFilePath);
+
+ } catch (IOException e) {
+ log.error("宸ュ簭闄勪欢杩佺Щ澶辫触: {}", tempFile.getTempPath(), e);
+ throw new ServiceException("宸ュ簭闄勪欢澶勭悊寮傚父: " + e.getMessage());
+ }
+ }
+ }
+ }
+ }
+
+}
--
Gitblit v1.9.3