package com.ruoyi.business.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; 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 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; /** *

* 待入库表 服务实现类 *

* * @author ruoyi * @since 2025-06-04 */ @Service @RequiredArgsConstructor public class PendingInventoryServiceImpl extends ServiceImpl implements PendingInventoryService { private final PendingInventoryMapper pendingInventoryMapper; private final OfficialInventoryMapper officialInventoryMapper; private final CoalValueMapper coalValueMapper; private final CoalFieldMapper coalFieldMapper; private final CoalInfoMapper coalInfoMapper; private final SysUserMapper sysUserMapper; private final InputInventoryRecordService inputInventoryRecordService; private final InventorySummaryService inventorySummaryService; private final CoalPlanMapper coalPlanMapper; private final CoalValueService coalValueService; @Override public IPage selectPendingInventoryList(Page page, PendingInventoryDto pendingInventoryDto) { // 1. 构建主查询 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); if (pendingInventoryDto.getRegistrationDate() != null) { queryWrapper.eq(PendingInventory::getRegistrationDate, pendingInventoryDto.getRegistrationDate()); } // 按煤种名称查询 if (StringUtils.isNotBlank(pendingInventoryDto.getCoal())) { LambdaQueryWrapper coalQueryWrapper = new LambdaQueryWrapper<>(); coalQueryWrapper.like(CoalInfo::getCoal, pendingInventoryDto.getCoal()); List coalInfos = coalInfoMapper.selectList(coalQueryWrapper); if (!coalInfos.isEmpty()) { List coalIds = coalInfos.stream() .map(CoalInfo::getId) .collect(Collectors.toList()); queryWrapper.in(PendingInventory::getCoalId, coalIds); } else { // 如果没有匹配的煤种,直接返回空结果 queryWrapper.eq(PendingInventory::getCoalId, -1L); // 使用不可能存在的ID } } queryWrapper.orderByDesc(PendingInventory::getCreateTime); // 2. 执行主表分页查询 IPage pendingInventoryPage = pendingInventoryMapper.selectPage(page, queryWrapper); // 3. 无数据快速返回 if (CollectionUtils.isEmpty(pendingInventoryPage.getRecords())) { return new Page<>(page.getCurrent(), page.getSize(), pendingInventoryPage.getTotal()); } // 4. 提取所有待处理库存ID List pendingIds = pendingInventoryPage.getRecords().stream() .map(PendingInventory::getId) .collect(Collectors.toList()); // 5. 批量查询关联的煤炭信息和正式库存信息 List coalIds = pendingInventoryPage.getRecords().stream() .map(PendingInventory::getCoalId) .distinct() .collect(Collectors.toList()); // 批量查询CoalInfo Map coalInfoMap; if (!coalIds.isEmpty()) { List coalInfos = coalInfoMapper.selectList(new LambdaQueryWrapper().in(CoalInfo::getId, coalIds)); coalInfoMap = coalInfos.stream().collect(Collectors.toMap(CoalInfo::getId, Function.identity())); } else { coalInfoMap = new HashMap<>(); } // 5. 批量查询登记人id List registrantIds = pendingInventoryPage.getRecords().stream() .map(PendingInventory::getRegistrantId) .distinct() .toList(); // 批量查询登记人 Map sysUserMap; if (!registrantIds.isEmpty()) { List sysUsers = sysUserMapper.selectList(registrantIds); sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity())); } else { sysUserMap = new HashMap<>(); } // 批量查询正式库存信息 Map pendingToOfficialMap = getOfficialInventoryMap(pendingIds); // 6. 转换DTO并设置相关字段 return pendingInventoryPage.convert(record -> { PendingInventoryDto dto = new PendingInventoryDto(); BeanUtils.copyProperties(record, dto); // 设置Coal信息 CoalInfo coalInfo = coalInfoMap.get(record.getCoalId()); if (coalInfo != null) { dto.setCoal(coalInfo.getCoal()); } // 设置登记人 SysUser sysUser = sysUserMap.get(record.getRegistrantId()); if (sysUser != null) { dto.setRegistrant(sysUser.getNickName()); } // 从预加载的Map中获取officialId dto.setOfficialId(pendingToOfficialMap.getOrDefault(record.getId(), null)); return dto; }); } // 批量获取待处理库存与正式库存的映射关系 private Map getOfficialInventoryMap(List pendingIds) { if (CollectionUtils.isEmpty(pendingIds)) { return Collections.emptyMap(); } // 查询关联的正式库存数据 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.select(OfficialInventory::getId, OfficialInventory::getPendingId) .in(OfficialInventory::getPendingId, pendingIds); return officialInventoryMapper.selectList(wrapper) .stream() .collect(Collectors.toMap( OfficialInventory::getPendingId, OfficialInventory::getId, (existing, replacement) -> existing // 如果有重复,保留第一个 )); } @Override public int addOrEditPending(PendingInventoryDto pendingInventoryDto) { PendingInventory pendingInventory = new PendingInventory(); BeanUtils.copyProperties(pendingInventoryDto, pendingInventory); if (Objects.isNull(pendingInventoryDto.getId())) { return pendingInventoryMapper.insert(pendingInventory); } else { return pendingInventoryMapper.updateById(pendingInventory); } } @Override public int delByIds(Long[] ids) { // 检查参数 if (ids == null || ids.length == 0) { return 0; } // 构造更新条件 UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.in("id", ids) .set("deleted", 1); // 设置 deleted 为 1 表示已删除 // 执行批量逻辑删除 return pendingInventoryMapper.update(null, updateWrapper); } @Transactional @Override public int addOrEditCoalValue(PendingInventoryDto pendingInventoryDto) { // Step 1: 删除原有 planId 相关数据 coalValueMapper.delete(new LambdaQueryWrapper() .eq(CoalValue::getPlanId, pendingInventoryDto.getPId())); // Step 2: 构建基础 CoalValue 对象 CoalValue coalValue = new CoalValue(); BeanUtils.copyProperties(coalValue, pendingInventoryDto); coalValue.setPlanId(pendingInventoryDto.getPId()); List> fieldValue = pendingInventoryDto.getFieldValue(); if (CollectionUtils.isEmpty(fieldValue)) { throw new BaseException("字段值不能为空"); } // Step 3: 提前获取所有 field -> CoalField 映射,避免重复查库 Set allFields = fieldValue.stream() .flatMap(map -> map.keySet().stream()) .collect(Collectors.toSet()); List coalFields = coalFieldMapper.selectList( new LambdaQueryWrapper().in(CoalField::getFields, allFields)); Map fieldMap = coalFields.stream() .collect(Collectors.toMap( CoalField::getFields, CoalField::getFieldName)); // Step 4: 批量插入 int i = 0; for (Map fieldMapEntry : fieldValue) { for (Map.Entry entry : fieldMapEntry.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); String fieldName = fieldMap.get(key); if (fieldName == null) { throw new BaseException("字段名不存在"); } coalValue.setId(null); // 清空 id,确保每次都是新记录 coalValue.setCoalValue(value); coalValue.setFields(key); coalValue.setFieldName(fieldName); coalValue.setType(String.valueOf(1)); i = coalValueMapper.insert(coalValue); } } if (i > 0) { BigDecimal quantity = pendingInventoryDto.getInventoryQuantity(); PendingInventory pendingInventory = pendingInventoryMapper.selectById(pendingInventoryDto.getPId()); if (pendingInventory == null) { throw new BaseException("待入库记录不存在"); } BigDecimal left = pendingInventory.getInventoryQuantity().subtract(quantity); if (left.compareTo(BigDecimal.ZERO) > 0) { pendingInventory.setInventoryQuantity(left); pendingInventory.setCoalPlanId(pendingInventoryDto.getCoalPlanId()); pendingInventoryMapper.updateById(pendingInventory); } else { pendingInventoryMapper.deleteById(pendingInventoryDto.getPId()); } //正式库 if (pendingInventoryDto.getOfficialId() == null) { OfficialInventory officialInventory = new OfficialInventory(); BeanUtils.copyProperties(pendingInventory, officialInventory); officialInventory.setId(null); officialInventory.setCoalPlanId(pendingInventoryDto.getCoalPlanId()); officialInventory.setPendingId(pendingInventoryDto.getPId()); officialInventory.setInventoryQuantity(quantity); officialInventory.setRegistrantId(1L); officialInventory.setSupplierId(pendingInventoryDto.getSupplierId()); officialInventoryMapper.insert(officialInventory); } else { OfficialInventory officialInventory = officialInventoryMapper.selectById(pendingInventoryDto.getOfficialId()); officialInventory.setInventoryQuantity(quantity.add(officialInventory.getInventoryQuantity())); officialInventoryMapper.updateById(officialInventory); } } return i; } @Override @Transactional public boolean addPending(PendingInventoryDto pendingInventoryDto) { try { CoalPlan coalPlan = coalPlanMapper.selectOne(new LambdaQueryWrapper().eq(CoalPlan::getPlan, "配煤计算器方案")); if (coalPlan == null) { return false; } // 添加到待入库 Long userId = SecurityUtils.getUserId(); PendingInventory pendingInventory = new PendingInventory(); pendingInventory.setUnit("t"); pendingInventory.setRegistrantId(userId); pendingInventory.setRegistrationDate(LocalDate.now()); for (Map map : pendingInventoryDto.getFieldsResultList()) { pendingInventory.setSupplierName("配煤计算器方案入库"); // 处理煤炭ID if (map.get("coalId") == null) { CoalInfo coalInfo = new CoalInfo(); coalInfo.setCoal((String) map.get("createCoal")); coalInfo.setMaintainerId(userId); coalInfo.setMaintenanceDate(LocalDate.now()); if (coalInfoMapper.insert(coalInfo) <= 0) { return false; } pendingInventory.setCoalId(coalInfo.getId()); } else { pendingInventory.setCoalId((Long) map.get("coalId")); } // 设置价格和数量 BigDecimal cost = BigDecimal.valueOf((Double) map.get("cost")); BigDecimal tonnage = BigDecimal.valueOf((Double) map.get("totalTonnage")); 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)); pendingInventory.setCoalPlanId(coalPlan.getId()); // 煤质字段值 String coalFields = coalPlan.getCoalFields(); List coalFieldList = Arrays.asList(coalFields.split(",")); for (String field : coalFieldList) { CoalField coalField = coalFieldMapper.selectOne( new LambdaQueryWrapper().eq(CoalField::getFields, field)); if (coalField == null) { 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((String) map.get("cv")); break; case "硫分": coalValue.setCoalValue((String) map.get("sulfur")); break; case "灰分": coalValue.setCoalValue((String) map.get("ash")); break; case "水分": coalValue.setCoalValue((String) map.get("moisture")); break; } // 保存煤质值 if (coalValueMapper.insert(coalValue) <= 0) { return false; } } } // 插入待入库记录 if (pendingInventoryMapper.insert(pendingInventory) <= 0) { return false; } // 更新正式库 for (Map coalResult : pendingInventoryDto.getCoalResultList()) { Long officialId = (Long) coalResult.get("officialId"); BigDecimal quantity = (BigDecimal) coalResult.get("quantity"); OfficialInventory officialInventory = officialInventoryMapper.selectById(officialId); if (officialInventory == null || officialInventory.getInventoryQuantity().compareTo(quantity) < 0) { throw new BaseException("库存数量不足,添加至待入库失败"); } officialInventory.setInventoryQuantity(officialInventory.getInventoryQuantity().subtract(quantity)); if (officialInventoryMapper.updateById(officialInventory) <= 0) { return false; } } return true; } catch (Exception e) { // 记录日志 log.error("添加待入库失败", e); throw new BaseException("添加待入库失败: " + e.getMessage()); } } }