liding
2 天以前 4c33acfe648e9b008f91c5e2cf446550e6b0174d
main-business/src/main/java/com/ruoyi/business/service/impl/OfficialInventoryServiceImpl.java
@@ -7,22 +7,39 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.entity.CoalField;
import com.ruoyi.basic.entity.CoalInfo;
import com.ruoyi.basic.entity.CoalValue;
import com.ruoyi.basic.entity.Supply;
import com.ruoyi.basic.mapper.CoalFieldMapper;
import com.ruoyi.basic.mapper.CoalInfoMapper;
import com.ruoyi.basic.mapper.CoalValueMapper;
import com.ruoyi.basic.mapper.SupplyMapper;
import com.ruoyi.business.dto.OfficialInventoryDto;
import com.ruoyi.business.dto.SalesRecordDto;
import com.ruoyi.business.entity.OfficialInventory;
import com.ruoyi.business.entity.SalesRecord;
import com.ruoyi.business.mapper.OfficialInventoryMapper;
import com.ruoyi.business.service.OfficialInventoryService;
import com.ruoyi.business.utils.DynamicExcelUtil;
import com.ruoyi.business.vo.OfficialInventoryExportVo;
import com.ruoyi.business.vo.OfficialInventoryVo;
import com.ruoyi.business.vo.SalesRecordExportVo;
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.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.mapper.SysUserMapper;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -34,6 +51,7 @@
 * @since 2025-06-04
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OfficialInventoryServiceImpl extends ServiceImpl<OfficialInventoryMapper, OfficialInventory> implements OfficialInventoryService {
@@ -43,12 +61,19 @@
    private final CoalFieldMapper coalFieldMapper;
    private final CoalInfoMapper coalInfoMapper;
    private final SupplyMapper supplyMapper;
    private final SysUserMapper sysUserMapper;
    @Override
    public IPage<OfficialInventoryDto> selectOfficialInventoryList(Page page, OfficialInventoryDto officialInventoryDto) {
    public IPage<OfficialInventoryDto> selectOfficialInventoryList(Page<OfficialInventory> page, OfficialInventoryDto officialInventoryDto) {
        //  先查出原始数据(OfficialInventory)
        LambdaQueryWrapper<OfficialInventory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(OfficialInventory::getCreateTime);
        IPage<OfficialInventory> entityPage = officialInventoryMapper.selectPage(page, queryWrapper);
        //  创建一个新的 Dto 分页结果
@@ -57,17 +82,70 @@
        List<OfficialInventoryDto> dtoList = new ArrayList<>();
        List<Long> supplierIds = entityPage.getRecords().stream()
                .map(OfficialInventory::getSupplierId)
                .toList();
        List<Long> registrantIds = entityPage.getRecords().stream()
                .map(OfficialInventory::getRegistrantId)
                .toList();
        Map<Long, Supply> supplyMap;
        if (!supplierIds.isEmpty()) {
            List<Supply> infos = supplyMapper.selectList(new LambdaQueryWrapper<Supply>().in(Supply::getId, supplierIds));
            supplyMap = infos.stream().collect(Collectors.toMap(Supply::getId, Function.identity()));
        } else {
            supplyMap = new HashMap<>();
        }
        //登记人
        Map<Long, SysUser> userMap;
        if (!registrantIds.isEmpty()) {
            List<SysUser> sysUsers = sysUserMapper.selectList(registrantIds);
            userMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
        } else {
            userMap = new HashMap<>();
        }
        //  查询所有可用字段(CoalField)
        List<CoalField> coalFields = coalFieldMapper.selectList(null);
        List<String> allFieldNames = coalFields.stream()
                .map(CoalField::getFields)
                .distinct()
                .collect(Collectors.toList());
                .toList();
        //查询煤种ids
        List<Long> coalIds = entityPage.getRecords().stream()
                .map(OfficialInventory::getCoalId)
                .distinct()
                .toList();
        // 批量查询CoalInfo
        Map<Long, CoalInfo> coalInfoMap;
        if (!coalIds.isEmpty()) {
            List<CoalInfo> coalInfos = coalInfoMapper.selectList(new LambdaQueryWrapper<CoalInfo>().in(CoalInfo::getId, coalIds));
            coalInfoMap = coalInfos.stream().collect(Collectors.toMap(CoalInfo::getId, Function.identity()));
        } else {
            coalInfoMap = new HashMap<>();
        }
        //  遍历每条记录,进行转换并填充 fields
        for (OfficialInventory entity : entityPage.getRecords()) {
            OfficialInventoryDto dto = new OfficialInventoryDto();
            BeanUtils.copyProperties(entity, dto);
            // 供应商信息
            Supply supply = supplyMap.get(entity.getSupplierId());
            if (supply != null) {
                dto.setSupplierName(supply.getSupplierName());
            }
            // 登记人
            SysUser sysUser = userMap.get(entity.getRegistrantId());
            if (sysUser != null) {
                dto.setRegistrant(sysUser.getNickName());
            }
            List<CoalValue> coalValues;
            if (entity.getMergeId() == null) {
                coalValues = coalValueMapper.selectList(new LambdaQueryWrapper<CoalValue>()
@@ -97,6 +175,12 @@
                fields.add(fieldMap);
            }
            // 设置Coal信息
            CoalInfo coalInfo = coalInfoMap.get(entity.getCoalId());
            if (coalInfo != null) {
                dto.setCoal(coalInfo.getCoal());
            }
            // 设置到 DTO 中
            dto.setFields(fields);
            dtoList.add(dto);
@@ -110,6 +194,64 @@
    public int editOfficial(OfficialInventoryDto officialInventoryDto) {
        OfficialInventory officialInventory = new OfficialInventory();
        BeanUtils.copyProperties(officialInventoryDto, officialInventory);
        if (officialInventoryDto.getMergeId() != null) {
            // 1. 构建查询条件
            LambdaQueryWrapper<CoalValue> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(CoalValue::getPlanId, officialInventoryDto.getId())
                    .eq(CoalValue::getType, "2");
            // 2. 查询多个符合条件的CoalValue记录
            List<CoalValue> coalValues = coalValueMapper.selectList(queryWrapper);
            if (!CollectionUtils.isEmpty(coalValues) && !CollectionUtils.isEmpty(officialInventoryDto.getFields())) {
                // 3. 创建字段映射关系 (field key -> coal_value)
                Map<String, String> fieldValueMap = new HashMap<>();
                for (Map<String, String> fieldMap : officialInventoryDto.getFields()) {
                    fieldValueMap.putAll(fieldMap);
                }
                // 4. 更新
                for (CoalValue coalValue : coalValues) {
                    String fieldKey = coalValue.getFields(); // 数据库中的field key
                    if (fieldValueMap.containsKey(fieldKey)) {
                        String newValue = fieldValueMap.get(fieldKey);
                        if (!Objects.equals(coalValue.getCoalValue(), newValue)) {
                            coalValue.setCoalValue(newValue);
                            coalValueMapper.updateById(coalValue);
                        }
                    }
                }
            }
        } else {
            // 构建查询条件
            LambdaQueryWrapper<CoalValue> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(CoalValue::getPlanId, officialInventoryDto.getPendingId())
                    .eq(CoalValue::getType, "1");
            // 2. 查询多个符合条件的CoalValue记录
            List<CoalValue> coalValues = coalValueMapper.selectList(queryWrapper);
            if (!CollectionUtils.isEmpty(coalValues) && !CollectionUtils.isEmpty(officialInventoryDto.getFields())) {
                // 3. 创建字段映射关系 (field key -> coal_value)
                Map<String, String> fieldValueMap = new HashMap<>();
                for (Map<String, String> fieldMap : officialInventoryDto.getFields()) {
                    fieldValueMap.putAll(fieldMap);
                }
                // 4. 更新
                for (CoalValue coalValue : coalValues) {
                    String fieldKey = coalValue.getFields(); // 数据库中的field key
                    if (fieldValueMap.containsKey(fieldKey)) {
                        String newValue = fieldValueMap.get(fieldKey);
                        if (!Objects.equals(coalValue.getCoalValue(), newValue)) {
                            coalValue.setCoalValue(newValue);
                            coalValueMapper.updateById(coalValue);
                        }
                    }
                }
            }
        }
        return officialInventoryMapper.updateById(officialInventory);
    }
@@ -120,6 +262,8 @@
                .map(OI -> {
                    OfficialInventoryVo vo = new OfficialInventoryVo();
                    BeanUtils.copyProperties(OI, vo);
                    CoalInfo coalInfo = coalInfoMapper.selectById(OI.getCoalId());
                    vo.setCoal(coalInfo.getCoal());
                    return vo;
                })
                .collect(Collectors.toList());
@@ -157,7 +301,8 @@
        BeanUtils.copyProperties(officialInventoryDto, officialInventory);
        officialInventory.setId(null);
        officialInventory.setMergeId(ids.toString());
        officialInventory.setRegistrantId(SecurityUtils.getLoginUser().getUser().getUserName());
        officialInventory.setSupplierId(officialInventoryDto.getSupplierId());
        officialInventory.setRegistrantId(SecurityUtils.getLoginUser().getUser().getUserId());
        if (officialInventoryMapper.insert(officialInventory) <= 0) {
            throw new BaseException("库存记录创建失败");
        }
@@ -218,4 +363,248 @@
        }
    }
    @Override
    public void officialInventoryExport(HttpServletResponse response, OfficialInventoryDto officialInventoryDto) {
        try {
            // 获取煤质字段配置
            List<CoalField> allCoalFields = coalFieldMapper.selectList(null);
            List<String> dynamicHeaders = allCoalFields.stream()
                    .map(CoalField::getFieldName)
                    .collect(Collectors.toList());
            // 获取数据
            List<OfficialInventory> list = officialInventoryDto.getExportIds() != null && !officialInventoryDto.getExportIds().isEmpty()
                    ? officialInventoryMapper.selectByIds(officialInventoryDto.getExportIds())
                    : officialInventoryMapper.selectList(null);
            // 转换为导出VO
            List<OfficialInventoryExportVo> exportData = convertToExportVo(list, allCoalFields);
            // 使用增强的Excel工具导出
            DynamicExcelUtil<OfficialInventoryExportVo> util =
                    new DynamicExcelUtil<>(OfficialInventoryExportVo.class, dynamicHeaders);
            // 导出Excel
            util.exportExcel(response, exportData, "库存数据");
        } catch (Exception e) {
            log.error("库存导出失败", e);
            // 可以考虑返回更友好的错误信息给前端
            throw new RuntimeException("导出失败: " + e.getMessage());
        }
    }
    private List<OfficialInventoryExportVo> convertToExportVo(List<OfficialInventory> list, List<CoalField> coalFields) {
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }
        // 收集所有需要查询的ID
        Set<Long> coalIds = list.stream()
                .map(OfficialInventory::getCoalId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        Set<Long> supplierIds = list.stream()
                .map(OfficialInventory::getSupplierId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        Set<Long> registrantIds = list.stream()
                .map(OfficialInventory::getRegistrantId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        Set<Long> planIds = list.stream()
                .map(OfficialInventory::getCoalPlanId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        // 批量查询关联数据
        Map<Long, CoalInfo> coalInfoMap = getCoalInfoMap(coalIds);
        Map<Long, Supply> supplyMap = getSupplyMap(supplierIds);
        Map<Long, SysUser> userMap = getUserMap(registrantIds);
        Map<Long, List<CoalValue>> coalValuesMap = getCoalValuesMap(planIds);
        // 构建字段ID到字段名称的映射,提高查找效率
        Map<String, String> fieldIdToNameMap = coalFields.stream()
                .collect(Collectors.toMap(CoalField::getFields, CoalField::getFieldName));
        // 转换数据
        return list.stream().map(record -> {
            OfficialInventoryExportVo vo = new OfficialInventoryExportVo();
            vo.initDynamicFields(); // 初始化
            // 设置基础属性
            BeanUtils.copyProperties(record, vo);
            // 设置关联信息
            setCoalInfo(vo, record.getCoalId(), coalInfoMap);
            setSupplierInfo(vo, record.getSupplierId(), supplyMap);
            setUserMapInfo(vo, record.getRegistrantId(), userMap);
            // 动态字段处理
            if (record.getCoalPlanId() != null) {
                List<CoalValue> values = coalValuesMap.getOrDefault(record.getCoalPlanId(), Collections.emptyList());
                setDynamicFields(vo, values, fieldIdToNameMap);
            }
            return vo;
        }).collect(Collectors.toList());
    }
    private void setCoalInfo(OfficialInventoryExportVo vo, Long coalId, Map<Long, CoalInfo> coalInfoMap) {
        if (coalId != null && coalInfoMap.containsKey(coalId)) {
            vo.setCoal(coalInfoMap.get(coalId).getCoal());
        }
    }
    private void setSupplierInfo(OfficialInventoryExportVo vo, Long supplierId, Map<Long, Supply> supplyMap) {
        if (supplierId != null && supplyMap.containsKey(supplierId)) {
            vo.setSupplierName(supplyMap.get(supplierId).getSupplierName());
        }
    }
    private void setUserMapInfo(OfficialInventoryExportVo vo, Long registrantId, Map<Long, SysUser> userMap) {
        if (registrantId != null && userMap.containsKey(registrantId)) {
            vo.setRegistrant(userMap.get(registrantId).getNickName());
        }
    }
    private void setDynamicFields(OfficialInventoryExportVo vo, List<CoalValue> values, Map<String, String> fieldIdToNameMap) {
        for (CoalValue value : values) {
            String fieldName = fieldIdToNameMap.get(value.getFields());
            if (fieldName != null) {
                vo.getCoalQualityProperties().put(fieldName, value.getCoalValue());
            }
        }
    }
    private Map<Long, List<CoalValue>> getCoalValuesMap(Set<Long> planIds) {
        if (CollectionUtils.isEmpty(planIds)) {
            return Collections.emptyMap();
        }
        List<CoalValue> allValues = coalValueMapper.selectList(
                new LambdaQueryWrapper<CoalValue>()
                        .in(CoalValue::getPlanId, planIds));
        return allValues.stream()
                .collect(Collectors.groupingBy(CoalValue::getPlanId));
    }
    private Map<Long, CoalInfo> getCoalInfoMap(Set<Long> coalIds) {
        if (CollectionUtils.isEmpty(coalIds)) {
            return Collections.emptyMap();
        }
        return coalInfoMapper.selectByIds(coalIds).stream()
                .collect(Collectors.toMap(CoalInfo::getId, Function.identity()));
    }
    private Map<Long, Supply> getSupplyMap(Set<Long> supplierIds) {
        if (CollectionUtils.isEmpty(supplierIds)) {
            return Collections.emptyMap();
        }
        return supplyMapper.selectByIds(supplierIds).stream()
                .collect(Collectors.toMap(Supply::getId, Function.identity()));
    }
    private Map<Long, SysUser> getUserMap(Set<Long> registrantIds) {
        if (CollectionUtils.isEmpty(registrantIds)) {
            return Collections.emptyMap();
        }
        return sysUserMapper.selectBatchIds(registrantIds).stream()
                .collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
    }
    @Override
    public List<OfficialInventoryDto> coalBlendingList() {
        // 1. 查询基础库存数据
        List<OfficialInventory> officialInventories = officialInventoryMapper.selectList(null);
        // 2. 收集所有需要查询的ID
        Set<Long> coalIds = new HashSet<>();
        Set<Long> supplierIds = new HashSet<>();
        Set<Long> planIds = new HashSet<>();
        officialInventories.forEach(inventory -> {
            coalIds.add(inventory.getCoalId());
            supplierIds.add(inventory.getSupplierId());
            planIds.add(inventory.getCoalPlanId());
        });
        // 3. 批量查询关联数据
        Map<Long, CoalInfo> coalInfoMap;
        if (!coalIds.isEmpty()) {
            coalInfoMap = coalInfoMapper.selectByIds(coalIds).stream()
                    .collect(Collectors.toMap(CoalInfo::getId, Function.identity()));
        } else {
            coalInfoMap = new HashMap<>();
        }
        Map<Long, Supply> supplyMap;
        if (!supplierIds.isEmpty()) {
            supplyMap = supplyMapper.selectByIds(supplierIds).stream()
                    .collect(Collectors.toMap(Supply::getId, Function.identity()));
        } else {
            supplyMap = new HashMap<>();
            log.warn("supplierIds 为空,跳过查询 Supply");
        }
        Map<Long, List<CoalValue>> coalValuesMap;
        if (!planIds.isEmpty()) {
            coalValuesMap = coalValueMapper.selectList(
                            new LambdaQueryWrapper<CoalValue>().in(CoalValue::getPlanId, planIds))
                    .stream()
                    .collect(Collectors.groupingBy(CoalValue::getPlanId));
        } else {
            coalValuesMap = new HashMap<>();
            log.warn("planIds 为空,跳过查询 CoalValue");
        }
        // 4. 组装DTO
        return officialInventories.stream()
                .map(inventory -> {
                    OfficialInventoryDto dto = new OfficialInventoryDto();
                    BeanUtils.copyProperties(inventory, dto);
                    // 设置煤种信息
                    CoalInfo coalInfo = coalInfoMap.get(inventory.getCoalId());
                    Supply supply = supplyMap.get(inventory.getSupplierId());
                    if (coalInfo != null && supply != null) {
                        dto.setSupplierCoal(supply.getSupplierName() + " - " + coalInfo.getCoal());
                    }
                    // 设置煤质数据
                    dto.setCoalValues(coalValuesMap.getOrDefault(inventory.getCoalPlanId(), Collections.emptyList())
                            .stream()
                            .map(coalValue -> {
                                Map<String, String> map = new HashMap<>();
                                map.put("fieldName", coalValue.getFieldName());
                                map.put("coalValue", coalValue.getCoalValue());
                                return map;
                            })
                            .collect(Collectors.toList()));
                    return dto;
                })
                .collect(Collectors.toList());
    }
    @Override
    public Map<String, BigDecimal> selectOfficialAllInfo() {
        // 1. 查询 official_inventory 表数据
        List<OfficialInventory> officialInventories = officialInventoryMapper.selectList(null);
        // 用于存储最终结果,key 为煤种名称,value 为库存数量拼接“吨”
        Map<String, BigDecimal> resultMap = new LinkedHashMap<>();
        // 2. 遍历查询结果,关联 coalInfo 获取煤种名称并组装数据
        for (OfficialInventory inventory : officialInventories) {
            Long coalId = inventory.getCoalId();
            // 根据 coalId 到 coalInfoMapper 查询煤种名称
            CoalInfo coalInfo = coalInfoMapper.selectById(coalId);
            if (coalInfo != null) {
                String coalName = coalInfo.getCoal(); // 假设 CoalInfo 有 getCoalName 方法获取煤种名称
                BigDecimal quantity = inventory.getInventoryQuantity();
                resultMap.put(coalName, quantity);
            }
        }
        return resultMap;
    }
}