dc99e8a28673af16796bdd434d7f47b434b6a4d6..ada06626c3f81258e01837d09a10135f8ec3232f
2026-03-28 gongchunyi
refactor: 生产报工参数与投入表分离
ada066 对比 | 目录
2026-03-28 zss
销售看板统计的汇总
171c41 对比 | 目录
2026-03-28 zss
关于能耗的统计调整2.0
bb6aec 对比 | 目录
2026-03-28 zss
关于能耗的统计调整
9c685d 对比 | 目录
已添加2个文件
已修改25个文件
857 ■■■■ 文件已修改
doc/宁夏-中盛建材.sql 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/dto/EnergyAccountDto.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/dto/EnergyCollectDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/dto/EnergyCostDto.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/dto/EnergyDetailDto.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/mapper/EnergyConsumptionDetailMapper.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/service/impl/EnergyConsumptionDetailServiceImpl.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/vo/EnergyStatisticsVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/controller/HomeController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/HomeService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductionProductRouteItemParamDto.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductionRecordDto.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionProductRouteItemParam.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java 151 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/controller/SalesDeliveryController.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/enums/AddressRegionEnum.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/IQualityInspectService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/energy/EnergyConsumptionDetailMapper.xml 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductOrderMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductInputMapper.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductMainMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductRouteItemParamMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/ÄþÏÄ-ÖÐÊ¢½¨²Ä.sql
@@ -417,4 +417,33 @@
DROP TABLE IF EXISTS product_structure_instance;
ALTER TABLE `product-inventory-management-zsjc`.`production_product_route_item_param`
    MODIFY COLUMN `order_item_param_id` bigint NULL DEFAULT NULL COMMENT '生产订单绑定的工艺路线工序--参数表ID' AFTER `production_product_route_item_id`;
    MODIFY COLUMN `order_item_param_id` bigint NULL DEFAULT NULL COMMENT '生产订单绑定的工艺路线工序--参数表ID' AFTER `production_product_route_item_id`;
CREATE TABLE `production_product_input`
(
    `id`              bigint          NOT NULL AUTO_INCREMENT,
    `product_main_id` bigint          NOT NULL COMMENT '报工单主表ID',
    `route_item_id`   bigint      DEFAULT NULL COMMENT '关联具体的报工工序ID (对应原参数表的关联ID)',
    `product_id`      bigint          NOT NULL COMMENT '产品/物料ID',
    `bom_id`          bigint      DEFAULT NULL COMMENT 'BOM ID',
    `quantity`        decimal(30, 15) NOT NULL COMMENT '投入数量 (对应原product_value)',
    `unit`            varchar(20) DEFAULT NULL COMMENT '单位',
    `create_user`     bigint      DEFAULT NULL COMMENT '录入人',
    `create_time`     datetime    DEFAULT CURRENT_TIMESTAMP COMMENT '录入时间',
    `update_time`     datetime    DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    `tenant_id`       bigint          NOT NULL COMMENT '租户ID',
    PRIMARY KEY (`id`) USING BTREE,
    KEY `idx_main_id` (`product_main_id`),
    KEY `idx_product_id` (`product_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_general_ci COMMENT ='生产报工物料投入表';
ALTER TABLE `production_product_route_item_param`
    DROP COLUMN `product_id`,
    DROP COLUMN `bom_id`,
    DROP COLUMN `product_value`,
    DROP COLUMN `dict_code`;
ALTER TABLE `product-inventory-management-zsjc`.`production_product_output`
    ADD COLUMN `total_quantity` decimal(20, 15) NULL COMMENT '总数量' AFTER `scrap_qty`;
src/main/java/com/ruoyi/energy/dto/EnergyAccountDto.java
@@ -27,5 +27,5 @@
    private List<EnergyConsumptionTypeDto> energyConsumptionTypeProportion;
    @ApiModelProperty("能耗类型明细")
    private List<EnergyConsumptionDetailDto> energyConsumptionDetailDtoList;
    private List<EnergyDetailDto> energyConsumptionDetailDtoList;
}
src/main/java/com/ruoyi/energy/dto/EnergyCollectDto.java
@@ -15,5 +15,7 @@
    @ApiModelProperty("能耗类型占比")
    private List<EnergyConsumptionTypeDto> energyConsumptionTypeProportion;
    @ApiModelProperty("能耗单耗趋势")
    private List<EnergyCostDto> energyCostDtos;
}
src/main/java/com/ruoyi/energy/dto/EnergyCostDto.java
@@ -16,9 +16,7 @@
public class EnergyCostDto {
    @ApiModelProperty("日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate meterReadingDate;
    private String meterReadingDate;
    @ApiModelProperty("用水量")
    private BigDecimal waterConsumption;
src/main/java/com/ruoyi/energy/dto/EnergyDetailDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
package com.ruoyi.energy.dto;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.energy.pojo.EnergyConsumptionDetail;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
//能耗明细
@Data
public class EnergyDetailDto {
    @ApiModelProperty("能源类型")
    private String energyTyep;
    @ApiModelProperty("能源名称")
    private String energyName;
    @ApiModelProperty("单位")
    private String unit;
    //创建人
    private String createUserName;
    //费用
    private BigDecimal cost;
    //单价
    private BigDecimal unitPrice;
    @ApiModelProperty("办公/生产")
    private String type;
    @ApiModelProperty("抄表位置")
    private String meterReadingLocation;
    @ApiModelProperty("日期")
    private String meterReadingDate;
    @ApiModelProperty("用量")
    private BigDecimal dosage;
    @ApiModelProperty("备注")
    private String remark;
}
src/main/java/com/ruoyi/energy/mapper/EnergyConsumptionDetailMapper.java
@@ -5,6 +5,7 @@
import com.ruoyi.energy.dto.EnergyConsumptionDetailDto;
import com.ruoyi.energy.dto.EnergyConsumptionTypeDto;
import com.ruoyi.energy.dto.EnergyCostDto;
import com.ruoyi.energy.dto.EnergyDetailDto;
import com.ruoyi.energy.pojo.EnergyConsumptionDetail;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.energy.vo.EnergyStatisticsVo;
@@ -32,7 +33,17 @@
    List<EnergyConsumptionTypeDto> energyConsumptionTypeProportion(@Param("c") EnergyStatisticsVo energyStatisticsVo);
    List<EnergyCostDto> energyCostDtos(@Param("c") EnergyStatisticsVo energyStatisticsVo);
    //日能耗明细
    List<EnergyCostDto> energyCostDtos1(@Param("c") EnergyStatisticsVo energyStatisticsVo);
    //月能耗明细
    List<EnergyCostDto> energyCostDtos2(@Param("c") EnergyStatisticsVo energyStatisticsVo);
    //年能耗明细
    List<EnergyCostDto> energyCostDtos3(@Param("c") EnergyStatisticsVo energyStatisticsVo);
    List<EnergyConsumptionDetailDto> energyConsumptionDetailDtos(@Param("c") EnergyStatisticsVo energyStatisticsVo);
    //日能耗类型明细
    List<EnergyDetailDto> energyConsumptionDetailDtos1(@Param("c") EnergyStatisticsVo energyStatisticsVo);
    //月能耗类型明细
    List<EnergyDetailDto> energyConsumptionDetailDtos2(@Param("c") EnergyStatisticsVo energyStatisticsVo);
    //年能耗类型明细
    List<EnergyDetailDto> energyConsumptionDetailDtos3(@Param("c") EnergyStatisticsVo energyStatisticsVo);
}
src/main/java/com/ruoyi/energy/service/impl/EnergyConsumptionDetailServiceImpl.java
@@ -24,6 +24,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -123,7 +124,19 @@
        List<EnergyConsumptionTypeDto> energyConsumptionTypeDtos=energyConsumptionDetailMapper.energyConsumptionTypeProportion(energyStatisticsVo);
        energyStatisticsDto.setEnergyConsumptionTypeProportion(energyConsumptionTypeDtos);
        //能耗明细
        List<EnergyCostDto> energyCostDtos=energyConsumptionDetailMapper.energyCostDtos(energyStatisticsVo);
        List<EnergyCostDto> energyCostDtos=new ArrayList<>();
        //判断日/月/å¹´
        switch (energyStatisticsVo.getState()){
            case "日":
                energyCostDtos=energyConsumptionDetailMapper.energyCostDtos1(energyStatisticsVo);
                break;
            case "月":
                energyCostDtos=energyConsumptionDetailMapper.energyCostDtos2(energyStatisticsVo);
                break;
            case "å¹´":
                energyCostDtos=energyConsumptionDetailMapper.energyCostDtos3(energyStatisticsVo);
                break;
        }
        energyStatisticsDto.setEnergyCostDtos(energyCostDtos);
        return energyStatisticsDto;
    }
@@ -147,8 +160,20 @@
        List<EnergyConsumptionTypeDto> energyConsumptionTypeDtos=energyConsumptionDetailMapper.energyConsumptionTypeProportion(energyStatisticsVo);
        energyAccountDto.setEnergyConsumptionTypeProportion(energyConsumptionTypeDtos);
        //能耗类型明细
        List<EnergyConsumptionDetailDto> energyConsumptionDetailDtoList=energyConsumptionDetailMapper.energyConsumptionDetailDtos(energyStatisticsVo);
        energyAccountDto.setEnergyConsumptionDetailDtoList(energyConsumptionDetailDtoList);
        List<EnergyDetailDto> energyDetailDtos = new ArrayList<>();
        //判断日/月/å¹´
        switch (energyStatisticsVo.getState()){
            case "日":
                energyDetailDtos=energyConsumptionDetailMapper.energyConsumptionDetailDtos1(energyStatisticsVo);
                break;
            case "月":
                energyDetailDtos=energyConsumptionDetailMapper.energyConsumptionDetailDtos2(energyStatisticsVo);
                break;
            case "å¹´":
                energyDetailDtos=energyConsumptionDetailMapper.energyConsumptionDetailDtos3(energyStatisticsVo);
                break;
        }
        energyAccountDto.setEnergyConsumptionDetailDtoList(energyDetailDtos);
        return energyAccountDto;
    }
@@ -158,7 +183,21 @@
        //能耗单耗数据
        List<EnergyConsumptionTypeDto> energyConsumptionTypeDtos=energyConsumptionDetailMapper.energyConsumptionTypeProportion(energyStatisticsVo);
        energyCollectDto.setEnergyConsumptionTypeProportion(energyConsumptionTypeDtos);
        //能耗单耗趋势(待实现)
        //能耗单耗趋势
        List<EnergyCostDto> energyCostDtos=new ArrayList<>();
        //判断日/月/å¹´
        switch (energyStatisticsVo.getState()){
            case "日":
                energyCostDtos=energyConsumptionDetailMapper.energyCostDtos1(energyStatisticsVo);
                break;
            case "月":
                energyCostDtos=energyConsumptionDetailMapper.energyCostDtos2(energyStatisticsVo);
                break;
            case "å¹´":
                energyCostDtos=energyConsumptionDetailMapper.energyCostDtos3(energyStatisticsVo);
                break;
        }
        energyCollectDto.setEnergyCostDtos(energyCostDtos);
        return energyCollectDto;
    }
}
src/main/java/com/ruoyi/energy/vo/EnergyStatisticsVo.java
@@ -29,4 +29,7 @@
    //能耗类型(æ°´/电/气)
    private String energyName;
    //日/月/å¹´
    private String state;
}
src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -1,14 +1,17 @@
package com.ruoyi.home.controller;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.energy.vo.EnergyStatisticsVo;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.home.annotation.DefaultType;
import com.ruoyi.home.dto.*;
import com.ruoyi.home.service.HomeService;
import com.ruoyi.dto.MapDto;
import com.ruoyi.productionPlan.service.SalesDeliveryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -26,7 +29,7 @@
 * @date : 2025/7/25 9:15
 */
@RestController
@Api(tags = "首页统计")
@Api(tags = "统计")
@RequestMapping("/home")
public class HomeController extends BaseController {
@@ -321,4 +324,16 @@
        return AjaxResult.success(list);
    }
    /*******************************************宁夏中盛建材的大屏统计***************************************************/
    @GetMapping("/total")
    @ApiOperation("销售统计看板---总数据汇总")
    public AjaxResult total() {
        return AjaxResult.success(homeService.total());
    }
}
src/main/java/com/ruoyi/home/service/HomeService.java
@@ -95,4 +95,6 @@
    QualityStatisticsDto qualityInspectionStatistics(Integer type);
    List<processDataProductionStatisticsDto> processDataProductionStatistics(Integer type, List<Long> processIds);
    Map<String,Long> total();
}
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.account.mapper.AccountIncomeMapper;
import com.ruoyi.account.pojo.AccountExpense;
@@ -41,6 +42,9 @@
import com.ruoyi.production.mapper.SalesLedgerProductionAccountingMapper;
import com.ruoyi.production.pojo.ProductProcess;
import com.ruoyi.production.pojo.ProductWorkOrder;
import com.ruoyi.productionPlan.enums.AddressRegionEnum;
import com.ruoyi.productionPlan.mapper.SalesDeliveryMapper;
import com.ruoyi.productionPlan.pojo.SalesDelivery;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.purchase.mapper.PaymentRegistrationMapper;
@@ -145,12 +149,15 @@
    @Autowired
    private ProductProcessMapper productProcessMapper;
    @Autowired
    private AccountExpenseMapper accountExpenseMapper;
    @Autowired
    private AccountIncomeMapper accountIncomeMapper;
    @Autowired
    private SalesDeliveryMapper salesDeliveryMapper;
    @Override
    public HomeBusinessDto business() {
@@ -2512,4 +2519,20 @@
        return productProcessMapper.calculateProductionStatistics(startDateTime, endDateTime, userId, processIds);
    }
    @Override
    public Map<String, Long> total() {
        Map<String, Long> map = new HashMap<>();
        //总销售金额
        List<SalesDelivery> salesDeliveries = salesDeliveryMapper.selectList(null);
        long sum = salesDeliveries.stream().mapToLong(value -> Long.parseLong(value.getPrice().toString())).sum();
        map.put("price",sum/1000);//单位w
        //总发货单
        map.put("delivery",salesDeliveries.stream().count());
        //总销售区?
        //累计客户
        Long count = customerMapper.selectCount(null);
        map.put("customer",count);
        return map;
    }
}
src/main/java/com/ruoyi/production/dto/ProductionProductRouteItemParamDto.java
@@ -4,6 +4,7 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
 * <br>
@@ -27,6 +28,18 @@
    @ApiModelProperty("物料编码")
    private String materialCode;
    @ApiModelProperty("产品ID")
    private Long productId;
    @ApiModelProperty("BOM ID")
    private Long bomId;
    @ApiModelProperty("投入数量")
    private BigDecimal quantity;
    @ApiModelProperty("物料值")
    private BigDecimal productValue;
    @ApiModelProperty("强度")
    private String strength;
src/main/java/com/ruoyi/production/dto/ProductionRecordDto.java
@@ -57,10 +57,10 @@
    @ApiModelProperty(value = "更新时间")
    private LocalDateTime updateTime;
    @ApiModelProperty("合格数量")
    @ApiModelProperty("合格数量/产出方量")
    private BigDecimal qualifiedQuantity;
    @ApiModelProperty("不合格数量")
    @ApiModelProperty("不合格数量/不合格方量")
    private BigDecimal unqualifiedQuantity;
    @ApiModelProperty("产出数量")
src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
@@ -14,20 +14,37 @@
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "报工id")
    @ApiModelProperty(value = "报工单主表ID")
    private Long productMainId;
    @ApiModelProperty(value = "产品id")
    private Long productModelId;
    @ApiModelProperty(value = "关联具体的报工工序ID")
    private Long routeItemId;
    @ApiModelProperty(value = "数量")
    @ApiModelProperty(value = "产品/物料ID")
    @TableField("product_id")
    private Long productId;
    @ApiModelProperty(value = "BOM ID")
    private Long bomId;
    @ApiModelProperty(value = "投入数量")
    private BigDecimal quantity;
    @ApiModelProperty(value = "创建时间")
    @ApiModelProperty(value = "单位")
    private String unit;
    @ApiModelProperty(value = "录入人")
    private Long createUser;
    @ApiModelProperty(value = "录入时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
}
src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
@@ -20,7 +20,7 @@
    @ApiModelProperty(value = "产品id")
    private Long productModelId;
    @ApiModelProperty(value = "合格数量")
    @ApiModelProperty(value = "合格数量/产出方量")
    private BigDecimal quantity;
    @ApiModelProperty(value = "创建时间")
@@ -31,6 +31,9 @@
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    @ApiModelProperty(value = "不合格数量")
    @ApiModelProperty(value = "不合格数量/不合格方量")
    private BigDecimal scrapQty;
    @ApiModelProperty(value = "总数量")
    private BigDecimal totalQuantity;
}
src/main/java/com/ruoyi/production/pojo/ProductionProductRouteItemParam.java
@@ -64,15 +64,6 @@
    @ApiModelProperty(value = "参数值")
    private String paramValue;
    @ApiModelProperty(value = "产品ID")
    private Long productId;
    @ApiModelProperty(value = "产品投入值")
    private BigDecimal productValue;
    @ApiModelProperty(value = "BOM ID")
    private Long bomId;
    @ApiModelProperty(value = "单位")
    private String unit;
@@ -82,25 +73,21 @@
    @ApiModelProperty(value = "参数排序")
    private Integer sourceSort;
    @ApiModelProperty(value = "产品类型")
    private Long dictCode;
    @ApiModelProperty(value = "上传者")
    private Long createUser;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "修改者")
    private Long updateUser;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    @TableField(value = "tenant_id", fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -123,14 +123,16 @@
            productStructureDtos.add(productStructureDto);
        }
        for (ProductStructureDto productStructureDto : productStructureDtos) {
            ProductionProductInput productionProductInput = new ProductionProductInput();
            productionProductInput.setProductModelId(productStructureDto.getProductModelId());
            productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity()));
            productionProductInput.setProductId(productStructureDto.getProductModelId());
            BigDecimal unitQty = productStructureDto.getUnitQuantity() != null ? productStructureDto.getUnitQuantity() : BigDecimal.ZERO;
            BigDecimal mainQty = dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO;
            productionProductInput.setQuantity(unitQty.multiply(mainQty));
            productionProductInput.setUnit(productStructureDto.getUnit());
            productionProductInput.setProductMainId(productionProductMain.getId());
            productionProductInput.setRouteItemId(productProcessRouteItem.getId());
            productionProductInputMapper.insert(productionProductInput);
            stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId());
        }
        /*新增报工产出表*/
        ProductionProductOutput productionProductOutput = new ProductionProductOutput();
src/main/java/com/ruoyi/production/service/impl/ProductionRecordServiceImpl.java
@@ -241,20 +241,12 @@
            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());
        productionProductOutput.setTotalQuantity(dto.getQuantity());
        result = productionProductOutputService.save(productionProductOutput);
        if (!result) {
            throw new ServiceException("报工失败,生产产出存储失败");
@@ -276,19 +268,40 @@
            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());
                    paramEntity.setOrderItemParamId(productRouteItemParamDto.getId());
                    if (paramEntity.getProductId() == null) {
                        ProductionOrderRouteItemParam productionOrderRouteItemParam = productionOrderRouteItemParamService.getById(productRouteItemParamDto.getId());
                        paramEntity.setParamName(productionOrderRouteItemParam.getParamName());
                        paramEntity.setParamType(productionOrderRouteItemParam.getParamType());
                        paramEntity.setParamFormat(productionOrderRouteItemParam.getParamFormat());
                        paramEntity.setValueMode(productionOrderRouteItemParam.getValueMode());
                    }
                    if (productRouteItemParamDto.getProductId() != null) {
                        // å¦‚果有产品ID,则是投入物料,存入投入表
                        ProductionProductInput inputEntity = new ProductionProductInput();
                        inputEntity.setProductMainId(productionProductMain.getId());
                        inputEntity.setRouteItemId(productRouteItemEntity.getId());
                        inputEntity.setProductId(productRouteItemParamDto.getProductId());
                        inputEntity.setBomId(productRouteItemParamDto.getBomId());
                        BigDecimal qty = productRouteItemParamDto.getQuantity();
                        if (qty == null) {
                            qty = productRouteItemParamDto.getProductValue();
                        }
                        inputEntity.setQuantity(qty != null ? qty : BigDecimal.ZERO);
                        inputEntity.setUnit(productRouteItemParamDto.getUnit());
                        productionProductInputService.save(inputEntity);
                    } else {
                        // å¦åˆ™æ˜¯æ™®é€šå‚数,存入参数表
                        ProductionProductRouteItemParam paramEntity = new ProductionProductRouteItemParam();
                        BeanUtils.copyProperties(productRouteItemParamDto, paramEntity, "id");
                        paramEntity.setProductionProductRouteItemId(productRouteItemEntity.getId());
                        paramEntity.setOrderItemParamId(productRouteItemParamDto.getId());
                    productionProductRouteItemParamService.save(paramEntity);
                        // ä»Žè®¢å•参数表补全基础信息(名称、类型、单位等)
                        if (productRouteItemParamDto.getId() != null) {
                            ProductionOrderRouteItemParam orderParam = productionOrderRouteItemParamService.getById(productRouteItemParamDto.getId());
                            if (orderParam != null) {
                                paramEntity.setParamName(orderParam.getParamName());
                                paramEntity.setParamType(orderParam.getParamType());
                                paramEntity.setParamFormat(orderParam.getParamFormat());
                                paramEntity.setValueMode(orderParam.getValueMode());
                                paramEntity.setUnit(orderParam.getUnit());
                            }
                        }
                        productionProductRouteItemParamService.save(paramEntity);
                    }
                }
            }
@@ -481,13 +494,14 @@
        dto.setMaterialCode(productMaterialSkuDto.getMaterialCode());
        dto.setModel(productMaterialSkuDto.getModel());
        //  æŸ¥è¯¢æ€»çš„产出数量(这里把投入表弄成了产出总表)
        //  æŸ¥è¯¢æ€»çš„æŠ•入数量
        ProductionProductInput input = productionProductInputService.getOne(
                new LambdaQueryWrapper<ProductionProductInput>()
                        .eq(ProductionProductInput::getProductMainId, productMainId)
                        .isNull(ProductionProductInput::getRouteItemId)
                        .last("LIMIT 1"));
        if (input != null) {
            dto.setProductId(input.getProductModelId());
            dto.setProductId(input.getProductId());
            dto.setQuantity(input.getQuantity());
        }
@@ -497,6 +511,7 @@
                        .eq(ProductionProductOutput::getProductMainId, productMainId)
                        .last("LIMIT 1"));
        if (output != null) {
            dto.setQuantity(output.getTotalQuantity());
            dto.setQualifiedQuantity(output.getQuantity());
            dto.setUnqualifiedQuantity(output.getScrapQty());
        }
@@ -520,21 +535,44 @@
                List<ProductionProductRouteItemParam> paramList = productionProductRouteItemParamService.list(
                        new LambdaQueryWrapper<ProductionProductRouteItemParam>()
                                .eq(ProductionProductRouteItemParam::getProductionProductRouteItemId, routeItem.getId()));
                List<ProductionProductRouteItemParamDto> paramDtoList = new ArrayList<>();
                if (paramList != null && !paramList.isEmpty()) {
                    List<ProductionProductRouteItemParamDto> paramDtoList = paramList.stream().map(param -> {
                    paramDtoList.addAll(paramList.stream().map(param -> {
                        ProductionProductRouteItemParamDto paramDto = new ProductionProductRouteItemParamDto();
                        BeanUtils.copyProperties(param, paramDto);
                        if (paramDto.getProductId() != null) {
                            ProductMaterialSkuDto materialSkuDto = productMaterialService.selectProductByModelId(paramDto.getProductId());
                            productMaterialService.selectProductByModelId(paramDto.getProductId());
                        return paramDto;
                    }).collect(Collectors.toList()));
                }
                //  æŸ¥è¯¢å·¥åºæŠ•入物料
                List<ProductionProductInput> routeItemInputList = productionProductInputService.list(
                        new LambdaQueryWrapper<ProductionProductInput>()
                                .eq(ProductionProductInput::getProductMainId, productMainId)
                                .eq(ProductionProductInput::getRouteItemId, routeItem.getId()));
                if (routeItemInputList != null && !routeItemInputList.isEmpty()) {
                    paramDtoList.addAll(routeItemInputList.stream().map(inputItem -> {
                        ProductionProductRouteItemParamDto paramDto = new ProductionProductRouteItemParamDto();
                        paramDto.setProductId(inputItem.getProductId());
                        paramDto.setBomId(inputItem.getBomId());
                        paramDto.setQuantity(inputItem.getQuantity());
                        paramDto.setProductValue(inputItem.getQuantity());
                        paramDto.setUnit(inputItem.getUnit());
                        ProductMaterialSkuDto materialSkuDto = productMaterialService.selectProductByModelId(inputItem.getProductId());
                        if (materialSkuDto != null) {
                            paramDto.setParamName(materialSkuDto.getProductName());
                            paramDto.setProductName(materialSkuDto.getProductName());
                            paramDto.setModel(materialSkuDto.getModel());
                            paramDto.setMaterialCode(materialSkuDto.getMaterialCode());
                            String strength = productBomService.strengthById(paramDto.getBomId());
                            paramDto.setStrength(strength);
                        }
                        String strength = productBomService.strengthById(inputItem.getBomId());
                        paramDto.setStrength(strength);
                        return paramDto;
                    }).collect(Collectors.toList());
                    }).collect(Collectors.toList()));
                }
                if (!paramDtoList.isEmpty()) {
                    routeItemDto.setProductionProductRouteItemParamDtoList(paramDtoList);
                }
@@ -627,10 +665,11 @@
        //  æ›´æ–°æŠ•入表
        ProductionProductInput input = productionProductInputService.getOne(new LambdaQueryWrapper<ProductionProductInput>()
                .eq(ProductionProductInput::getProductMainId, productMainId)
                .isNull(ProductionProductInput::getRouteItemId)
                .last("LIMIT 1"));
        if (input != null) {
            input.setProductModelId(dto.getProductId());
            input.setQuantity(dto.getQuantity());
            input.setProductId(dto.getProductId());
            input.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO);
            productionProductInputService.updateById(input);
        }
@@ -639,6 +678,7 @@
            oldOutput.setProductModelId(dto.getProductId());
            oldOutput.setQuantity(dto.getQualifiedQuantity());
            oldOutput.setScrapQty(dto.getUnqualifiedQuantity());
            oldOutput.setTotalQuantity(dto.getQuantity());
            productionProductOutputService.updateById(oldOutput);
        }
@@ -660,27 +700,48 @@
            final Long routeItemId = routeItemEntity.getId();
            //  å¤„理工序参数: å…ˆåˆ é™¤è¯¥å·¥åºä¸‹æ‰€æœ‰æ—§å‚数,再重新插入传入的参数
            //  å¤„理工序参数及投入: å…ˆåˆ é™¤è¯¥å·¥åºä¸‹æ‰€æœ‰æ—§å‚数和旧投入,再重新插入传入的数据
            productionProductRouteItemParamService.remove(new LambdaQueryWrapper<ProductionProductRouteItemParam>()
                    .eq(ProductionProductRouteItemParam::getProductionProductRouteItemId, routeItemId));
            productionProductInputService.remove(new LambdaQueryWrapper<ProductionProductInput>()
                    .eq(ProductionProductInput::getProductMainId, productMainId)
                    .eq(ProductionProductInput::getRouteItemId, routeItemId));
            List<ProductionProductRouteItemParamDto> paramDtoList = routeItemDto.getProductionProductRouteItemParamDtoList();
            if (paramDtoList != null && !paramDtoList.isEmpty()) {
                for (ProductionProductRouteItemParamDto paramDto : paramDtoList) {
                    ProductionProductRouteItemParam paramEntity = new ProductionProductRouteItemParam();
                    BeanUtils.copyProperties(paramDto, paramEntity, "id");
                    paramEntity.setProductionProductRouteItemId(routeItemId);
                    if (paramEntity.getProductId() == null && paramDto.getId() != null) {
                        ProductionOrderRouteItemParam orderParam = productionOrderRouteItemParamService.getById(paramDto.getId());
                        if (orderParam != null) {
                            paramEntity.setOrderItemParamId(orderParam.getId());
                            paramEntity.setParamName(orderParam.getParamName());
                            paramEntity.setParamType(orderParam.getParamType());
                            paramEntity.setParamFormat(orderParam.getParamFormat());
                            paramEntity.setValueMode(orderParam.getValueMode());
                    if (paramDto.getProductId() != null) {
                        // æŠ•入物料
                        ProductionProductInput inputEntity = new ProductionProductInput();
                        inputEntity.setProductMainId(productMainId);
                        inputEntity.setRouteItemId(routeItemId);
                        inputEntity.setProductId(paramDto.getProductId());
                        inputEntity.setBomId(paramDto.getBomId());
                        BigDecimal qty = paramDto.getQuantity();
                        if (qty == null) {
                            qty = paramDto.getProductValue();
                        }
                        inputEntity.setQuantity(qty != null ? qty : BigDecimal.ZERO);
                        inputEntity.setUnit(paramDto.getUnit());
                        productionProductInputService.save(inputEntity);
                    } else {
                        // æ™®é€šå‚æ•°
                        ProductionProductRouteItemParam paramEntity = new ProductionProductRouteItemParam();
                        BeanUtils.copyProperties(paramDto, paramEntity, "id");
                        paramEntity.setProductionProductRouteItemId(routeItemId);
                        if (paramDto.getId() != null) {
                            ProductionOrderRouteItemParam orderParam = productionOrderRouteItemParamService.getById(paramDto.getId());
                            if (orderParam != null) {
                                paramEntity.setOrderItemParamId(orderParam.getId());
                                paramEntity.setParamName(orderParam.getParamName());
                                paramEntity.setParamType(orderParam.getParamType());
                                paramEntity.setParamFormat(orderParam.getParamFormat());
                                paramEntity.setValueMode(orderParam.getValueMode());
                                paramEntity.setUnit(orderParam.getUnit());
                            }
                        }
                        productionProductRouteItemParamService.save(paramEntity);
                    }
                    productionProductRouteItemParamService.save(paramEntity);
                }
            }
src/main/java/com/ruoyi/productionPlan/controller/SalesDeliveryController.java
@@ -1,6 +1,13 @@
package com.ruoyi.productionPlan.controller;
import com.ruoyi.energy.vo.EnergyStatisticsVo;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.productionPlan.pojo.SalesDelivery;
import com.ruoyi.productionPlan.service.SalesDeliveryService;
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.RestController;
@@ -16,5 +23,4 @@
@RequestMapping("/salesDelivery")
@Api(tags = "销售发货明细")
public class SalesDeliveryController {
}
src/main/java/com/ruoyi/productionPlan/enums/AddressRegionEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,133 @@
package com.ruoyi.productionPlan.enums;
import lombok.Getter;
import java.util.Arrays;
import java.util.List;
/**
 * åœ°å€å½’属地枚举
 * æ ¹æ®åœ°å€å…³é”®å­—自动匹配:银川/石嘴山/吴忠/固原/中卫/自提/内蒙古/其他
 */
@Getter
public enum  AddressRegionEnum {
    /**
     * é“¶å·å¸‚
     */
    YINCHUAN("银川", Arrays.asList("兴庆", "西夏", "金凤", "永宁", "贺兰", "灵武")),
    /**
     * çŸ³å˜´å±±å¸‚
     */
    SHIZUISHAN("石嘴山", Arrays.asList("大武口", "平罗", "惠农", "利通")),
    /**
     * å´å¿ å¸‚
     */
    WUZHONG("吴忠", Arrays.asList("红寺堡", "盐池", "同心", "青铜峡")),
    /**
     * å›ºåŽŸå¸‚
     */
    GUYUAN("固原",Arrays.asList("原州", "泾源", "彭阳", "中宁", "海原", "隆德", "西吉")),
    /**
     * ä¸­å«å¸‚
     */
    ZHONGWEI("中卫", Arrays.asList("沙坡头", "中宁", "海原")),
    /**
     * è‡ªæ
     */
    SELF_PICKUP("自提", Arrays.asList("自提")),
    /**
     * å†…蒙古(包含你提供的所有区县关键字)
     */
    INNER_MONGOLIA("内蒙古", Arrays.asList(
            // å‘¼å’Œæµ©ç‰¹
            "呼和浩特", "新城", "回民", "玉泉", "赛罕", "土默特左旗", "土默特", "托克托", "和林格尔", "清水河", "武川",
            // åŒ…头
            "包头", "东河", "昆都仑", "青山", "石拐", "白云鄂博", "九原", "土默特右旗", "固阳", "达尔罕茂明安联合旗",
            // ä¹Œæµ·
            "乌海", "海勃湾", "海南", "乌达",
            // èµ¤å³°
            "赤峰", "红山", "元宝山", "松山", "阿鲁科尔沁旗", "巴林左旗", "巴林右旗", "林西", "克什克腾旗", "翁牛特旗", "喀喇沁旗", "宁城", "敖汉旗",
            // é€šè¾½
            "通辽", "科尔沁", "霍林郭勒", "科尔沁左翼中旗", "科尔沁左翼后旗", "开鲁", "库伦旗", "奈曼旗", "扎鲁特旗",
            // é„‚尔多斯(含自定义地址)
            "鄂尔多斯", "东胜", "康巴什", "达拉特旗", "准格尔旗", "鄂托克前旗", "鄂托克旗", "杭锦旗", "乌审旗", "伊金霍洛旗",
            // å‘¼ä¼¦è´å°”
            "呼伦贝尔", "海拉尔", "扎赉诺尔", "满洲里", "牙克石", "扎兰屯", "额尔古纳", "根河",
            "阿荣旗", "莫力达瓦达斡尔族自治旗", "鄂伦春自治旗", "鄂温克族自治旗", "陈巴尔虎旗", "新巴尔虎左旗", "新巴尔虎右旗",
            // å·´å½¦æ·–å°”
            "巴彦淖尔", "临河", "五原", "磴口", "乌拉特前旗", "乌拉特中旗", "乌拉特后旗", "杭锦后旗",
            // ä¹Œå…°å¯Ÿå¸ƒ
            "乌兰察布", "集宁", "丰镇", "卓资", "化德", "商都", "兴和", "凉城",
            "察哈尔右翼前旗", "察哈尔右翼中旗", "察哈尔右翼后旗", "四子王旗",
            // å…´å®‰ç›Ÿ
            "兴安盟", "乌兰浩特", "阿尔山", "科尔沁右翼前旗", "科尔沁右翼中旗", "扎赉特旗", "突泉",
            // é”¡æž—郭勒盟
            "锡林郭勒盟", "锡林浩特", "二连浩特", "阿巴嘎旗", "苏尼特左旗", "苏尼特右旗",
            "东乌珠穆沁旗", "西乌珠穆沁旗", "太仆寺旗", "镶黄旗", "正镶白旗", "正蓝旗", "多伦",
            // é˜¿æ‹‰å–„盟
            "阿拉善盟", "阿拉善左旗", "阿拉善右旗", "额济纳旗",
            //自定义
            "苏里格经济开发区", "杭锦旗伊和乌素苏木草原站", "鄂托克前旗上海庙镇","内蒙"
    )),
    /**
     * å…¶ä»–地区
     */
    OTHER("其他", Arrays.asList());
    /**
     * å½’属地名称
     */
    private final String regionName;
    /**
     * åŒ¹é…å…³é”®å­—列表
     */
    private final List<String> keyWords;
    /**
     * æž„造方法
     */
    AddressRegionEnum(String regionName, List<String> keyWords) {
        this.regionName = regionName;
        this.keyWords = keyWords;
    }
    // ==================== æ ¸å¿ƒæ–¹æ³•:根据地址字符串匹配归属地 ====================
    /**
     * æ ¹æ®åœ°å€æ–‡æœ¬è‡ªåŠ¨è¯†åˆ«å½’å±žåœ°
     * @param address è¯¦ç»†åœ°å€å­—符串
     * @return åŒ¹é…åˆ°çš„归属地枚举(默认返回OTHER)
     */
    public static AddressRegionEnum matchRegion(String address) {
        // åœ°å€ä¸ºç©º/空字符串,直接返回其他
        if (address == null || address.trim().isEmpty()) {
            return OTHER;
        }
        // æŒ‰ä¼˜å…ˆçº§åŒ¹é…ï¼šè‡ªæ > å®å¤å„地市 > å†…蒙古 > å…¶ä»–
        for (AddressRegionEnum region : values()) {
            // è·³è¿‡æ— å…³é”®å­—çš„OTHER
            if (region.keyWords.isEmpty()) {
                continue;
            }
            // éåŽ†å…³é”®å­—ï¼Œåœ°å€åŒ…å«ä»»æ„å…³é”®å­—åˆ™åŒ¹é…æˆåŠŸ
            for (String keyword : region.keyWords) {
                if (address.contains(keyword)) {
                    return region;
                }
            }
        }
        // æ— åŒ¹é…å…³é”®å­—,返回其他
        return OTHER;
    }
}
src/main/java/com/ruoyi/quality/service/IQualityInspectService.java
@@ -3,9 +3,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.production.dto.ProcessRouteItemParamDto;
import com.ruoyi.production.pojo.ProductionOrderRouteItemParam;
import com.ruoyi.production.pojo.ProductionProductRouteItemParam;
import com.ruoyi.production.dto.ProductionProductRouteItemParamDto;
import com.ruoyi.quality.dto.FinishedPageDto;
import com.ruoyi.quality.dto.FinishedRatioDto;
import com.ruoyi.quality.dto.ProcessPageDto;
@@ -34,7 +32,7 @@
    IPage<ProcessPageDto> processPage(Page page, ProcessPageDto processPageDto);
    List<ProductionProductRouteItemParam> processDetails(ProcessPageDto processPageDto);
    List<ProductionProductRouteItemParamDto> processDetails(ProcessPageDto processPageDto);
    IPage<FinishedPageDto> finishedPage(Page page, FinishedPageDto finishedPageDto);
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -9,17 +9,20 @@
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.production.dto.ProcessRouteItemParamDto;
import com.ruoyi.production.dto.ProductMaterialSkuDto;
import com.ruoyi.production.dto.ProductionProductRouteItemParamDto;
import com.ruoyi.production.mapper.ProductOrderMapper;
import com.ruoyi.production.mapper.ProductionProductRouteItemMapper;
import com.ruoyi.production.mapper.ProductionProductRouteItemParamMapper;
import com.ruoyi.production.pojo.ProductionOrderRouteItemParam;
import com.ruoyi.production.pojo.ProductionProductInput;
import com.ruoyi.production.pojo.ProductionProductRouteItemParam;
import com.ruoyi.production.service.ProductBomService;
import com.ruoyi.production.service.ProductMaterialService;
import com.ruoyi.production.service.ProductionProductInputService;
import com.ruoyi.quality.dto.FinishedPageDto;
import com.ruoyi.quality.dto.FinishedRatioDto;
import com.ruoyi.quality.dto.ProcessPageDto;
@@ -42,6 +45,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
@@ -52,23 +56,29 @@
public class QualityInspectServiceImpl extends ServiceImpl<QualityInspectMapper, QualityInspect> implements IQualityInspectService {
    private final StockUtils stockUtils;
    private QualityInspectMapper qualityInspectMapper;
    private final QualityInspectMapper qualityInspectMapper;
    private IQualityInspectParamService qualityInspectParamService;
    private final IQualityInspectParamService qualityInspectParamService;
    private QualityTestStandardMapper qualityTestStandardMapper;
    private final QualityTestStandardMapper qualityTestStandardMapper;
    private QualityUnqualifiedMapper qualityUnqualifiedMapper;
    private final QualityUnqualifiedMapper qualityUnqualifiedMapper;
    private SalesLedgerProductMapper salesLedgerProductMapper;
    private final SalesLedgerProductMapper salesLedgerProductMapper;
    private ProcurementRecordService procurementRecordService;
    private final ProcurementRecordService procurementRecordService;
    private ProductionProductRouteItemMapper productionProductRouteItemMapper;
    private final ProductionProductRouteItemMapper productionProductRouteItemMapper;
    private ProductionProductRouteItemParamMapper productionProductRouteItemParamMapper;
    private final ProductionProductRouteItemParamMapper productionProductRouteItemParamMapper;
    private ProductOrderMapper productOrderMapper;
    private final ProductOrderMapper productOrderMapper;
    private final ProductionProductInputService productionProductInputService;
    private final ProductMaterialService productMaterialService;
    private final ProductBomService productBomService;
    @Override
    public int add(QualityInspectDto qualityInspectDto) {
@@ -177,8 +187,54 @@
    }
    @Override
    public List<ProductionProductRouteItemParam> processDetails(ProcessPageDto processPageDto) {
        return productionProductRouteItemParamMapper.processDetails(processPageDto.getProductionProductRouteItemId());
    public List<ProductionProductRouteItemParamDto> processDetails(ProcessPageDto processPageDto) {
        List<ProductionProductRouteItemParamDto> resultList = new ArrayList<>();
        // 1. æŸ¥è¯¢æ™®é€šå‚æ•°
        List<ProductionProductRouteItemParam> paramList = productionProductRouteItemParamMapper.processDetails(processPageDto.getProductionProductRouteItemId());
        if (paramList != null && !paramList.isEmpty()) {
            resultList.addAll(paramList.stream().map(param -> {
                ProductionProductRouteItemParamDto dto = new ProductionProductRouteItemParamDto();
                BeanUtils.copyProperties(param, dto);
                return dto;
            }).collect(Collectors.toList()));
        }
        // 2. æŸ¥è¯¢ç‰©æ–™æŠ•å…¥
        // æ³¨æ„ï¼šæˆå“æ£€çš„æ—¶å€™å¯èƒ½æ²¡æœ‰å…·ä½“单条报工记录ID,所以成品检详情可能需要按订单查询,
        // ä½†è¿™é‡Œçš„processDetails是“过程检详情”,通常有具体报工记录。
        // æ ¹æ®æŠ¥å·¥è®°å½• ID æŸ¥æ‰¾å¯¹åº”çš„ ProductMainId
        Long routeItemId = processPageDto.getProductionProductRouteItemId();
        if (routeItemId != null) {
            List<ProductionProductInput> inputList = productionProductInputService.list(Wrappers.<ProductionProductInput>lambdaQuery()
                    .eq(ProductionProductInput::getRouteItemId, routeItemId));
            if (inputList != null && !inputList.isEmpty()) {
                for (ProductionProductInput input : inputList) {
                    ProductionProductRouteItemParamDto dto = new ProductionProductRouteItemParamDto();
                    dto.setProductId(input.getProductId());
                    dto.setBomId(input.getBomId());
                    dto.setQuantity(input.getQuantity());
                    dto.setProductValue(input.getQuantity());
                    dto.setUnit(input.getUnit());
                    // å¡«å……物料信息
                    ProductMaterialSkuDto materialSkuDto = productMaterialService.selectProductByModelId(input.getProductId());
                    if (materialSkuDto != null) {
                        dto.setParamName(materialSkuDto.getProductName());
                        dto.setProductName(materialSkuDto.getProductName());
                        dto.setModel(materialSkuDto.getModel());
                        dto.setMaterialCode(materialSkuDto.getMaterialCode());
                    }
                    String strength = productBomService.strengthById(input.getBomId());
                    dto.setStrength(strength);
                    resultList.add(dto);
                }
            }
        }
        return resultList;
    }
    @Override
src/main/resources/mapper/energy/EnergyConsumptionDetailMapper.xml
@@ -66,8 +66,9 @@
            </if>
            group by e.energy_tyep
    </select>
    <select id="energyCostDtos" resultType="com.ruoyi.energy.dto.EnergyCostDto">
   select  z.meter_reading_date,
    <select id="energyCostDtos1" resultType="com.ruoyi.energy.dto.EnergyCostDto">
    select distinct
           z.meter_reading_date,
           COALESCE(A.waterConsumption, 0) waterConsumption,
           COALESCE(A.waterCost, 0) waterCost,
           COALESCE(B.electricityConsumption, 0) electricityConsumption,
@@ -118,9 +119,115 @@
        on z.meter_reading_date=C.meter_reading_date
    order by z.meter_reading_date
    </select>
    <select id="energyConsumptionDetailDtos"
            resultType="com.ruoyi.energy.dto.EnergyConsumptionDetailDto">
        select ecd.meter_reading_date,
    <select id="energyCostDtos2" resultType="com.ruoyi.energy.dto.EnergyCostDto">
    select distinct
           DATE_FORMAT(z.meter_reading_date, '%Y-%m') AS meterReadingDate ,
           COALESCE(A.waterConsumption, 0) waterConsumption,
           COALESCE(A.waterCost, 0) waterCost,
           COALESCE(B.electricityConsumption, 0) electricityConsumption,
           COALESCE(B.electricityCost, 0) electricityCost,
           COALESCE(C.gasConsumption, 0) gasConsumption,
           COALESCE(C.gasCost, 0) gasCost,
           COALESCE(A.waterConsumption, 0)+ COALESCE(B.electricityConsumption, 0)+ COALESCE(C.gasConsumption, 0) totalConsumption,
           COALESCE(A.waterCost, 0)+ COALESCE(B.electricityCost, 0)+ COALESCE(C.gasCost, 0) totalCost
    from   energy_consumption_detail z
    left join
    (select    DATE_FORMAT(ecd.meter_reading_date, '%Y-%m') AS meterReadingDate ,
               sum(ecd.dosage) waterConsumption,
               sum(ecd.dosage * e1.unit_price) waterCost
            from energy_consumption_detail ecd
            left join  energy e1 on ecd.energy_id = e1.id
            where ecd.meter_reading_date between #{c.startDate} and #{c.endDate}
            and e1.energy_tyep='æ°´'
            <if test="c.type != null and c.type != ''">
                and ecd.type =#{c.type}
            </if>
            group by DATE_FORMAT(ecd.meter_reading_date, '%Y-%m'))A
        on DATE_FORMAT(z.meter_reading_date, '%Y-%m')=A.meterReadingDate
    left join
    (select    DATE_FORMAT(ecd.meter_reading_date, '%Y-%m') AS meterReadingDate,
               sum(ecd.dosage) electricityConsumption,
               sum(ecd.dosage * e2.unit_price) electricityCost
            from energy_consumption_detail ecd
            left join  energy e2 on ecd.energy_id = e2.id
            where ecd.meter_reading_date between #{c.startDate} and #{c.endDate}
            and e2.energy_tyep='电'
            <if test="c.type != null and c.type != ''">
                and ecd.type =#{c.type}
            </if>
            group by DATE_FORMAT(ecd.meter_reading_date, '%Y-%m'))B
        on DATE_FORMAT(z.meter_reading_date, '%Y-%m')=B.meterReadingDate
    left join
    (select    DATE_FORMAT(ecd.meter_reading_date, '%Y-%m') AS meterReadingDate,
               sum(ecd.dosage) gasConsumption,
               sum(ecd.dosage * e3.unit_price) gasCost
            from energy_consumption_detail ecd
            left join  energy e3 on ecd.energy_id = e3.id
            where ecd.meter_reading_date between #{c.startDate} and #{c.endDate}
            and e3.energy_tyep='气'
            <if test="c.type != null and c.type != ''">
                and ecd.type =#{c.type}
            </if>
            group by DATE_FORMAT(ecd.meter_reading_date, '%Y-%m'))C
        on DATE_FORMAT(z.meter_reading_date, '%Y-%m')=C.meterReadingDate
    order by DATE_FORMAT(z.meter_reading_date, '%Y-%m')
    </select>
    <select id="energyCostDtos3" resultType="com.ruoyi.energy.dto.EnergyCostDto">
    select distinct
           DATE_FORMAT(z.meter_reading_date, '%Y') AS  meterReadingDate,
           COALESCE(A.waterConsumption, 0) waterConsumption,
           COALESCE(A.waterCost, 0) waterCost,
           COALESCE(B.electricityConsumption, 0) electricityConsumption,
           COALESCE(B.electricityCost, 0) electricityCost,
           COALESCE(C.gasConsumption, 0) gasConsumption,
           COALESCE(C.gasCost, 0) gasCost,
           COALESCE(A.waterConsumption, 0)+ COALESCE(B.electricityConsumption, 0)+ COALESCE(C.gasConsumption, 0) totalConsumption,
           COALESCE(A.waterCost, 0)+ COALESCE(B.electricityCost, 0)+ COALESCE(C.gasCost, 0) totalCost
    from   energy_consumption_detail z
    left join
    (select   DATE_FORMAT(ecd.meter_reading_date, '%Y') AS meterReadingDate,
               sum(ecd.dosage) waterConsumption,
               sum(ecd.dosage * e1.unit_price) waterCost
            from energy_consumption_detail ecd
            left join  energy e1 on ecd.energy_id = e1.id
            where ecd.meter_reading_date between #{c.startDate} and #{c.endDate}
            and e1.energy_tyep='æ°´'
            <if test="c.type != null and c.type != ''">
                and ecd.type =#{c.type}
            </if>
            group by DATE_FORMAT(ecd.meter_reading_date, '%Y'))A
        on DATE_FORMAT(z.meter_reading_date, '%Y')=A.meterReadingDate
    left join
    (select DATE_FORMAT(ecd.meter_reading_date, '%Y') AS meterReadingDate,
               sum(ecd.dosage) electricityConsumption,
               sum(ecd.dosage * e2.unit_price) electricityCost
            from energy_consumption_detail ecd
            left join  energy e2 on ecd.energy_id = e2.id
            where ecd.meter_reading_date between #{c.startDate} and #{c.endDate}
            and e2.energy_tyep='电'
            <if test="c.type != null and c.type != ''">
                and ecd.type =#{c.type}
            </if>
            group by DATE_FORMAT(ecd.meter_reading_date, '%Y'))B
        on DATE_FORMAT(z.meter_reading_date, '%Y')=B.meterReadingDate
    left join
    (select DATE_FORMAT(ecd.meter_reading_date, '%Y') AS meterReadingDate,
               sum(ecd.dosage) gasConsumption,
               sum(ecd.dosage * e3.unit_price) gasCost
            from energy_consumption_detail ecd
            left join  energy e3 on ecd.energy_id = e3.id
            where ecd.meter_reading_date between #{c.startDate} and #{c.endDate}
            and e3.energy_tyep='气'
            <if test="c.type != null and c.type != ''">
                and ecd.type =#{c.type}
            </if>
            group by DATE_FORMAT(ecd.meter_reading_date, '%Y'))C
        on DATE_FORMAT(z.meter_reading_date, '%Y')=C.meterReadingDate
    order by DATE_FORMAT(z.meter_reading_date, '%Y')
    </select>
    <select id="energyConsumptionDetailDtos1" resultType="com.ruoyi.energy.dto.EnergyDetailDto">
        select distinct
               ecd.meter_reading_date,
               e.energy_tyep,
               ecd.type,
               e.unit,
@@ -137,5 +244,42 @@
                     e.unit_price
        order by ecd.meter_reading_date
    </select>
    <select id="energyConsumptionDetailDtos2" resultType="com.ruoyi.energy.dto.EnergyDetailDto">
        select distinct
               DATE_FORMAT(ecd.meter_reading_date, '%Y-%m') AS meterReadingDate ,
               e.energy_tyep,
               ecd.type,
               e.unit,
               e.unit_price,
               sum(ecd.dosage) dosage,
               sum(ecd.dosage * e.unit_price) cost
        from energy_consumption_detail ecd
                 left join  energy e on ecd.energy_id = e.id
        where ecd.meter_reading_date between #{c.startDate} and #{c.endDate}
        group by DATE_FORMAT(ecd.meter_reading_date, '%Y-%m'),
                 e.energy_tyep,
                 ecd.type,
                 e.unit,
                 e.unit_price
        order by DATE_FORMAT(ecd.meter_reading_date, '%Y-%m')
    </select>
    <select id="energyConsumptionDetailDtos3" resultType="com.ruoyi.energy.dto.EnergyDetailDto">
        select distinct
               DATE_FORMAT(ecd.meter_reading_date, '%Y') AS meterReadingDate,
               e.energy_tyep,
               ecd.type,
               e.unit,
               e.unit_price,
               sum(ecd.dosage) dosage,
               sum(ecd.dosage * e.unit_price) cost
        from energy_consumption_detail ecd
                 left join  energy e on ecd.energy_id = e.id
        where ecd.meter_reading_date between #{c.startDate} and #{c.endDate}
        group by DATE_FORMAT(ecd.meter_reading_date, '%Y'),
                 e.energy_tyep,
                 ecd.type,
                 e.unit,
                 e.unit_price
        order by DATE_FORMAT(ecd.meter_reading_date, '%Y')
    </select>
</mapper>
src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -210,25 +210,23 @@
               sku.material_code,
               pm.product_name,
               sku.model,
               pprip.unit,
               ppi.unit,
               pos.unit_quantity,
               sum(pprip.product_value) actualInputQuantity,
               sum(ppi.quantity) actualInputQuantity,
               sum(ppo.quantity+ppo.scrap_qty) actualOutputQuantity
        from   production_product_route_item_param pprip
        left join production_product_route_item ppri on ppri.id=pprip.production_product_route_item_id
        left join production_product_main ppm on ppm.id=ppri.product_main_id
        from   production_product_input ppi
        left join production_product_main ppm on ppm.id=ppi.product_main_id
        left join production_product_output ppo on ppm.id=ppo.product_main_id
        left join product_material_sku sku ON pprip.product_id = sku.id
        left join product_material_sku sku ON ppi.product_id = sku.id
        left join product_material pm ON sku.product_id = pm.id
        left join production_order_structure pos ON pos.product_model_id = pprip.product_id
        left join production_order_structure pos ON pos.product_model_id = ppi.product_id
        where ppm.product_order_id = #{productOrderId}
        and pos.order_id = #{productOrderId}
        and pprip.order_item_param_id is null
        group by sku.material_code,
                 pm.product_name,
                 sku.model,
                 pos.unit_quantity,
                 pprip.unit)A
                 ppi.unit)A
        
    </select>
</mapper>
src/main/resources/mapper/production/ProductionProductInputMapper.xml
@@ -5,11 +5,17 @@
    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductionProductInput">
        <id property="id" column="id"/>
        <result property="productMainId" column="product_main_id"/>
        <result property="productModelId" column="product_model_id"/>
        <result property="routeItemId" column="route_item_id"/>
        <result property="productId" column="product_id"/>
        <result property="bomId" column="bom_id"/>
        <result property="quantity" column="quantity"/>
        <result property="tenantId" column="tenant_id"/>
        <result property="unit" column="unit"/>
        <result property="createUser" column="create_user"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
        <result property="tenantId" column="tenant_id"/>
    </resultMap>
    <select id="listPageProductionProductInputDto" resultType="com.ruoyi.production.dto.ProductionProductInputDto">
        select ppi.*,
        pm.model as model,
src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -23,13 +23,12 @@
        pms.material_code as materialCode,
        pm.product_name as productName,
        pms.model as productModelName,
        IFNULL(ppi.quantity, 0) as totalQuantity,
        IFNULL(ppo.total_quantity, 0) as totalQuantity,
        IFNULL(ppo.scrap_qty, 0) as scrapQty,
        IFNULL(ppo.quantity, 0) as quantity
        from
        production_product_main ppm
        left join production_product_output ppo on ppo.product_main_id = ppm.id
        left join production_product_input ppi on ppi.product_main_id = ppm.id
        left join product_order po on po.id = ppm.product_order_id
        left join product_order_plan pop on po.id = pop.product_order_id
        left join production_plan pp on pop.production_plan_id = pp.id
src/main/resources/mapper/production/ProductionProductRouteItemParamMapper.xml
@@ -14,13 +14,9 @@
        <result column="min_value" property="minValue"/>
        <result column="max_value" property="maxValue"/>
        <result column="param_value" property="paramValue"/>
        <result column="product_id" property="productId"/>
        <result column="bom_id" property="bomId"/>
        <result column="product_value" property="productValue"/>
        <result column="unit" property="unit"/>
        <result column="is_required" property="isRequired"/>
        <result column="source_sort" property="sourceSort"/>
        <result column="dict_code" property="dictCode"/>
        <result column="create_user" property="createUser"/>
        <result column="create_time" property="createTime"/>
        <result column="update_user" property="updateUser"/>
@@ -31,7 +27,7 @@
        select pprip.*
        from production_product_route_item_param pprip
        where pprip.production_product_route_item_id = #{productionProductRouteItemId}
        and pprip.order_item_param_id is not null
          and pprip.order_item_param_id is not null
    </select>
</mapper>