liujie
2026-08-21 77649c76ec1c3afcb93e9963243d637665b3a307
backend/src/main/java/com/tourguide/modules/user/service/GuideAutoDisableService.java
@@ -18,6 +18,7 @@
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@Service
@@ -48,18 +49,42 @@
    public void disableEligibleGuides() {
        GuideAutoDisableConfig config = configMapper.selectById(1);
        if (!valid(config)) return;
        Long lastGuideId = null;
        do {
            List<GuideUser> candidates = selectCandidates(config, lastGuideId);
            if (candidates.isEmpty()) return;
            for (GuideUser guide : candidates) {
                disableIfEligible(guide, config);
            }
            lastGuideId = candidates.get(candidates.size() - 1).getId();
            if (candidates.size() < BATCH_SIZE) return;
        } while (true);
    }
    /** 导游移出白名单后立即复核,避免等待下一次定时扫描。 */
    @Transactional
    public void disableGuideIfEligible(Long guideId) {
        if (guideId == null) return;
        GuideAutoDisableConfig config = configMapper.selectById(1);
        if (!valid(config)) return;
        GuideUser guide = guideUserMapper.selectById(guideId);
        if (!matchesRule(guide, config)) return;
        disableIfEligible(guide, config);
    }
    private List<GuideUser> selectCandidates(GuideAutoDisableConfig config, Long lastGuideId) {
        List<GuideUser> candidates = guideUserMapper.selectList(
                new LambdaQueryWrapper<GuideUser>()
                        .eq(GuideUser::getStatus, GuideUserService.STATUS_ENABLED)
                        .eq(GuideUser::getAutoDisableWhitelisted, 0)
                        .and(wrapper -> wrapper.isNull(GuideUser::getAutoDisableWhitelisted)
                                .or().eq(GuideUser::getAutoDisableWhitelisted, 0))
                        .ge(GuideUser::getAcceptedOrderCount, config.getOrderThreshold())
                        .gt(GuideUser::getRating, BigDecimal.ZERO)
                        .le(GuideUser::getRating, config.getRatingThreshold())
                        .gt(lastGuideId != null, GuideUser::getId, lastGuideId)
                        .orderByAsc(GuideUser::getId)
                        .last("LIMIT " + BATCH_SIZE));
        for (GuideUser guide : candidates) {
            disableIfEligible(guide, config);
        }
        return candidates == null ? Collections.emptyList() : candidates;
    }
    void disableIfEligible(GuideUser guide, GuideAutoDisableConfig config) {
@@ -81,6 +106,17 @@
                        OrderStatus.PENDING_MEETING.getCode(), OrderStatus.IN_SERVICE.getCode()))) > 0;
    }
    private boolean matchesRule(GuideUser guide, GuideAutoDisableConfig config) {
        return guide != null
                && Integer.valueOf(GuideUserService.STATUS_ENABLED).equals(guide.getStatus())
                && !Integer.valueOf(1).equals(guide.getAutoDisableWhitelisted())
                && guide.getAcceptedOrderCount() != null
                && guide.getAcceptedOrderCount() >= config.getOrderThreshold()
                && guide.getRating() != null
                && guide.getRating().compareTo(BigDecimal.ZERO) > 0
                && guide.getRating().compareTo(config.getRatingThreshold()) <= 0;
    }
    private boolean valid(GuideAutoDisableConfig config) {
        return config != null
                && config.getOrderThreshold() != null && config.getOrderThreshold() > 0