|
|
@@ -0,0 +1,157 @@
|
|
|
+package com.etotem.cfc.task;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.etotem.cfc.entity.CommissionRecord;
|
|
|
+import com.etotem.cfc.entity.User;
|
|
|
+import com.etotem.cfc.entity.WithdrawalRequest;
|
|
|
+import com.etotem.cfc.mapper.CommissionRecordMapper;
|
|
|
+import com.etotem.cfc.mapper.UserMapper;
|
|
|
+import com.etotem.cfc.mapper.WithdrawalRequestMapper;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.Calendar;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 分佣定时任务
|
|
|
+ * - 更新推荐统计(每日2:00)
|
|
|
+ * - 结算待处理佣金(每日3:00)
|
|
|
+ * - 批量处理提现(每日23:30)
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class CommissionScheduledTasks {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private CommissionRecordMapper commissionRecordMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private WithdrawalRequestMapper withdrawalRequestMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private UserMapper userMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 每天 2:00 AM 执行
|
|
|
+ * 重新计算所有推荐人的直接推荐人数和间接推荐人数
|
|
|
+ */
|
|
|
+ @Scheduled(cron = "0 0 2 * * ?")
|
|
|
+ public void updateDistributionStats() {
|
|
|
+ log.info("开始执行推荐统计更新定时任务");
|
|
|
+ try {
|
|
|
+ // 查询所有有推荐人的用户,提取不重复的推荐人ID
|
|
|
+ List<User> referredUsers = userMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<User>().isNotNull(User::getReferrerId)
|
|
|
+ );
|
|
|
+ List<Long> referrerIds = referredUsers.stream()
|
|
|
+ .map(User::getReferrerId)
|
|
|
+ .distinct()
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
+
|
|
|
+ int updatedCount = 0;
|
|
|
+ for (Long referrerId : referrerIds) {
|
|
|
+ // 直接推荐人数 = referrer_id = referrerId 的用户数
|
|
|
+ Long directCount = userMapper.selectCount(
|
|
|
+ new LambdaQueryWrapper<User>().eq(User::getReferrerId, referrerId)
|
|
|
+ );
|
|
|
+
|
|
|
+ // 间接推荐人数 = 所有L1用户的直接推荐人数之和
|
|
|
+ List<User> l1Users = userMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<User>().eq(User::getReferrerId, referrerId)
|
|
|
+ );
|
|
|
+ long indirectCount = 0;
|
|
|
+ for (User l1User : l1Users) {
|
|
|
+ indirectCount += userMapper.selectCount(
|
|
|
+ new LambdaQueryWrapper<User>().eq(User::getReferrerId, l1User.getId())
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新推荐人统计
|
|
|
+ User referrer = userMapper.selectById(referrerId);
|
|
|
+ if (referrer != null) {
|
|
|
+ referrer.setDirectCount(directCount.intValue());
|
|
|
+ referrer.setIndirectCount((int) indirectCount);
|
|
|
+ referrer.setUpdatedAt(new Date());
|
|
|
+ userMapper.updateById(referrer);
|
|
|
+ updatedCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("推荐统计更新定时任务执行完成,共更新{}个推荐人", updatedCount);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("推荐统计更新定时任务执行失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 每天 3:00 AM 执行
|
|
|
+ * 结算创建超过7天的待处理佣金记录
|
|
|
+ */
|
|
|
+ @Scheduled(cron = "0 0 3 * * ?")
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void processPendingCommissions() {
|
|
|
+ log.info("开始执行待结算佣金处理定时任务");
|
|
|
+ try {
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
+ calendar.add(Calendar.DAY_OF_MONTH, -7);
|
|
|
+ Date sevenDaysAgo = calendar.getTime();
|
|
|
+
|
|
|
+ List<CommissionRecord> pendingRecords = commissionRecordMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<CommissionRecord>()
|
|
|
+ .eq(CommissionRecord::getStatus, "pending")
|
|
|
+ .lt(CommissionRecord::getCreatedAt, sevenDaysAgo)
|
|
|
+ );
|
|
|
+
|
|
|
+ for (CommissionRecord record : pendingRecords) {
|
|
|
+ record.setStatus("settled");
|
|
|
+ record.setSettledAt(new Date());
|
|
|
+ commissionRecordMapper.updateById(record);
|
|
|
+ }
|
|
|
+ log.info("待结算佣金处理定时任务执行完成,共处理{}条记录", pendingRecords.size());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("待结算佣金处理定时任务执行失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 每天 23:30 执行
|
|
|
+ * 批量处理已审核通过的提现请求
|
|
|
+ */
|
|
|
+ @Scheduled(cron = "0 30 23 * * ?")
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void batchProcessWithdrawals() {
|
|
|
+ log.info("开始执行批量提现处理定时任务");
|
|
|
+ try {
|
|
|
+ List<WithdrawalRequest> approvedRequests = withdrawalRequestMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<WithdrawalRequest>()
|
|
|
+ .eq(WithdrawalRequest::getStatus, "approved")
|
|
|
+ );
|
|
|
+
|
|
|
+ for (WithdrawalRequest request : approvedRequests) {
|
|
|
+ // 将该用户所有已结算的佣金记录标记为已提现
|
|
|
+ List<CommissionRecord> settledRecords = commissionRecordMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<CommissionRecord>()
|
|
|
+ .eq(CommissionRecord::getReferrerId, request.getUserId())
|
|
|
+ .eq(CommissionRecord::getStatus, "settled")
|
|
|
+ );
|
|
|
+ for (CommissionRecord record : settledRecords) {
|
|
|
+ record.setStatus("withdrawn");
|
|
|
+ record.setWithdrawnAt(new Date());
|
|
|
+ commissionRecordMapper.updateById(record);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新提现请求状态
|
|
|
+ request.setStatus("processed");
|
|
|
+ request.setRemark("批量处理");
|
|
|
+ withdrawalRequestMapper.updateById(request);
|
|
|
+ }
|
|
|
+ log.info("批量提现处理定时任务执行完成,共处理{}条请求", approvedRequests.size());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("批量提现处理定时任务执行失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|