package com.tourguide.modules.user.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.tourguide.modules.order.domain.OrderStatus;
|
import com.tourguide.modules.order.entity.TourOrder;
|
import com.tourguide.modules.order.mapper.TourOrderMapper;
|
import com.tourguide.modules.user.entity.GuideAutoDisableConfig;
|
import com.tourguide.modules.user.entity.GuideUser;
|
import com.tourguide.modules.user.mapper.GuideAutoDisableConfigMapper;
|
import com.tourguide.modules.user.mapper.GuideRealtimeStatusMapper;
|
import com.tourguide.modules.user.mapper.GuideReceivingSessionMapper;
|
import com.tourguide.modules.user.mapper.GuideUserMapper;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.math.BigDecimal;
|
import java.util.Arrays;
|
import java.util.List;
|
|
@Service
|
public class GuideAutoDisableService {
|
private static final Logger log = LoggerFactory.getLogger(GuideAutoDisableService.class);
|
private static final int BATCH_SIZE = 100;
|
|
private final GuideAutoDisableConfigMapper configMapper;
|
private final GuideUserMapper guideUserMapper;
|
private final TourOrderMapper orderMapper;
|
private final GuideRealtimeStatusMapper realtimeStatusMapper;
|
private final GuideReceivingSessionMapper receivingSessionMapper;
|
|
public GuideAutoDisableService(GuideAutoDisableConfigMapper configMapper,
|
GuideUserMapper guideUserMapper,
|
TourOrderMapper orderMapper,
|
GuideRealtimeStatusMapper realtimeStatusMapper,
|
GuideReceivingSessionMapper receivingSessionMapper) {
|
this.configMapper = configMapper;
|
this.guideUserMapper = guideUserMapper;
|
this.orderMapper = orderMapper;
|
this.realtimeStatusMapper = realtimeStatusMapper;
|
this.receivingSessionMapper = receivingSessionMapper;
|
}
|
|
@Scheduled(fixedDelayString = "${tourguide.guide.auto-disable-scan-delay-millis:60000}")
|
@Transactional
|
public void disableEligibleGuides() {
|
GuideAutoDisableConfig config = configMapper.selectById(1);
|
if (!valid(config)) return;
|
List<GuideUser> candidates = guideUserMapper.selectList(
|
new LambdaQueryWrapper<GuideUser>()
|
.eq(GuideUser::getStatus, GuideUserService.STATUS_ENABLED)
|
.eq(GuideUser::getAutoDisableWhitelisted, 0)
|
.ge(GuideUser::getAcceptedOrderCount, config.getOrderThreshold())
|
.gt(GuideUser::getRating, BigDecimal.ZERO)
|
.le(GuideUser::getRating, config.getRatingThreshold())
|
.orderByAsc(GuideUser::getId)
|
.last("LIMIT " + BATCH_SIZE));
|
for (GuideUser guide : candidates) {
|
disableIfEligible(guide, config);
|
}
|
}
|
|
void disableIfEligible(GuideUser guide, GuideAutoDisableConfig config) {
|
if (guide == null || Integer.valueOf(1).equals(guide.getAutoDisableWhitelisted())) return;
|
if (hasActiveServiceOrder(guide.getId())) return;
|
int updated = guideUserMapper.autoDisableIfEligible(guide.getId(),
|
config.getOrderThreshold(), config.getRatingThreshold());
|
if (updated != 1) return;
|
realtimeStatusMapper.disableReceiving(guide.getId());
|
receivingSessionMapper.stopReceivingByGuide(guide.getId());
|
log.warn("Guide auto-disabled, guideId={}, acceptedOrderCount={}, rating={}",
|
guide.getId(), guide.getAcceptedOrderCount(), guide.getRating());
|
}
|
|
private boolean hasActiveServiceOrder(Long guideId) {
|
return orderMapper.selectCount(new LambdaQueryWrapper<TourOrder>()
|
.eq(TourOrder::getGuideId, guideId)
|
.in(TourOrder::getStatus, Arrays.asList(
|
OrderStatus.PENDING_MEETING.getCode(), OrderStatus.IN_SERVICE.getCode()))) > 0;
|
}
|
|
private boolean valid(GuideAutoDisableConfig config) {
|
return config != null
|
&& config.getOrderThreshold() != null && config.getOrderThreshold() > 0
|
&& config.getRatingThreshold() != null;
|
}
|
}
|