|
|
@@ -0,0 +1,153 @@
|
|
|
+package com.etotem.cfc.service;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.etotem.cfc.entity.PromotionTier;
|
|
|
+import com.etotem.cfc.entity.PromotionTierConfig;
|
|
|
+import com.etotem.cfc.entity.User;
|
|
|
+import com.etotem.cfc.mapper.PromotionTierConfigMapper;
|
|
|
+import com.etotem.cfc.mapper.PromotionTierMapper;
|
|
|
+import com.etotem.cfc.mapper.UserMapper;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class PromotionTierEvalService {
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(PromotionTierEvalService.class);
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private PromotionTierMapper tierMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private PromotionTierConfigMapper configMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private PromotionTierService promotionTierService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private UserMapper userMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private WechatService wechatService;
|
|
|
+
|
|
|
+ @Value("${wechat.promotion-tier-template-id:}")
|
|
|
+ private String promotionTierTemplateId;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取所有启用且按sortOrder desc排序的等级配置
|
|
|
+ */
|
|
|
+ public List<PromotionTierConfig> getEnabledConfigs() {
|
|
|
+ return configMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<PromotionTierConfig>()
|
|
|
+ .eq(PromotionTierConfig::getEnabled, 1)
|
|
|
+ .orderByDesc(PromotionTierConfig::getSortOrder)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据用户的 PromotionTier 数据,计算应该属于哪个等级
|
|
|
+ * 遍历配置,从高到低找到第一个满足所有条件的等级
|
|
|
+ * @return 目标等级代码,如 "R2",如果没有任何配置匹配返回 "R0"
|
|
|
+ */
|
|
|
+ public String evaluateTier(Long userId) {
|
|
|
+ PromotionTier tier = promotionTierService.getCurrentTier(userId);
|
|
|
+ List<PromotionTierConfig> configs = getEnabledConfigs();
|
|
|
+
|
|
|
+ int teamSize = tier != null && tier.getTotalTeamSize() != null ? tier.getTotalTeamSize() : 0;
|
|
|
+ int referralEarnings = tier != null && tier.getTotalReferralEarnings() != null ? tier.getTotalReferralEarnings() : 0;
|
|
|
+ int shareEarnings = tier != null && tier.getTotalShareEarnings() != null ? tier.getTotalShareEarnings() : 0;
|
|
|
+
|
|
|
+ // 从高等级到低等级遍历,找到第一个满足所有条件的
|
|
|
+ // configs 已按 sortOrder desc 排序(高等级在前)
|
|
|
+ for (PromotionTierConfig config : configs) {
|
|
|
+ boolean teamSizeOk = teamSize >= config.getMinTeamSize();
|
|
|
+ boolean referralOk = config.getMinReferralEarnings() == null
|
|
|
+ || config.getMinReferralEarnings() == 0
|
|
|
+ || referralEarnings >= config.getMinReferralEarnings();
|
|
|
+ boolean shareOk = config.getMinShareEarnings() == null
|
|
|
+ || config.getMinShareEarnings() == 0
|
|
|
+ || shareEarnings >= config.getMinShareEarnings();
|
|
|
+
|
|
|
+ if (teamSizeOk && referralOk && shareOk) {
|
|
|
+ return config.getTierCode();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return "R0";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对指定用户执行等级评估,如有晋级/降级则更新
|
|
|
+ * @return true if tier changed, false if unchanged
|
|
|
+ */
|
|
|
+ public boolean evaluateAndUpdateTier(Long userId) {
|
|
|
+ PromotionTier currentTier = promotionTierService.getCurrentTier(userId);
|
|
|
+ String currentTierCode = currentTier != null ? currentTier.getTier() : null;
|
|
|
+ String newTierCode = evaluateTier(userId);
|
|
|
+
|
|
|
+ if (newTierCode.equals(currentTierCode)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Tier changed — use existing PromotionTierService.updateTier which logs the change
|
|
|
+ promotionTierService.updateTier(userId, newTierCode, "qualify");
|
|
|
+
|
|
|
+ PromotionTier updatedTier = promotionTierService.getCurrentTier(userId);
|
|
|
+ log.info("推广等级变更: userId={}, {}→{}, 团队={}, 推荐佣金={}, 分润={}",
|
|
|
+ userId, currentTierCode, newTierCode,
|
|
|
+ updatedTier != null ? updatedTier.getTotalTeamSize() : 0,
|
|
|
+ updatedTier != null ? updatedTier.getTotalReferralEarnings() : 0,
|
|
|
+ updatedTier != null ? updatedTier.getTotalShareEarnings() : 0);
|
|
|
+
|
|
|
+ // Send WeChat template notification
|
|
|
+ sendPromotionNotification(userId, currentTierCode, newTierCode);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量评估所有有 PromotionTier 记录的用户
|
|
|
+ * @return 变更数量
|
|
|
+ */
|
|
|
+ public int evaluateAllUsers() {
|
|
|
+ List<PromotionTier> allTiers = tierMapper.selectList(null);
|
|
|
+ int changed = 0;
|
|
|
+ for (PromotionTier tier : allTiers) {
|
|
|
+ if (evaluateAndUpdateTier(tier.getUserId())) {
|
|
|
+ changed++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("批量推广等级评估完成,共{}个用户,检查了{}条记录", changed, allTiers.size());
|
|
|
+ return changed;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送推广等级变更通知(微信模板消息)
|
|
|
+ */
|
|
|
+ private void sendPromotionNotification(Long userId, String oldTier, String newTier) {
|
|
|
+ if (promotionTierTemplateId == null || promotionTierTemplateId.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
+ if (user == null || user.getOpenid() == null || user.getOpenid().isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Map<String, Object> keywordMap = new HashMap<>();
|
|
|
+ keywordMap.put("keyword1", oldTier != null ? oldTier : "无");
|
|
|
+ keywordMap.put("keyword2", newTier);
|
|
|
+ keywordMap.put("keyword3", new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date()));
|
|
|
+ wechatService.sendTemplateMessage(user.getOpenid(), promotionTierTemplateId, keywordMap);
|
|
|
+ log.info("已发送推广等级变更通知: userId={}, {}→{}", userId, oldTier, newTier);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("发送推广等级变更通知失败 userId={}", userId, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|