main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java
@@ -4,10 +4,12 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.ruoyi.basic.entity.CoalInfo;
import com.ruoyi.basic.entity.Customer;
import com.ruoyi.basic.entity.Supply;
import com.ruoyi.basic.mapper.CoalInfoMapper;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.business.dto.SalesRecordDto;
@@ -17,12 +19,16 @@
import com.ruoyi.business.mapper.OfficialInventoryMapper;
import com.ruoyi.business.mapper.SalesRecordMapper;
import com.ruoyi.business.service.SalesRecordService;
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.StringUtils;
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;
@@ -51,6 +57,7 @@
 * @since 2025-06-11
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SalesRecordServiceImpl extends ServiceImpl<SalesRecordMapper, SalesRecord> implements SalesRecordService {
@@ -155,7 +162,10 @@
            throw new BaseException("销售数量不能大于库存数量");
        }
        officialInventory.setInventoryQuantity(officialInventory.getInventoryQuantity().subtract(salesRecordDto.getSaleQuantity()));
        officialInventory.setPendingReplenishment(salesRecordDto.getSaleQuantity());
        if (salesRecordDto.isAdd()){
            officialInventory.setPendingReplenishment(salesRecordDto.getSaleQuantity());
        }
        officialInventoryMapper.updateById(officialInventory);
        // 构建销售记录实体
@@ -193,7 +203,7 @@
        if (registrant == null) {
            throw new BaseException("登记人信息不存在");
        }
        record.setRegistrant(registrant.getUserName());
        record.setRegistrant(registrant.getNickName());
        // 设置客户信息
        Customer customer = customerMapper.selectById(dto.getCustomerId());
@@ -255,6 +265,59 @@
    }
    @Override
    public void salesRecordExport(HttpServletResponse response, SalesRecordDto salesRecordDto) {
        List<Long> ids = salesRecordDto.getExportIds();
        List<SalesRecord> list;
        if (ids != null && !ids.isEmpty()) {
            list = salesRecordMapper.selectByIds(ids);
        } else {
            list = salesRecordMapper.selectList(null);
        }
        List<SalesRecordExportVo> exportData = convertToExportVo(list);
        ExcelUtil<SalesRecordExportVo> util = new ExcelUtil<>(SalesRecordExportVo.class);
        util.exportExcel(response, exportData, "销售出库数据");
    }
    private List<SalesRecordExportVo> convertToExportVo(List<SalesRecord> list) {
        // 1. 提前收集所有需要查询的coalId,避免N+1查询问题
        Set<Long> coalIds = list.stream()
                .filter(Objects::nonNull)
                .map(SalesRecord::getCoalId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        // 2. 批量查询coalInfo数据
        Map<Long, CoalInfo> coalInfoMap = CollectionUtils.isEmpty(coalIds)
                ? Collections.emptyMap()
                : coalInfoMapper.selectByIds(coalIds).stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(CoalInfo::getId, Function.identity()));
        // 3. 转换数据
        return list.stream()
                .filter(Objects::nonNull)
                .map(record -> {
                    try {
                        SalesRecordExportVo vo = new SalesRecordExportVo();
                        // 拷贝基础属性
                        BeanUtils.copyProperties(record, vo);
                        // 设置关联的coal信息
                        Optional.ofNullable(record.getCoalId())
                                .map(coalInfoMap::get)
                                .ifPresent(coalInfo -> vo.setCoal(coalInfo.getCoal()));
                        return vo;
                    } catch (Exception e) {
                        log.error("转换销售记录VO异常,记录ID: {}", record.getId(), e);
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
    @Override
    public Map<String, Object> getYearlyMonthlySales(YearlyQueryDto query) {
        // 1. 处理默认查询(不传参数时)
        if (query == null || query.getTimeRange() == null || query.getTimeRange().length == 0) {