gongchunyi
3 天以前 3faea5bad90c8e55e8bf83f7a9c603f789ed6c84
feat: 原料生产统计单耗表接口
已添加1个文件
已修改3个文件
206 ■■■■■ 文件已修改
src/main/java/com/ruoyi/home/controller/HomeController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/dto/RawMaterialProductionDto.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/HomeService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -12,10 +12,7 @@
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.text.ParseException;
import java.util.List;
@@ -425,4 +422,12 @@
        return AjaxResult.success(list);
    }
    @GetMapping("/rawMaterialProductions/{month}")
    @ApiOperation("成本核算-原料生产统计单耗表")
    public AjaxResult rawMaterialProductions(@PathVariable String month){
        List<RawMaterialProductionDto> list = homeService.rawMaterialProductions(month);
        return AjaxResult.success(list);
    }
}
src/main/java/com/ruoyi/home/dto/RawMaterialProductionDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.ruoyi.home.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * æˆæœ¬æ ¸ç®—-原料生产统计单耗表 DTO
 */
@Data
@ApiModel("成本核算-原料生产统计单耗表记录")
public class RawMaterialProductionDto {
    @ApiModelProperty("项目名称")
    private String itemName;
    @ApiModelProperty("3.5 ç”¨é‡/产量")
    private BigDecimal usage35;
    @ApiModelProperty("3.5 å•耗")
    private BigDecimal unitConsumption35;
    @ApiModelProperty("5.0 ç”¨é‡/产量")
    private BigDecimal usage50;
    @ApiModelProperty("5.0 å•耗")
    private BigDecimal unitConsumption50;
    @ApiModelProperty("板材 ç”¨é‡/产量")
    private BigDecimal usagePlate;
    @ApiModelProperty("板材 å•耗")
    private BigDecimal unitConsumptionPlate;
    @ApiModelProperty("月实际用量/总产量")
    private BigDecimal totalUsage;
    @ApiModelProperty("砌块合计(3.5 + 5.0)")
    private BigDecimal blockTotalUsage;
}
src/main/java/com/ruoyi/home/service/HomeService.java
@@ -125,4 +125,6 @@
    Map<String,Long> manage();
    List<PlanTrendsDto> planTrends(Integer type);
    List<RawMaterialProductionDto> rawMaterialProductions(String month);
}
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -3645,5 +3645,154 @@
        return new ArrayList<>(resultMap.values());
    }
    @Override
    public List<RawMaterialProductionDto> rawMaterialProductions(String month) {
        YearMonth yearMonth;
        try {
            yearMonth = YearMonth.parse(month);
        } catch (Exception e) {
            log.error("解析月份失败: {}", month);
            return Collections.emptyList();
        }
        LocalDateTime monthStart = yearMonth.atDay(1).atStartOfDay();
        LocalDateTime monthEnd = yearMonth.atEndOfMonth().atTime(LocalTime.MAX);
        //  èŽ·å–äº§å“ç±»åž‹å­—å…¸
        List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByType("product_type");
        Map<Long, String> dictCodeToLabelMap = sysDictDataList.stream()
                .filter(d -> d.getDictCode() != null && d.getDictLabel() != null)
                .collect(Collectors.toMap(SysDictData::getDictCode, SysDictData::getDictLabel));
        //  æŸ¥è¯¢å½“月报工主表
        List<ProductionProductMain> mainList = productionProductMainService.list(Wrappers.<ProductionProductMain>lambdaQuery()
                .between(ProductionProductMain::getReportingTime, monthStart, monthEnd));
        if (CollectionUtils.isEmpty(mainList)) {
            return Collections.emptyList();
        }
        List<Long> mainIds = mainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList());
        List<Long> orderIds = mainList.stream().map(ProductionProductMain::getProductOrderId).distinct().collect(Collectors.toList());
        Map<Long, ProductionProductMain> mainMap = mainList.stream().collect(Collectors.toMap(ProductionProductMain::getId, m -> m));
        //  èŽ·å–è®¢å•å¯¹åº”çš„äº§å“ç±»åž‹
        Map<Long, Long> orderRouteMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(orderIds)) {
            List<ProductionOrderRoute> routes = productionOrderRouteService.list(Wrappers.<ProductionOrderRoute>lambdaQuery()
                    .in(ProductionOrderRoute::getOrderId, orderIds));
            orderRouteMap = routes.stream()
                    .filter(r -> r.getOrderId() != null && r.getDictCode() != null)
                    .collect(Collectors.toMap(ProductionOrderRoute::getOrderId, ProductionOrderRoute::getDictCode, (v1, v2) -> v1));
        }
        //  èŽ·å–æŠ•å…¥å’Œäº§å‡ºæ˜Žç»†
        List<ProductionProductInput> allInputs = productionProductInputService.list(Wrappers.<ProductionProductInput>lambdaQuery()
                .in(ProductionProductInput::getProductMainId, mainIds));
        List<ProductionProductOutput> allOutputs = productionProductOutputService.list(Wrappers.<ProductionProductOutput>lambdaQuery()
                .in(ProductionProductOutput::getProductMainId, mainIds));
        //  èŽ·å– SKU çš„物料名称
        Set<Long> inputSkuIds = allInputs.stream().map(ProductionProductInput::getProductId).filter(Objects::nonNull).collect(Collectors.toSet());
        Map<Long, String> skuToMaterialNameMap = new HashMap<>();
        if (!inputSkuIds.isEmpty()) {
            List<ProductMaterialSku> skus = productMaterialSkuService.listByIds(inputSkuIds);
            Set<Long> productIds = skus.stream().map(ProductMaterialSku::getProductId).filter(Objects::nonNull).collect(Collectors.toSet());
            Map<Long, String> materialNameMap = productMaterialService.listByIds(productIds).stream()
                    .collect(Collectors.toMap(ProductMaterial::getId, ProductMaterial::getProductName));
            skuToMaterialNameMap = skus.stream()
                    .filter(s -> s.getProductId() != null && materialNameMap.containsKey(s.getProductId()))
                    .collect(Collectors.toMap(ProductMaterialSku::getId, s -> materialNameMap.get(s.getProductId())));
        }
        BigDecimal yield35 = BigDecimal.ZERO;
        BigDecimal yield50 = BigDecimal.ZERO;
        BigDecimal yieldPlate = BigDecimal.ZERO;
        // æè´¨åç§° -> [3.5用量, 5.0用量, æ¿æç”¨é‡]
        Map<String, BigDecimal[]> materialConsumptionMap = new LinkedHashMap<>();
        //  ç»Ÿè®¡äº§é‡
        for (ProductionProductOutput output : allOutputs) {
            ProductionProductMain main = mainMap.get(output.getProductMainId());
            if (main == null) continue;
            Long dictCode = orderRouteMap.get(main.getProductOrderId());
            String label = dictCodeToLabelMap.get(dictCode);
            BigDecimal qty = output.getQuantity() != null ? output.getQuantity() : BigDecimal.ZERO;
            if (label != null) {
                if (label.contains("3.5")) yield35 = yield35.add(qty);
                else if (label.contains("5.0")) yield50 = yield50.add(qty);
                else if (label.contains("板材")) yieldPlate = yieldPlate.add(qty);
            }
        }
        //  ç»Ÿè®¡æ¶ˆè€—量
        for (ProductionProductInput input : allInputs) {
            ProductionProductMain main = mainMap.get(input.getProductMainId());
            if (main == null) continue;
            Long dictCode = orderRouteMap.get(main.getProductOrderId());
            String label = dictCodeToLabelMap.get(dictCode);
            String materialName = skuToMaterialNameMap.get(input.getProductId());
            if (materialName == null) continue;
            BigDecimal qty = UnitUtils.convertValueToTon(input.getQuantity(), input.getUnit());
            materialConsumptionMap.putIfAbsent(materialName, new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO});
            BigDecimal[] consumptions = materialConsumptionMap.get(materialName);
            if (label != null) {
                if (label.contains("3.5")) consumptions[0] = consumptions[0].add(qty);
                else if (label.contains("5.0")) consumptions[1] = consumptions[1].add(qty);
                else if (label.contains("板材")) consumptions[2] = consumptions[2].add(qty);
            }
        }
        List<RawMaterialProductionDto> result = new ArrayList<>();
        // äº§é‡è¡Œ
        RawMaterialProductionDto yieldRow = new RawMaterialProductionDto();
        yieldRow.setItemName("产量");
        yieldRow.setUsage35(yield35);
        yieldRow.setUsage50(yield50);
        yieldRow.setUsagePlate(yieldPlate);
        yieldRow.setTotalUsage(yield35.add(yield50).add(yieldPlate));
        yieldRow.setBlockTotalUsage(yield35.add(yield50));
        result.add(yieldRow);
        // ç‰©æ–™è¡Œ
        List<String> targetMaterials = Arrays.asList(
                "粉煤灰", "æ°´æ³¥", "石灰", "铝粉", "石膏", "脱模剂",
                "打包带", "冷拔丝", "氧化镁", "卡扣", "防腐剂"
        );
        for (String materialName : targetMaterials) {
            BigDecimal[] consumptions = materialConsumptionMap.getOrDefault(materialName,
                    new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO});
            RawMaterialProductionDto row = new RawMaterialProductionDto();
            row.setItemName(materialName);
            row.setUsage35(consumptions[0]);
            row.setUsage50(consumptions[1]);
            row.setUsagePlate(consumptions[2]);
            // è®¡ç®—单耗
            row.setUnitConsumption35(calculateUnitConsumption(consumptions[0], yield35));
            row.setUnitConsumption50(calculateUnitConsumption(consumptions[1], yield50));
            row.setUnitConsumptionPlate(calculateUnitConsumption(consumptions[2], yieldPlate));
            row.setTotalUsage(consumptions[0].add(consumptions[1]).add(consumptions[2]));
            row.setBlockTotalUsage(consumptions[0].add(consumptions[1]));
            result.add(row);
        }
        return result;
    }
    private BigDecimal calculateUnitConsumption(BigDecimal usage, BigDecimal yield) {
        if (yield == null || yield.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        return usage.divide(yield, 4, RoundingMode.HALF_UP);
    }
}