| | |
| | | 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; |
| | |
| | | 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; |
| | | |
| | |
| | | * @since 2025-06-11 |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | public class SalesRecordServiceImpl extends ServiceImpl<SalesRecordMapper, SalesRecord> implements SalesRecordService { |
| | | |
| | |
| | | public IPage<SalesRecordDto> selectSalesRecordList(Page<SalesRecord> page, SalesRecordDto salesRecordDto) { |
| | | // 1. 创建查询条件,按创建时间倒序排序 |
| | | LambdaQueryWrapper<SalesRecord> queryWrapper = new LambdaQueryWrapper<>(); |
| | | |
| | | // 按日期查询 |
| | | if (salesRecordDto.getSaleDate() != null) { |
| | | queryWrapper.eq(SalesRecord::getSaleDate, salesRecordDto.getSaleDate()); |
| | | } |
| | | |
| | | // 按煤种名称查询 |
| | | if (StringUtils.isNotBlank(salesRecordDto.getCoal())) { |
| | | LambdaQueryWrapper<CoalInfo> coalQueryWrapper = new LambdaQueryWrapper<>(); |
| | | coalQueryWrapper.like(CoalInfo::getCoal, salesRecordDto.getCoal()); |
| | | List<CoalInfo> coalInfos = coalInfoMapper.selectList(coalQueryWrapper); |
| | | |
| | | if (!coalInfos.isEmpty()) { |
| | | List<Long> coalIds = coalInfos.stream() |
| | | .map(CoalInfo::getId) |
| | | .collect(Collectors.toList()); |
| | | queryWrapper.in(SalesRecord::getCoalId, coalIds); |
| | | } else { |
| | | // 如果没有匹配的煤种,直接返回空结果 |
| | | queryWrapper.eq(SalesRecord::getCoalId, -1L); // 使用不可能存在的ID |
| | | } |
| | | } |
| | | |
| | | queryWrapper.orderByDesc(SalesRecord::getCreateTime); |
| | | |
| | | // 2. 获取分页的销售记录 |
| | |
| | | throw new BaseException("销售数量不能大于库存数量"); |
| | | } |
| | | officialInventory.setInventoryQuantity(officialInventory.getInventoryQuantity().subtract(salesRecordDto.getSaleQuantity())); |
| | | officialInventory.setPendingReplenishment(salesRecordDto.getSaleQuantity()); |
| | | |
| | | if (salesRecordDto.isAdd()){ |
| | | officialInventory.setPendingReplenishment(salesRecordDto.getSaleQuantity()); |
| | | } |
| | | officialInventoryMapper.updateById(officialInventory); |
| | | |
| | | // 构建销售记录实体 |
| | |
| | | if (registrant == null) { |
| | | throw new BaseException("登记人信息不存在"); |
| | | } |
| | | record.setRegistrant(registrant.getUserName()); |
| | | record.setRegistrant(registrant.getNickName()); |
| | | |
| | | // 设置客户信息 |
| | | Customer customer = customerMapper.selectById(dto.getCustomerId()); |
| | |
| | | .set("deleted", 1); // 设置 deleted 为 1 表示已删除 |
| | | // 执行批量逻辑删除 |
| | | return salesRecordMapper.update(null, updateWrapper); |
| | | } |
| | | |
| | | @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 |
| | |
| | | ) |
| | | )); |
| | | |
| | | //构建结果(保持煤种顺序,销量默认为0) |
| | | List<Map<String, Object>> resultMouth = new ArrayList<>(); |
| | | // 2. 创建 resultMouth,存储煤种及其销量(Map 结构) |
| | | Map<String, BigDecimal> resultMouthMap = new LinkedHashMap<>(); |
| | | for (CoalInfo coal : allCoalTypes) { |
| | | Map<String, Object> item = new LinkedHashMap<>(); |
| | | item.put("coal", coal.getCoal()); // 煤种名称 |
| | | item.put("saleQuantity", salesByCoalId.getOrDefault(coal.getId(), BigDecimal.valueOf(0))); // 销量 |
| | | resultMouth.add(item); |
| | | resultMouthMap.put( |
| | | coal.getCoal(), // 煤种名称(如 "无烟煤") |
| | | salesByCoalId.getOrDefault(coal.getId(), BigDecimal.valueOf(0)) // 销量 |
| | | ); |
| | | } |
| | | |
| | | result.put("revenueAmount", revenueAmount.setScale(2, RoundingMode.HALF_UP)); |
| | |
| | | result.put("trendQuantity", trendQuantity); |
| | | result.put("revenueDistribution", revenueDistribution); |
| | | result.put("salesResults", results); |
| | | result.put("resultMouth", resultMouth); |
| | | result.put("resultMouth", resultMouthMap); |
| | | |
| | | return result; |
| | | } |