liyong
2026-05-14 971d450e8627d7d8116c741a0306cce05ad5f57c
src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java
@@ -1,6 +1,9 @@
package com.ruoyi.basic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.ProductDto;
import com.ruoyi.basic.dto.ProductTreeDto;
@@ -9,18 +12,20 @@
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.service.IProductService;
import com.ruoyi.basic.vo.ProductModelVo;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.stock.mapper.WarehouseInfoMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.math.BigDecimal;
import java.util.*;
@Service
@AllArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {
    private final WarehouseInfoMapper warehouseInfoMapper;
    private ProductMapper productMapper;
    private ProductModelMapper productModelMapper;
@@ -35,6 +40,12 @@
        if (productDto.getProductName() != null && !productDto.getProductName().isEmpty()) {
            queryWrapper.like(Product::getProductName, productDto.getProductName());
        }
        // 浪潮用于区分成品和物料
        if (productDto.getProductType() != null && !productDto.getProductType().isEmpty()) {
            if (productDto.getProductType().equals("成品")){
                queryWrapper.eq(Product::getProductName, productDto.getProductType());
            }else queryWrapper.ne(Product::getProductName, "成品");
        }
        // 查询根节点列表
        List<Product> rootProducts = productMapper.selectList(queryWrapper);
@@ -47,6 +58,89 @@
            tree.add(node);
        }
        return tree;
    }
    @Override
    public IPage<ProductModelVo> listPageProductModel(Page<ProductModelVo> page, ProductModel productModel) {
        return productModelMapper.listPageProductModel(page, productModel);
    }
    @Override
    public IPage<ProductModelVo> pageModelAndQua(Page<ProductModelVo> page, ProductModel productModel) {
        IPage<ProductModelVo> result = productModelMapper.pageModelAndQua(page, productModel);
        fillBatchNoMaps(result.getRecords());
        return result;
    }
    private void fillBatchNoMaps(List<ProductModelVo> records) {
        if (records == null || records.isEmpty()) {
            return;
        }
        List<Long> productModelIds = records.stream()
                .map(ProductModelVo::getId)
                .filter(Objects::nonNull)
                .toList();
        if (productModelIds.isEmpty()) {
            return;
        }
        List<Map<String, Object>> batchRows = productModelMapper.selectBatchNoQtyByProductModelIds(productModelIds);
        Map<Long, HashMap<String, HashMap<String, BigDecimal>>> batchNoQtyMapsByProductModelId = new HashMap<>();
        for (Map<String, Object> batchRow : batchRows) {
            Long productModelId = toLong(batchRow.get("productModelId"));
            Long warehouseId = toLong(batchRow.get("warehouseId"));
            String batchNo = (String) batchRow.get("batchNo");
            if (productModelId == null || warehouseId == null || batchNo == null || batchNo.isBlank()) {
                continue;
            }
            batchNoQtyMapsByProductModelId
                    .computeIfAbsent(productModelId, key -> new HashMap<>())
                    .computeIfAbsent(String.valueOf(warehouseId), key -> new HashMap<>())
                    .merge(batchNo, toBigDecimal(batchRow.get("qty")), BigDecimal::add);
        }
        for (ProductModelVo record : records) {
            HashMap<String, List<Map<String, BigDecimal>>> batchNoMaps = new HashMap<>();
            HashMap<String, HashMap<String, BigDecimal>> stockBatchNoQtyMaps =
                    batchNoQtyMapsByProductModelId.getOrDefault(record.getId(), new HashMap<>());
            for (Map.Entry<String, HashMap<String, BigDecimal>> entry : stockBatchNoQtyMaps.entrySet()) {
                List<Map<String, BigDecimal>> batchList = new ArrayList<>();
                for (Map.Entry<String, BigDecimal> batchEntry : entry.getValue().entrySet()) {
                    Map<String, BigDecimal> batchItem = new HashMap<>();
                    batchItem.put(batchEntry.getKey(), batchEntry.getValue());
                    batchList.add(batchItem);
                }
                batchNoMaps.put(entry.getKey(), batchList);
            }
            record.setBatchNoMaps(batchNoMaps);
        }
    }
    private Long toLong(Object value) {
        if (value instanceof Number number) {
            return number.longValue();
        }
        if (value instanceof String str && !str.isBlank()) {
            return Long.parseLong(str);
        }
        return null;
    }
    private BigDecimal toBigDecimal(Object value) {
        if (value instanceof BigDecimal bigDecimal) {
            return bigDecimal;
        }
        if (value instanceof Number number) {
            return BigDecimal.valueOf(number.doubleValue());
        }
        if (value instanceof String str && !str.isBlank()) {
            return new BigDecimal(str);
        }
        return BigDecimal.ZERO;
    }
    // 递归构建子节点
@@ -78,6 +172,9 @@
    @Override
    public int addOrEditProduct(ProductDto productDto) {
        if (ObjectUtils.isEmpty(productDto.getParentId())) {
            throw new IllegalArgumentException("请选择父节点");
        }
        if (productDto.getId() == null) {
            // 新增产品逻辑
            if (productDto.getParentId() == null) {