liding
2 天以前 6733a32d4bcd7ad3ec3f109da0f3d2524766f7bb
main-business/src/main/java/com/ruoyi/business/service/impl/PendingInventoryServiceImpl.java
@@ -6,36 +6,51 @@
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.mchange.v2.lang.SystemUtils;
import com.ruoyi.basic.dto.CoalFieldDto;
import com.ruoyi.basic.entity.CoalField;
import com.ruoyi.basic.entity.CoalInfo;
import com.ruoyi.basic.entity.CoalPlan;
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.basic.service.CoalValueService;
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;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
 * <p>
@@ -46,6 +61,7 @@
 * @since 2025-06-04
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class PendingInventoryServiceImpl extends ServiceImpl<PendingInventoryMapper, PendingInventory> implements PendingInventoryService {
@@ -64,33 +80,31 @@
    private final InputInventoryRecordService inputInventoryRecordService;
    private final InventorySummaryService inventorySummaryService;
    private final CoalPlanMapper coalPlanMapper;
    private final CoalValueService coalValueService;
    @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. 如果不是日期,则作为煤种名称查询
                LambdaQueryWrapper<CoalInfo> coalQueryWrapper = new LambdaQueryWrapper<>();
                coalQueryWrapper.like(CoalInfo::getCoal, searchValue);
                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
                }
        if (pendingInventoryDto.getRegistrationDate() != null) {
            queryWrapper.eq(PendingInventory::getRegistrationDate, pendingInventoryDto.getRegistrationDate());
        }
        // 按煤种名称查询
        if (StringUtils.isNotBlank(pendingInventoryDto.getCoal())) {
            LambdaQueryWrapper<CoalInfo> coalQueryWrapper = new LambdaQueryWrapper<>();
            coalQueryWrapper.like(CoalInfo::getCoal, pendingInventoryDto.getCoal());
            List<CoalInfo> coalInfos = coalInfoMapper.selectList(coalQueryWrapper);
            if (!coalInfos.isEmpty()) {
                List<Long> coalIds = coalInfos.stream()
                        .map(CoalInfo::getId)
                        .collect(Collectors.toList());
                queryWrapper.in(PendingInventory::getCoalId, coalIds);
            } else {
                // 如果没有匹配的煤种,直接返回空结果
                queryWrapper.eq(PendingInventory::getCoalId, -1L); // 使用不可能存在的ID
            }
        }
@@ -286,4 +300,200 @@
        }
        return i;
    }
    @Override
    @Transactional
    public boolean addPending(PendingInventoryDto pendingInventoryDto) {
        try {
            // 1. 获取配煤计算器方案
            CoalPlan coalPlan = coalPlanMapper.selectOne(
                    new LambdaQueryWrapper<CoalPlan>().eq(CoalPlan::getPlan, "配煤计算器方案"));
            if (coalPlan == null) {
                log.error("配煤计算器方案不存在");
                return false;
            }
            // 2. 准备待入库记录
            Long userId = SecurityUtils.getUserId();
            PendingInventory pendingInventory = new PendingInventory();
            pendingInventory.setUnit("t");
            pendingInventory.setRegistrantId(userId);
            pendingInventory.setRegistrationDate(LocalDate.now());
            pendingInventory.setSupplierName("配煤计算器方案入库");
            pendingInventory.setCoalPlanId(coalPlan.getId());
            // 3. 安全获取字段结果
            Map<String, Object> map = Optional.ofNullable(pendingInventoryDto.getFieldsResultList())
                    .orElseThrow(() -> new BaseException("字段结果列表不能为空"));
            // 4. 处理煤炭ID
            if (map.get("coalId") == null) {
                String coalName = safeGetString(map, "createCoal");
                if (coalName == null || coalName.isEmpty()) {
                    throw new BaseException("煤炭名称不能为空");
                }
                CoalInfo coalInfo = new CoalInfo();
                coalInfo.setCoal(coalName);
                coalInfo.setMaintainerId(userId);
                coalInfo.setMaintenanceDate(LocalDate.now());
                if (coalInfoMapper.insert(coalInfo) <= 0) {
                    log.error("创建煤炭信息失败");
                    return false;
                }
                pendingInventory.setCoalId(coalInfo.getId());
            } else {
                Long coalId = safeGetLong(map, "coalId");
                if (coalId == null) {
                    throw new BaseException("煤炭ID格式错误");
                }
                pendingInventory.setCoalId(coalId);
            }
            // 5. 设置价格和数量
            BigDecimal cost = safeGetBigDecimal(map, "cost");
            BigDecimal tonnage = safeGetBigDecimal(map, "totalTonnage");
            if (cost == null || tonnage == null) {
                throw new BaseException("成本或吨位不能为空");
            }
            pendingInventory.setPriceIncludingTax(cost);
            pendingInventory.setInventoryQuantity(tonnage);
            pendingInventory.setTotalPriceIncludingTax(cost.multiply(tonnage));
            BigDecimal costExcludingTax = cost.divide(BigDecimal.valueOf(1.13), 2, RoundingMode.HALF_UP);
            pendingInventory.setPriceExcludingTax(costExcludingTax);
            pendingInventory.setTotalPriceExcludingTax(costExcludingTax.multiply(tonnage));
            // 6. 处理煤质字段值
            String coalFields = coalPlan.getCoalFields();
            if (coalFields == null || coalFields.isEmpty()) {
                throw new BaseException("煤质字段配置不能为空");
            }
            String[] coalFieldList = coalFields.split(",");
            for (String field : coalFieldList) {
                CoalField coalField = coalFieldMapper.selectOne(
                        new LambdaQueryWrapper<CoalField>().eq(CoalField::getFields, field));
                if (coalField == null) {
                    log.warn("未找到煤质字段配置: {}", field);
                    continue;
                }
                CoalValue coalValue = new CoalValue();
                coalValue.setPlanId(coalPlan.getId());
                coalValue.setFields(field);
                coalValue.setFieldName(coalField.getFieldName());
                coalValue.setType("1");
                // 安全设置煤质值
                switch (coalField.getFieldName()) {
                    case "发热量":
                        coalValue.setCoalValue(safeGetString(map, "cv"));
                        break;
                    case "硫分":
                        coalValue.setCoalValue(safeGetString(map, "sulfur"));
                        break;
                    case "灰分":
                        coalValue.setCoalValue(safeGetString(map, "ash"));
                        break;
                    case "水分":
                        coalValue.setCoalValue(safeGetString(map, "moisture"));
                        break;
                    default:
                        log.warn("未知煤质字段: {}", coalField.getFieldName());
                        continue;
                }
                if (coalValueMapper.insert(coalValue) <= 0) {
                    log.error("保存煤质值失败: {}", field);
                    return false;
                }
            }
            // 7. 插入待入库记录
            if (pendingInventoryMapper.insert(pendingInventory) <= 0) {
                log.error("插入待入库记录失败");
                return false;
            }
            // 8. 更新正式库
            List<Map<String, Object>> coalResults = Optional.ofNullable(pendingInventoryDto.getCoalResultList())
                    .orElseThrow(() -> new BaseException("煤炭结果列表不能为空"));
            for (Map<String, Object> coalResult : coalResults) {
                Long officialId = safeGetLong(coalResult, "officialId");
                BigDecimal quantity = safeGetBigDecimal(coalResult, "quantity");
                if (officialId == null || quantity == null) {
                    throw new BaseException("正式库存ID或数量不能为空");
                }
                OfficialInventory officialInventory = officialInventoryMapper.selectById(officialId);
                if (officialInventory == null) {
                    throw new BaseException("找不到正式库存记录: " + officialId);
                }
                if (officialInventory.getInventoryQuantity().compareTo(quantity) < 0) {
                    throw new BaseException("库存数量不足,添加至待入库失败");
                }
                officialInventory.setInventoryQuantity(officialInventory.getInventoryQuantity().subtract(quantity));
                if (officialInventoryMapper.updateById(officialInventory) <= 0) {
                    log.error("更新正式库存失败: {}", officialId);
                    return false;
                }
            }
            return true;
        } catch (Exception e) {
            log.error("添加待入库失败", e);
            throw new BaseException("添加待入库失败: " + e.getMessage());
        }
    }
    // 安全类型转换辅助方法
    private String safeGetString(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        return value.toString();
    }
    private Long safeGetLong(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        try {
            return Long.parseLong(value.toString());
        } catch (NumberFormatException e) {
            log.warn("无法转换为Long: key={}, value={}", key, value);
            return null;
        }
    }
    private BigDecimal safeGetBigDecimal(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        if (value instanceof Number) {
            return BigDecimal.valueOf(((Number) value).doubleValue());
        }
        try {
            return new BigDecimal(value.toString());
        } catch (NumberFormatException e) {
            log.warn("无法转换为BigDecimal: key={}, value={}", key, value);
            return null;
        }
    }
}