package com.tourguide.modules.order.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.tourguide.common.exception.BusinessException;
|
import com.tourguide.modules.order.domain.OrderStatus;
|
import com.tourguide.modules.order.domain.RefundStatus;
|
import com.tourguide.modules.order.dto.GuideEarningItemResponse;
|
import com.tourguide.modules.order.dto.GuideEarningsResponse;
|
import com.tourguide.modules.order.entity.TourOrder;
|
import com.tourguide.modules.order.mapper.TourOrderMapper;
|
import com.tourguide.modules.user.service.GuideUserService;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.StringUtils;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.util.Arrays;
|
import java.util.Collections;
|
import java.util.List;
|
import java.util.stream.Collectors;
|
|
/** 查询导游已完成订单的业绩快照。 */
|
@Service
|
public class GuideEarningsService {
|
private final TourOrderMapper orderMapper;
|
private final GuideUserService guideUserService;
|
|
public GuideEarningsService(TourOrderMapper orderMapper, GuideUserService guideUserService) {
|
this.orderMapper = orderMapper;
|
this.guideUserService = guideUserService;
|
}
|
|
public GuideEarningsResponse get(Long guideId, String serviceType, String scenicName,
|
LocalDate date, long pageNum, long pageSize) {
|
guideUserService.findEnabledById(guideId);
|
validateServiceType(serviceType);
|
long safePage = Math.max(pageNum, 1);
|
long safeSize = Math.min(Math.max(pageSize, 1), 100);
|
LocalDate today = LocalDate.now();
|
BigDecimal todayEarnings = safeAmount(orderMapper.selectGuideEarningSum(
|
guideId, today.atStartOfDay(), today.plusDays(1).atStartOfDay()));
|
LocalDate monthStart = today.withDayOfMonth(1);
|
BigDecimal monthEarnings = safeAmount(orderMapper.selectGuideEarningSum(
|
guideId, monthStart.atStartOfDay(), monthStart.plusMonths(1).atStartOfDay()));
|
|
LambdaQueryWrapper<TourOrder> query = new LambdaQueryWrapper<TourOrder>()
|
.eq(TourOrder::getGuideId, guideId)
|
.eq(TourOrder::getStatus, OrderStatus.COMPLETED.getCode())
|
.isNotNull(TourOrder::getGuideEarningAmount)
|
.and(wrapper -> wrapper.isNull(TourOrder::getRefundStatus)
|
.or().in(TourOrder::getRefundStatus,
|
Arrays.asList(RefundStatus.NONE.getCode(),
|
RefundStatus.REFUND_FAILED.getCode())))
|
.eq(StringUtils.hasText(scenicName), TourOrder::getScenicName,
|
StringUtils.hasText(scenicName) ? scenicName.trim() : null)
|
.ge(date != null, TourOrder::getCompletedAt, date == null ? null : date.atStartOfDay())
|
.lt(date != null, TourOrder::getCompletedAt,
|
date == null ? null : date.plusDays(1).atStartOfDay())
|
.orderByDesc(TourOrder::getCompletedAt)
|
.orderByDesc(TourOrder::getId);
|
if (StringUtils.hasText(serviceType)) {
|
query.in(TourOrder::getOrderType, resolveOrderTypes(serviceType));
|
}
|
Page<TourOrder> result = orderMapper.selectPage(new Page<TourOrder>(safePage, safeSize), query);
|
List<GuideEarningItemResponse> records = result.getRecords().stream()
|
.map(GuideEarningItemResponse::new)
|
.collect(Collectors.toList());
|
return new GuideEarningsResponse(todayEarnings, monthEarnings,
|
orderMapper.selectGuideEarningScenics(guideId), records,
|
result.getTotal(), result.getCurrent(), result.getSize());
|
}
|
|
private void validateServiceType(String serviceType) {
|
if (StringUtils.hasText(serviceType)
|
&& !"QUICK".equals(serviceType)
|
&& !"PREMIUM".equals(serviceType)
|
&& !"GROUP_QUICK".equals(serviceType)
|
&& !"GROUP_PREMIUM".equals(serviceType)
|
&& !"PRIVATE_QUICK".equals(serviceType)
|
&& !"PRIVATE_PREMIUM".equals(serviceType)) {
|
throw new BusinessException(400, "订单类型不支持");
|
}
|
}
|
|
private List<String> resolveOrderTypes(String serviceType) {
|
if ("QUICK".equals(serviceType)) {
|
return Arrays.asList("GROUP_QUICK", "PRIVATE_QUICK");
|
}
|
if ("PREMIUM".equals(serviceType)) {
|
return Arrays.asList("GROUP_PREMIUM", "PRIVATE_PREMIUM");
|
}
|
return Collections.singletonList(serviceType);
|
}
|
|
private BigDecimal safeAmount(BigDecimal amount) {
|
return amount == null ? BigDecimal.ZERO.setScale(2) : amount;
|
}
|
}
|