已修改16个文件
310 ■■■■ 文件已修改
src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/consumables/execl/ConsumablesInRecordExportData.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/consumables/execl/ConsumablesInventoryExportData.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/consumables/service/impl/ConsumablesInventoryServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/service/impl/DeviceRepairServiceImpl.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/dto/HomeBusinessDto.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/dto/QualityStatisticsDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductBomController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductBomService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/pojo/RawMaterial.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/consumables/ConsumablesInventoryMapper.xml 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/quality/QualityUnqualifiedMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInventoryMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/work-order-template.docx 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java
@@ -5,7 +5,7 @@
@Getter
public enum StockOutQualifiedRecordTypeEnum implements BaseEnum<String> {
    CUSTOMIZATION_STOCK_OUT("1", "合格自定义出库");
    CUSTOMIZATION_STOCK_OUT("0", "合格自定义出库");
//    PRODUCTION_REPORT_STOCK_OUT("3", "生产报工-出库");
//    SALE_STOCK_OUT("8", "销售-出库"),
//    SALE_SHIP_STOCK_OUT("13", "销售-发货出库");
src/main/java/com/ruoyi/consumables/execl/ConsumablesInRecordExportData.java
@@ -21,7 +21,7 @@
    @Excel(name = "入库来源")
    private String recordType;
    @Excel(name = "入库数量")
    private String ConsumablesInNum;
    private String stockInNum;
    @Excel(name = "入库时间")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
src/main/java/com/ruoyi/consumables/execl/ConsumablesInventoryExportData.java
@@ -21,13 +21,16 @@
    @Excel(name = "库存数量")
    private BigDecimal qualitity;
    @Excel(name = "预警数量")
    private BigDecimal warnNum;
//
//    @Excel(name = "预警数量")
//    private BigDecimal warnNum;
    @Excel(name = "冻结数量")
    private BigDecimal lockedQuantity;
    @Excel(name = "净重(吨)")
    private BigDecimal netWeight;
    @Excel(name = "备注")
    private String remark;
//
src/main/java/com/ruoyi/consumables/service/impl/ConsumablesInventoryServiceImpl.java
@@ -162,7 +162,7 @@
                        consumablesInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode());
                        consumablesInventoryDto.setQualitity(dto.getQualitity());
                        consumablesInventoryDto.setRemark(dto.getRemark());
                        consumablesInventoryDto.setWarnNum(dto.getWarnNum());
                        consumablesInventoryDto.setNetWeight(dto.getNetWeight());
                        if (ObjectUtils.isNotEmpty(dto.getLockedQuantity()) && dto.getLockedQuantity().compareTo(dto.getQualitity()) > 0) {
                            throw new RuntimeException("冻结数量不能超过本次导入的库存数量");
                        }
src/main/java/com/ruoyi/device/service/impl/DeviceRepairServiceImpl.java
@@ -110,21 +110,23 @@
    @Override
    public AjaxResult saveDeviceRepair(DeviceRepair deviceRepair) {
        DeviceLedger byId = deviceLedgerService.getById(deviceRepair.getDeviceLedgerId());
        if (CollectionUtils.isNotEmpty(deviceRepair.getFileList())) {
            List<String> fileIds = deviceRepair.getFileList().stream()
                    .map(TempFile::getTempId)
                    .collect(Collectors.toList());
            try {
                tempFileService.migrateTempFilesToFormal(deviceRepair.getId(), fileIds, FileNameType.DeviceRepair.getValue());
            } catch (Exception e) {
                log.error("设备维修文件迁移错误", e);
            }
        }
        deviceRepair.setDeviceName(byId.getDeviceName());
        deviceRepair.setDeviceModel(byId.getDeviceModel());
        if (deviceRepair.getRemark() == null) {
            deviceRepair.setRemark("");
        }
        boolean save = this.save(deviceRepair);
        if (save) {
            if (CollectionUtils.isNotEmpty(deviceRepair.getFileList())) {
                List<String> fileIds = deviceRepair.getFileList().stream()
                        .map(TempFile::getTempId)
                        .collect(Collectors.toList());
                try {
                    tempFileService.migrateTempFilesToFormal(deviceRepair.getId(), fileIds, FileNameType.DeviceRepair.getValue());
                } catch (Exception e) {
                    log.error("设备维修文件迁移错误", e);
                }
            }
            return AjaxResult.success();
        }
        return AjaxResult.error();
src/main/java/com/ruoyi/home/dto/HomeBusinessDto.java
@@ -4,8 +4,6 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @author :yys
 * @date : 2025/7/25 9:25
@@ -29,7 +27,13 @@
    @ApiModelProperty("当前库存数量")
    private String inventoryNum = "0.00";
    @ApiModelProperty("当前耗材库存数量")
    private String consumablesQuantityTotal = "0.00";
    @ApiModelProperty("今日库存数量")
    private String todayInventoryNum = "0.00";
    @ApiModelProperty("今日耗材库存数量")
    private String consumablesTodayNum = "0.00";
}
src/main/java/com/ruoyi/home/dto/QualityStatisticsDto.java
@@ -1,5 +1,6 @@
package com.ruoyi.home.dto;
import com.ruoyi.quality.pojo.RawMaterial;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -26,4 +27,6 @@
    private List<QualityStatisticsItem> item;
    private List<RawMaterial> rawItem;
}
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -19,6 +19,7 @@
import com.ruoyi.common.enums.ApproveTypeEnum;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.consumables.mapper.ConsumablesInventoryMapper;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.device.pojo.DeviceRepair;
import com.ruoyi.dto.MapDto;
@@ -38,8 +39,10 @@
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.mapper.QualityUnqualifiedMapper;
import com.ruoyi.quality.mapper.RawMaterialMapper;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.quality.pojo.QualityUnqualified;
import com.ruoyi.quality.pojo.RawMaterial;
import com.ruoyi.sales.mapper.ReceiptPaymentMapper;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
@@ -85,6 +88,9 @@
    private StockInventoryMapper stockInventoryMapper;
    @Autowired
    private ConsumablesInventoryMapper consumablesInventoryMapper;
    @Autowired
    private QualityInspectMapper qualityStatisticsMapper;
    @Autowired
@@ -128,6 +134,9 @@
    @Autowired
    private QualityInspectMapper qualityInspectMapper;
    @Autowired
    private RawMaterialMapper rawMaterialMapper;
    @Autowired
    private QualityUnqualifiedMapper qualityUnqualifiedMapper;
@@ -202,11 +211,15 @@
        }
        // 统计库存
        BigDecimal stockQuantityTotal = stockInventoryMapper.selectTotal();
        BigDecimal consumablesQuantityTotal = consumablesInventoryMapper.selectTotal();
        homeBusinessDto.setInventoryNum(stockQuantityTotal.setScale(2, RoundingMode.HALF_UP).toString());
        homeBusinessDto.setConsumablesQuantityTotal(consumablesQuantityTotal.setScale(2, RoundingMode.HALF_UP).toString());
        // 获取当天入库数量
        BigDecimal bigDecimal = stockInventoryMapper.selectTotalByDate(LocalDate.now());
        BigDecimal consumablesTodayNum = consumablesInventoryMapper.selectTotalByDate(LocalDate.now());
        homeBusinessDto.setTodayInventoryNum(bigDecimal.setScale(2, RoundingMode.HALF_UP).toString());
        homeBusinessDto.setConsumablesTodayNum(consumablesTodayNum.setScale(2, RoundingMode.HALF_UP).toString());
        return homeBusinessDto;
    }
@@ -2389,87 +2402,88 @@
                endDate = today.with(DayOfWeek.SUNDAY);
        }
        List<QualityInspect> qualityInspectList = qualityInspectMapper
                .selectList(new LambdaQueryWrapper<QualityInspect>()
                        .ge(QualityInspect::getCheckTime, startDate.toString())
                        .le(QualityInspect::getCheckTime, endDate.toString())
                        .eq(QualityInspect::getInspectState, 1));
        List<RawMaterial> rawMaterialList = rawMaterialMapper
                .selectList(new LambdaQueryWrapper<RawMaterial>()
                        .ge(RawMaterial::getCheckTime, startDate.toString())
                        .le(RawMaterial::getCheckTime, endDate.toString())
                        .eq(RawMaterial::getInspectState, 1));
        QualityStatisticsDto dto = new QualityStatisticsDto();
        dto.setSupplierNum(sumQuantity(qualityInspectList, 0)); // 原材料
        dto.setProcessNum(sumQuantity(qualityInspectList, 1)); // 过程
        dto.setFactoryNum(sumQuantity(qualityInspectList, 2)); // 出厂
        Map<Integer, BigDecimal> countMap = rawMaterialList.stream()
                .collect(Collectors.groupingBy(
                        RawMaterial::getCheckType,
                        Collectors.collectingAndThen(
                                Collectors.counting(),
                                count -> BigDecimal.valueOf(count)
                        )
                ));
        Map<String, List<QualityInspect>> groupedByCheckResult = qualityInspectList.stream()
                .collect(Collectors.groupingBy(QualityInspect::getCheckResult));
        dto.setSupplierNum(countMap.getOrDefault(0, BigDecimal.ZERO)); // 入厂
        dto.setProcessNum(countMap.getOrDefault(1, BigDecimal.ZERO));  // 车间
        dto.setFactoryNum(countMap.getOrDefault(2, BigDecimal.ZERO));  // 出厂
        List<QualityInspect> qualityInspects = groupedByCheckResult.getOrDefault("不合格", new ArrayList<>());
        // 3. 筛选不合格的记录(check_result = 0)
        List<RawMaterial> unqualifiedList = rawMaterialList.stream()
                .filter(i -> i.getCheckResult() == 0)  // 0表示不合格
                .collect(Collectors.toList());
        // 4. 处理图表项 (Item)
        List<QualityStatisticsItem> itemList = new ArrayList<>();
        Map<QualityInspect, LocalDate> dateMap = qualityInspects.isEmpty() ?
                new HashMap<>() :
                qualityInspectList.stream()
                        .collect(Collectors.toMap(
                                i -> i,
                                i -> i.getCheckTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
                                (existing, replacement) -> existing));
        List<RawMaterial> itemList = new ArrayList<>();
        if (type == 3) {
            // 季度模式:按月分组
            Map<String, List<QualityInspect>> groupByMonth = qualityInspects.isEmpty() ?
            Map<String, List<RawMaterial>> groupByMonth = unqualifiedList.isEmpty() ?
                    new HashMap<>() :
                    qualityInspects.stream()
                    unqualifiedList.stream()
                            .collect(Collectors.groupingBy(i -> {
                                LocalDate ld = dateMap.get(i);
                                LocalDate ld = i.getCheckTime().toInstant()
                                        .atZone(ZoneId.systemDefault()).toLocalDate();
                                return ld.format(DateTimeFormatter.ofPattern("yyyy-MM"));
                            }));
            for (int i = 0; i < 3; i++) {
                LocalDate monthDate = startDate.plusMonths(i);
                String monthStr = monthDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
                itemList.add(buildItem(monthStr, groupByMonth.getOrDefault(monthStr, new ArrayList<>())));
                List<RawMaterial> monthData = groupByMonth.getOrDefault(monthStr, new ArrayList<>());
                itemList.add(buildItem(monthStr, monthData));
            }
        } else {
            // 周或月模式:按天分组
            Map<String, List<QualityInspect>> groupByDay = qualityInspects.isEmpty() ?
            Map<String, List<RawMaterial>> groupByDay = unqualifiedList.isEmpty() ?
                    new HashMap<>() :
                    qualityInspects.stream()
                    unqualifiedList.stream()
                            .collect(Collectors.groupingBy(i -> {
                                LocalDate ld = dateMap.get(i);
                                LocalDate ld = i.getCheckTime().toInstant()
                                        .atZone(ZoneId.systemDefault()).toLocalDate();
                                return ld.format(DateTimeFormatter.ofPattern("MM/dd"));
                            }));
            long days = ChronoUnit.DAYS.between(startDate, endDate);
            for (int i = 0; i <= days; i++) {
                LocalDate tempDay = startDate.plusDays(i);
                String dayStr = tempDay.format(DateTimeFormatter.ofPattern("MM/dd"));
                itemList.add(buildItem(dayStr, groupByDay.getOrDefault(dayStr, new ArrayList<>())));
                List<RawMaterial> dayData = groupByDay.getOrDefault(dayStr, new ArrayList<>());
                itemList.add(buildItem(dayStr, dayData));
            }
        }
        dto.setItem(itemList);
        dto.setRawItem(itemList);
        return dto;
    }
    private BigDecimal sumQuantity(List<QualityInspect> list, Integer type) {
        return list.stream()
                .filter(i -> i.getInspectType().equals(type))
                .map(QualityInspect::getQuantity)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    private QualityStatisticsItem buildItem(String dateLabel, List<QualityInspect> list) {
        QualityStatisticsItem item = new QualityStatisticsItem();
    private RawMaterial buildItem(String dateLabel, List<RawMaterial> list) {
        RawMaterial item = new RawMaterial();
        item.setDate(dateLabel);
        item.setSupplierNum(list.stream().filter(i -> i.getInspectType() == 0).map(QualityInspect::getQuantity)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        item.setProcessNum(list.stream().filter(i -> i.getInspectType() == 1).map(QualityInspect::getQuantity)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        item.setFactoryNum(list.stream().filter(i -> i.getInspectType() == 2).map(QualityInspect::getQuantity)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        item.setSupplierNum(
                BigDecimal.valueOf(list.stream().filter(i -> i.getCheckType() == 0).count())
        );
        item.setProcessNum(
                BigDecimal.valueOf(list.stream().filter(i -> i.getCheckType() == 1).count())
        );
        item.setFactoryNum(
                BigDecimal.valueOf(list.stream().filter(i -> i.getCheckType() == 2).count())
        );
        return item;
    }
src/main/java/com/ruoyi/production/controller/ProductBomController.java
@@ -73,7 +73,7 @@
    @Log(title = "修改", businessType = BusinessType.UPDATE)
    @PutMapping("/update")
    public AjaxResult update(@RequestBody ProductBom productBom) {
        return AjaxResult.success(productBomService.updateById(productBom));
        return AjaxResult.success(productBomService.update(productBom));
    }
    @ApiOperation("删除BOM")
src/main/java/com/ruoyi/production/service/ProductBomService.java
@@ -24,6 +24,8 @@
    AjaxResult add(ProductBom productBom);
    AjaxResult update(ProductBom productBom);
    AjaxResult uploadBom(MultipartFile file);
    void exportBom(HttpServletResponse response, Integer bomId);
src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
@@ -13,12 +13,11 @@
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.production.dto.BomImportDto;
import com.ruoyi.production.dto.ProcessRouteDto;
import com.ruoyi.production.dto.ProductBomDto;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.ProductBomMapper;
import com.ruoyi.production.pojo.ProductBom;
import com.ruoyi.production.pojo.ProductProcess;
import com.ruoyi.production.pojo.ProductStructure;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.ProductBomService;
import com.ruoyi.production.service.ProductProcessService;
import com.ruoyi.production.service.ProductStructureService;
@@ -59,6 +58,18 @@
    @Autowired
    private ProductProcessService productProcessService;
    @Autowired
    private ProductStructureMapper productStructureMapper;
    @Autowired
    private ProductOrderMapper productOrderMapper;
    @Autowired
    private ProductProcessRouteMapper productProcessRouteMapper;
    @Autowired
    private ProcessRouteMapper processRouteMapper;
    @Override
    public IPage<ProductBomDto> listPage(Page page, ProductBomDto productBomDto) {
        return productBomMapper.listPage(page, productBomDto);
@@ -99,6 +110,85 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(ProductBom productBom) {
        //  查询出产品模型信息
        if (productBom.getProductModelId() == null) {
            throw new ServiceException("请选择产品模型");
        }
        ProductBom oldBom = productBomMapper.selectById(productBom.getId());
        // 如果规格改变,关联的生产订单如果订单完成数量>0,则不许改bom;否则删除之前关联的产品结构, 修改关联订单的产品信息
        if (!oldBom.getProductModelId().equals(productBom.getProductModelId())) {
            ProductModel productModel = productModelService.getById(productBom.getProductModelId());
            if (productModel == null) {
                throw new ServiceException("选择的产品模型不存在");
            }
            // 关联的生产订单如果订单完成数量>0,则不许改bom
            // 先查询与该BOM关联的工艺路线
            List<ProductProcessRoute> productProcessRoutes = productProcessRouteMapper.selectList(new LambdaQueryWrapper<ProductProcessRoute>()
                    .eq(ProductProcessRoute::getBomId, oldBom.getId()));
            // 检查是否有关联的工艺路线
            if (!productProcessRoutes.isEmpty()) {
                // 提取工艺路线关联的生产订单ID
                List<Long> orderIds = productProcessRoutes.stream()
                        .map(ProductProcessRoute::getProductOrderId)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());
                // 查询关联的生产订单
                if (!orderIds.isEmpty()) {
                    List<ProductOrder> productOrders = productOrderMapper.selectList(new LambdaQueryWrapper<ProductOrder>()
                            .in(ProductOrder::getId, orderIds));
                    // 检查订单完成数量
                    for (ProductOrder order : productOrders) {
                        if (order.getCompleteQuantity() != null && order.getCompleteQuantity().compareTo(BigDecimal.ZERO) > 0) {
                            throw new ServiceException("该BOM已关联生产订单且有完成数量,无法修改");
                        } else {
                            // 修改关联订单的产品信息
                            order.setProductModelId(productBom.getProductModelId());
                            productOrderMapper.updateById(order);
                        }
                    }
                }
                // 修改关联产品工艺路线的产品信息
                for (ProductProcessRoute route : productProcessRoutes) {
                    route.setProductModelId(productBom.getProductModelId());
                    productProcessRouteMapper.updateById(route);
                }
                // 查询关联的工艺路线
                List<ProcessRoute> processRoutes = processRouteMapper.selectList(new LambdaQueryWrapper<ProcessRoute>()
                        .eq(ProcessRoute::getBomId, oldBom.getId()));
                if (!processRoutes.isEmpty()) {
                    // 修改关联工艺路线的产品信息
                    for (ProcessRoute route : processRoutes) {
                        route.setProductModelId(productBom.getProductModelId());
                        processRouteMapper.updateById(route);
                    }
                }
            }
            // 删除之前关联的产品结构
            productStructureMapper.delete(new LambdaQueryWrapper<ProductStructure>().eq(ProductStructure::getBomId, productBom.getId()));
            // 关联新的产品结构
            ProductStructure productStructure = new ProductStructure();
            productStructure.setProductModelId(productBom.getProductModelId());
            productStructure.setUnit(productModel.getUnit());
            productStructure.setUnitQuantity(BigDecimal.valueOf(1));
            productStructure.setBomId(productBom.getId());
            productStructureService.save(productStructure);
        }
        productBomMapper.updateById(productBom);
        return AjaxResult.success();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult uploadBom(MultipartFile file) {
        ExcelUtil<BomImportDto> util = new ExcelUtil<>(BomImportDto.class);
        List<BomImportDto> list;
src/main/java/com/ruoyi/quality/pojo/RawMaterial.java
@@ -10,6 +10,7 @@
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
@@ -68,4 +69,20 @@
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "原材料不合格数")
    @TableField(exist = false)
    private BigDecimal supplierNum;
    @ApiModelProperty(value = "出厂不合格数")
    @TableField(exist = false)
    private BigDecimal factoryNum;
    @TableField(exist = false)
    @ApiModelProperty(value = "过程不合格数")
    private BigDecimal processNum;
    @TableField(exist = false)
    private String date;
}
src/main/resources/mapper/consumables/ConsumablesInventoryMapper.xml
@@ -110,6 +110,8 @@
    <select id="listConsumablesInventoryExportData" resultType="com.ruoyi.consumables.execl.ConsumablesInventoryExportData">
        select si.qualitity,
        -- 当前净重 = 入库净重 - 出库净重
        (COALESCE(sir.total_net_weight,0) - COALESCE(sor.total_net_weight,0)) as net_weight,
        pm.model,
        pm.unit,
        p.product_name,
@@ -120,6 +122,21 @@
        from consumables_inventory si
        left join product_model pm on si.product_model_id = pm.id
        left join product p on pm.product_id = p.id
        left join (
        select
        product_model_id,
        sum(net_weight) as total_net_weight
        from Consumables_in_record
        group by product_model_id
        ) sir on si.product_model_id = sir.product_model_id
        -- 出库净重
        left join (
        select
        product_model_id,
        sum(net_weight) as total_net_weight
        from Consumables_out_record
        group by product_model_id
        ) sor on si.product_model_id = sor.product_model_id
        where 1 = 1
        <if test="ew.productName != null and ew.productName !=''">
            and p.product_name like concat('%',#{ew.productName},'%')
src/main/resources/mapper/quality/QualityUnqualifiedMapper.xml
@@ -30,20 +30,20 @@
        LEFT JOIN product_model pm ON qu.model = pm.id
        where
        1=1
        <if test="qualityUnqualified.inspectType != null ">
            AND inspect_type = #{qualityUnqualified.inspectType}
        <if test="qualityUnqualified.checkType != null ">
            AND check_type = #{qualityUnqualified.checkType}
        </if>
        <if test="qualityUnqualified.inspectState != null ">
            AND inspect_state = #{qualityUnqualified.inspectState}
        </if>
        <if test="qualityUnqualified.productName != null and qualityUnqualified.productName != '' ">
            AND product_name = #{qualityUnqualified.productName}
            AND product_name like concat('%',#{qualityUnqualified.productName},'%')
        </if>
        <if test="qualityUnqualified.entryDateStart != null and qualityUnqualified.entryDateStart != '' ">
            AND check_time &gt;= DATE_FORMAT(#{qualityUnqualified.entryDateStart},'%Y-%m-%d')
        </if>
        <if test="qualityUnqualified.entryDateEnd != null and qualityUnqualified.entryDateEnd != '' ">
            AND  check_time &lt;= DATE_FORMAT(#{qualityUnqualified.entryDateEnd},'%Y-%m-%d')
            AND check_time &lt;= DATE_FORMAT(#{qualityUnqualified.entryDateEnd},'%Y-%m-%d')
        </if>
    </select>
    <select id="qualityUnqualifiedExport" resultType="com.ruoyi.quality.pojo.QualityUnqualified">
src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -102,6 +102,8 @@
    <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData">
        select si.qualitity,
        -- 当前净重 = 入库净重 - 出库净重
        (COALESCE(sir.total_net_weight, 0) - COALESCE(sor.total_net_weight, 0)) AS net_weight,-
        pm.model,
        pm.unit,
        p.product_name,
@@ -112,6 +114,16 @@
        from stock_inventory si
        left join product_model pm on si.product_model_id = pm.id
        left join product p on pm.product_id = p.id
        LEFT JOIN (
        SELECT product_model_id, SUM(net_weight) AS total_net_weight
        FROM stock_in_record
        GROUP BY product_model_id
        ) sir ON si.product_model_id = sir.product_model_id
        LEFT JOIN (
        SELECT product_model_id, SUM(net_weight) AS total_net_weight
        FROM stock_out_record
        GROUP BY product_model_id
        ) sor ON si.product_model_id = sor.product_model_id
        where 1 = 1
        <if test="ew.productName != null and ew.productName !=''">
            and p.product_name like concat('%',#{ew.productName},'%')
src/main/resources/static/work-order-template.docx
Binary files differ