| | |
| | | package com.ruoyi.account.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.ruoyi.account.api.model.AgentApplication; |
| | | import com.ruoyi.account.api.model.AppUser; |
| | | import com.ruoyi.account.mapper.AgentApplicationMapper; |
| | | import com.ruoyi.account.service.AgentApplicationService; |
| | | import com.ruoyi.account.service.AppUserService; |
| | | import com.ruoyi.account.service.VipCenterService; |
| | | import com.ruoyi.account.service.VipSettingService; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import lombok.RequiredArgsConstructor; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import com.ruoyi.order.feignClient.RemoteOrderGoodsClient; |
| | | import com.ruoyi.order.model.Order; |
| | | import com.ruoyi.other.api.domain.Goods; |
| | | import com.ruoyi.other.api.domain.Shop; |
| | | import com.ruoyi.other.api.domain.VipGood; |
| | | import com.ruoyi.other.api.domain.VipSetting; |
| | | import com.ruoyi.other.api.feignClient.GoodsClient; |
| | | import com.ruoyi.other.api.feignClient.ShopClient; |
| | | import com.ruoyi.other.api.feignClient.VipGoodClient; |
| | | import com.ruoyi.system.api.model.LoginUser; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.List; |
| | | import javax.annotation.Resource; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class VipCenterServiceImpl implements VipCenterService { |
| | | private final AppUserService appUserService; |
| | | @Override |
| | | public Boolean checkReadyToBeProxy(Long userId) { |
| | | @Resource |
| | | private AppUserService appUserService; |
| | | @Resource |
| | | private RemoteOrderGoodsClient remoteOrderGoodsClient; |
| | | @Resource |
| | | private VipSettingService vipSettingService; |
| | | @Resource |
| | | private ShopClient shopClient; |
| | | @Resource |
| | | private TokenService tokenService; |
| | | @Resource |
| | | private AgentApplicationMapper agentApplicationMapper; |
| | | |
| | | // 钻石会员 |
| | | private static final int VIP_ID_DIAMOND = 3; |
| | | // 门店合伙人 |
| | | private static final int VIP_ID_STORE_PARTNER = 4; |
| | | // 城市合伙人 |
| | | private static final int VIP_ID_CITY_PARTNER = 5; |
| | | // 全国合伙人 |
| | | private static final int VIP_ID_NATIONAL_PARTNER = 6; |
| | | // 全球合伙人 |
| | | private static final int VIP_ID_GLOBAL_PARTNER = 7; |
| | | |
| | | /** |
| | | * 判断是否满足申请门店合伙人的条件 |
| | | * @param userId 用户ID |
| | | * @param vipId 会员等级ID |
| | | * @return 是否满足条件 |
| | | */ |
| | | public Boolean isEligibleForStorePartner(Long userId, Integer vipId) { |
| | | AppUser appUser = appUserService.getById(userId); |
| | | if (appUser.getShopPoint() >= 500){ |
| | | return true; |
| | | } |
| | | if (appUser.getSharePoint() >= 400){ |
| | | |
| | | VipSetting vipSetting = vipSettingService.getVipSettingById(VIP_ID_STORE_PARTNER); |
| | | // 判断是否已经购买过指定商品 |
| | | if (hasPurchasedGoods(userId, vipSetting.getGoodIds())) { |
| | | return true; |
| | | } |
| | | |
| | | // 当前用户的直推用户 |
| | | List<AppUser> bottomUsers = appUserService.list(new LambdaQueryWrapper<AppUser>() |
| | | .eq(AppUser::getInviteUserId, userId) |
| | | .eq(AppUser::getVipId,3)); |
| | | if (bottomUsers.size() >= 5){ |
| | | // 判断是否满足条件 |
| | | return meetsPointsAndDirectUsersCriteria(appUser, vipSetting); |
| | | } |
| | | |
| | | /** |
| | | * 判断是否满足申请城市合伙人的条件 |
| | | * @param userId 用户ID |
| | | * @return 是否满足条件 |
| | | */ |
| | | public Boolean isEligibleForCityPartner(Long userId) { |
| | | AppUser appUser = appUserService.getById(userId); |
| | | |
| | | VipSetting vipSetting = vipSettingService.getVipSettingById(VIP_ID_CITY_PARTNER); |
| | | |
| | | if (hasPurchasedGoods(userId, vipSetting.getGoodIds())) { |
| | | return true; |
| | | } |
| | | |
| | | return meetsPointsAndDirectUsersCriteria(appUser, vipSetting); |
| | | } |
| | | |
| | | /** |
| | | * 判断是否满足申请全国合伙人的条件 |
| | | * @param userId 用户ID |
| | | * @return 是否满足条件 |
| | | */ |
| | | public Boolean isEligibleForNationalPartner(Long userId) { |
| | | AppUser appUser = appUserService.getById(userId); |
| | | VipSetting vipSetting = vipSettingService.getVipSettingById(VIP_ID_NATIONAL_PARTNER); |
| | | |
| | | // 判断是否已经购买过指定商品 |
| | | if (hasPurchasedGoods(userId, vipSetting.getGoodIds())) { |
| | | return true; |
| | | } |
| | | |
| | | if (vipSetting.getVipLevelUpProxyRole() == 1 && appUser.getVipId() == VIP_ID_CITY_PARTNER) { |
| | | return true; |
| | | } |
| | | |
| | | return meetsPointsAndDirectUsersCriteria(appUser, vipSetting); |
| | | } |
| | | |
| | | /** |
| | | * 判断是否满足申请全球合伙人的条件 |
| | | * @param userId 用户ID |
| | | * @return 是否满足条件 |
| | | */ |
| | | public Boolean isEligibleForGlobalPartner(Long userId) { |
| | | AppUser appUser = appUserService.getById(userId); |
| | | VipSetting vipSetting = vipSettingService.getVipSettingById(VIP_ID_GLOBAL_PARTNER); |
| | | |
| | | if (hasPurchasedGoods(userId, vipSetting.getGoodIds())) { |
| | | return true; |
| | | } |
| | | |
| | | return meetsPointsAndDirectUsersCriteria(appUser, vipSetting); |
| | | } |
| | | |
| | | /** |
| | | * 判断是否已经申请过 |
| | | * @param userId 用户ID |
| | | * @param vipId 会员等级ID |
| | | * @return 是否已经申请过 |
| | | */ |
| | | private boolean hasPendingApplication(Long userId, Integer vipId) { |
| | | return agentApplicationMapper.selectCount(new QueryWrapper<AgentApplication>() |
| | | .eq("app_user_id", userId) |
| | | .eq("application_vip_id", vipId) |
| | | .ne("status", 3) |
| | | .eq("del_flag", 0)) > 0; |
| | | } |
| | | |
| | | /** |
| | | * 判断是否已经购买过指定商品 |
| | | * @param userId 用户ID |
| | | * @param goodIds 商品ID列表 |
| | | * @return 是否已经购买过指定商品 |
| | | */ |
| | | private boolean hasPurchasedGoods(Long userId, String goodIds) { |
| | | if (goodIds == null || goodIds.isEmpty()) { |
| | | return false; |
| | | } |
| | | return Arrays.stream(goodIds.split(",")) |
| | | .anyMatch(goodId -> { |
| | | R<List<Order>> orderResponse = remoteOrderGoodsClient.getOrderListByUserIdAndGoodsId(userId, Integer.valueOf(goodId)); |
| | | return R.isSuccess(orderResponse) && !orderResponse.getData().isEmpty(); |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 判断是否满足条件 |
| | | * @param appUser 用户信息 |
| | | * @param vipSetting 会员设置 |
| | | * @return 是否满足条件 |
| | | */ |
| | | private boolean meetsPointsAndDirectUsersCriteria(AppUser appUser, VipSetting vipSetting) { |
| | | // 满足消费积分和返佣积分 |
| | | if (vipSetting.getVipLevelUpShopRole() == 1) { |
| | | if (appUser.getShopPoint() >= vipSetting.getVipLevelUpShop() && |
| | | appUser.getSharePoint() >= vipSetting.getVipLevelUpShare()) { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | long directDiamondUserCount = getDirectDiamondUserCount(appUser.getId()); // 直推钻石会员数量 |
| | | if (vipSetting.getId() < VIP_ID_NATIONAL_PARTNER){ // 门店合伙人、城市合伙人 |
| | | if (vipSetting.getVipLevelUpNumRole() == 1) { |
| | | return directDiamondUserCount >= vipSetting.getVipDirectNum(); //直推钻石会员数量大于等于指定数量 |
| | | } |
| | | }else if (vipSetting.getId() == VIP_ID_NATIONAL_PARTNER){ // 全国合伙人 |
| | | if (vipSetting.getVipLevelUpNumRole() == 1){ |
| | | List<AppUser> appUsers = appUserService.list(new LambdaQueryWrapper<AppUser>() |
| | | .eq(AppUser::getInviteUserId, appUser.getId()) |
| | | .ge(AppUser::getVipId, VIP_ID_CITY_PARTNER) |
| | | .eq(AppUser::getDelFlag, 0)); |
| | | |
| | | if (appUsers.size() >= vipSetting.getVipDirectNum()){ // 直推城市合伙人数量大于等于指定数量 |
| | | List<Long> userIds = appUsers.stream().map(AppUser::getId).collect(Collectors.toList()); |
| | | long directStorePartnerCount = getDirectStorePartnerCount(userIds); |
| | | return directStorePartnerCount >= vipSetting.getVipDirectVipNum(); // 城市合伙人下的门店合伙人数量大于等于指定数量 |
| | | } |
| | | |
| | | } |
| | | }else if (vipSetting.getId() == VIP_ID_GLOBAL_PARTNER){ // 全球合伙人 |
| | | if (vipSetting.getVipLevelUpNumRole() == 1){ |
| | | |
| | | // 城市合伙人用户数阈值 |
| | | Integer vipDirectNum = vipSetting.getVipDirectNum(); |
| | | // 门店合伙人用户数阈值 |
| | | Integer vipDirectVipNum = vipSetting.getVipDirectVipNum(); |
| | | // 全国合伙人用户数阈值 |
| | | Integer vipTeamVipNum = vipSetting.getVipTeamVipNum(); |
| | | // 开店数量阈值 |
| | | Integer vipOpenShopNum = vipSetting.getVipOpenShopNum(); |
| | | |
| | | |
| | | // 1.直推用户达到指定数量会员等级最低为城市合伙人 |
| | | List<AppUser> appUsers = appUserService.list(new LambdaQueryWrapper<AppUser>() |
| | | .eq(AppUser::getInviteUserId, appUser.getId()) |
| | | .ge(AppUser::getVipId, VIP_ID_CITY_PARTNER) |
| | | .eq(AppUser::getDelFlag, 0)); |
| | | |
| | | |
| | | if (appUsers.size() >= vipDirectNum ){ |
| | | // 2.城市合伙人下的门店合伙人数量达到指定人数 |
| | | List<Long> userIds = appUsers.stream().map(AppUser::getId).collect(Collectors.toList()); |
| | | long directStorePartnerCount = getDirectStorePartnerCount(userIds); |
| | | if (directStorePartnerCount >= vipDirectVipNum){ |
| | | |
| | | // 3.直推用户达到指定数量会员等级最低为全国合伙人并且已经开了指定门店数量 |
| | | List<AppUser> appUsers2 = appUserService.list(new LambdaQueryWrapper<AppUser>() |
| | | .eq(AppUser::getInviteUserId, appUser.getId()) |
| | | .ge(AppUser::getVipId, VIP_ID_NATIONAL_PARTNER) |
| | | .eq(AppUser::getDelFlag, 0)); |
| | | return appUsers2.size() >= vipTeamVipNum && appUsers2.size() >= vipOpenShopNum; |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean checkReadyToBeAgent(Long userId) { |
| | | return false; |
| | | /** |
| | | * 获取指定用户直推钻石会员的数量 |
| | | */ |
| | | public long getDirectDiamondUserCount(Long userId) { |
| | | AppUser appUser = appUserService.getById(userId); |
| | | if (appUser == null) { |
| | | return 0; |
| | | } |
| | | return appUserService.count(new LambdaQueryWrapper<AppUser>() |
| | | .eq(AppUser::getInviteUserId, appUser.getId()) |
| | | .eq(AppUser::getVipId, VIP_ID_DIAMOND)); |
| | | } |
| | | |
| | | @Override |
| | | public Boolean checkReadyToBeTotalAgent(Long userId) { |
| | | return false; |
| | | /** |
| | | * 获取指定用户下级门店合伙人的数量 |
| | | */ |
| | | public long getDirectStorePartnerCount(List<Long> userIds) { |
| | | List<AppUser> allSubordinates = getAllSubordinates(userIds); |
| | | return allSubordinates.stream() |
| | | .filter(appUser -> appUser.getVipId().equals(VIP_ID_STORE_PARTNER)) |
| | | .count(); |
| | | } |
| | | |
| | | @Override |
| | | public Boolean checkReadyToBePartner(Long userId) { |
| | | return false; |
| | | public List<AppUser> getAllSubordinates(List<Long> userIds) { |
| | | List<AppUser> allSubordinates = new ArrayList<>(); |
| | | Set<Long> processedUsers = new HashSet<>(); // 用于避免重复添加用户 |
| | | |
| | | // 遍历每个用户ID |
| | | for (Long userId : userIds) { |
| | | collectSubordinates(userId, allSubordinates, processedUsers); |
| | | } |
| | | |
| | | return allSubordinates; |
| | | } |
| | | |
| | | private void collectSubordinates(Long userId, List<AppUser> allSubordinates, Set<Long> processedUsers) { |
| | | if (processedUsers.contains(userId)) { |
| | | // 如果已经处理过该用户,则跳过,防止循环引用导致的无限递归 |
| | | return; |
| | | } |
| | | processedUsers.add(userId); |
| | | |
| | | List<AppUser> directChildren = appUserService.list(new LambdaQueryWrapper<AppUser>() |
| | | .eq(AppUser::getInviteUserId, userId)); |
| | | |
| | | for (AppUser child : directChildren) { |
| | | if (!allSubordinates.contains(child)) { // 确保不添加重复的用户 |
| | | allSubordinates.add(child); // 添加直接下级 |
| | | } |
| | | collectSubordinates(child.getId(), allSubordinates, processedUsers); // 递归添加间接下级 |
| | | } |
| | | } |
| | | |
| | | public Boolean checkEligibility(Integer type) { |
| | | LoginUser loginUser = tokenService.getLoginUserApplet(); |
| | | Long userId = loginUser.getUserid(); |
| | | |
| | | switch (type) { |
| | | case VIP_ID_STORE_PARTNER: |
| | | return isEligibleForStorePartner(userId, type); |
| | | case VIP_ID_CITY_PARTNER: |
| | | return isEligibleForCityPartner(userId); |
| | | case VIP_ID_NATIONAL_PARTNER: |
| | | return isEligibleForNationalPartner(userId); |
| | | case VIP_ID_GLOBAL_PARTNER: |
| | | return isEligibleForGlobalPartner(userId); |
| | | default: |
| | | throw new ServiceException("参数错误"); |
| | | } |
| | | } |
| | | } |