a8a78a1b733914ea97393ccc5a81bf7ea76ed5aa..973b5221a85660b3b1e026e119256e35e95336ea
7 天以前 gongchunyi
fix: 产品规则返回命名修改
973b52 对比 | 目录
7 天以前 zss
Merge remote-tracking branch 'origin/dev_宁夏_中盛建材' into dev_宁夏_中盛建材
46b2ee 对比 | 目录
7 天以前 zss
能耗统计调整
08f82c 对比 | 目录
7 天以前 gongchunyi
chore: 合并失败
b4c3f1 对比 | 目录
7 天以前 gongchunyi
Merge remote-tracking branch 'origin/dev_宁夏_中盛建材' into dev_宁夏_中盛建材
f05fd2 对比 | 目录
7 天以前 gongchunyi
fix: 移除数据同步类型,修改数据来源方式
843d20 对比 | 目录
7 天以前 huminmin
Merge branch 'dev_宁夏_中盛建材' of http://114.132.189.42:9002/r/product-inventor...
f45f99 对比 | 目录
7 天以前 huminmin
主生产计划:增加部分下发状态
a10ad9 对比 | 目录
7 天以前 gongchunyi
refactor: 代码回退
f78c1d 对比 | 目录
7 天以前 gongchunyi
fix: 区分基础数据与生产计划数据查询
2d94dd 对比 | 目录
7 天以前 gongchunyi
fix: 物料数据类别数据集合接口优化
49f390 对比 | 目录
7 天以前 huminmin
Merge branch 'dev_宁夏_中盛建材' of http://114.132.189.42:9002/r/product-inventor...
080017 对比 | 目录
7 天以前 huminmin
主生产计划增加状态字段,根据状态判断是否编辑删除
e28990 对比 | 目录
7 天以前 gongchunyi
fix: 产品规格增加物料编号、(规格 + 编号)的筛选
20bf99 对比 | 目录
7 天以前 gongchunyi
chore: 部署端口修改
61ae3b 对比 | 目录
已添加1个文件
已修改16个文件
已删除1个文件
392 ■■■■■ 文件已修改
doc/宁夏-中盛建材.sql 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductMaterialController.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductMaterialSkuController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductMaterialDto.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductMaterialGroupDto.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductMaterialSkuDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductMaterialService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductMaterialSkuService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductMaterialServiceImpl.java 105 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductMaterialSkuServiceImpl.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/dto/ProductionPlanSummaryDto.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/enums/DataSourceTypeEnum.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/enums/DataSyncTypeEnum.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/pojo/ProductionPlan.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-zsjc.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/energy/EnergyConsumptionDetailMapper.xml 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/productionPlan/ProductionPlanMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/ÄþÏÄ-ÖÐÊ¢½¨²Ä.sql
@@ -167,3 +167,12 @@
  ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
alter table production_plan
    add status tinyint default 0 not null comment '状态 0未下发 1已下发';
ALTER TABLE `product-inventory-management-zsjc`.`production_plan`
    DROP COLUMN `data_sync_type`,
    MODIFY COLUMN `data_source_type` tinyint NULL DEFAULT 1 COMMENT '数据来源类型:1=钉钉同步 2=手动新增' AFTER `form_modified_time`;
src/main/java/com/ruoyi/production/controller/ProductMaterialController.java
@@ -43,10 +43,18 @@
    }
    @GetMapping("/list")
    @ApiOperation("物料数据")
    @Log(title = "物料数据", businessType = BusinessType.OTHER)
    public AjaxResult productMaterialList(String materialName) {
        List<ProductMaterialGroupDto> productMaterialMap = productMaterialService.ProductMaterialList(materialName);
    @ApiOperation("物料数据类别数据集合")
    @Log(title = "物料数据类别数据集合", businessType = BusinessType.OTHER)
    public AjaxResult productMaterialList(@RequestParam("type") Integer type) {
        List<ProductMaterialGroupDto> productMaterialMap = productMaterialService.ProductMaterialList(type);
        return AjaxResult.success(productMaterialMap);
    }
    @GetMapping("/listQuery")
    @ApiOperation("物料数据类别子类数据集合")
    @Log(title = "物料数据类别子类数据集合", businessType = BusinessType.OTHER)
    public AjaxResult productMaterialListByQuery(@RequestParam(value = "materialName", required = false) String materialName, @RequestParam(value = "materialTypeId", required = false) Integer materialTypeId) {
        List<ProductMaterialGroupDto> productMaterialMap = productMaterialService.productMaterialListByQuery(materialName, materialTypeId);
        return AjaxResult.success(productMaterialMap);
    }
src/main/java/com/ruoyi/production/controller/ProductMaterialSkuController.java
@@ -1,5 +1,6 @@
package com.ruoyi.production.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
@@ -37,8 +38,8 @@
    @GetMapping("/list")
    @ApiOperation("物料规格数据集合")
    @Log(title = "物料规格数据集合", businessType = BusinessType.OTHER)
    public AjaxResult productMaterialSkuList(@RequestParam("materialId") Long materialId) {
        List<ProductMaterialSkuDto> list = productMaterialSkuService.productMaterialSkuList(materialId);
    public AjaxResult productMaterialSkuList(Page<ProductMaterialSku> page, ProductMaterialSkuDto dto) {
        Page<ProductMaterialSkuDto> list = productMaterialSkuService.productMaterialSkuList(page, dto);
        return AjaxResult.success(list);
    }
src/main/java/com/ruoyi/production/dto/ProductMaterialDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.ruoyi.production.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
 * <br>
 * äº§å“ç‰©æ–™ä¿¡æ¯ Dto
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/13 10:50
 */
@Data
@ApiModel(value = "ProductMaterialDto", description = "物料主表Dto")
public class ProductMaterialDto {
    @ApiModelProperty("主键ID")
    private Long id;
    @ApiModelProperty("物料类型ID")
    private Integer materialTypeId;
    @ApiModelProperty("存货类别ID")
    private Integer inventoryCategoryId;
    @ApiModelProperty("物料名称")
    private String materialName;
}
src/main/java/com/ruoyi/production/dto/ProductMaterialGroupDto.java
@@ -26,5 +26,5 @@
    private String configName;
    @ApiModelProperty("物料列表")
    private List<ProductMaterial> materialList;
    private List<ProductMaterialDto> materialList;
}
src/main/java/com/ruoyi/production/dto/ProductMaterialSkuDto.java
@@ -23,6 +23,9 @@
    @ApiModelProperty("物料名称")
    private String materialName;
    @ApiModelProperty("物料编码")
    private String materialCode;
    @ApiModelProperty("单位")
    private String baseUnit;
src/main/java/com/ruoyi/production/service/ProductMaterialService.java
@@ -21,11 +21,13 @@
    void syncProductMaterialJob();
    List<ProductMaterialGroupDto> ProductMaterialList(String materialName);
    List<ProductMaterialGroupDto> ProductMaterialList(Integer type);
    void addProductMaterial(ProductMaterial productMaterial);
    void updateProductMaterial(ProductMaterial productMaterial);
    void deleteProductMaterial(List<Long> ids);
    List<ProductMaterialGroupDto> productMaterialListByQuery(String materialName, Integer materialTypeId);
}
src/main/java/com/ruoyi/production/service/ProductMaterialSkuService.java
@@ -1,5 +1,6 @@
package com.ruoyi.production.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.production.dto.ProductMaterialSkuDto;
import com.ruoyi.production.pojo.ProductMaterialSku;
@@ -17,7 +18,7 @@
 * @since 2026/03/12 10:04
 */
public interface ProductMaterialSkuService extends IService<ProductMaterialSku> {
    List<ProductMaterialSkuDto> productMaterialSkuList(Long materialId);
    Page<ProductMaterialSkuDto> productMaterialSkuList(Page<ProductMaterialSku> page, ProductMaterialSkuDto dto);
    void addProductMaterialSku(ProductMaterialSku productMaterialSku);
src/main/java/com/ruoyi/production/service/impl/ProductMaterialServiceImpl.java
@@ -4,11 +4,13 @@
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.framework.config.AliDingConfig;
import com.ruoyi.production.dto.ProductMaterialDto;
import com.ruoyi.production.dto.ProductMaterialGroupDto;
import com.ruoyi.production.enums.MaterialConfigTypeEnum;
import com.ruoyi.production.mapper.ProductMaterialMapper;
@@ -31,6 +33,7 @@
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
/**
 * <br>
@@ -345,27 +348,97 @@
    }
    @Override
    public List<ProductMaterialGroupDto> ProductMaterialList(String materialName) {
    public List<ProductMaterialGroupDto> ProductMaterialList(Integer type) {
        List<ProductMaterialConfig> configList = productMaterialConfigService.list(new LambdaQueryWrapper<ProductMaterialConfig>()
                .eq(ProductMaterialConfig::getConfigType, MaterialConfigTypeEnum.MATERIAL_TYPE.name())
        );
        if (CollectionUtils.isEmpty(configList)) {
            return new ArrayList<>();
        }
        List<ProductMaterialGroupDto> result = new ArrayList<>();
        Map<Integer, List<ProductMaterialDto>> materialMap = new HashMap<>();
        if (type != null && type == 2) {
            List<ProductMaterial> materialList = this.list(new LambdaQueryWrapper<ProductMaterial>()
                    .select(
                            ProductMaterial::getId,
                            ProductMaterial::getMaterialTypeId,
                            ProductMaterial::getInventoryCategoryId,
                            ProductMaterial::getMaterialName
                    )
            );
            materialMap = materialList.stream()
                    .map(this::convert)
                    .collect(Collectors.groupingBy(ProductMaterialDto::getMaterialTypeId));
        }
        List<ProductMaterialConfig> materialConfigList = productMaterialConfigService.list(new LambdaQueryWrapper<ProductMaterialConfig>()
        for (ProductMaterialConfig config : configList) {
            ProductMaterialGroupDto dto = new ProductMaterialGroupDto();
            dto.setConfigId(config.getId());
            dto.setConfigName(config.getConfigName());
            if (type != null && type == 2) {
                dto.setMaterialList(materialMap.getOrDefault(config.getId(), new ArrayList<>()));
            }
            result.add(dto);
        }
        return result;
    }
    @Override
    public List<ProductMaterialGroupDto> productMaterialListByQuery(String materialName, Integer materialTypeId) {
        if (StringUtils.isEmpty(materialName) && materialTypeId == null) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<ProductMaterial> wrapper = new LambdaQueryWrapper<>();
        //  åªæŸ¥è¯¢éœ€è¦çš„字段数据
        wrapper.select(
                ProductMaterial::getId,
                ProductMaterial::getMaterialTypeId,
                ProductMaterial::getInventoryCategoryId,
                ProductMaterial::getMaterialName
        );
        if (StringUtils.isNotEmpty(materialName)) {
            wrapper.like(ProductMaterial::getMaterialName, materialName);
        }
        if (materialTypeId != null) {
            wrapper.eq(ProductMaterial::getMaterialTypeId, materialTypeId);
        }
        List<ProductMaterial> materials = this.list(wrapper);
        if (CollectionUtils.isEmpty(materials)) {
            return new ArrayList<>();
        }
        Map<Integer, List<ProductMaterialDto>> map = materials.stream()
                .map(this::convert)
                .collect(Collectors.groupingBy(ProductMaterialDto::getMaterialTypeId));
        List<ProductMaterialConfig> configList = productMaterialConfigService.list(new LambdaQueryWrapper<ProductMaterialConfig>()
                .eq(ProductMaterialConfig::getConfigType, MaterialConfigTypeEnum.MATERIAL_TYPE.name()));
        List<ProductMaterialGroupDto> productMaterialMap = new ArrayList<>();
        if (materialConfigList == null || materialConfigList.isEmpty()) {
            return productMaterialMap;
        }
        for (ProductMaterialConfig materialConfig : materialConfigList) {
            LambdaQueryWrapper<ProductMaterial> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ProductMaterial::getMaterialTypeId, materialConfig.getId())
                    .like(materialName != null && !materialName.isEmpty(), ProductMaterial::getMaterialName, materialName);
            List<ProductMaterial> productMaterialList = list(wrapper);
        List<ProductMaterialGroupDto> result = new ArrayList<>();
        for (ProductMaterialConfig config : configList) {
            List<ProductMaterialDto> dtoList = map.get(config.getId());
            if (CollectionUtils.isEmpty(dtoList)) {
                continue;
            }
            ProductMaterialGroupDto dto = new ProductMaterialGroupDto();
            dto.setConfigId(materialConfig.getId());
            dto.setConfigName(materialConfig.getConfigName());
            dto.setMaterialList(productMaterialList);
            productMaterialMap.add(dto);
            dto.setConfigId(config.getId());
            dto.setConfigName(config.getConfigName());
            dto.setMaterialList(dtoList);
            result.add(dto);
        }
        return productMaterialMap;
        return result;
    }
    private ProductMaterialDto convert(ProductMaterial m) {
        ProductMaterialDto dto = new ProductMaterialDto();
        dto.setId(m.getId());
        dto.setMaterialName(m.getMaterialName());
        dto.setMaterialTypeId(m.getMaterialTypeId());
        dto.setInventoryCategoryId(m.getInventoryCategoryId());
        return dto;
    }
    @Override
src/main/java/com/ruoyi/production/service/impl/ProductMaterialSkuServiceImpl.java
@@ -1,6 +1,7 @@
package com.ruoyi.production.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
@@ -49,37 +50,45 @@
     * æŸ¥è¯¢ç‰©æ–™è§„格列表
     */
    @Override
    public List<ProductMaterialSkuDto> productMaterialSkuList(Long materialId) {
        if (materialId == null) {
            return Collections.emptyList();
    public Page<ProductMaterialSkuDto> productMaterialSkuList(Page<ProductMaterialSku> page, ProductMaterialSkuDto dto) {
        if (dto == null || dto.getMaterialId() == null) {
            return new Page<>();
        }
        LambdaQueryWrapper<ProductMaterialSku> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProductMaterialSku::getMaterialId, materialId)
        queryWrapper.eq(ProductMaterialSku::getMaterialId, dto.getMaterialId())
                .like(StringUtils.isNotBlank(dto.getSpecification()),
                        ProductMaterialSku::getSpecification, dto.getSpecification())
                .like(StringUtils.isNotBlank(dto.getMaterialCode()),
                        ProductMaterialSku::getMaterialCode, dto.getMaterialCode())
                .orderByAsc(ProductMaterialSku::getId);
        List<ProductMaterialSku> skuList = this.list(queryWrapper);
        if (skuList == null || skuList.isEmpty()) {
            return Collections.emptyList();
        }
        // æŸ¥è¯¢ç‰©æ–™ä¿¡æ¯
        ProductMaterial material = productMaterialMapper.selectById(materialId);
        Page<ProductMaterialSku> skuPage = this.page(page, queryWrapper);
        List<ProductMaterialSku> skuList = skuPage.getRecords();
        if (skuList == null || skuList.isEmpty()) {
            return new Page<>();
        }
        ProductMaterial material = productMaterialMapper.selectById(dto.getMaterialId());
        String materialName = material != null ? material.getMaterialName() : null;
        String baseUnit = material != null ? material.getBaseUnit() : null;
        List<ProductMaterialSkuDto> result = new ArrayList<>(skuList.size());
        for (ProductMaterialSku sku : skuList) {
            ProductMaterialSkuDto dto = new ProductMaterialSkuDto();
            dto.setMaterialId(materialId);
            dto.setMaterialName(materialName);
            dto.setBaseUnit(baseUnit);
            dto.setSkuId(sku.getId());
            dto.setSpecification(sku.getSpecification());
            dto.setSupplyType(sku.getSupplyType());
            result.add(dto);
            ProductMaterialSkuDto productMaterialSkuDto = new ProductMaterialSkuDto();
            productMaterialSkuDto.setMaterialId(dto.getMaterialId());
            productMaterialSkuDto.setMaterialName(materialName);
            productMaterialSkuDto.setMaterialCode(sku.getMaterialCode());
            productMaterialSkuDto.setBaseUnit(baseUnit);
            productMaterialSkuDto.setSkuId(sku.getId());
            productMaterialSkuDto.setSpecification(sku.getSpecification());
            productMaterialSkuDto.setSupplyType(sku.getSupplyType());
            result.add(productMaterialSkuDto);
        }
        return result;
        Page<ProductMaterialSkuDto> dtoPage = new Page<>();
        dtoPage.setCurrent(skuPage.getCurrent());
        dtoPage.setSize(skuPage.getSize());
        dtoPage.setTotal(skuPage.getTotal());
        dtoPage.setRecords(result);
        return dtoPage;
    }
    /**
src/main/java/com/ruoyi/productionPlan/dto/ProductionPlanSummaryDto.java
@@ -35,7 +35,7 @@
     * äº§å“è§„æ ¼
     */
    @ApiModelProperty("产品规格")
    private String productSpec;
    private String specification;
    /**
     * äº§å“é•¿åº¦
@@ -67,4 +67,10 @@
    @ApiModelProperty("汇总方数")
    private BigDecimal volume;
    /**
     * åŸºæœ¬å•位
     */
    @ApiModelProperty("基本单位")
    private String baseUnit;
}
src/main/java/com/ruoyi/productionPlan/enums/DataSourceTypeEnum.java
@@ -14,8 +14,8 @@
@Getter
public enum DataSourceTypeEnum {
    SALES_ORDER(1, "同步"),
    PRODUCTION_FORECAST(2, "新增");
    DING_TALK(1, "钉钉同步"),
    MANUAL(2, "手动新增");
    private final Integer code;
    private final String desc;
src/main/java/com/ruoyi/productionPlan/enums/DataSyncTypeEnum.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/productionPlan/pojo/ProductionPlan.java
@@ -106,6 +106,10 @@
    @Excel(name = "强度")
    private String strength;
    @ApiModelProperty("状态 0未下发 1部分下发 2已下发")
    @Excel(name = "状态", readConverterExp = "0=未下发,1=部分下发,2=已下发")
    private Integer status;
    /**
     * å¼€å§‹æ—¥æœŸ
     */
@@ -180,16 +184,11 @@
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime formModifiedTime;
    /**
     * æ•°æ®åŒæ­¥ç±»åž‹ï¼š1=手动 2=定时任务
     */
    @ApiModelProperty("数据同步类型:1=手动 2=定时任务")
    private Integer dataSyncType;
    /**
     * æ•°æ®æ¥æºç±»åž‹ï¼š1=同步 2=新增
     * æ•°æ®æ¥æºç±»åž‹ï¼š1=钉钉同步 2=手动新增
     */
    @ApiModelProperty("数据来源类型:1=同步 2=新增")
    @ApiModelProperty("数据来源类型:1=钉钉同步 2=手动新增")
    private Integer dataSourceType;
    /**
src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java
@@ -24,6 +24,7 @@
import com.ruoyi.productionPlan.dto.ProductionPlanDto;
import com.ruoyi.productionPlan.dto.ProductionPlanImportDto;
import com.ruoyi.productionPlan.dto.ProductionPlanSummaryDto;
import com.ruoyi.productionPlan.enums.DataSourceTypeEnum;
import com.ruoyi.productionPlan.mapper.ProductOrderPlanMapper;
import com.ruoyi.productionPlan.mapper.ProductionPlanMapper;
import com.ruoyi.productionPlan.pojo.ProductOrderPlan;
@@ -45,7 +46,6 @@
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import static com.ruoyi.productionPlan.enums.DataSourceTypeEnum.PRODUCTION_FORECAST;
/**
 * <br>
@@ -120,20 +120,20 @@
        //  æ ¡éªŒæ˜¯å¦å­˜åœ¨ä¸åŒçš„产品名称
        String firstProductName = plans.get(0).getProductName();
        if (plans.stream().anyMatch(p -> !p.getProductName().equals(firstProductName))) {
        if (plans.stream().anyMatch(p -> p.getProductName() == null || !p.getProductName().equals(firstProductName))) {
            throw new BaseException("合并失败,存在不同的产品名称");
        }
        // æ ¡éªŒæ˜¯å¦å­˜åœ¨ä¸åŒçš„产品规格
        String firstProductSpec = plans.get(0).getSpecification();
        if (plans.stream().anyMatch(p -> !p.getSpecification().equals(firstProductSpec))) {
        if (plans.stream().anyMatch(p -> p.getSpecification() == null || !p.getSpecification().equals(firstProductSpec))) {
            throw new BaseException("合并失败,存在不同的产品规格");
        }
        // å åŠ å‰©ä½™æ–¹æ•°
        BigDecimal totalRemainingVolume = plans.stream()
                .map(ProductionPlan::getRemainingVolume)
                .filter(v -> v != null)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // åˆ¤æ–­ä¸‹å‘数量是否大于等于剩余方数
        if (productionPlanDto.getTotalAssignedQuantity().compareTo(totalRemainingVolume) > 0) {
@@ -166,6 +166,10 @@
            if (assignedVolume.add(remainingVolume).compareTo(productionPlanDto.getTotalAssignedQuantity()) >= 0) {
                // æœ€åŽä¸€ä¸ªè®¡åˆ’,分配剩余方数
                BigDecimal lastRemainingVolume = productionPlanDto.getTotalAssignedQuantity().subtract(assignedVolume);
                plan.setStatus(1);
                if (lastRemainingVolume.compareTo(BigDecimal.ZERO) <= 0) {
                    plan.setStatus(2);
                }
                plan.setAssignedQuantity(plan.getAssignedQuantity().add(lastRemainingVolume));
                productOrderPlan.setAssignedQuantity(lastRemainingVolume);
                productionPlanMapper.updateById(plan);
@@ -174,6 +178,10 @@
            }
            // åˆ†é…å½“前计划方数
            plan.setStatus(1);
            if (remainingVolume.compareTo(BigDecimal.ZERO) <= 0) {
                plan.setStatus(2);
            }
            plan.setAssignedQuantity(plan.getAssignedQuantity().add(remainingVolume));
            productOrderPlan.setAssignedQuantity(remainingVolume);
            // æ›´æ–°ç”Ÿäº§è®¡åˆ’
@@ -188,7 +196,8 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(ProductionPlanDto productionPlanDto) {
        productionPlanDto.setDataSourceType(PRODUCTION_FORECAST.getCode());
        productionPlanDto.setDataSourceType(DataSourceTypeEnum.MANUAL.getCode());
        productionPlanDto.setStatus(0);
        productionPlanMapper.insert(productionPlanDto);
        return true;
    }
@@ -196,6 +205,10 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(ProductionPlanDto productionPlanDto) {
        // å·²ä¸‹å‘状态,不能编辑
        if (productionPlanDto.getStatus() != 0) {
            throw new BaseException("已下发或部分下发状态,不能编辑");
        }
        // æŸ¥è¯¢æ˜¯å¦æœ‰å…³è”订单
        boolean hasProductOrderPlan = productOrderPlanMapper.selectList(Wrappers.<ProductOrderPlan>lambdaQuery().eq(ProductOrderPlan::getProductionPlanId, productionPlanDto.getId())).stream().anyMatch(p -> p.getProductOrderId() != null);
        if (hasProductOrderPlan) {
@@ -212,6 +225,10 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(List<Long> ids) {
        // å¦‚果存在已下发的计划,则不能删除
        if (productionPlanMapper.selectList(Wrappers.<ProductionPlan>lambdaQuery().in(ProductionPlan::getId, ids)).stream().anyMatch(p -> p.getStatus() == 1 || p.getStatus() == 2)) {
            throw new BaseException("删除失败,存在已下发或部分下发的计划");
        }
        // å¦‚果有关联订单,则不能删除
        if (productOrderPlanMapper.selectList(Wrappers.<ProductOrderPlan>lambdaQuery().in(ProductOrderPlan::getProductionPlanId, ids)).stream().anyMatch(p -> p.getProductOrderId() != null)) {
            throw new BaseException("删除失败,存在关联订单");
@@ -226,7 +243,7 @@
    @Transactional(rollbackFor = Exception.class)
    public void syncProdData(Integer dataSyncType) {
        if (!syncLock.tryLock()) {
            log.warn("同步正在进行中,本次 {} åŒæ­¥è¯·æ±‚被跳过", dataSyncType == 1 ? "手动" : "定时任务");
            log.warn("同步正在进行中,本次 {} åŒæ­¥è¯·æ±‚被跳过", dataSyncType == 1 ? "手动同步" : "定时任务同步");
            return;
        }
@@ -443,8 +460,7 @@
                plan.setFormCreatedTime(parseUtcTime(item.getString("createdTimeGMT")));
                plan.setFormModifiedTime(parseUtcTime(item.getString("modifiedTimeGMT")));
                plan.setDataSyncType(dataSyncType);
                plan.setDataSourceType(1);
                plan.setDataSourceType(DataSourceTypeEnum.DING_TALK.getCode());
                plan.setCreateTime(now);
                plan.setUpdateTime(now);
                plan.setTotalCount(totalCount);
@@ -543,8 +559,7 @@
            entity.setAssignedQuantity(BigDecimal.ZERO);
            entity.setCreateTime(LocalDateTime.now());
            entity.setUpdateTime(LocalDateTime.now());
            entity.setDataSourceType(2);
            entity.setDataSyncType(1);
            entity.setDataSourceType(DataSourceTypeEnum.DING_TALK.getCode());
            // æ ¹æ®ç‰©æ–™ç¼–码填充关联ID
            if (StringUtils.isNotEmpty(dto.getMaterialCode())) {
src/main/resources/application-zsjc.yml
@@ -40,7 +40,7 @@
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9003
  port: 9019
  servlet:
    # åº”用的访问路径
    context-path: /
src/main/resources/mapper/energy/EnergyConsumptionDetailMapper.xml
@@ -53,8 +53,8 @@
    <select id="energyConsumptionTypeProportion"
            resultType="com.ruoyi.energy.dto.EnergyConsumptionTypeDto">
         select e.energy_tyep,
                SUM(ecd.dosage) energyConsumption,
               SUM(ecd.dosage * e.unit_price) energyCost
                SUM(COALESCE(ecd.dosage, 0)) energyConsumption,
               SUM(COALESCE(ecd.dosage, 0) * e.unit_price) energyCost
            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}
@@ -64,16 +64,17 @@
            group by e.energy_tyep
    </select>
    <select id="energyCostDtos" resultType="com.ruoyi.energy.dto.EnergyCostDto">
    select A.meter_reading_date,
           A.waterConsumption,
           A.waterCost,
           B.electricityConsumption,
           B.electricityCost,
           C.gasConsumption,
           C.gasCost,
           sum(A.waterConsumption+B.electricityConsumption+C.gasConsumption) totalConsumption,
           sum(A.waterCost+B.electricityCost+C.gasCost) totalCost
    from
   select  z.meter_reading_date,
           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 ecd.meter_reading_date,
               sum(ecd.dosage) waterConsumption,
               sum(ecd.dosage * e1.unit_price) waterCost
@@ -85,7 +86,8 @@
                and ecd.type =#{c.type}
            </if>
            group by ecd.meter_reading_date)A
    join
        on z.meter_reading_date=A.meter_reading_date
    left join
    (select ecd.meter_reading_date,
               sum(ecd.dosage) electricityConsumption,
               sum(ecd.dosage * e2.unit_price) electricityCost
@@ -97,8 +99,8 @@
                and ecd.type =#{c.type}
            </if>
            group by ecd.meter_reading_date)B
        on A.meter_reading_date=B.meter_reading_date
    join
        on z.meter_reading_date=B.meter_reading_date
    left join
    (select ecd.meter_reading_date,
               sum(ecd.dosage) gasConsumption,
               sum(ecd.dosage * e3.unit_price) gasCost
@@ -110,8 +112,8 @@
                and ecd.type =#{c.type}
            </if>
            group by ecd.meter_reading_date)C
        on A.meter_reading_date=C.meter_reading_date
        on z.meter_reading_date=C.meter_reading_date
    order by z.meter_reading_date
    </select>
</mapper>
src/main/resources/mapper/productionPlan/ProductionPlanMapper.xml
@@ -28,7 +28,6 @@
        <result property="modifierName" column="modifier_name"/>
        <result property="formCreatedTime" column="form_created_time"/>
        <result property="formModifiedTime" column="form_modified_time"/>
        <result property="dataSyncType" column="data_sync_type"/>
        <result property="dataSourceType" column="data_source_type"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
@@ -68,16 +67,18 @@
        <if test="c.endDate != null">
            AND pp.end_date &lt;= DATE_FORMAT(#{c.endDate},'%Y-%m-%d')
        </if>
        ORDER BY COALESCE(pp.form_modified_time, pp.id) DESC
    </select>
    <select id="selectSummaryByProductType" resultType="com.ruoyi.productionPlan.dto.ProductionPlanSummaryDto">
        SELECT
        sku.material_code,
        pm.material_name AS product_name,
        sku.specification AS product_spec,
        sku.material_code AS materialCode,
        pm.material_name AS productName,
        sku.specification AS specification,
        pp.length,
        pp.width,
        pp.height,
        pm.base_unit AS baseUnit,
        COALESCE(SUM(pp.quantity),0) AS quantity,
        COALESCE(SUM(pp.volume),0) AS volume
        FROM production_plan pp
@@ -93,6 +94,10 @@
            <if test="productName != null and productName != ''">
                AND pm.material_name LIKE CONCAT('%', #{productName}, '%')
            </if>
            <if test="specification != null and specification != ''">
                AND sku.specification LIKE CONCAT('%', #{specification}, '%')
            </if>
        </where>
        GROUP BY
        sku.material_code,
@@ -100,7 +105,8 @@
        sku.specification,
        pp.length,
        pp.width,
        pp.height
        pp.height,
        pm.base_unit
    </select>
    <select id="selectWithMaterialByIds" resultType="com.ruoyi.productionPlan.dto.ProductionPlanDto">