liujie
2026-08-21 ad5db85e540947e82c7a4d5612879b3b3ecdf459
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package com.tourguide.modules.order.service;
 
import com.tourguide.common.exception.BusinessException;
import com.tourguide.modules.operation.service.PlatformSettingsService;
import com.tourguide.modules.order.entity.TourOrder;
import com.tourguide.modules.user.entity.GuideTeam;
import com.tourguide.modules.user.entity.GuideUser;
import com.tourguide.modules.user.mapper.GuideTeamMapper;
import com.tourguide.modules.user.service.GuideUserService;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
import java.math.RoundingMode;
 
/** 接单时固化订单抽成规则和导游实际业绩。 */
@Service
public class GuideOrderEarningSnapshotService {
    private static final BigDecimal ONE_HUNDRED = new BigDecimal("100");
 
    private final GuideUserService guideUserService;
    private final GuideTeamMapper guideTeamMapper;
    private final PlatformSettingsService platformSettingsService;
 
    public GuideOrderEarningSnapshotService(GuideUserService guideUserService,
                                            GuideTeamMapper guideTeamMapper,
                                            PlatformSettingsService platformSettingsService) {
        this.guideUserService = guideUserService;
        this.guideTeamMapper = guideTeamMapper;
        this.platformSettingsService = platformSettingsService;
    }
 
    public void apply(TourOrder order, Long guideId) {
        apply(order, guideUserService.findEnabledById(guideId));
    }
 
    public void apply(TourOrder order, GuideUser guide) {
        BigDecimal commissionRate;
        if (guide.getTeamId() == null) {
            order.setCommissionSource("PERSONAL");
            order.setCommissionTeamId(null);
            commissionRate = platformSettingsService.getSettings().getCommissionRate();
        } else {
            GuideTeam team = guideTeamMapper.selectById(guide.getTeamId());
            if (team == null || team.getStatus() == null || team.getStatus() != 1) {
                throw new BusinessException(409, "导游所属讲解队不存在或已停用");
            }
            order.setCommissionSource("TEAM");
            order.setCommissionTeamId(team.getId());
            commissionRate = team.getCommissionRatio();
        }
        validateCommissionRate(commissionRate);
        order.setCommissionRate(commissionRate.setScale(2, RoundingMode.HALF_UP));
        order.setGuideEarningAmount(calculateEarning(paymentAmount(order), commissionRate));
    }
 
    BigDecimal calculateEarning(BigDecimal orderAmount, BigDecimal commissionRate) {
        BigDecimal guideRate = ONE_HUNDRED.subtract(commissionRate).movePointLeft(2);
        return orderAmount.multiply(guideRate).setScale(2, RoundingMode.HALF_UP);
    }
 
    private BigDecimal paymentAmount(TourOrder order) {
        BigDecimal amount = order.getPaymentAmount() == null ? order.getAmount() : order.getPaymentAmount();
        if (amount == null || amount.signum() < 0) {
            throw new BusinessException(400, "订单实付金额不正确");
        }
        return amount;
    }
 
    private void validateCommissionRate(BigDecimal commissionRate) {
        if (commissionRate == null || commissionRate.signum() < 0
                || commissionRate.compareTo(ONE_HUNDRED) > 0) {
            throw new BusinessException(500, "导游抽成比例配置不正确");
        }
    }
}