From fb6eee80334ae23a2eca8c37baeef05e86c919ed Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期二, 10 十二月 2024 17:09:00 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java                              |    1 
 ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports   |    3 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/weChat/WeChatUtil.java                                         |   88 ++++++---
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/AppUserServiceImpl.java                                |  156 +++++++++++++++++
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/UserChangeLogFallbackFactory.java                       |   23 ++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/VipSettingController.java                                    |   11 +
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/TaskUtil.java                                                  |   16 +
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/UserChangeLogClient.java                            |   26 ++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/weChat/EnvVersion.java                                         |   35 +++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserChangeLogController.java                             |   25 ++
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/VipSettingClient.java                                   |   26 ++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java                               |   79 ++++++++
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/VipSettingClientFallbackFactory.java                        |   23 ++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/RefundPassController.java                                    |    2 
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/AppUser.java                                              |    4 
 ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports |    3 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/AppUserService.java                                         |    6 
 17 files changed, 480 insertions(+), 47 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/UserChangeLogFallbackFactory.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/UserChangeLogFallbackFactory.java
new file mode 100644
index 0000000..947c9f9
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/UserChangeLogFallbackFactory.java
@@ -0,0 +1,23 @@
+package com.ruoyi.account.api.factory;
+
+import com.ruoyi.account.api.feignClient.UserChangeLogClient;
+import com.ruoyi.account.api.model.UserChangeLog;
+import com.ruoyi.common.core.domain.R;
+import org.springframework.cloud.openfeign.FallbackFactory;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/10 15:01
+ */
+public class UserChangeLogFallbackFactory implements FallbackFactory<UserChangeLogClient> {
+	@Override
+	public UserChangeLogClient create(Throwable cause) {
+		return new UserChangeLogClient(){
+			
+			@Override
+			public R saveUserChangeLog(UserChangeLog userChangeLog) {
+				return R.fail("保存会员等级变更记录失败:" + cause.getMessage());
+			}
+		};
+	}
+}
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/UserChangeLogClient.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/UserChangeLogClient.java
new file mode 100644
index 0000000..ebce10f
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/UserChangeLogClient.java
@@ -0,0 +1,26 @@
+package com.ruoyi.account.api.feignClient;
+
+import com.ruoyi.account.api.factory.UserChangeLogFallbackFactory;
+import com.ruoyi.account.api.model.UserChangeLog;
+import com.ruoyi.common.core.constant.ServiceNameConstants;
+import com.ruoyi.common.core.domain.R;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/10 15:01
+ */
+@FeignClient(contextId = "UserChangeLogClient", value = ServiceNameConstants.ACCOUNT_SERVICE, fallbackFactory = UserChangeLogFallbackFactory.class)
+public interface UserChangeLogClient {
+	
+	
+	/**
+	 * 保存会员等级变更记录
+	 * @param userChangeLog
+	 * @return
+	 */
+	@PostMapping("/user-change-log/saveUserChangeLog")
+	R saveUserChangeLog(@RequestBody UserChangeLog userChangeLog);
+}
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/AppUser.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/AppUser.java
index 9d92ba2..c251413 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/AppUser.java
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/AppUser.java
@@ -167,6 +167,10 @@
     @TableField("lave_point")
     private Integer lavePoint;
     
+    @ApiModelProperty(value = "总积分")
+    @TableField("total_point")
+    private Integer totalPoint;
+    
     @ApiModelProperty(value = "是否可更换推广人(0=否,1=是)")
     @TableField("change_promoter")
     private Integer changePromoter;
diff --git a/ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 3261002..781adb8 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -2,4 +2,5 @@
 com.ruoyi.account.api.factory.UserAddressClientFallbackFactory
 com.ruoyi.account.api.factory.UserCouponClientFallbackFactory
 com.ruoyi.account.api.factory.UserPointFallbackFactory
-com.ruoyi.account.api.factory.BalanceChangeRecordClientFallbackFactory
\ No newline at end of file
+com.ruoyi.account.api.factory.BalanceChangeRecordClientFallbackFactory
+com.ruoyi.account.api.factory.UserChangeLogFallbackFactory
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/VipSettingClientFallbackFactory.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/VipSettingClientFallbackFactory.java
new file mode 100644
index 0000000..7c6872b
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/VipSettingClientFallbackFactory.java
@@ -0,0 +1,23 @@
+package com.ruoyi.other.api.factory;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.other.api.domain.VipSetting;
+import com.ruoyi.other.api.feignClient.VipSettingClient;
+import org.springframework.cloud.openfeign.FallbackFactory;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/10 13:53
+ */
+public class VipSettingClientFallbackFactory implements FallbackFactory<VipSettingClient> {
+	@Override
+	public VipSettingClient create(Throwable cause) {
+		return new VipSettingClient(){
+			
+			@Override
+			public R<VipSetting> getVipSetting(Integer id) {
+				return R.fail("查询会员配置失败:" + cause.getMessage());
+			}
+		};
+	}
+}
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/VipSettingClient.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/VipSettingClient.java
new file mode 100644
index 0000000..aafc0ff
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/VipSettingClient.java
@@ -0,0 +1,26 @@
+package com.ruoyi.other.api.feignClient;
+
+import com.ruoyi.common.core.constant.ServiceNameConstants;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.other.api.domain.VipSetting;
+import com.ruoyi.other.api.factory.VipSettingClientFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/10 13:52
+ */
+@FeignClient(contextId = "VipSettingClient", value = ServiceNameConstants.OTHER_SERVICE, fallbackFactory = VipSettingClientFallbackFactory.class)
+public interface VipSettingClient {
+	
+	
+	/**
+	 * 查询会员配置
+	 * @param id
+	 * @return
+	 */
+	@PostMapping("/vip-setting/getVipSetting")
+	R<VipSetting> getVipSetting(@RequestParam("id") Integer id);
+}
diff --git a/ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 0105e63..5f05c42 100644
--- a/ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -14,4 +14,5 @@
 com.ruoyi.other.api.factory.CouponClientFallbackFactory
 com.ruoyi.other.api.factory.TechnicianClientFallbackFactory
 com.ruoyi.other.api.factory.PointSettingClientFallbackFactory
-com.ruoyi.other.api.factory.VipGoodClientFallbackFactory
\ No newline at end of file
+com.ruoyi.other.api.factory.VipGoodClientFallbackFactory
+com.ruoyi.other.api.factory.VipSettingClientFallbackFactory
\ No newline at end of file
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserChangeLogController.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserChangeLogController.java
index 068f6a3..3cd25ba 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserChangeLogController.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserChangeLogController.java
@@ -1,8 +1,15 @@
 package com.ruoyi.account.controller;
 
 
+import com.ruoyi.account.api.model.UserChangeLog;
+import com.ruoyi.account.service.UserChangeLogService;
+import com.ruoyi.common.core.domain.R;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
 
 /**
  * <p>
@@ -15,6 +22,24 @@
 @RestController
 @RequestMapping("/user-change-log")
 public class UserChangeLogController {
+	
+	@Resource
+	private UserChangeLogService userChangeLogService;
+	
+	
+	/**
+	 * 保存会员等级变更记录
+	 * @param userChangeLog
+	 * @return
+	 */
+	@PostMapping("/saveUserChangeLog")
+	public R saveUserChangeLog(@RequestBody UserChangeLog userChangeLog){
+		userChangeLogService.save(userChangeLog);
+		return R.ok();
+	}
+	
+	
+	
 
 }
 
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/AppUserService.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/AppUserService.java
index a51d268..f5a5335 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/AppUserService.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/AppUserService.java
@@ -67,4 +67,10 @@
 	 * 获取指定用户的直帮上级用户(消费用户绑定的上级,最近一个用户会员类型为【创业者】的用户)
 	 */
 	AppUser getSuperiorLeader(Long id);
+	
+	
+	/**
+	 * 解绑推广人
+	 */
+	void unbindThePromoter();
 }
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/AppUserServiceImpl.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/AppUserServiceImpl.java
index b9b1ac1..0d4ac5c 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/AppUserServiceImpl.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/AppUserServiceImpl.java
@@ -5,10 +5,13 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.account.api.model.AppUserShop;
+import com.ruoyi.account.api.model.UserChangeLog;
 import com.ruoyi.account.mapper.AppUserMapper;
 import com.ruoyi.account.api.model.AppUser;
 import com.ruoyi.account.service.AppUserService;
 import com.ruoyi.account.service.AppUserShopService;
+import com.ruoyi.account.service.UserChangeLogService;
+import com.ruoyi.account.util.weChat.EnvVersion;
 import com.ruoyi.account.util.weChat.WXCore;
 import com.ruoyi.account.util.weChat.WeChatUtil;
 import com.ruoyi.account.vo.*;
@@ -17,16 +20,23 @@
 import com.ruoyi.common.redis.service.RedisService;
 import com.ruoyi.common.security.service.TokenService;
 import com.ruoyi.other.api.domain.Shop;
+import com.ruoyi.other.api.domain.VipSetting;
 import com.ruoyi.other.api.feignClient.ShopClient;
+import com.ruoyi.other.api.feignClient.VipSettingClient;
 import com.ruoyi.system.api.domain.SysUser;
 import com.ruoyi.system.api.feignClient.SysUserClient;
 import com.ruoyi.system.api.model.LoginUser;
+import org.apache.logging.log4j.core.util.UuidUtil;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation.ANONYMOUS.optional;
 
 /**
  * <p>
@@ -56,6 +66,18 @@
 	
 	@Resource
 	private SysUserClient sysUserClient;
+	
+	@Resource
+	private VipSettingClient vipSettingClient;
+	
+	@Resource
+	private UserChangeLogService userChangeLogService;
+	
+	@Value("${file.upload.location}")
+	private String filePath;
+	
+	@Value("${file.upload.accessPath}")
+	private String accessPath;
 	
 	
 	
@@ -107,6 +129,9 @@
 		Map<String, Object> tokenApplet = tokenService.createTokenApplet(loginUser);
 		loginVo.setToken(tokenApplet.get("access_token").toString());
 		loginVo.setFailureTime(Long.valueOf(tokenApplet.get("expires_in").toString()));
+		
+		appUser.setLastLoginTime(LocalDateTime.now());
+		this.updateById(appUser);
 		return R.ok(loginVo);
 	}
 	
@@ -147,6 +172,9 @@
 		Map<String, Object> tokenApplet = tokenService.createTokenApplet(loginUser);
 		loginVo.setToken(tokenApplet.get("access_token").toString());
 			loginVo.setFailureTime(Long.valueOf(tokenApplet.get("expires_in").toString()));
+		
+		appUser.setLastLoginTime(LocalDateTime.now());
+		this.updateById(appUser);
 		return R.ok(loginVo);
 	}
 	
@@ -259,6 +287,7 @@
 			appUser.setTotalDistributionAmount(BigDecimal.ZERO);
 			appUser.setBalance(BigDecimal.ZERO);
 			appUser.setLavePoint(0);
+			appUser.setTotalPoint(0);
 			//根据平台的配置未达标,则标注为可修改推广人
 			appUser.setChangePromoter(0);
 			appUser.setLongitude(registerAccount.getLongitude());
@@ -271,6 +300,15 @@
 //			appUser.setDistrict();
 //			appUser.setDistrictCode();
 			this.save(appUser);
+			//获取微信推广二维码
+			String fileName = UUID.randomUUID() + ".jpg";
+			weChatUtil.getwxacodeunlimit("pages/login/login", "id=" + appUser.getId(), EnvVersion.DEVELOP, filePath + fileName);
+			appUser.setQrCode(accessPath + fileName);
+			this.updateById(appUser);
+			//直推用户检查是否满足升级条件
+			if(null != appUser.getInviteUserId()){
+				vipUpgrade(appUser.getInviteUserId());
+			}
 			
 			//查询当前注册的手机号是都和门店管理员手机号相同
 			Shop shop = shopClient.getShopByPhone(registerAccount.getPhone()).getData();
@@ -314,6 +352,67 @@
 	
 	
 	/**
+	 * 会员等级变化
+	 */
+	public void vipUpgrade(Long id){
+		AppUser appUser = this.getById(id);
+		Integer vipId = appUser.getVipId();
+		//钻石会员
+		VipSetting vipSetting3 = vipSettingClient.getVipSetting(3).getData();
+		Integer vipLevelUpNumRole = vipSetting3.getVipLevelUpNumRole();
+		Integer vipDirectNum = vipSetting3.getVipDirectNum();
+		Integer vipTeamNum = vipSetting3.getVipTeamNum();
+		if(1 == vipLevelUpNumRole && appUser.getVipId() < 3){
+			//查询直推用户达到X人或者团队人数达到X人后,可升级
+			//直推用户数
+			long count = this.count(new LambdaQueryWrapper<AppUser>().eq(AppUser::getDelFlag, 0).eq(AppUser::getStatus, 1).eq(AppUser::getInviteUserId, id));
+			//团队用户数
+			List<AppUser> subordinate = getSubordinate(id);
+			if(vipDirectNum <= count || vipTeamNum <= subordinate.size()){
+				appUser.setVipId(3);
+				this.updateById(appUser);
+				//添加等级变化记录
+				UserChangeLog userChangeLog = new UserChangeLog();
+				userChangeLog.setDelFlag(0);
+				userChangeLog.setCreateTime(LocalDateTime.now());
+				userChangeLog.setAppUserId(appUser.getId());
+				userChangeLog.setBeforeVipId(vipId);
+				userChangeLog.setAfterVipId(appUser.getVipId());
+				userChangeLog.setChangeType(1);
+				userChangeLogService.save(userChangeLog);
+				return;
+			}
+		}
+		//黄金会员
+		VipSetting vipSetting2 = vipSettingClient.getVipSetting(2).getData();
+		vipLevelUpNumRole = vipSetting2.getVipLevelUpNumRole();
+		vipDirectNum = vipSetting2.getVipDirectNum();
+		vipTeamNum = vipSetting2.getVipTeamNum();
+		if(1 == vipLevelUpNumRole && appUser.getVipId() < 2){
+			//查询直推用户达到X人或者团队人数达到X人后,可升级
+			//直推用户数
+			long count = this.count(new LambdaQueryWrapper<AppUser>().eq(AppUser::getDelFlag, 0).eq(AppUser::getStatus, 1).eq(AppUser::getInviteUserId, id));
+			//团队用户数
+			List<AppUser> subordinate = getSubordinate(id);
+			if(vipDirectNum <= count || vipTeamNum <= subordinate.size()){
+				appUser.setVipId(2);
+				this.updateById(appUser);
+				//添加等级变化记录
+				UserChangeLog userChangeLog = new UserChangeLog();
+				userChangeLog.setDelFlag(0);
+				userChangeLog.setCreateTime(LocalDateTime.now());
+				userChangeLog.setAppUserId(appUser.getId());
+				userChangeLog.setBeforeVipId(vipId);
+				userChangeLog.setAfterVipId(appUser.getVipId());
+				userChangeLog.setChangeType(1);
+				userChangeLogService.save(userChangeLog);
+			}
+		}
+	}
+	
+	
+	
+	/**
 	 * 递归查询顶级推广人
 	 * @param id
 	 * @return
@@ -330,6 +429,36 @@
 		}
 		return getTopAppUser(list, appUser.getInviteUserId());
 	}
+	
+	/**
+	 * 获取所有下级数据
+	 * @param id
+	 * @return
+	 */
+	public List<AppUser> getSubordinate(Long id){
+		List<AppUser> list = this.list(new LambdaQueryWrapper<AppUser>().eq(AppUser::getDelFlag, 0));
+		List<AppUser> result = new ArrayList<>();
+		List<Long> ids = new ArrayList<>();
+		ids.add(id);
+		return getSubordinate(list, ids, result);
+	}
+	
+	public List<AppUser> getSubordinate(List<AppUser> list, List<Long> ids, List<AppUser> result){
+		List<Long> idss = new ArrayList<>();
+		for (Long id : ids) {
+			List<AppUser> collect = list.stream().filter(s -> s.getInviteUserId().equals(id)).collect(Collectors.toList());
+			if(collect.size() == 0){
+				return result;
+			}else{
+				result.addAll(collect);
+				List<Long> collect1 = collect.stream().map(AppUser::getId).collect(Collectors.toList());
+				idss.addAll(collect1);
+			}
+		}
+		return getSubordinate(list, idss, result);
+	}
+	
+	
 	
 	
 	/**
@@ -395,4 +524,31 @@
 		}
 		return null;
 	}
+	
+	
+	/**
+	 * 定时解绑推广人
+	 */
+	@Override
+	public void unbindThePromoter() {
+		//注册X天后没有升级成黄金会员则自动解绑推广人
+		VipSetting vipSetting = vipSettingClient.getVipSetting(1).getData();
+		Integer vipCancelDay = vipSetting.getVipCancelDay();
+		Integer vipChangeDay = vipSetting.getVipChangeDay();
+		List<AppUser> list = this.list(new LambdaQueryWrapper<AppUser>().eq(AppUser::getVipId, 1).eq(AppUser::getDelFlag, 0).isNotNull(AppUser::getInviteUserId)
+				.eq(AppUser::getStatus, 1).last(" and (UNIX_TIMESTAMP(create_time) + " + vipCancelDay + ") <= UNIX_TIMESTAMP()"));
+		for (AppUser appUser : list) {
+			appUser.setInviteUserId(null);
+			appUser.setShopId(null);
+			this.updateById(appUser);
+		}
+		
+		//可更换推广人
+		list = this.list(new LambdaQueryWrapper<AppUser>().eq(AppUser::getVipId, 1).eq(AppUser::getDelFlag, 0).eq(AppUser::getChangePromoter, 0)
+				.isNull(AppUser::getLastShopTime).eq(AppUser::getStatus, 1).last(" and (UNIX_TIMESTAMP(create_time) + " + vipCancelDay + ") <= UNIX_TIMESTAMP()"));
+		for (AppUser appUser : list) {
+			appUser.setChangePromoter(1);
+			this.updateById(appUser);
+		}
+	}
 }
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java
index 3775d83..922bf81 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java
@@ -149,6 +149,7 @@
         }
 
         appUserForPhoe.setLavePoint(appUserForPhoe.getLavePoint() + point.intValue());
+        appUserForPhoe.setTotalPoint(appUserForPhoe.getTotalPoint() + point.intValue());
         appUserService.updateById(appUserForPhoe);
 
         log.info("积分转赠完成,用户ID: {}, 新积分: {}", appUserForPhoe.getId(), appUserForPhoe.getLavePoint());
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/TaskUtil.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/TaskUtil.java
index 7f028bc..b57e53f 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/TaskUtil.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/TaskUtil.java
@@ -1,9 +1,11 @@
 package com.ruoyi.account.util;
 
 
+import com.ruoyi.account.service.AppUserService;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.Resource;
 
 
 /**
@@ -11,6 +13,11 @@
  */
 @Component
 public class TaskUtil {
+    
+    @Resource
+    private AppUserService appUserService;
+    
+    
 
 
     /**
@@ -18,13 +25,8 @@
      */
     @Scheduled(fixedRate = 1000 * 60)
     public void sendVipCoupon(){
-    
-    }
-
-    @Scheduled(fixedRate = 1000 * 60)
-    public void changeVipId(){
-    
-
+        //解绑推广人
+        appUserService.unbindThePromoter();
     }
 
 
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/weChat/EnvVersion.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/weChat/EnvVersion.java
new file mode 100644
index 0000000..e47f81b
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/weChat/EnvVersion.java
@@ -0,0 +1,35 @@
+package com.ruoyi.account.util.weChat;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/10 15:56
+ */
+public enum EnvVersion {
+	/**
+	 * 开发版
+	 */
+	DEVELOP("develop"),
+	/**
+	 * 体验版
+	 */
+	TRIAL("trial"),
+	/**
+	 * 线上版本
+	 */
+	RELEASE("release");
+	
+	
+	EnvVersion(String version) {
+		this.version = version;
+	}
+	
+	private String version;
+	
+	public String getVersion() {
+		return version;
+	}
+	
+	public void setVersion(String version) {
+		this.version = version;
+	}
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/weChat/WeChatUtil.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/weChat/WeChatUtil.java
index 34adfb8..caa7cce 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/weChat/WeChatUtil.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/weChat/WeChatUtil.java
@@ -1,5 +1,7 @@
 package com.ruoyi.account.util.weChat;
 
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.http.Header;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpUtil;
@@ -7,10 +9,20 @@
 import com.alibaba.fastjson.JSONObject;
 import com.ruoyi.common.redis.service.RedisService;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.HttpHeaders;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
 
 import javax.annotation.Resource;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
@@ -186,35 +198,49 @@
     
 
 
-//    /**
-//     * 获取小程序二维码
-//     * @param page      跳转页 例如 pages/index/index
-//     * @param scene     参数 a=1&b=2
-//     */
-//    public InputStream getwxacodeunlimit(String page, String scene){
-//        try {
-//            String token = getWxAppletsAccessToken();
-//            if(StringUtils.isEmpty(token)){
-//                System.err.println("获取接口调用凭证失败");
-//            }
-//            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token;
-//            Map<String, Object> param = new HashMap<>();
-//            param.put("scene", scene);
-//            param.put("page", page);
-//            HttpHeaders httpHeaders = new HttpHeaders();
-//            MediaType type=MediaType.parseMediaType("application/json;charset=UTF-8");
-//            httpHeaders.setContentType(type);
-//            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(param, httpHeaders);
-//            ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class, new Object[0]);
-//            String body1 = exchange.getBody();
-////            System.err.println(body1);
-//            ResponseEntity<byte[]> entity  = restTemplate.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
-//            byte[] body = entity.getBody();
-////            System.err.println(Base64.encodeBase64String(body));
-//            return new ByteArrayInputStream(body);
-//        }catch (Exception e){
-//            e.printStackTrace();
-//        }
-//        return null;
-//    }
+    /**
+     * 获取小程序二维码
+     * @param page      跳转页 例如 pages/index/index
+     * @param scene     参数 a=1&b=2
+     */
+    public InputStream getwxacodeunlimit(String page, String scene, EnvVersion env_version){
+        try {
+            String token = getWxAppletsAccessToken();
+            if(StringUtils.isEmpty(token)){
+                System.err.println("获取接口调用凭证失败");
+            }
+            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token;
+            Map<String, Object> param = new HashMap<>();
+            param.put("scene", scene);
+            param.put("page", page);
+            param.put("env_version", env_version.getVersion());
+    
+            HttpRequest post = HttpUtil.createPost(url);
+            post.header(Header.CONTENT_TYPE, "application/json;charset=UTF-8");
+            post.body(JSON.toJSONString(param));
+            HttpResponse execute = post.execute();
+            byte[] bytes = execute.bodyBytes();
+            String body1 = execute.body();
+            System.err.println(body1);
+            System.err.println(Base64.encodeBase64String(bytes));
+            return new ByteArrayInputStream(bytes);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+    
+    
+    /**
+     * 获取微信小程序二维码
+     * @param page
+     * @param scene
+     * @param filePath
+     * @return
+     */
+    public String getwxacodeunlimit(String page, String scene, EnvVersion env_version, String filePath){
+        InputStream getwxacodeunlimit = getwxacodeunlimit(page, scene, env_version);
+        File file = FileUtil.writeFromStream(getwxacodeunlimit, new File(filePath));
+        return file.getPath();
+    }
 }
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/RefundPassController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/RefundPassController.java
index 3938eb7..893ae60 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/RefundPassController.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/RefundPassController.java
@@ -85,7 +85,7 @@
 		if(Arrays.asList(2, 3).contains(refundPass.getStatus())){
 			return R.fail("售后取消失败");
 		}
-		refundPass.setDelFlag(1);
+//		refundPass.setDelFlag(1);
 		refundPassService.removeById(id);
 		order.setOrderStatus(4);
 		orderService.updateById(order);
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java
index d0dad92..d589c8d 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java
@@ -6,10 +6,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.account.api.feignClient.*;
-import com.ruoyi.account.api.model.AppUser;
-import com.ruoyi.account.api.model.BalanceChangeRecord;
-import com.ruoyi.account.api.model.UserAddress;
-import com.ruoyi.account.api.model.UserPoint;
+import com.ruoyi.account.api.model.*;
 import com.ruoyi.account.api.vo.CouponInfoVo;
 import com.ruoyi.account.api.vo.PaymentUserCoupon;
 import com.ruoyi.account.api.vo.PaymentUserCouponVo;
@@ -101,6 +98,12 @@
 	
 	@Resource
 	private CommissionService commissionService;
+	
+	@Resource
+	private VipSettingClient vipSettingClient;
+	
+	@Resource
+	private UserChangeLogClient userChangeLogClient;
 	
 	
 	
@@ -664,9 +667,14 @@
 		//积分支付的订单积分
 		Integer orderPoint = 0;
 		if(3 != shoppingCartPayment.getPaymentType()){
-			orderMoney = goodsList.stream().map(MyShoppingCartVo::getCash).reduce(BigDecimal::add).get();
+			for (MyShoppingCartVo myShoppingCartVo : goodsList) {
+				orderMoney = orderMoney.add(myShoppingCartVo.getCash().multiply(new BigDecimal(myShoppingCartVo.getNumber())));
+			}
 		}else{
 			orderPoint = goodsList.stream().mapToInt(MyShoppingCartVo::getPoint).sum();
+			for (MyShoppingCartVo myShoppingCartVo : goodsList) {
+				orderPoint += (myShoppingCartVo.getPoint() * myShoppingCartVo.getNumber());
+			}
 			if(appUser.getLavePoint().intValue() < orderPoint){
 				return R.fail("账户剩余积分不足");
 			}
@@ -768,7 +776,10 @@
 		}
 		
 		//可获得的消费积分
-		int earnPoint = goodsList.stream().mapToInt(MyShoppingCartVo::getEarnSpendingPoints).sum();
+		int earnPoint = 0;
+		for (MyShoppingCartVo myShoppingCartVo : goodsList) {
+			earnPoint += (myShoppingCartVo.getEarnSpendingPoints() * myShoppingCartVo.getNumber());
+		}
 		if(null != shoppingCartPayment.getUserAddressId()){
 			userAddressClient.getUserAddressById(shoppingCartPayment.getUserAddressId()).getData();
 		}
@@ -940,6 +951,7 @@
 			if(earnPoint > 0){
 				appUser.setShopPoint(appUser.getShopPoint() + earnPoint);
 				appUser.setLavePoint(appUser.getLavePoint() + earnPoint);
+				appUser.setTotalPoint(appUser.getTotalPoint() + earnPoint);
 				
 				UserPoint userPoint = new UserPoint();
 				userPoint.setType(1);
@@ -951,6 +963,8 @@
 				userPoint.setObjectId(order.getId());
 				userPointClient.saveUserPoint(userPoint);
 			}
+			appUser.setShopAmount(appUser.getShopAmount().add(paymentMoney).setScale(2, RoundingMode.HALF_EVEN));
+			appUser.setLastShopTime(LocalDateTime.now());
 			appUserClient.editAppUserById(appUser);
 			//构建余额明细变动记录
 			BalanceChangeRecord balanceChangeRecord = new BalanceChangeRecord();
@@ -968,6 +982,8 @@
 			orderService.updateById(order);
 			//删除购物车数据
 			this.removeBatchByIds(ids);
+			//检查消费积分满足后升级会员
+			vipUpgrade(appUser);
 		}
 		//积分支付
 		if(3 == shoppingCartPayment.getPaymentType()){
@@ -975,7 +991,13 @@
 			appUser.setLavePoint(lavePoint - orderPoint);
 			appUser.setShopPoint(appUser.getShopPoint() + earnPoint);
 			appUser.setLavePoint(appUser.getLavePoint() + earnPoint);
+			appUser.setTotalPoint(appUser.getTotalPoint() + earnPoint);
+			appUser.setShopAmount(appUser.getShopAmount().add(paymentMoney).setScale(2, RoundingMode.HALF_EVEN));
+			appUser.setLastShopTime(LocalDateTime.now());
 			appUserClient.editAppUserById(appUser);
+			//检查消费积分满足后升级会员
+			vipUpgrade(appUser);
+			
 			//构建积分流水记录
 			UserPoint userPoint = new UserPoint();
 			userPoint.setType(4);
@@ -1067,4 +1089,49 @@
 		}
 		return str;
 	}
+	
+	
+	/**
+	 * 会员等级变化
+	 * @param appUser
+	 */
+	public void vipUpgrade(AppUser appUser){
+		Integer shopPoint = appUser.getShopPoint();
+		Integer vipId = appUser.getVipId();
+		//钻石会员
+		VipSetting vipSetting3 = vipSettingClient.getVipSetting(3).getData();
+		Integer vipLevelUpShopRole = vipSetting3.getVipLevelUpShopRole();
+		Integer vipLevelUpShop = vipSetting3.getVipLevelUpShop();
+		if(1 == vipLevelUpShopRole && appUser.getVipId() < 3 && shopPoint >= vipLevelUpShop){
+			appUser.setVipId(3);
+			appUserClient.editAppUserById(appUser);
+			//添加等级变化记录
+			UserChangeLog userChangeLog = new UserChangeLog();
+			userChangeLog.setDelFlag(0);
+			userChangeLog.setCreateTime(LocalDateTime.now());
+			userChangeLog.setAppUserId(appUser.getId());
+			userChangeLog.setBeforeVipId(vipId);
+			userChangeLog.setAfterVipId(appUser.getVipId());
+			userChangeLog.setChangeType(1);
+			userChangeLogClient.saveUserChangeLog(userChangeLog);
+			return;
+		}
+		//黄金会员
+		VipSetting vipSetting2 = vipSettingClient.getVipSetting(2).getData();
+		vipLevelUpShopRole = vipSetting2.getVipLevelUpShopRole();
+		vipLevelUpShop = vipSetting2.getVipLevelUpShop();
+		if(1 == vipLevelUpShopRole && appUser.getVipId() < 2 && shopPoint >= vipLevelUpShop){
+			appUser.setVipId(2);
+			appUserClient.editAppUserById(appUser);
+			//添加等级变化记录
+			UserChangeLog userChangeLog = new UserChangeLog();
+			userChangeLog.setDelFlag(0);
+			userChangeLog.setCreateTime(LocalDateTime.now());
+			userChangeLog.setAppUserId(appUser.getId());
+			userChangeLog.setBeforeVipId(vipId);
+			userChangeLog.setAfterVipId(appUser.getVipId());
+			userChangeLog.setChangeType(1);
+			userChangeLogClient.saveUserChangeLog(userChangeLog);
+		}
+	}
 }
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/VipSettingController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/VipSettingController.java
index 733f887..ceb74b9 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/VipSettingController.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/VipSettingController.java
@@ -95,6 +95,17 @@
     public R<VipSetting> getVipSettingById(@ApiParam(value = "会员id") @RequestParam("id") Integer id) {
         return R.ok(vipSettingService.getById(id));
     }
+    
+    
+    /**
+     * 查询会员配置
+     * @param id
+     * @return
+     */
+    @PostMapping("/getVipSetting")
+    public R<VipSetting> getVipSetting(@RequestParam("id") Integer id) {
+        return R.ok(vipSettingService.getById(id));
+    }
 }
 
 

--
Gitblit v1.7.1