liding
23 小时以前 f29c8786807015d78b9be8a33397f69478d92a76
1.设备优化 2.配煤计算器
已修改20个文件
335 ■■■■ 文件已修改
basic-server/src/main/java/com/ruoyi/basic/dto/CoalFieldDto.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/entity/CoalField.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/mapper/CoalFieldMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/service/CoalFieldService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/service/impl/CoalFieldServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/resources/mapper/CoalFieldMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/controller/PendingInventoryController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/dto/EquipmentManagementDto.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/dto/EquipmentUsageRecordDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/dto/PendingInventoryDto.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/dto/SalesRecordDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/entity/SalesRecord.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/PendingInventoryService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentManagementServiceImpl.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentUsageRecordServiceImpl.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/PendingInventoryServiceImpl.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/ProductionMasterServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/resources/db/migration/postgresql/V20250613112800__create_table_production_inventory.sql 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/init/MyStartupRunner.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/dto/CoalFieldDto.java
@@ -6,5 +6,15 @@
@Data
public class CoalFieldDto extends CoalField {
    private String fieldName;
    public CoalFieldDto(String name) {
        this.fieldName = name;
    }
    public static CoalFieldDto from(String name) {
        return new CoalFieldDto(name);
    }
    private String searchAll;
}
basic-server/src/main/java/com/ruoyi/basic/entity/CoalField.java
@@ -37,4 +37,5 @@
     */
    @TableField(value = "field_description")
    private String fieldDescription;
}
basic-server/src/main/java/com/ruoyi/basic/mapper/CoalFieldMapper.java
@@ -4,6 +4,8 @@
import com.ruoyi.basic.entity.CoalField;
import org.apache.ibatis.annotations.Mapper;
import java.util.Set;
/**
 * <p>
 * 煤质信息表,记录煤炭质量检测相关数据 Mapper 接口
@@ -15,4 +17,5 @@
@Mapper
public interface CoalFieldMapper extends BaseMapper<CoalField> {
    Set<String> getFieldNamesByNames(Set<String> fieldNames);
}
basic-server/src/main/java/com/ruoyi/basic/service/CoalFieldService.java
@@ -7,6 +7,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Set;
/**
 * <p>
@@ -25,4 +26,6 @@
    int delCoalFieldByIds(Long[] ids);
    List<CoalField> selectAllList(CoalFieldDto coalFieldDto);
    Set<String> getFieldNamesByNames(Set<String> collect);
}
basic-server/src/main/java/com/ruoyi/basic/service/impl/CoalFieldServiceImpl.java
@@ -16,6 +16,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -80,6 +81,11 @@
        return coalFieldMapper.selectList(null);
    }
    @Override
    public Set<String> getFieldNamesByNames(Set<String> fieldNames) {
        return coalFieldMapper.getFieldNamesByNames(fieldNames);
    }
    private String generateNextFieldNumber() {
        // 获取所有已存在的 CoalField 记录,包括已删除的
        LambdaQueryWrapper<CoalField> queryWrapper = new LambdaQueryWrapper<>();
basic-server/src/main/resources/mapper/CoalFieldMapper.xml
@@ -24,5 +24,11 @@
                update_time,
            id, fields, field_name, field_description
    </sql>
    <select id="getFieldNamesByNames" resultType="java.lang.String">
        SELECT field_name FROM coal_field WHERE field_name IN
        <foreach collection="fieldNames" item="name" open="(" separator="," close=")">
            #{fieldNames}
        </foreach>
    </select>
</mapper>
main-business/src/main/java/com/ruoyi/business/controller/PendingInventoryController.java
@@ -58,4 +58,11 @@
        return R.ok(pendingInventoryService.delByIds(ids));
    }
    /**
     * 配煤计算器到待入库
     */
    @PostMapping("/addPending")
    public R addPending(@RequestBody PendingInventoryDto pendingInventoryDto) {
        return R.ok(pendingInventoryService.addPending(pendingInventoryDto));
    }
}
main-business/src/main/java/com/ruoyi/business/dto/EquipmentManagementDto.java
@@ -5,4 +5,8 @@
@Data
public class EquipmentManagementDto extends EquipmentManagement {
    private String searchAll;//搜索
    private Integer usedNo;//已使用数量
}
main-business/src/main/java/com/ruoyi/business/dto/EquipmentUsageRecordDto.java
@@ -9,4 +9,6 @@
    private String equipmentNo; //设备编号
    private String equipmentName; //设备名称
    private String userName; //领用人
}
main-business/src/main/java/com/ruoyi/business/dto/PendingInventoryDto.java
@@ -6,6 +6,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Data
public class PendingInventoryDto extends PendingInventory {
@@ -13,41 +14,27 @@
    @JsonProperty("pId")
    private Long pId;
    /**
     * 正式库id
     */
    @JsonProperty("officialId")
    private Long officialId;
    private Long officialId;//正式库id
    private List<Map<String, String>> fieldValue;
    private List<Map<String, String>> fieldValue;//煤种方案字段list
    /**
     * 字段值
     */
    private String coalValue;
    /**
     * 字段
     */
    private String fields;
    /**
     * 字段名
     */
    private String fieldName;
    private String coalValue;//煤种方案字段值
    /**
     * 字段名
     */
    private Integer type;
    private String fields;//煤种方案字段
    /**
     * 煤种
     */
    private String coal;
    private String fieldName; //煤种方案字段名
    /**
     * 登记人
     */
    private String registrant;
    private Integer type; //类型
    private String searchAll;
    private String coal;//煤种
    private String registrant;//登记人
    private String searchAll;//搜索
    private List<Map<String, Object>> coalResultList;//配煤计算器煤种信息list
    private List<Map<String, Object>> fieldsResultList;//配煤计算器方案字段信息list
}
main-business/src/main/java/com/ruoyi/business/dto/SalesRecordDto.java
@@ -6,7 +6,5 @@
@Data
public class SalesRecordDto extends SalesRecord {
    private String searchAll;
    private String coal;
}
main-business/src/main/java/com/ruoyi/business/entity/SalesRecord.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.MyBaseEntity;
import lombok.Data;
@@ -31,6 +32,7 @@
     * 销售日期
     */
    @TableField(value = "sale_date")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate saleDate;
    /**
     * 客户id
@@ -116,5 +118,6 @@
     * 登记日期
     */
    @TableField(value = "registration_date")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate registrationDate;
}
main-business/src/main/java/com/ruoyi/business/service/PendingInventoryService.java
@@ -23,4 +23,6 @@
    int delByIds(Long[] ids);
    int addOrEditCoalValue(PendingInventoryDto pendingInventoryDto);
    int addPending(PendingInventoryDto pendingInventoryDto);
}
main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentManagementServiceImpl.java
@@ -4,13 +4,14 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.business.dto.EquipmentManagementDto;
import com.ruoyi.business.dto.ProductionMasterDto;
import com.ruoyi.business.entity.EquipmentManagement;
import com.ruoyi.business.entity.Production;
import com.ruoyi.business.entity.EquipmentUsageRecord;
import com.ruoyi.business.mapper.EquipmentManagementMapper;
import com.ruoyi.business.mapper.EquipmentUsageRecordMapper;
import com.ruoyi.business.service.EquipmentManagementService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.vo.EquipmentManagementVo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
@@ -33,10 +34,52 @@
    private final EquipmentManagementMapper equipmentManagementMapper;
    private final EquipmentUsageRecordMapper equipmentUsageRecordMapper;
    public IPage<EquipmentManagementDto> selectProductionList(Page<EquipmentManagement> page, EquipmentManagementDto equipmentManagementDto) {
        Page<EquipmentManagement> entityPage = equipmentManagementMapper.selectPage(page, null);
        // 1. 构建查询条件(searchAll 模糊查询)
        LambdaQueryWrapper<EquipmentManagement> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(equipmentManagementDto.getSearchAll())) {
            String searchValue = equipmentManagementDto.getSearchAll();
            queryWrapper.and(wrapper ->
                    wrapper.like(EquipmentManagement::getEquipmentNo, searchValue)
                            .or()
                            .like(EquipmentManagement::getEquipmentName, searchValue)
                            .or()
                            .like(EquipmentManagement::getSpecification, searchValue)
            );
        }
        // 2. 执行分页查询
        Page<EquipmentManagement> entityPage = equipmentManagementMapper.selectPage(page, queryWrapper);
        // 3. 转换为 DTO 分页
        IPage<EquipmentManagementDto> dtoPage = new Page<>();
        BeanUtils.copyProperties(entityPage, dtoPage);
        BeanUtils.copyProperties(entityPage, dtoPage, "records");
        // 4. 查询每个设备的使用总量(usageQuantity)并设置到 DTO
        List<EquipmentManagementDto> dtoRecords = entityPage.getRecords().stream()
                .map(entity -> {
                    EquipmentManagementDto dto = new EquipmentManagementDto();
                    BeanUtils.copyProperties(entity, dto);
                    // 查询该设备的使用总量(usageQuantity)
                    LambdaQueryWrapper<EquipmentUsageRecord> usageQueryWrapper = new LambdaQueryWrapper<>();
                    usageQueryWrapper.eq(EquipmentUsageRecord::getEquipmentId, entity.getId());
                    // 计算总使用量
                    Integer totalUsage = equipmentUsageRecordMapper.selectList(usageQueryWrapper).stream()
                            .mapToInt(EquipmentUsageRecord::getUsageQuantity)
                            .sum();
                    // 设置使用总量
                    dto.setUsedNo(totalUsage);
                    return dto;
                })
                .toList();
        dtoPage.setRecords(dtoRecords);
        return dtoPage;
    }
main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentUsageRecordServiceImpl.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.entity.Supply;
import com.ruoyi.basic.mapper.CoalInfoMapper;
import com.ruoyi.business.dto.EquipmentManagementDto;
import com.ruoyi.business.dto.EquipmentUsageRecordDto;
import com.ruoyi.business.entity.EquipmentManagement;
@@ -12,9 +13,12 @@
import com.ruoyi.business.mapper.EquipmentUsageRecordMapper;
import com.ruoyi.business.service.EquipmentUsageRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
@@ -39,6 +43,8 @@
    private  final EquipmentManagementMapper equipmentManagementMapper;
    private final SysUserMapper sysUserMapper;
    @Override
    public IPage<EquipmentUsageRecordDto> selectUsageRecordList(Page<EquipmentUsageRecord> page, EquipmentUsageRecordDto equipmentUsageRecordDto) {
        Page<EquipmentUsageRecord> entityPage = equipmentUsageRecordMapper.selectPage(page, null);
@@ -46,7 +52,8 @@
        BeanUtils.copyProperties(entityPage, dtoPage);
        List<Long> eqIds = entityPage.getRecords().stream().map(EquipmentUsageRecord::getEquipmentId).toList();
        //批量查询
        List<Long> userIds = entityPage.getRecords().stream().map(EquipmentUsageRecord::getUserId).toList();
        //批量查询设备
        Map<Long, EquipmentManagement> equipmentManagementMap;
        if (!eqIds.isEmpty()) {
            List<EquipmentManagement> infos = equipmentManagementMapper.selectList(new LambdaQueryWrapper<EquipmentManagement>().in(EquipmentManagement::getId, eqIds));
@@ -54,15 +61,26 @@
        } else {
            equipmentManagementMap = new HashMap<>();
        }
        //人员查询
        Map<Long, SysUser> userMap;
        if (!userIds.isEmpty()) {
            List<SysUser> sysUsers = sysUserMapper.selectList(userIds);
            userMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
        }else {
            userMap = new HashMap<>();
        }
        //匹配数据
        List<EquipmentUsageRecordDto> dtoRecords = entityPage.getRecords().stream().map(entity -> {
            EquipmentUsageRecordDto dto = new EquipmentUsageRecordDto();
            BeanUtils.copyProperties(entity, dto);
            EquipmentManagement equipment = equipmentManagementMap.get(entity.getEquipmentId());
            if (equipment != null) {
                dto.setEquipmentNo(equipment.getEquipmentNo());
                dto.setEquipmentName(equipment.getEquipmentName());
            }
            SysUser sysUser = userMap.get(entity.getUserId());
            if (sysUser != null) {
                dto.setUserName(sysUser.getNickName());
            }
            return dto;
        }).toList();
@@ -72,12 +90,58 @@
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrEditUsageRecord(EquipmentUsageRecordDto equipmentUsageRecordDto) {
        EquipmentUsageRecord equipmentUsageRecord = new EquipmentUsageRecord();
        BeanUtils.copyProperties(equipmentUsageRecordDto, equipmentUsageRecord);
        // 获取设备ID和领用数量
        Long equipmentId = equipmentUsageRecordDto.getEquipmentId();
        Integer newUsageQuantity = equipmentUsageRecordDto.getUsageQuantity();
        // 查询设备信息(带乐观锁版本号)
        EquipmentManagement equipment = equipmentManagementMapper.selectById(equipmentId);
        if (equipment == null) {
            throw new RuntimeException("设备不存在");
        }
        if (Objects.isNull(equipmentUsageRecordDto.getId())) {
            // 检查库存是否充足
            if (equipment.getQuantity() < newUsageQuantity) {
                throw new RuntimeException("库存不足,当前库存:" + equipment.getQuantity());
            }
            // 扣减库存
            equipment.setQuantity(equipment.getQuantity() - newUsageQuantity);
            equipmentManagementMapper.updateById(equipment);
            // 创建领用记录
            return equipmentUsageRecordMapper.insert(equipmentUsageRecord);
        } else {
            // 1. 查询原领用记录
            EquipmentUsageRecord originalRecord = equipmentUsageRecordMapper.selectById(equipmentUsageRecordDto.getId());
            if (originalRecord == null) {
                throw new RuntimeException("领用记录不存在");
            }
            // 2. 计算库存变化量(新数量 - 旧数量)
            int quantityDelta = newUsageQuantity - originalRecord.getUsageQuantity();
            if (quantityDelta != 0) {
                // 3. 检查调整后库存是否充足(考虑增加和减少两种情况)
                int newInventory = equipment.getQuantity() - quantityDelta;
                if (newInventory < 0) {
                    throw new RuntimeException("库存不足,调整后库存将为:" + newInventory);
                }
                // 4. 调整库存
                equipment.setQuantity(newInventory);
                if (equipmentManagementMapper.updateById(equipment) == 0) {
                    throw new RuntimeException("库存更新失败,可能已被其他操作修改");
                }
            }
            // 5. 更新领用记录
            return equipmentUsageRecordMapper.updateById(equipmentUsageRecord);
        }
    }
main-business/src/main/java/com/ruoyi/business/service/impl/PendingInventoryServiceImpl.java
@@ -6,18 +6,24 @@
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.CoalFieldDto;
import com.ruoyi.basic.entity.CoalField;
import com.ruoyi.basic.entity.CoalInfo;
import com.ruoyi.basic.entity.CoalValue;
import com.ruoyi.basic.mapper.CoalFieldMapper;
import com.ruoyi.basic.mapper.CoalInfoMapper;
import com.ruoyi.basic.mapper.CoalPlanMapper;
import com.ruoyi.basic.mapper.CoalValueMapper;
import com.ruoyi.basic.service.CoalFieldService;
import com.ruoyi.basic.service.CoalPlanService;
import com.ruoyi.business.dto.PendingInventoryDto;
import com.ruoyi.business.entity.OfficialInventory;
import com.ruoyi.business.entity.PendingInventory;
import com.ruoyi.business.entity.SalesRecord;
import com.ruoyi.business.mapper.InventorySummaryMapper;
import com.ruoyi.business.mapper.OfficialInventoryMapper;
import com.ruoyi.business.mapper.PendingInventoryMapper;
import com.ruoyi.business.mapper.SalesRecordMapper;
import com.ruoyi.business.service.InputInventoryRecordService;
import com.ruoyi.business.service.InventorySummaryService;
import com.ruoyi.business.service.PendingInventoryService;
@@ -29,6 +35,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.math.BigDecimal;
import java.time.LocalDate;
@@ -36,6 +43,7 @@
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
 * <p>
@@ -65,32 +73,32 @@
    private final InventorySummaryService inventorySummaryService;
    private final CoalFieldService coalFieldService;
    private final CoalPlanService coalPlanService;
    @Override
    public IPage<PendingInventoryDto> selectPendingInventoryList(Page page, PendingInventoryDto pendingInventoryDto) {
        // 1. 构建主查询
        LambdaQueryWrapper<PendingInventory> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(pendingInventoryDto.getSearchAll())) {
            String searchValue = pendingInventoryDto.getSearchAll();
            // 1. 先尝试作为日期查询
            try {
                LocalDate RegistrationDate = LocalDate.parse(searchValue);
                queryWrapper.eq(PendingInventory::getRegistrationDate, RegistrationDate);
            } catch (DateTimeParseException e) {
                // 2. 如果不是日期,则作为煤种名称查询
        if (pendingInventoryDto.getRegistrationDate() != null) {
            queryWrapper.eq(PendingInventory::getRegistrationDate, pendingInventoryDto.getRegistrationDate());
        }
        // 按煤种名称查询
        if (StringUtils.isNotBlank(pendingInventoryDto.getCoal())) {
                LambdaQueryWrapper<CoalInfo> coalQueryWrapper = new LambdaQueryWrapper<>();
                coalQueryWrapper.like(CoalInfo::getCoal, searchValue);
            coalQueryWrapper.like(CoalInfo::getCoal, pendingInventoryDto.getCoal());
                List<CoalInfo> coalInfos = coalInfoMapper.selectList(coalQueryWrapper);
                if (!coalInfos.isEmpty()) {
                    // 提取所有匹配的煤种ID
                    List<Long> coalIds = coalInfos.stream()
                            .map(CoalInfo::getId)
                            .collect(Collectors.toList());
                    // 使用in查询匹配任意一个煤种ID
                    queryWrapper.in(PendingInventory::getCoalId, coalIds);
                } else {
                    // 3. 如果找不到煤种,可以返回空结果
                    queryWrapper.eq(PendingInventory::getCoalId, "-1"); // 使用不可能存在的ID
                }
                // 如果没有匹配的煤种,直接返回空结果
                queryWrapper.eq(PendingInventory::getCoalId, -1L); // 使用不可能存在的ID
            }
        }
@@ -286,4 +294,10 @@
        }
        return i;
    }
    @Override
    @Transactional
    public int addPending(PendingInventoryDto pendingInventoryDto) {
      return 1;
    }
}
main-business/src/main/java/com/ruoyi/business/service/impl/ProductionMasterServiceImpl.java
@@ -287,10 +287,8 @@
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String formattedDate = currentDate.format(formatter);
        // 常量定义:保留2位小数,四舍五入模式
        final int SCALE = 2;
        final RoundingMode ROUNDING_MODE = RoundingMode.HALF_UP;
        // 税率13%,用字符串构造BigDecimal避免精度误差
        final BigDecimal TAX_RATE = new BigDecimal("1.13");
        for (Production p : list) {
@@ -300,24 +298,23 @@
            pending.setUnit("t");
            pending.setSupplierName(formattedDate + " - " + "生产加工入库");
            // 1. 非空处理:避免null导致的运算异常
            // 非空处理
            BigDecimal totalCost = p.getTotalCost() == null ? BigDecimal.ZERO : p.getTotalCost();
            BigDecimal productionQuantity = p.getProductionQuantity() == null ? BigDecimal.ZERO : p.getProductionQuantity();
            // 2. 含税总价 = 含税单价 * 产量 → 保留2位小数
            // 含税总价
            BigDecimal totalPriceIncludingTax = totalCost.multiply(productionQuantity)
                    .setScale(SCALE, ROUNDING_MODE);
            pending.setTotalPriceIncludingTax(totalPriceIncludingTax);
            // 3. 含税单价 → 直接保留2位小数
            // 含税单价
            pending.setPriceIncludingTax(totalCost.setScale(SCALE, ROUNDING_MODE));
            // 4. 不含税单价 = 含税单价 / 1.13 → 先高精度计算,再保留2位
            BigDecimal priceExcludingTax = totalCost.divide(TAX_RATE, 10, ROUNDING_MODE) // 中间保留10位防误差
                    .setScale(SCALE, ROUNDING_MODE);   // 最终保留2位
            // 不含税单价(直接保留2位小数)
            BigDecimal priceExcludingTax = totalCost.divide(TAX_RATE, SCALE, ROUNDING_MODE);
            pending.setPriceExcludingTax(priceExcludingTax);
            // 5. 不含税总价 = 不含税单价 * 产量 → 保留2位小数
            // 不含税总价
            BigDecimal totalPriceExcludingTax = priceExcludingTax.multiply(productionQuantity)
                    .setScale(SCALE, ROUNDING_MODE);
            pending.setTotalPriceExcludingTax(totalPriceExcludingTax);
main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java
@@ -69,28 +69,25 @@
        // 1. 创建查询条件,按创建时间倒序排序
        LambdaQueryWrapper<SalesRecord> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(salesRecordDto.getSearchAll())) {
            String searchValue = salesRecordDto.getSearchAll();
            // 1. 先尝试作为日期查询
            try {
                LocalDate saleDate = LocalDate.parse(searchValue);
                queryWrapper.eq(SalesRecord::getSaleDate, saleDate);
            } catch (DateTimeParseException e) {
                // 2. 如果不是日期,则作为煤种名称查询
        // 按日期查询
        if (salesRecordDto.getSaleDate() != null) {
            queryWrapper.eq(SalesRecord::getSaleDate, salesRecordDto.getSaleDate());
        }
        // 按煤种名称查询
        if (StringUtils.isNotBlank(salesRecordDto.getCoal())) {
                LambdaQueryWrapper<CoalInfo> coalQueryWrapper = new LambdaQueryWrapper<>();
                coalQueryWrapper.like(CoalInfo::getCoal, searchValue);
            coalQueryWrapper.like(CoalInfo::getCoal, salesRecordDto.getCoal());
                List<CoalInfo> coalInfos = coalInfoMapper.selectList(coalQueryWrapper);
                if (!coalInfos.isEmpty()) {
                    // 提取所有匹配的煤种ID
                    List<Long> coalIds = coalInfos.stream()
                            .map(CoalInfo::getId)
                            .collect(Collectors.toList());
                    // 使用in查询匹配任意一个煤种ID
                    queryWrapper.in(SalesRecord::getCoalId, coalIds);
                } else {
                    // 3. 如果找不到煤种,可以返回空结果
                    queryWrapper.eq(SalesRecord::getCoalId, "-1"); // 使用不可能存在的ID
                }
                // 如果没有匹配的煤种,直接返回空结果
                queryWrapper.eq(SalesRecord::getCoalId, -1L); // 使用不可能存在的ID
            }
        }
main-business/src/main/resources/db/migration/postgresql/V20250613112800__create_table_production_inventory.sql
@@ -16,7 +16,7 @@
);
-- 添加表注释
COMMENT ON TABLE production_inventory IS '生产主表';
COMMENT ON TABLE production_inventory IS '生产库存使用记录表';
-- 添加字段注释
COMMENT ON COLUMN production_inventory.id IS '主键ID';
ruoyi-admin/src/main/java/com/ruoyi/web/controller/init/MyStartupRunner.java
@@ -1,12 +1,15 @@
package com.ruoyi.web.controller.init;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.basic.dto.CoalFieldDto;
import com.ruoyi.basic.entity.City;
import com.ruoyi.basic.entity.CoalField;
import com.ruoyi.basic.entity.District;
import com.ruoyi.basic.entity.Province;
import com.ruoyi.basic.mapper.CityMapper;
import com.ruoyi.basic.mapper.DistrictMapper;
import com.ruoyi.basic.mapper.ProvinceMapper;
import com.ruoyi.basic.mapper.*;
import com.ruoyi.basic.service.CoalFieldService;
import com.ruoyi.basic.service.CoalPlanService;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.web.controller.init.dto.AreaDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -15,7 +18,11 @@
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Slf4j
@Component
@@ -26,6 +33,10 @@
    private CityMapper cityMapper;
    @Autowired
    private DistrictMapper districtMapper;
    @Autowired
    private CoalFieldService coalFieldService;
    @Autowired
    private CoalPlanService coalPlanService;
    /**
     * 项目启动时需要执行的方法
@@ -37,6 +48,8 @@
    public void run(String... args) throws Exception {
        // 初始化省市区
        initRegion();
        // 初始新增配煤计算器中的字段和方案
        initCoalFields();
    }
    private void initRegion() {
@@ -105,4 +118,21 @@
    }
    private void initCoalFields() {
        List<CoalFieldDto> fields = Stream.of("发热量", "硫分", "灰分", "水分")
                .map(CoalFieldDto::from)
                .toList();
        // 批量获取已存在的 fieldNames
        Set<String> existingFieldNames = coalFieldService.getFieldNamesByNames(
                fields.stream().map(CoalFieldDto::getFieldName).collect(Collectors.toSet())
        );
        fields.forEach(field -> {
            if (!existingFieldNames.contains(field.getFieldName())) {
                coalFieldService.addOrEditCoalField(field);
            }
        });
    }
}