Browse Source

积分支付策略

LIDEXI 4 years ago
parent
commit
dd37dc416a
17 changed files with 1803 additions and 143 deletions
  1. 1 1
      src/main/java/org/springblade/common/enums/PayWay.java
  2. 27 0
      src/main/java/org/springblade/common/enums/PointPayTypeEnum.java
  3. 90 2
      src/main/java/org/springblade/modules/ldt/loginuser/controller/LoginUserController.java
  4. 4 0
      src/main/java/org/springblade/modules/ldt/loginuser/dto/PayDto.java
  5. 5 0
      src/main/java/org/springblade/modules/ldt/loginuser/service/ILoginUserService.java
  6. 178 137
      src/main/java/org/springblade/modules/ldt/loginuser/service/impl/LoginUserServiceImpl.java
  7. 74 0
      src/main/java/org/springblade/modules/ldt/member/utils/MemberUtil.java
  8. 14 0
      src/main/java/org/springblade/modules/payment/paystrategy/loginuser/IPayStrategy.java
  9. 200 0
      src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelEnoughStrategy.java
  10. 215 0
      src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelNoEnoughRareEnoughStrategy.java
  11. 199 0
      src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelNoEnoughRareNoEnoughStrategy.java
  12. 171 0
      src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelNoEnoughRareZeroStrategy.java
  13. 194 0
      src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelZeroRareEnoughStrategy.java
  14. 151 0
      src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelZeroRareNoEnoughStrategy.java
  15. 174 0
      src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelZeroRareZeroStrategy.java
  16. 103 0
      src/main/java/org/springblade/modules/payment/paystrategy/loginuser/util/PayUtil.java
  17. 3 3
      src/main/java/org/springblade/sms/service/impl/HuaweiSmsServiceImpl.java

+ 1 - 1
src/main/java/org/springblade/common/enums/PayWay.java

@@ -17,5 +17,5 @@ public enum  PayWay {
 	WECHAT("微信用户"),
 	ALIPAY("支付宝用户");
 
-	String name;
+	final String name;
 }

+ 27 - 0
src/main/java/org/springblade/common/enums/PointPayTypeEnum.java

@@ -0,0 +1,27 @@
+package org.springblade.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * Created By lidexi in 2021/8/19
+ **/
+@Getter
+@AllArgsConstructor
+public enum  PointPayTypeEnum {
+	CHANNEL_ENOUGN(1,"渠道积分足够支付"),
+
+	CHANNEL_ZERO_RARE_ZERO(2,"渠道积分为0,用户余额为0"),
+	CHANNEL_ZERO_RARE_ENOUGH(3,"渠道积分为0,用户余额够扣"),
+	CHANNEL_ZERO_RARE_NOENOUGH(4,"渠道积分为0,用户余额不够扣"),
+
+	CHANNEL_NOENOUGH_RARE_ZERO(5,"渠道积分不为0,用户余额为0"),
+	CHANNEL_NOENOUGH_RARE_ENOUGH(6,"渠道积分不为0,用户余额足够扣"),
+	CHANNEL_NOENOUGH_RARE_NOENOUGH(7,"渠道积分不为0,用户余额不够扣");
+
+
+
+	final Integer value;
+	final String name;
+
+}

+ 90 - 2
src/main/java/org/springblade/modules/ldt/loginuser/controller/LoginUserController.java

@@ -33,6 +33,7 @@ import org.springblade.common.cache.CacheNames;
 import org.springblade.common.constant.SystemConstant;
 import org.springblade.common.enums.OrderType;
 import org.springblade.common.enums.PayWay;
+import org.springblade.common.enums.PointPayTypeEnum;
 import org.springblade.common.utils.OtpUtils;
 import org.springblade.core.cache.utils.CacheUtil;
 import org.springblade.core.mp.support.Condition;
@@ -59,6 +60,7 @@ import org.springblade.modules.ldt.shop.entity.Shop;
 import org.springblade.modules.ldt.shop.service.IShopService;
 import org.springblade.modules.ldt.shopyingshou.entity.ShopYingshou;
 import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
+import org.springblade.modules.payment.paystrategy.loginuser.IPayStrategy;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -89,6 +91,13 @@ public class LoginUserController extends BladeController {
 
 	private final IShopService shopService;
 	private final IBillRecordService billRecordService;
+	private final IPayStrategy channelEnoughStrategy;
+	private final IPayStrategy channelNoEnoughRareEnoughStrategy;
+	private final IPayStrategy channelNoEnoughRareNoEnoughStrategy;
+	private final IPayStrategy channelNoEnoughRareZeroStrategy;
+	private final IPayStrategy channelZeroRareEnoughStrategy;
+	private final IPayStrategy channelZeroRareNoEnoughStrategy;
+	private final IPayStrategy channelZeroRareZeroStrategy;
 
 	private final static String USER_INFO = "userId:";
 	private final RedisTemplate<String, String> redisTemplate;
@@ -179,7 +188,7 @@ public class LoginUserController extends BladeController {
 	}
 
 	/**
-	 * 用户扫码支付生成预订单
+	 * 用户扫码支付生成预订单,调用之前先调用getPointPayType方法获取用户支付类型,判断用户积分是否够扣
 	 */
 	@PostMapping("/payBefore")
 	@ApiOperationSupport(order = 8)
@@ -210,6 +219,64 @@ public class LoginUserController extends BladeController {
 		return R.data(billRecord);
 	}
 
+	/**
+	 * 用户扫码支付生成预订单,调用之前先调用getPointPayType方法获取用户支付类型,判断用户积分是否够扣
+	 */
+	@PostMapping("/payBeforeNew")
+	@ApiOperationSupport(order = 8)
+	@ApiOperation(value = "用户扫码支付", notes = "传入loginUser")
+	public R<BillRecord> payBeforeNew(@RequestBody PayDto payDto) {
+		if (payDto.getSecret() != null) {
+			String id = OtpUtils.getIdFormCode(payDto.getSecret());
+			boolean validate = OtpUtils.validate(id, payDto.getSecret());
+			if (validate) {
+
+			} else {
+//				Assert.isTrue(false,"用户授权无效");
+			}
+			payDto.setLoginUserId(Long.valueOf(id));
+
+		}
+		Assert.notNull(payDto.getPointPayType(),"积分支付类型未获取");
+		Assert.notNull(payDto.getLoginUserId(), "用户信息不能为空");
+		Assert.notNull(payDto.getMoney(), "商品价格不能为空");
+		Assert.notNull(payDto.getShopId(), "商店信息不能为空");
+		Shop shop = shopService.getById(payDto.getShopId());
+		Assert.notNull(shop, "商店信息不存在");
+		LoginUser loginUser = loginUserService.getById(payDto.getLoginUserId());
+		Assert.notNull(loginUser, "用户信息不存在");
+
+		BillRecord billRecord = null;
+
+		switch (payDto.getPointPayType()){
+			case CHANNEL_ENOUGN://渠道积分足够支付
+				billRecord = channelEnoughStrategy.payBefore(payDto,loginUser,shop);
+				break;
+			case CHANNEL_ZERO_RARE_ZERO://渠道积分为0,用户余额为0
+				billRecord = channelZeroRareZeroStrategy.payBefore(payDto,loginUser,shop);
+				break;
+			case CHANNEL_ZERO_RARE_NOENOUGH://渠道积分为0,用户余额不够扣
+				billRecord = channelZeroRareNoEnoughStrategy.payBefore(payDto,loginUser,shop);
+				break;
+			case CHANNEL_ZERO_RARE_ENOUGH://渠道积分为0,用户余额够扣
+				billRecord = channelZeroRareEnoughStrategy.payBefore(payDto,loginUser,shop);
+				break;
+			case CHANNEL_NOENOUGH_RARE_ZERO://渠道积分不为0,用户余额为0
+				billRecord = channelNoEnoughRareZeroStrategy.payBefore(payDto,loginUser,shop);
+				break;
+			case CHANNEL_NOENOUGH_RARE_NOENOUGH://渠道积分不为0,用户余额不够扣
+				billRecord = channelNoEnoughRareNoEnoughStrategy.payBefore(payDto,loginUser,shop);
+				break;
+			case CHANNEL_NOENOUGH_RARE_ENOUGH://渠道积分不为0,用户余额足够扣
+				billRecord = channelNoEnoughRareEnoughStrategy.payBefore(payDto,loginUser,shop);
+				break;
+		}
+		if (payDto.getType() != null && 2 == payDto.getType() &&billRecord != null) {//商户扫用户付款码需要存缓存
+			redisTemplate.opsForValue().set(CacheNames.SHOPSCANUSER + "::" + USER_INFO + payDto.getLoginUserId(), JSON.toJSONString(billRecord), 5, TimeUnit.MINUTES);
+		}
+		return R.data(billRecord);
+	}
+
 	/**
 	 * 非平台用户扫码支付生成预订单-直接用微信原生的扫一扫支付,没有userId
 	 */
@@ -246,7 +313,7 @@ public class LoginUserController extends BladeController {
 	@GetMapping("/getBillrecordFromRedis")
 	@ApiOperationSupport(order = 8)
 	@ApiOperation(value = "用户扫码支付", notes = "传入loginUser")
-	public R<BillRecord> payBefore(BillRecord billRecord) {
+	public R<BillRecord> getBillrecordFromRedis(BillRecord billRecord) {
 		String s = redisTemplate.opsForValue().get(CacheNames.SHOPSCANUSER + "::" + USER_INFO + billRecord.getUserId());
 		if (s != null) {
 			JSONObject billRecord1 = JSON.parseObject(s);
@@ -256,6 +323,27 @@ public class LoginUserController extends BladeController {
 		return R.data(null);
 	}
 
+	/**
+	 * 用户点击支付如果积分足够支付,则提示用户是否使用积分支付
+	 */
+	@GetMapping("/getPointPayType")
+	@ApiOperationSupport(order = 8)
+	@ApiOperation(value = "getPointPayType", notes = "payDto")
+	public R getPointPayType(@RequestBody PayDto payDto) {
+		Assert.notNull(payDto.getLoginUserId(), "用户信息不能为空");
+		Assert.notNull(payDto.getMoney(), "商品价格不能为空");
+		Assert.notNull(payDto.getShopId(), "商店信息不能为空");
+		Shop shop = shopService.getById(payDto.getShopId());
+		Assert.notNull(shop, "商店信息不存在");
+		Assert.isFalse(shop.getIsOpenMember() == 0,"该商店未开启会员中心");
+		Assert.isFalse(shop.getPoint().compareTo(BigDecimal.ZERO)==0,"该商户会员中心的积分数不能为0");
+		LoginUser loginUser = loginUserService.getById(payDto.getLoginUserId());
+		Assert.notNull(loginUser, "用户信息不存在");
+
+		return R.data(this.loginUserService.getPointPayType(payDto,shop,loginUser));
+	}
+
+
 	/**
 	 * 清除缓存
 	 */

+ 4 - 0
src/main/java/org/springblade/modules/ldt/loginuser/dto/PayDto.java

@@ -2,6 +2,7 @@ package org.springblade.modules.ldt.loginuser.dto;
 
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import org.springblade.common.enums.PointPayTypeEnum;
 
 import java.math.BigDecimal;
 import java.util.Date;
@@ -40,4 +41,7 @@ public class PayDto {
 	@ApiModelProperty("type: 1-用户扫商户收款码支付  2-商户扫用户付款码支付")
 	private Integer type;
 
+	@ApiModelProperty("积分支付类型,由loginuserController.getPointPayType获取")
+	private PointPayTypeEnum pointPayType;
+
 }

+ 5 - 0
src/main/java/org/springblade/modules/ldt/loginuser/service/ILoginUserService.java

@@ -16,6 +16,8 @@
  */
 package org.springblade.modules.ldt.loginuser.service;
 
+import org.springblade.common.enums.PointPayTypeEnum;
+import org.springblade.core.tool.api.R;
 import org.springblade.modules.ldt.billrecord.entity.BillRecord;
 import org.springblade.modules.ldt.loginuser.dto.LoginUserDTO;
 import org.springblade.modules.ldt.loginuser.dto.PayDto;
@@ -50,4 +52,7 @@ public interface ILoginUserService extends BaseService<LoginUser> {
 	LoginUser login(LoginUserDTO loginUserDTO);
 
     BillRecord payBefore(LoginUser loginUser,Shop shop, PayDto payDto);
+
+	PointPayTypeEnum getPointPayType(PayDto payDto, Shop shop, LoginUser loginUser);
+
 }

+ 178 - 137
src/main/java/org/springblade/modules/ldt/loginuser/service/impl/LoginUserServiceImpl.java

@@ -26,6 +26,7 @@ import org.springblade.common.constant.SystemConstant;
 import org.springblade.common.enums.OrderType;
 import org.springblade.common.enums.PayWay;
 import org.springblade.common.enums.PaymentType;
+import org.springblade.common.enums.PointPayTypeEnum;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.DigestUtil;
@@ -49,12 +50,15 @@ import org.springblade.modules.ldt.mall.service.IMallService;
 import org.springblade.modules.ldt.mallarea.service.IMallAreaService;
 import org.springblade.modules.ldt.member.entity.Member;
 import org.springblade.modules.ldt.member.service.IMemberService;
+import org.springblade.modules.ldt.member.utils.MemberUtil;
 import org.springblade.modules.ldt.pointdetail.entity.PointDetail;
 import org.springblade.modules.ldt.pointdetail.service.IPointDetailService;
 import org.springblade.modules.ldt.shop.entity.Shop;
 import org.springblade.modules.ldt.shop.service.IShopService;
 import org.springblade.modules.ldt.shopyingshou.entity.ShopYingshou;
 import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
+import org.springblade.modules.payment.paystrategy.loginuser.IPayStrategy;
+import org.springblade.modules.payment.paystrategy.loginuser.util.PayUtil;
 import org.springblade.modules.system.service.IParamService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -104,6 +108,7 @@ public class LoginUserServiceImpl extends BaseServiceImpl<LoginUserMapper, Login
 
 
 
+
 	@Override
 	public IPage<LoginUserVO> selectLoginUserPage(IPage<LoginUserVO> page, LoginUserVO loginUser) {
 		return page.setRecords(baseMapper.selectLoginUserPage(page, loginUser));
@@ -144,7 +149,8 @@ public class LoginUserServiceImpl extends BaseServiceImpl<LoginUserMapper, Login
 
 		BigDecimal gxServerRate =BigDecimal.valueOf(0); //国信活动服务费
 		BigDecimal scoreServerRate = BigDecimal.valueOf(Double.valueOf(paramService.getValue(CommonConstant.SCORE_SERVIVE_RATE)));//积分服务费
-		Map<String,Member> memberMap = this.getMembers(shop,payDto);
+		Map<String,Member> memberMap = MemberUtil.getMembers(shop,loginUser.getId(),memberService,shopService,mallService);
+
 		Member shopMember = memberMap.get("shopMember");//商店会员
 		Member mallMember = memberMap.get("mallMember");//商场会员
 		Assert.notNull(shopMember,"程序异常");
@@ -246,15 +252,28 @@ public class LoginUserServiceImpl extends BaseServiceImpl<LoginUserMapper, Login
 
 					billRecordService.updateById(billRecord);
 					//商家应收明细
-					this.saveShopYingShou(billRecord,pointChannel,pointDetail,shop);
+					PayUtil.saveShopYingShou(billRecord,pointChannel,pointDetail,shop,shopYingshouService);
 
 					//商场积分成本
 					if(mall.getIsOpenMember() == 1){//商场开启会员中心
-						this.addMallPointValue(mall,loginUser,billRecord,channelUserPoint);
+						PointDetail mallSendPoint = PayUtil.addMallPointValue(mall,loginUser,billRecord,mallMember,pointDetailService);
+						//新增该用户在该商场渠道的积分和积分价值
+						channelUserPoint.setUsablePointValue(channelUserPoint.getUsablePointValue().add(mallSendPoint.getPointValue()));
+						channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().add(mallSendPoint.getPoint()));
+						channelUserPoint.setTotalPoint(channelUserPoint.getTotalPoint().add(mallSendPoint.getPoint()));
+						channelUserPointService.updateById(channelUserPoint);
+						//	增加該用戶的渠道总积分价值
+						loginUser.setChannelPointValue(loginUser.getChannelPointValue().add(mallSendPoint.getPointValue()));
+						this.updateById(loginUser);
+
 					}
 					//新增该用户的积分余额--商家积分成本
 					if(shop.getIsOpenMember() == 1){//判断该商店是否开启会员中心
-						this.addShopPointValue(mall,shop,loginUser,billRecord);
+						PointDetail shopPointDetail = PayUtil.addShopPointValue(mall,shop,loginUser,billRecord,pointDetailService);
+						//新增用户的余额(积分价值)
+						loginUser.setPointValue(loginUser.getPointValue().add(shopPointDetail.getPointValue()));
+						loginUser.setPoint(loginUser.getPoint().add(shopPointDetail.getPoint()));
+						this.updateById(loginUser);
 					}
 
 					return billRecord;
@@ -336,11 +355,23 @@ public class LoginUserServiceImpl extends BaseServiceImpl<LoginUserMapper, Login
 
 								//商场积分成本
 								if(mall.getIsOpenMember() == 1){//商场开启会员中心
-									this.addMallPointValue(mall,loginUser,billRecord,channelUserPoint);
+									PointDetail mallSendPoint = PayUtil.addMallPointValue(mall, loginUser, billRecord, mallMember, pointDetailService);
+									//新增该用户在该商场渠道的积分和积分价值
+									channelUserPoint.setUsablePointValue(channelUserPoint.getUsablePointValue().add(mallSendPoint.getPointValue()));
+									channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().add(mallSendPoint.getPoint()));
+									channelUserPoint.setTotalPoint(channelUserPoint.getTotalPoint().add(mallSendPoint.getPoint()));
+									channelUserPointService.updateById(channelUserPoint);
+									//	增加該用戶的渠道总积分价值
+									loginUser.setChannelPointValue(loginUser.getChannelPointValue().add(mallSendPoint.getPointValue()));
+									this.updateById(loginUser);
 								}
 								//新增该用户的积分余额--商家积分成本
 								if(shop.getIsOpenMember() == 1){//判断该商店是否开启会员中心
-									this.addShopPointValue(mall,shop,loginUser,billRecord);
+									PointDetail shopPointDetail = PayUtil.addShopPointValue(mall,shop,loginUser,billRecord,pointDetailService);
+									//新增用户的余额(积分价值)
+									loginUser.setPointValue(loginUser.getPointValue().add(shopPointDetail.getPointValue()));
+									loginUser.setPoint(loginUser.getPoint().add(shopPointDetail.getPoint()));
+									this.updateById(loginUser);
 								}
 
 								billRecordService.updateById(billRecord);
@@ -409,7 +440,7 @@ public class LoginUserServiceImpl extends BaseServiceImpl<LoginUserMapper, Login
 						loginUser.setChannelPointValue(loginUser.getChannelPointValue().subtract(channelPointDetail.getPointValue()));
 						this.updateById(loginUser);
 						//商家应收明细
-						this.saveShopYingShou(billRecord,pointChannel,channelPointDetail,shop);
+						PayUtil.saveShopYingShou(billRecord,pointChannel,channelPointDetail,shop,shopYingshouService);
 
 
 						//还应支付余额
@@ -445,11 +476,23 @@ public class LoginUserServiceImpl extends BaseServiceImpl<LoginUserMapper, Login
 
 								//商场积分成本
 								if(mall.getIsOpenMember() == 1){//商场开启会员中心
-									this.addMallPointValue(mall,loginUser,billRecord,channelUserPoint);
+									PointDetail mallSendPoint = PayUtil.addMallPointValue(mall, loginUser, billRecord, mallMember, pointDetailService);
+									//新增该用户在该商场渠道的积分和积分价值
+									channelUserPoint.setUsablePointValue(channelUserPoint.getUsablePointValue().add(mallSendPoint.getPointValue()));
+									channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().add(mallSendPoint.getPoint()));
+									channelUserPoint.setTotalPoint(channelUserPoint.getTotalPoint().add(mallSendPoint.getPoint()));
+									channelUserPointService.updateById(channelUserPoint);
+									//	增加該用戶的渠道总积分价值
+									loginUser.setChannelPointValue(loginUser.getChannelPointValue().add(mallSendPoint.getPointValue()));
+									this.updateById(loginUser);
 								}
 								//新增该用户的积分余额--商家积分成本
 								if(shop.getIsOpenMember() == 1){//判断该商店是否开启会员中心
-									this.addShopPointValue(mall,shop,loginUser,billRecord);
+									PointDetail shopPointDetail = PayUtil.addShopPointValue(mall,shop,loginUser,billRecord,pointDetailService);
+									//新增用户的余额(积分价值)
+									loginUser.setPointValue(loginUser.getPointValue().add(shopPointDetail.getPointValue()));
+									loginUser.setPoint(loginUser.getPoint().add(shopPointDetail.getPoint()));
+									this.updateById(loginUser);
 								}
 
 
@@ -484,9 +527,7 @@ public class LoginUserServiceImpl extends BaseServiceImpl<LoginUserMapper, Login
 								pointDetail.setName(shop.getName());
 								pointDetailService.save(pointDetail);
 
-								//该用户的余额 = 0 待支付回调后才能扣余额
-//								loginUser.setPointValue(BigDecimal.ZERO);
-//								this.updateById(loginUser);
+
 
 								billRecordService.updateById(billRecord);
 
@@ -540,139 +581,139 @@ public class LoginUserServiceImpl extends BaseServiceImpl<LoginUserMapper, Login
 		return billRecord;
 	}
 
+	@Override
+	public PointPayTypeEnum getPointPayType(PayDto payDto, Shop shop, LoginUser loginUser) {
+		DecimalFormat decimalFormat = new DecimalFormat("0.00");
+		decimalFormat.setRoundingMode(RoundingMode.CEILING);
+		BillRecord billRecord = new BillRecord();
+		billRecord.setShopId(payDto.getShopId());
+		billRecord.setMallId(shop.getMallId());
+		billRecord.setType(OrderType.USER_PAY.getName());
+		billRecord.setBillsTitle(payDto.getBillsTitle());
+		billRecord.setAppId(payDto.getAppId());
+		billRecord.setOpenId(loginUser.getOpenid());
+		billRecord.setExpireTime(payDto.getExpireTime());
+		billRecord.setPayAmount(decimalFormat.format(payDto.getMoney()));
+		billRecord.setUserId(payDto.getLoginUserId());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecord.setPrice(payDto.getMoney());//总价
+		billRecord.setSubsidy(BigDecimal.valueOf(1));
 
-	/**
-	 * 获取用户在该店该商场的会员信息
-	 */
-
-	private Map<String,Member> getMembers(Shop shop,PayDto payDto){
-		Map<String,Member> memberMap = new HashMap<>();
-		//获取该用户在该店的会员信息
-		Member isMember = memberService.getBaseMapper().selectOne(new QueryWrapper<>(new Member()).lambda()
-			.eq(Member::getType, SystemConstant.MALLORSHOP.SHOP.getValue())
-			.eq(Member::getShopId, payDto.getShopId()).eq(Member::getUserId, payDto.getLoginUserId()));
-		if(isMember != null){//是该店的会员
-			memberMap.put("shopMember",isMember);
-		}else{//不是该店的会员,新建会员信息,并判断是否为该商场的会员
-
-			Member shopMember = new Member();
-			shopMember.setType(SystemConstant.MALLORSHOP.SHOP.getValue());
-			shopMember.setMallId(shop.getMallId());
-			shopMember.setShopId(shop.getId());
-			shopMember.setPointTotal(BigDecimal.ZERO);
-			shopMember.setPointValue(BigDecimal.ZERO);
-			shopMember.setUserId(payDto.getLoginUserId());
-			memberService.save(shopMember);
-			shop.setMemberCount(shop.getMemberCount()+1);
-			shopService.updateById(shop);
-			memberMap.put("shopMember",shopMember);
-			//获取该用户在该商场的会员信息
-			if(shop.getMallId() != null){//该商店有商场信息
-				Member isMallMember = memberService.getBaseMapper().selectOne(new QueryWrapper<>(new Member()).lambda()
-					.eq(Member::getMallId,shop.getMallId()).eq(Member::getType,SystemConstant.MALLORSHOP.MALL.getValue())
-					.eq(Member::getUserId,payDto.getLoginUserId()));
-				if(isMallMember != null){//该用户是该商场的会员
-					memberMap.put("mallMember",isMallMember);
-				}else{//不是该商场的会员,创建
-					Member mallMember = new Member();
-					mallMember.setUserId(payDto.getLoginUserId());
-					mallMember.setPointValue(BigDecimal.ZERO);
-					mallMember.setPointTotal(BigDecimal.ZERO);
-					mallMember.setType(SystemConstant.MALLORSHOP.MALL.getValue());
-					mallMember.setMallId(shop.getMallId());
-					memberService.save(mallMember);
-					Mall mall = mallService.getById(shop.getMallId());
-					mall.setMemberCount(mall.getMemberCount()+1);
-					mallService.updateById(mall);
-					memberMap.put("mallMember",mallMember);
+		BigDecimal gxServerRate =BigDecimal.valueOf(0); //国信活动服务费
+		BigDecimal scoreServerRate = BigDecimal.valueOf(Double.valueOf(paramService.getValue(CommonConstant.SCORE_SERVIVE_RATE)));//积分服务费
+		Map<String,Member> memberMap = MemberUtil.getMembers(shop,loginUser.getId(),memberService,shopService,mallService);
+		Member shopMember = memberMap.get("shopMember");//商店会员
+		Member mallMember = memberMap.get("mallMember");//商场会员
+		Assert.notNull(shopMember,"程序异常");
+		billRecord.setMemberId(shopMember.getId());
+		if(shop.getIsOpenMember() != 1){
+			System.out.println("该商户未开通会员中心");
+			Assert.isTrue(false,"该商户未开通会员中心");
+		}
+
+		//先查询该小B的活动折扣
+		List<ActivityJoinRecord> activityJoinRecords = activityJoinRecordService.getBaseMapper().selectList(new QueryWrapper<>(new ActivityJoinRecord()).lambda()
+			.eq(ActivityJoinRecord::getJoinType, SystemConstant.MALLORSHOP.SHOP.getValue())
+			.eq(ActivityJoinRecord::getJoinId, payDto.getShopId()));
+		if(activityJoinRecords.size()>0){//小B参与了大B的活动
+			//联营折扣
+			billRecord.setSubsidy(activityJoinRecords.get(0).getFinalSupplyPrice().divide(BigDecimal.valueOf(100)));
+			gxServerRate = activityJoinRecords.get(0).getGxRewardSupply().divide(BigDecimal.valueOf(100));
+		}else{//小B没有参加大B的活动,查看小B是否自己有创建活动
+
+		}
+
+
+
+		//用户应付金额 = 商品价格* 小B折扣*大B折扣+国信活动服务费
+		BigDecimal yingfu = payDto.getMoney().multiply(billRecord.getSubsidy().add(gxServerRate));
+		billRecord.setYingfuAmount(yingfu);
+
+
+		//1.先看该用户在该大B下的积分够不够用
+		//获取该大B的渠道信息
+		if(shop.getMallId() != null){
+			Mall mall = mallService.getById(shop.getMallId());
+			Assert.notNull(mall,"商场不存在");
+			PointChannel pointChannel = pointChannelService.getBaseMapper().selectOne(new QueryWrapper<>(new PointChannel()).lambda()
+				.eq(PointChannel::getType, SystemConstant.PointChannelType.MALL.getValue())
+				.eq(PointChannel::getRelationId, shop.getMallId()));
+			if(pointChannel == null){//没有则创建
+				pointChannel = new PointChannel();
+				pointChannel.setType(SystemConstant.PointChannelType.MALL.getValue());
+				pointChannel.setRelationId(mall.getId());
+				pointChannel.setSort(1);
+				if(mall.getIsOpenMember() != 1){
+					Assert.isTrue(false,"商场未开启会员中心");
 				}
+				pointChannel.setPointValue(mall.getPointValue().multiply(BigDecimal.valueOf(100)).divide(mall.getPoint()));//100积分等于多少积分价值
+				pointChannel.setDiscount(BigDecimal.valueOf(100));
+				pointChannel.setName(mall.getName());
+				pointChannel.setLogo(mall.getPic());
+				pointChannel.setPaymentDays(mall.getPaymentDays()!= null? mall.getPaymentDays():0);
+				pointChannelService.save(pointChannel);
 			}
+			//获取该用户在该商场的可用积分
+			if(pointChannel != null){
+				ChannelUserPoint channelUserPoint = channelUserPointService.getBaseMapper().selectOne(new QueryWrapper<>(new ChannelUserPoint()).lambda()
+					.eq(ChannelUserPoint::getUserId,loginUser.getId()).eq(ChannelUserPoint::getChannelId,pointChannel.getId()));
+				//渠道积分价值
+				if(channelUserPoint == null){//没有则创建
+					channelUserPoint = new ChannelUserPoint();
+					channelUserPoint.setUserId(loginUser.getId());
+					channelUserPoint.setChannelId(pointChannel.getId());
+					channelUserPoint.setTotalPoint(BigDecimal.ZERO);
+					channelUserPoint.setUsablePoint(BigDecimal.ZERO);
+					channelUserPoint.setUsedPoint(BigDecimal.ZERO);
+					channelUserPoint.setChannelName(mall.getName());
+					channelUserPoint.setUserPhone(loginUser.getNickName());
+					channelUserPointService.save(channelUserPoint);
+				}
 
-		}
+				BigDecimal channelPointValue = channelUserPoint.getUsablePoint().multiply(pointChannel.getPointValue()).divide(BigDecimal.valueOf(100));
+				//判断大B渠道的积分是否足够支付
+				boolean channelScoreEnough = yingfu.subtract(channelPointValue.multiply(BigDecimal.ONE.add(scoreServerRate))).compareTo(BigDecimal.ZERO) > 0 ? false : true;
 
-		return memberMap;
-	}
+				if(channelScoreEnough){//大B渠道的积分足够支付
+					return PointPayTypeEnum.CHANNEL_ENOUGN;
+				}else{//大B渠道的积分不足支付,
+					if(channelPointValue.compareTo(BigDecimal.ZERO) == 0){//大B渠道积分价值为零,扣用户余额
+						if(loginUser.getPointValue().compareTo(BigDecimal.ZERO) == 0){//大B渠道积分价值为零,用户余额为0
+							return PointPayTypeEnum.CHANNEL_ZERO_RARE_ZERO;
+						}else{//大B渠道积分价值为零,余额不为0
+							boolean userAccoutEnough = yingfu.subtract(loginUser.getPointValue().multiply(BigDecimal.ONE.add(gxServerRate))).compareTo(BigDecimal.ZERO) > 0 ? false : true;
+							if(userAccoutEnough){//大B渠道积分价值为零,余额够扣
+								return PointPayTypeEnum.CHANNEL_ZERO_RARE_ENOUGH;
+							}else{//大B渠道积分价值为零,余额不够扣
+								return PointPayTypeEnum.CHANNEL_ZERO_RARE_NOENOUGH;
+							}
+						}
+					}else{ //大B渠道积分不为0且不够扣,先扣大B渠道积分价值,再扣用户余额
+						//大B渠道可抵用积分
+						BigDecimal channelEnablePointValue = channelUserPoint.getUsablePoint().multiply(BigDecimal.ONE.subtract(gxServerRate));
 
-	/**
-	 * 当用户不需要支付时新增商家的积分成本,增加用户的渠道可用积分
-	 * @param mall
-	 * @param loginUser
-	 * @param billRecord
-	 * @param channelUserPoint
-	 */
-
-	private void addMallPointValue(Mall mall,LoginUser loginUser,BillRecord billRecord,ChannelUserPoint channelUserPoint){
-		PointDetail mallSendPoint = new PointDetail();
-		mallSendPoint.setMallId(mall.getId());
-		mallSendPoint.setUserId(loginUser.getId());
-		mallSendPoint.setType(SystemConstant.PointDetailType.MALL_SEND.getValue());
-		mallSendPoint.setName(mall.getName());
-		mallSendPoint.setLogo(mall.getPic());
-		mallSendPoint.setPrice(billRecord.getPrice());//总价
-		mallSendPoint.setChannelId(mall.getId());
-		//商场送的积分数 = 总价*商场会员中心每消费一元赠送的积分数
-		mallSendPoint.setPoint(billRecord.getPrice().multiply(mall.getConsumeOnePoint()));
-		//商场赠送的积分价值 = 商场送的积分数*商场会员中心的积分价值/商场会员中心的积分数
-		mallSendPoint.setPointValue(mallSendPoint.getPoint().multiply(mall.getPointValue()).divide(mall.getPoint()));
-		mallSendPoint.setBillRecordId(billRecord.getId());
-		mallSendPoint.setBillRecordStatus(billRecord.getPayStatus());
-		pointDetailService.save(mallSendPoint);
-		//新增该用户在该商场渠道的积分和积分价值
-		channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().add(mallSendPoint.getPoint()));
-		channelUserPoint.setTotalPoint(channelUserPoint.getTotalPoint().add(mallSendPoint.getPoint()));
-		channelUserPointService.updateById(channelUserPoint);
-	}
+						//还应支付余额
+						yingfu = yingfu.subtract(channelEnablePointValue);
+						//判断用户是否有余额可扣
+						if(loginUser.getPointValue().compareTo(BigDecimal.ZERO) > 0 ){//用户有余额可扣
+							boolean userAccoutEnough = yingfu.subtract(loginUser.getPointValue().multiply(BigDecimal.ONE.add(gxServerRate))).compareTo(BigDecimal.ZERO) > 0 ? false : true;
+							if(userAccoutEnough){//大B渠道积分不够扣,用户余额够扣,扣用户余额即可
+								return PointPayTypeEnum.CHANNEL_NOENOUGH_RARE_ENOUGH;
+							}else{//余额不够扣,先扣除余额,再支付
+								return PointPayTypeEnum.CHANNEL_NOENOUGH_RARE_NOENOUGH;
+							}
+						}else{//用户无余额可扣
 
-	/**
-	 *  当用户不需要支付时新增商店的积分成本,增加用户的可用积分(余额)
-	 * @param mall
-	 * @param shop
-	 * @param loginUser
-	 * @param billRecord
-	 */
-	private void addShopPointValue(Mall mall, Shop shop,LoginUser loginUser,BillRecord billRecord){
-		PointDetail shopPointDetail = new PointDetail();
-		shopPointDetail.setMallId(mall.getId());
-		shopPointDetail.setShopId(shop.getId());
-		shopPointDetail.setUserId(loginUser.getId());
-		shopPointDetail.setType(SystemConstant.PointDetailType.SHOP_SEND.getValue());
-		shopPointDetail.setName(shop.getName());
-//						shopPointDetail.setLogo(shop.getShopPic());
-		shopPointDetail.setPrice(billRecord.getPrice());
-		//商家送的积分 = 总价*商家的会议中心每消费一元赠送的积分数
-		shopPointDetail.setPoint(billRecord.getPrice().multiply(shop.getConsumeOnePoint()));
-		//商家赠送的积分价值 = 商家送的积分数*商家会员中心的积分价值/商家会员中心的积分数
-		shopPointDetail.setPointValue(shopPointDetail.getPoint().multiply(shop.getPointValue()).divide(shop.getPoint()));
-		shopPointDetail.setBillRecordStatus(billRecord.getPayStatus());
-		shopPointDetail.setBillRecordId(billRecord.getId());
-		pointDetailService.save(shopPointDetail);
-		//新增用户的余额(积分价值)
-		loginUser.setPointValue(loginUser.getPointValue().add(shopPointDetail.getPointValue()));
-		loginUser.setPoint(loginUser.getPoint().add(shopPointDetail.getPoint()));
-		this.updateById(loginUser);
-	}
+							return PointPayTypeEnum.CHANNEL_NOENOUGH_RARE_ZERO;
+						}
+					}
+				}
+			}
+
+
+		}
 
-	/**
-	 * 当用户不需要支付时直接新增商家应收明细
-	 * @param billRecord
-	 * @param pointChannel
-	 * @param pointDetail
-	 * @param shop
-	 */
-	private void saveShopYingShou(BillRecord billRecord,PointChannel pointChannel,PointDetail pointDetail,Shop shop){
-		ShopYingshou shopYingshou = new ShopYingshou();
-		shopYingshou.setBillRecordId(billRecord.getId());
-		shopYingshou.setBillRecordStatus(billRecord.getPayStatus());
-		shopYingshou.setChannelId(pointChannel.getId());
-		shopYingshou.setChannelLogo(pointChannel.getLogo());
-		shopYingshou.setChannelName(pointChannel.getName());
-		shopYingshou.setJsStatus(SystemConstant.JieSuanStatus.jsing.getValue());
-		shopYingshou.setPaymentDays(pointChannel.getPaymentDays());
-		shopYingshou.setJsTime(LocalDateTime.now().plusDays(Long.valueOf(pointChannel.getPaymentDays())));//当前时间加上账期
-		shopYingshou.setPoint(pointDetail.getPoint());
-		shopYingshou.setPointValue(pointDetail.getPointValue());
-		shopYingshou.setShopId(shop.getId());
-		shopYingshouService.save(shopYingshou);
+		return null;
 	}
 
 

+ 74 - 0
src/main/java/org/springblade/modules/ldt/member/utils/MemberUtil.java

@@ -0,0 +1,74 @@
+package org.springblade.modules.ldt.member.utils;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.springblade.common.constant.SystemConstant;
+import org.springblade.modules.ldt.loginuser.dto.PayDto;
+import org.springblade.modules.ldt.mall.entity.Mall;
+import org.springblade.modules.ldt.mall.service.IMallService;
+import org.springblade.modules.ldt.member.entity.Member;
+import org.springblade.modules.ldt.member.service.IMemberService;
+import org.springblade.modules.ldt.shop.entity.Shop;
+import org.springblade.modules.ldt.shop.service.IShopService;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created By lidexi in 2021/8/19
+ **/
+public class MemberUtil {
+
+	/**
+	 * 获取用户在该店该商场的会员信息,若没有会员信息则创建
+	 */
+
+	public static Map<String, Member> getMembers(Shop shop, Long loginUserId, IMemberService memberService,
+												 IShopService shopService, IMallService mallService){
+		Map<String,Member> memberMap = new HashMap<>();
+		//获取该用户在该店的会员信息
+		Member isMember = memberService.getBaseMapper().selectOne(new QueryWrapper<>(new Member()).lambda()
+			.eq(Member::getType, SystemConstant.MALLORSHOP.SHOP.getValue())
+			.eq(Member::getShopId,shop.getId()).eq(Member::getUserId, loginUserId));
+		if(isMember != null){//是该店的会员
+			memberMap.put("shopMember",isMember);
+		}else{//不是该店的会员,新建会员信息,并判断是否为该商场的会员
+
+			Member shopMember = new Member();
+			shopMember.setType(SystemConstant.MALLORSHOP.SHOP.getValue());
+			shopMember.setMallId(shop.getMallId());
+			shopMember.setShopId(shop.getId());
+			shopMember.setPointTotal(BigDecimal.ZERO);
+			shopMember.setPointValue(BigDecimal.ZERO);
+			shopMember.setUserId(loginUserId);
+			memberService.save(shopMember);
+			shop.setMemberCount(shop.getMemberCount()+1);
+			shopService.updateById(shop);
+			memberMap.put("shopMember",shopMember);
+			//获取该用户在该商场的会员信息
+			if(shop.getMallId() != null){//该商店有商场信息
+				Member isMallMember = memberService.getBaseMapper().selectOne(new QueryWrapper<>(new Member()).lambda()
+					.eq(Member::getMallId,shop.getMallId()).eq(Member::getType,SystemConstant.MALLORSHOP.MALL.getValue())
+					.eq(Member::getUserId,loginUserId));
+				if(isMallMember != null){//该用户是该商场的会员
+					memberMap.put("mallMember",isMallMember);
+				}else{//不是该商场的会员,创建
+					Member mallMember = new Member();
+					mallMember.setUserId(loginUserId);
+					mallMember.setPointValue(BigDecimal.ZERO);
+					mallMember.setPointTotal(BigDecimal.ZERO);
+					mallMember.setType(SystemConstant.MALLORSHOP.MALL.getValue());
+					mallMember.setMallId(shop.getMallId());
+					memberService.save(mallMember);
+					Mall mall = mallService.getById(shop.getMallId());
+					mall.setMemberCount(mall.getMemberCount()+1);
+					mallService.updateById(mall);
+					memberMap.put("mallMember",mallMember);
+				}
+			}
+
+		}
+
+		return memberMap;
+	}
+}

+ 14 - 0
src/main/java/org/springblade/modules/payment/paystrategy/loginuser/IPayStrategy.java

@@ -0,0 +1,14 @@
+package org.springblade.modules.payment.paystrategy.loginuser;
+
+import org.springblade.modules.ldt.billrecord.entity.BillRecord;
+import org.springblade.modules.ldt.loginuser.dto.PayDto;
+import org.springblade.modules.ldt.loginuser.entity.LoginUser;
+import org.springblade.modules.ldt.shop.entity.Shop;
+
+/**
+ * Created By lidexi in 2021/8/19
+ **/
+public interface IPayStrategy {
+
+	BillRecord payBefore(PayDto payDto, LoginUser loginUser, Shop shop);
+}

+ 200 - 0
src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelEnoughStrategy.java

@@ -0,0 +1,200 @@
+package org.springblade.modules.payment.paystrategy.loginuser.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.constant.SystemConstant;
+import org.springblade.common.enums.OrderType;
+import org.springblade.common.enums.PayWay;
+import org.springblade.modules.ldt.activityjoinrecord.entity.ActivityJoinRecord;
+import org.springblade.modules.ldt.activityjoinrecord.service.IActivityJoinRecordService;
+import org.springblade.modules.ldt.billrecord.entity.BillRecord;
+import org.springblade.modules.ldt.billrecord.service.IBillRecordService;
+import org.springblade.modules.ldt.channel.entity.PointChannel;
+import org.springblade.modules.ldt.channel.service.IPointChannelService;
+import org.springblade.modules.ldt.channeluserpoint.entity.ChannelUserPoint;
+import org.springblade.modules.ldt.channeluserpoint.service.IChannelUserPointService;
+import org.springblade.modules.ldt.loginuser.dto.PayDto;
+import org.springblade.modules.ldt.loginuser.entity.LoginUser;
+import org.springblade.modules.ldt.loginuser.service.ILoginUserService;
+import org.springblade.modules.ldt.mall.entity.Mall;
+import org.springblade.modules.ldt.mall.service.IMallService;
+import org.springblade.modules.ldt.member.entity.Member;
+import org.springblade.modules.ldt.member.service.IMemberService;
+import org.springblade.modules.ldt.member.utils.MemberUtil;
+import org.springblade.modules.ldt.pointdetail.entity.PointDetail;
+import org.springblade.modules.ldt.pointdetail.service.IPointDetailService;
+import org.springblade.modules.ldt.shop.entity.Shop;
+import org.springblade.modules.ldt.shop.service.IShopService;
+import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
+import org.springblade.modules.payment.paystrategy.loginuser.IPayStrategy;
+import org.springblade.modules.payment.paystrategy.loginuser.util.PayUtil;
+import org.springblade.modules.system.service.IParamService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created By lidexi in 2021/8/19
+ *
+ * 渠道积分足够支付
+ **/
+@Component
+public class ChannelEnoughStrategy implements IPayStrategy {
+	@Autowired
+	private IParamService paramService;
+	@Autowired
+	private IMemberService memberService;
+	@Autowired
+	private IShopService shopService;
+	@Autowired
+	private IMallService mallService;
+	@Autowired
+	private IActivityJoinRecordService activityJoinRecordService;
+	@Autowired
+	private IBillRecordService billRecordService;
+	@Autowired
+	private IPointChannelService pointChannelService;
+	@Autowired
+	private IChannelUserPointService channelUserPointService;
+	@Autowired
+	private IPointDetailService pointDetailService;
+	@Autowired
+	private IShopYingshouService shopYingshouService;
+	@Autowired
+	private ILoginUserService loginUserService;
+
+	@Override
+	@Transactional
+	public BillRecord payBefore(PayDto payDto, LoginUser loginUser, Shop shop) {
+		DecimalFormat decimalFormat = new DecimalFormat("0.00");
+		//生成预订单
+		decimalFormat.setRoundingMode(RoundingMode.CEILING);
+		BillRecord billRecord = new BillRecord();
+		billRecord.setShopId(payDto.getShopId());
+		billRecord.setMallId(shop.getMallId());
+		billRecord.setType(OrderType.USER_PAY.getName());
+		billRecord.setBillsTitle(payDto.getBillsTitle());
+		billRecord.setAppId(payDto.getAppId());
+		billRecord.setOpenId(loginUser.getOpenid());
+		billRecord.setExpireTime(payDto.getExpireTime());
+		billRecord.setPayAmount(decimalFormat.format(payDto.getMoney()));
+		billRecord.setUserId(payDto.getLoginUserId());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecord.setPrice(payDto.getMoney());//总价
+		billRecordService.save(billRecord);
+		billRecord.setSubsidy(BigDecimal.valueOf(1));
+
+		BigDecimal gxServerRate =BigDecimal.valueOf(0); //国信活动服务费
+		BigDecimal scoreServerRate = BigDecimal.valueOf(Double.valueOf(paramService.getValue(CommonConstant.SCORE_SERVIVE_RATE)));//积分服务费
+		Map<String,Member> memberMap = MemberUtil.getMembers(shop,loginUser.getId(),memberService,shopService,mallService);
+
+		Member shopMember = memberMap.get("shopMember");//商店会员
+		Member mallMember = memberMap.get("mallMember");//商场会员
+		Assert.notNull(shopMember,"程序异常");
+		billRecord.setMemberId(shopMember.getId());
+		if(shop.getIsOpenMember() != 1){
+			System.out.println("该商户未开通会员中心");
+			Assert.isTrue(false,"该商户未开通会员中心");
+		}
+
+		//先查询该小B的活动折扣
+		List<ActivityJoinRecord> activityJoinRecords = activityJoinRecordService.getBaseMapper().selectList(new QueryWrapper<>(new ActivityJoinRecord()).lambda()
+			.eq(ActivityJoinRecord::getJoinType, SystemConstant.MALLORSHOP.SHOP.getValue())
+			.eq(ActivityJoinRecord::getJoinId, payDto.getShopId()));
+		if(activityJoinRecords.size()>0){//小B参与了大B的活动
+			//联营折扣
+			billRecord.setSubsidy(activityJoinRecords.get(0).getFinalSupplyPrice().divide(BigDecimal.valueOf(100)));
+			gxServerRate = activityJoinRecords.get(0).getGxRewardSupply().divide(BigDecimal.valueOf(100));
+		}else{//小B没有参加大B的活动,查看小B是否自己有创建活动
+
+		}
+
+
+
+		//用户应付金额 = 商品价格* 小B折扣*大B折扣+国信活动服务费
+		BigDecimal yingfu = payDto.getMoney().multiply(billRecord.getSubsidy().add(gxServerRate));
+		billRecord.setYingfuAmount(yingfu);
+		if(shop.getMallId() != null) {
+			Mall mall = mallService.getById(shop.getMallId());
+
+			Assert.notNull(mall, "商场不存在");
+			//1.查询该大B的积分渠道
+			PointChannel pointChannel = pointChannelService.getBaseMapper().selectOne(new QueryWrapper<>(new PointChannel()).lambda()
+				.eq(PointChannel::getType, SystemConstant.PointChannelType.MALL.getValue())
+				.eq(PointChannel::getRelationId, shop.getMallId()));
+			//2.查询该用户在积分渠道可用积分
+			ChannelUserPoint channelUserPoint = channelUserPointService.getBaseMapper().selectOne(new QueryWrapper<>(new ChannelUserPoint()).lambda()
+				.eq(ChannelUserPoint::getUserId, loginUser.getId()).eq(ChannelUserPoint::getChannelId, pointChannel.getId()));
+//			BigDecimal channelPointValue = channelUserPoint.getUsablePoint().multiply(pointChannel.getPointValue()).divide(BigDecimal.valueOf(100));
+			//3.更新预订单的支付金额为0,支付方式为积分支付,支付状态为成功
+			billRecord.setRealPayAmount(BigDecimal.ZERO);
+			billRecord.setPayAmount(BigDecimal.ZERO.toString());
+			billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
+			billRecord.setPayWay(PayWay.POINT.getName());//全部由积分支付
+			billRecordService.updateById(billRecord);
+
+			//4.生成用户使用渠道积分支付的记录
+			PointDetail pointDetail = new PointDetail();
+			pointDetail.setType(SystemConstant.PointDetailType.USER_PAY.getValue());
+			pointDetail.setBillRecordId(billRecord.getId());
+			pointDetail.setUserId(payDto.getLoginUserId());
+			pointDetail.setMemberId(shopMember.getId());
+			pointDetail.setGxRewardPointValue(yingfu.multiply(gxServerRate));
+			pointDetail.setPoint(yingfu.multiply(mall.getPoint()).divide(mall.getPointValue()));
+			pointDetail.setPointValue(yingfu);
+			pointDetail.setLogo(mall.getPic());
+			pointDetail.setBillRecordStatus(billRecord.getPayStatus());
+			pointDetail.setShopId(shop.getId());
+			pointDetail.setChannelId(pointChannel.getId());
+			pointDetail.setName(mall.getName());
+			pointDetailService.save(pointDetail);
+
+			//5.扣除该用户在该大B渠道的积分价值,减少该用户的渠道总积分
+			channelUserPoint.setUsablePointValue(
+				channelUserPoint.getUsablePointValue().subtract(yingfu).subtract(pointDetail.getGxRewardPointValue())
+				);
+			channelUserPoint.setUsedPoint(channelUserPoint.getUsedPoint().add(pointDetail.getPoint()).add(pointDetail.getGxRewardPointValue()));
+			channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().subtract(pointDetail.getPoint()).subtract(pointDetail.getGxRewardPointValue()));
+			channelUserPointService.updateById(channelUserPoint);
+
+			loginUser.setChannelPointValue(loginUser.getChannelPointValue().subtract(yingfu).subtract(pointDetail.getGxRewardPointValue()));
+			loginUserService.updateById(loginUser);
+
+			//6.增加商家应收明细记录
+			PayUtil.saveShopYingShou(billRecord, pointChannel, pointDetail, shop, shopYingshouService);
+
+			//7.增加商场积分成本
+			if (mall.getIsOpenMember() == 1) {//商场开启会员中心
+				PointDetail mallSendPoint = PayUtil.addMallPointValue(mall, loginUser, billRecord, mallMember, pointDetailService);
+				//新增该用户在该商场渠道的积分和积分价值
+				channelUserPoint.setUsablePointValue(channelUserPoint.getUsablePointValue().add(mallSendPoint.getPointValue()));
+				channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().add(mallSendPoint.getPoint()));
+				channelUserPoint.setTotalPoint(channelUserPoint.getTotalPoint().add(mallSendPoint.getPoint()));
+				channelUserPointService.updateById(channelUserPoint);
+				//	增加該用戶的渠道总积分价值
+				loginUser.setChannelPointValue(loginUser.getChannelPointValue().add(mallSendPoint.getPointValue()));
+				loginUserService.updateById(loginUser);
+			}
+			//8.新增商家积分成本并新增该用户的积分余额
+			if (shop.getIsOpenMember() == 1) {//判断该商店是否开启会员中心
+				PointDetail shopPointDetail = PayUtil.addShopPointValue(mall, shop, loginUser, billRecord, pointDetailService);
+				//新增用户的余额(积分价值)
+				loginUser.setPointValue(loginUser.getPointValue().add(shopPointDetail.getPointValue()));
+				loginUser.setPoint(loginUser.getPoint().add(shopPointDetail.getPoint()));
+				loginUserService.updateById(loginUser);
+
+			}
+
+			return billRecord;
+
+		}
+		return null;
+	}
+}

+ 215 - 0
src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelNoEnoughRareEnoughStrategy.java

@@ -0,0 +1,215 @@
+package org.springblade.modules.payment.paystrategy.loginuser.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.constant.SystemConstant;
+import org.springblade.common.enums.OrderType;
+import org.springblade.common.enums.PayWay;
+import org.springblade.modules.ldt.activityjoinrecord.entity.ActivityJoinRecord;
+import org.springblade.modules.ldt.activityjoinrecord.service.IActivityJoinRecordService;
+import org.springblade.modules.ldt.billrecord.entity.BillRecord;
+import org.springblade.modules.ldt.billrecord.service.IBillRecordService;
+import org.springblade.modules.ldt.channel.entity.PointChannel;
+import org.springblade.modules.ldt.channel.service.IPointChannelService;
+import org.springblade.modules.ldt.channeluserpoint.entity.ChannelUserPoint;
+import org.springblade.modules.ldt.channeluserpoint.service.IChannelUserPointService;
+import org.springblade.modules.ldt.loginuser.dto.PayDto;
+import org.springblade.modules.ldt.loginuser.entity.LoginUser;
+import org.springblade.modules.ldt.loginuser.service.ILoginUserService;
+import org.springblade.modules.ldt.mall.entity.Mall;
+import org.springblade.modules.ldt.mall.service.IMallService;
+import org.springblade.modules.ldt.member.entity.Member;
+import org.springblade.modules.ldt.member.service.IMemberService;
+import org.springblade.modules.ldt.member.utils.MemberUtil;
+import org.springblade.modules.ldt.pointdetail.entity.PointDetail;
+import org.springblade.modules.ldt.pointdetail.service.IPointDetailService;
+import org.springblade.modules.ldt.shop.entity.Shop;
+import org.springblade.modules.ldt.shop.service.IShopService;
+import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
+import org.springblade.modules.payment.paystrategy.loginuser.IPayStrategy;
+import org.springblade.modules.payment.paystrategy.loginuser.util.PayUtil;
+import org.springblade.modules.system.service.IParamService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created By lidexi in 2021/8/19
+ * 渠道积分不为0,用户余额足够扣
+ **/
+@Component
+public class ChannelNoEnoughRareEnoughStrategy implements IPayStrategy {
+	@Autowired
+	private IParamService paramService;
+	@Autowired
+	private IMemberService memberService;
+	@Autowired
+	private IShopService shopService;
+	@Autowired
+	private IMallService mallService;
+	@Autowired
+	private IActivityJoinRecordService activityJoinRecordService;
+	@Autowired
+	private IBillRecordService billRecordService;
+	@Autowired
+	private IPointChannelService pointChannelService;
+	@Autowired
+	private IChannelUserPointService channelUserPointService;
+	@Autowired
+	private IPointDetailService pointDetailService;
+	@Autowired
+	private IShopYingshouService shopYingshouService;
+	@Autowired
+	private ILoginUserService loginUserService;
+	@Override
+	public BillRecord payBefore(PayDto payDto, LoginUser loginUser, Shop shop) {
+		DecimalFormat decimalFormat = new DecimalFormat("0.00");
+		//生成预订单
+		decimalFormat.setRoundingMode(RoundingMode.CEILING);
+		BillRecord billRecord = new BillRecord();
+		billRecord.setShopId(payDto.getShopId());
+		billRecord.setMallId(shop.getMallId());
+		billRecord.setType(OrderType.USER_PAY.getName());
+		billRecord.setBillsTitle(payDto.getBillsTitle());
+		billRecord.setAppId(payDto.getAppId());
+		billRecord.setOpenId(loginUser.getOpenid());
+		billRecord.setExpireTime(payDto.getExpireTime());
+		billRecord.setPayAmount(decimalFormat.format(payDto.getMoney()));
+		billRecord.setUserId(payDto.getLoginUserId());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecord.setPrice(payDto.getMoney());//总价
+		billRecordService.save(billRecord);
+		billRecord.setSubsidy(BigDecimal.valueOf(1));
+
+		BigDecimal gxServerRate =BigDecimal.valueOf(0); //国信活动服务费
+		BigDecimal scoreServerRate = BigDecimal.valueOf(Double.valueOf(paramService.getValue(CommonConstant.SCORE_SERVIVE_RATE)));//积分服务费
+		Map<String, Member> memberMap = MemberUtil.getMembers(shop,loginUser.getId(),memberService,shopService,mallService);
+
+		Member shopMember = memberMap.get("shopMember");//商店会员
+		Member mallMember = memberMap.get("mallMember");//商场会员
+		Assert.notNull(shopMember,"程序异常");
+		billRecord.setMemberId(shopMember.getId());
+		if(shop.getIsOpenMember() != 1){
+			System.out.println("该商户未开通会员中心");
+			Assert.isTrue(false,"该商户未开通会员中心");
+		}
+
+		//先查询该小B的活动折扣
+		List<ActivityJoinRecord> activityJoinRecords = activityJoinRecordService.getBaseMapper().selectList(new QueryWrapper<>(new ActivityJoinRecord()).lambda()
+			.eq(ActivityJoinRecord::getJoinType, SystemConstant.MALLORSHOP.SHOP.getValue())
+			.eq(ActivityJoinRecord::getJoinId, payDto.getShopId()));
+		if(activityJoinRecords.size()>0){//小B参与了大B的活动
+			//联营折扣
+			billRecord.setSubsidy(activityJoinRecords.get(0).getFinalSupplyPrice().divide(BigDecimal.valueOf(100)));
+			gxServerRate = activityJoinRecords.get(0).getGxRewardSupply().divide(BigDecimal.valueOf(100));
+		}else{//小B没有参加大B的活动,查看小B是否自己有创建活动
+
+		}
+
+
+
+		//用户应付金额 = 商品价格* 小B折扣*大B折扣+国信活动服务费
+		BigDecimal yingfu = payDto.getMoney().multiply(billRecord.getSubsidy().add(gxServerRate));
+		billRecord.setYingfuAmount(yingfu);
+
+		//1.查询该大B的积分渠道
+		PointChannel pointChannel = pointChannelService.getBaseMapper().selectOne(new QueryWrapper<>(new PointChannel()).lambda()
+			.eq(PointChannel::getType, SystemConstant.PointChannelType.MALL.getValue())
+			.eq(PointChannel::getRelationId, shop.getMallId()));
+		//2.查询该用户在积分渠道可用积分
+		ChannelUserPoint channelUserPoint = channelUserPointService.getBaseMapper().selectOne(new QueryWrapper<>(new ChannelUserPoint()).lambda()
+			.eq(ChannelUserPoint::getUserId, loginUser.getId()).eq(ChannelUserPoint::getChannelId, pointChannel.getId()));
+		Mall mall = mallService.getById(shop.getMallId());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		//大B渠道国信积分服务费
+		BigDecimal channelGxPointValue = channelUserPoint.getUsablePoint().multiply(gxServerRate);
+		//大B渠道可抵用积分
+		BigDecimal channelEnablePointValue = channelUserPoint.getUsablePoint().multiply(BigDecimal.ONE.subtract(gxServerRate));
+		//生成该用户使用渠道积分支付的记录
+		PointDetail channelPointDetail = new PointDetail();
+		channelPointDetail.setMemberId(mallMember.getId());
+		channelPointDetail.setType(SystemConstant.PointDetailType.USER_PAY.getValue());
+		channelPointDetail.setBillRecordId(billRecord.getId());
+		channelPointDetail.setUserId(payDto.getLoginUserId());
+		channelPointDetail.setGxRewardPointValue(channelGxPointValue);
+		channelPointDetail.setPoint(channelEnablePointValue.multiply(mall.getPoint()).divide(mall.getPointValue()));
+		channelPointDetail.setPointValue(channelEnablePointValue);
+		channelPointDetail.setLogo(mall.getPic());
+		channelPointDetail.setBillRecordStatus(billRecord.getPayStatus());
+		channelPointDetail.setShopId(shop.getId());
+		channelPointDetail.setName(mall.getName());
+		pointDetailService.save(channelPointDetail);
+
+		//2扣除该用户在该大B渠道的积分价值
+		channelUserPoint.setUsedPoint(channelUserPoint.getUsedPoint().add(channelPointDetail.getPoint()).add(channelPointDetail.getGxRewardPointValue()));
+		channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().subtract(channelPointDetail.getPoint()).subtract(channelPointDetail.getGxRewardPointValue()));
+		channelUserPointService.updateById(channelUserPoint);
+		//2修改该用户的渠道积分
+		loginUser.setChannelPointValue(loginUser.getChannelPointValue().subtract(channelPointDetail.getPointValue()));
+		loginUserService.updateById(loginUser);
+		//3增加商家应收记录
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
+		PayUtil.saveShopYingShou(billRecord,pointChannel,channelPointDetail,shop,shopYingshouService);
+
+
+		//还应支付余额
+		yingfu = yingfu.subtract(channelEnablePointValue);
+
+		billRecord.setPayWay(PayWay.POINT.getName());
+		billRecord.setRealPayAmount(BigDecimal.ZERO);
+		billRecord.setPayAmount(BigDecimal.ZERO.toString());
+		//扣除的国信积分服务费
+		BigDecimal gxRewardPointValue  = yingfu.multiply(gxServerRate);
+
+		PointDetail pointDetail = new PointDetail();
+		pointDetail.setType(SystemConstant.PointDetailType.USER_PAY.getValue());
+		pointDetail.setBillRecordId(billRecord.getId());
+		pointDetail.setMemberId(shopMember.getId());
+		pointDetail.setUserId(payDto.getLoginUserId());
+		pointDetail.setGxRewardPointValue(gxRewardPointValue);
+		pointDetail.setPoint(yingfu.multiply(shop.getPoint()).divide(shop.getPointValue()));
+		pointDetail.setPointValue(yingfu);
+		pointDetail.setLogo(shop.getCover());
+		pointDetail.setBillRecordStatus(billRecord.getPayStatus());
+		pointDetail.setShopId(shop.getId());
+		pointDetail.setName(shop.getName());
+		pointDetailService.save(pointDetail);
+
+		//5.修改用户可用余额    该用户的余额 = 余额 - 支付的积分价值-国信积分服务费
+		loginUser.setPointValue(loginUser.getPointValue().subtract(pointDetail.getPointValue()).subtract(pointDetail.getGxRewardPointValue()));
+		loginUserService.updateById(loginUser);
+
+		//66.增加商家送积分记录,增加该用户在该渠道的渠道积分,修改用户信息的渠道总积分价值
+		if(mall.getIsOpenMember() == 1){//商场开启会员中心
+			PointDetail mallSendPoint = PayUtil.addMallPointValue(mall, loginUser, billRecord, mallMember, pointDetailService);
+			//新增该用户在该商场渠道的积分和积分价值
+			channelUserPoint.setUsablePointValue(channelUserPoint.getUsablePointValue().add(mallSendPoint.getPointValue()));
+			channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().add(mallSendPoint.getPoint()));
+			channelUserPoint.setTotalPoint(channelUserPoint.getTotalPoint().add(mallSendPoint.getPoint()));
+			channelUserPointService.updateById(channelUserPoint);
+			//	增加該用戶的渠道总积分价值
+			loginUser.setChannelPointValue(loginUser.getChannelPointValue().add(mallSendPoint.getPointValue()));
+			loginUserService.updateById(loginUser);
+		}
+		//7.增加商家的送积分记录,修改用户信息的积分余额
+		if(shop.getIsOpenMember() == 1){//判断该商店是否开启会员中心
+			PointDetail shopPointDetail = PayUtil.addShopPointValue(mall,shop,loginUser,billRecord,pointDetailService);
+			//新增用户的余额(积分价值)
+			loginUser.setPointValue(loginUser.getPointValue().add(shopPointDetail.getPointValue()));
+			loginUser.setPoint(loginUser.getPoint().add(shopPointDetail.getPoint()));
+			loginUserService.updateById(loginUser);
+		}
+
+
+
+		billRecordService.updateById(billRecord);
+
+		return billRecord;
+	}
+}

+ 199 - 0
src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelNoEnoughRareNoEnoughStrategy.java

@@ -0,0 +1,199 @@
+package org.springblade.modules.payment.paystrategy.loginuser.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.constant.SystemConstant;
+import org.springblade.common.enums.OrderType;
+import org.springblade.common.enums.PayWay;
+import org.springblade.modules.ldt.activityjoinrecord.entity.ActivityJoinRecord;
+import org.springblade.modules.ldt.activityjoinrecord.service.IActivityJoinRecordService;
+import org.springblade.modules.ldt.billrecord.entity.BillRecord;
+import org.springblade.modules.ldt.billrecord.service.IBillRecordService;
+import org.springblade.modules.ldt.channel.entity.PointChannel;
+import org.springblade.modules.ldt.channel.service.IPointChannelService;
+import org.springblade.modules.ldt.channeluserpoint.entity.ChannelUserPoint;
+import org.springblade.modules.ldt.channeluserpoint.service.IChannelUserPointService;
+import org.springblade.modules.ldt.loginuser.dto.PayDto;
+import org.springblade.modules.ldt.loginuser.entity.LoginUser;
+import org.springblade.modules.ldt.loginuser.service.ILoginUserService;
+import org.springblade.modules.ldt.mall.entity.Mall;
+import org.springblade.modules.ldt.mall.service.IMallService;
+import org.springblade.modules.ldt.member.entity.Member;
+import org.springblade.modules.ldt.member.service.IMemberService;
+import org.springblade.modules.ldt.member.utils.MemberUtil;
+import org.springblade.modules.ldt.pointdetail.entity.PointDetail;
+import org.springblade.modules.ldt.pointdetail.service.IPointDetailService;
+import org.springblade.modules.ldt.shop.entity.Shop;
+import org.springblade.modules.ldt.shop.service.IShopService;
+import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
+import org.springblade.modules.payment.paystrategy.loginuser.IPayStrategy;
+import org.springblade.modules.payment.paystrategy.loginuser.util.PayUtil;
+import org.springblade.modules.system.service.IParamService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created By lidexi in 2021/8/19
+ * 渠道积分不为0,用户余额不够扣
+ **/
+@Component
+public class ChannelNoEnoughRareNoEnoughStrategy implements IPayStrategy {
+	@Autowired
+	private IParamService paramService;
+	@Autowired
+	private IMemberService memberService;
+	@Autowired
+	private IShopService shopService;
+	@Autowired
+	private IMallService mallService;
+	@Autowired
+	private IActivityJoinRecordService activityJoinRecordService;
+	@Autowired
+	private IBillRecordService billRecordService;
+	@Autowired
+	private IPointChannelService pointChannelService;
+	@Autowired
+	private IChannelUserPointService channelUserPointService;
+	@Autowired
+	private IPointDetailService pointDetailService;
+	@Autowired
+	private IShopYingshouService shopYingshouService;
+	@Autowired
+	private ILoginUserService loginUserService;
+
+	@Override
+	public BillRecord payBefore(PayDto payDto, LoginUser loginUser, Shop shop) {
+		DecimalFormat decimalFormat = new DecimalFormat("0.00");
+		//生成预订单
+		decimalFormat.setRoundingMode(RoundingMode.CEILING);
+		BillRecord billRecord = new BillRecord();
+		billRecord.setShopId(payDto.getShopId());
+		billRecord.setMallId(shop.getMallId());
+		billRecord.setType(OrderType.USER_PAY.getName());
+		billRecord.setBillsTitle(payDto.getBillsTitle());
+		billRecord.setAppId(payDto.getAppId());
+		billRecord.setOpenId(loginUser.getOpenid());
+		billRecord.setExpireTime(payDto.getExpireTime());
+		billRecord.setPayAmount(decimalFormat.format(payDto.getMoney()));
+		billRecord.setUserId(payDto.getLoginUserId());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecord.setPrice(payDto.getMoney());//总价
+		billRecordService.save(billRecord);
+		billRecord.setSubsidy(BigDecimal.valueOf(1));
+
+		BigDecimal gxServerRate =BigDecimal.valueOf(0); //国信活动服务费
+		BigDecimal scoreServerRate = BigDecimal.valueOf(Double.valueOf(paramService.getValue(CommonConstant.SCORE_SERVIVE_RATE)));//积分服务费
+		Map<String, Member> memberMap = MemberUtil.getMembers(shop,loginUser.getId(),memberService,shopService,mallService);
+
+		Member shopMember = memberMap.get("shopMember");//商店会员
+		Member mallMember = memberMap.get("mallMember");//商场会员
+		Assert.notNull(shopMember,"程序异常");
+		billRecord.setMemberId(shopMember.getId());
+		if(shop.getIsOpenMember() != 1){
+			System.out.println("该商户未开通会员中心");
+			Assert.isTrue(false,"该商户未开通会员中心");
+		}
+
+		//先查询该小B的活动折扣
+		List<ActivityJoinRecord> activityJoinRecords = activityJoinRecordService.getBaseMapper().selectList(new QueryWrapper<>(new ActivityJoinRecord()).lambda()
+			.eq(ActivityJoinRecord::getJoinType, SystemConstant.MALLORSHOP.SHOP.getValue())
+			.eq(ActivityJoinRecord::getJoinId, payDto.getShopId()));
+		if(activityJoinRecords.size()>0){//小B参与了大B的活动
+			//联营折扣
+			billRecord.setSubsidy(activityJoinRecords.get(0).getFinalSupplyPrice().divide(BigDecimal.valueOf(100)));
+			gxServerRate = activityJoinRecords.get(0).getGxRewardSupply().divide(BigDecimal.valueOf(100));
+		}else{//小B没有参加大B的活动,查看小B是否自己有创建活动
+
+		}
+
+
+
+		//用户应付金额 = 商品价格* 小B折扣*大B折扣+国信活动服务费
+		BigDecimal yingfu = payDto.getMoney().multiply(billRecord.getSubsidy().add(gxServerRate));
+		billRecord.setYingfuAmount(yingfu);
+
+
+		//1.查询该大B的积分渠道
+		PointChannel pointChannel = pointChannelService.getBaseMapper().selectOne(new QueryWrapper<>(new PointChannel()).lambda()
+			.eq(PointChannel::getType, SystemConstant.PointChannelType.MALL.getValue())
+			.eq(PointChannel::getRelationId, shop.getMallId()));
+		//2.查询该用户在积分渠道可用积分
+		ChannelUserPoint channelUserPoint = channelUserPointService.getBaseMapper().selectOne(new QueryWrapper<>(new ChannelUserPoint()).lambda()
+			.eq(ChannelUserPoint::getUserId, loginUser.getId()).eq(ChannelUserPoint::getChannelId, pointChannel.getId()));
+
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+
+		Mall mall = mallService.getById(shop.getMallId());
+
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		//大B渠道国信积分服务费
+		BigDecimal channelGxPointValue = channelUserPoint.getUsablePoint().multiply(gxServerRate);
+		//大B渠道可抵用积分
+		BigDecimal channelEnablePointValue = channelUserPoint.getUsablePoint().multiply(BigDecimal.ONE.subtract(gxServerRate));
+		//1.计算该用户在大b渠道的可扣积分金额,生成该用户使用渠道积分支付的记录
+		PointDetail channelPointDetail = new PointDetail();
+		channelPointDetail.setMemberId(mallMember.getId());
+		channelPointDetail.setType(SystemConstant.PointDetailType.USER_PAY.getValue());
+		channelPointDetail.setBillRecordId(billRecord.getId());
+		channelPointDetail.setUserId(payDto.getLoginUserId());
+		channelPointDetail.setGxRewardPointValue(channelGxPointValue);
+		channelPointDetail.setPoint(channelEnablePointValue.multiply(mall.getPoint()).divide(mall.getPointValue()));
+		channelPointDetail.setPointValue(channelEnablePointValue);
+		channelPointDetail.setLogo(mall.getPic());
+		channelPointDetail.setBillRecordStatus(billRecord.getPayStatus());
+		channelPointDetail.setShopId(shop.getId());
+		channelPointDetail.setName(mall.getName());
+		pointDetailService.save(channelPointDetail);
+
+
+		//2.新增商家应收记录,状态为待确认
+		PayUtil.saveShopYingShou(billRecord,pointChannel,channelPointDetail,shop,shopYingshouService);
+
+
+		//还应支付余额
+		yingfu = yingfu.subtract(channelEnablePointValue);
+
+
+
+		//3.计算用户余额可抵扣金额,生成用户使用余额支付的记录
+		//国信积分服务费
+		BigDecimal gxRewardPointValue = loginUser.getPointValue().multiply(gxServerRate);
+		//可抵扣的余额
+		BigDecimal userEnablePointValue = loginUser.getPointValue().multiply(BigDecimal.ONE.subtract(gxServerRate));
+
+
+
+		PointDetail pointDetail = new PointDetail();
+		pointDetail.setType(SystemConstant.PointDetailType.USER_PAY.getValue());
+		pointDetail.setBillRecordId(billRecord.getId());
+		pointDetail.setMemberId(shopMember.getId());
+		pointDetail.setUserId(payDto.getLoginUserId());
+		pointDetail.setGxRewardPointValue(gxRewardPointValue);
+		pointDetail.setPoint(userEnablePointValue.multiply(shop.getPoint()).divide(shop.getPointValue()));
+		pointDetail.setPointValue(userEnablePointValue);
+		pointDetail.setLogo(shop.getCover());
+		pointDetail.setBillRecordStatus(billRecord.getPayStatus());
+		pointDetail.setShopId(shop.getId());
+		pointDetail.setName(shop.getName());
+		pointDetailService.save(pointDetail);
+
+
+		//4.计算用户应付金额,修改订单信息
+		//用户实际付款 = 应付 - 可用余额
+		billRecord.setRealPayAmount(yingfu.subtract(userEnablePointValue));
+		billRecord.setPayAmount(decimalFormat.format(billRecord.getRealPayAmount()));
+		billRecord.setPayWay(PayWay.MIX.getName());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecordService.updateById(billRecord);
+
+
+		return billRecord;
+	}
+}

+ 171 - 0
src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelNoEnoughRareZeroStrategy.java

@@ -0,0 +1,171 @@
+package org.springblade.modules.payment.paystrategy.loginuser.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.constant.SystemConstant;
+import org.springblade.common.enums.OrderType;
+import org.springblade.common.enums.PayWay;
+import org.springblade.modules.ldt.activityjoinrecord.entity.ActivityJoinRecord;
+import org.springblade.modules.ldt.activityjoinrecord.service.IActivityJoinRecordService;
+import org.springblade.modules.ldt.billrecord.entity.BillRecord;
+import org.springblade.modules.ldt.billrecord.service.IBillRecordService;
+import org.springblade.modules.ldt.channel.entity.PointChannel;
+import org.springblade.modules.ldt.channel.service.IPointChannelService;
+import org.springblade.modules.ldt.channeluserpoint.entity.ChannelUserPoint;
+import org.springblade.modules.ldt.channeluserpoint.service.IChannelUserPointService;
+import org.springblade.modules.ldt.loginuser.dto.PayDto;
+import org.springblade.modules.ldt.loginuser.entity.LoginUser;
+import org.springblade.modules.ldt.loginuser.service.ILoginUserService;
+import org.springblade.modules.ldt.mall.entity.Mall;
+import org.springblade.modules.ldt.mall.service.IMallService;
+import org.springblade.modules.ldt.member.entity.Member;
+import org.springblade.modules.ldt.member.service.IMemberService;
+import org.springblade.modules.ldt.member.utils.MemberUtil;
+import org.springblade.modules.ldt.pointdetail.entity.PointDetail;
+import org.springblade.modules.ldt.pointdetail.service.IPointDetailService;
+import org.springblade.modules.ldt.shop.entity.Shop;
+import org.springblade.modules.ldt.shop.service.IShopService;
+import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
+import org.springblade.modules.payment.paystrategy.loginuser.IPayStrategy;
+import org.springblade.modules.payment.paystrategy.loginuser.util.PayUtil;
+import org.springblade.modules.system.service.IParamService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created By lidexi in 2021/8/19
+ * 渠道积分不为0,用户余额为0
+ **/
+@Component
+public class ChannelNoEnoughRareZeroStrategy implements IPayStrategy {
+	@Autowired
+	private IParamService paramService;
+	@Autowired
+	private IMemberService memberService;
+	@Autowired
+	private IShopService shopService;
+	@Autowired
+	private IMallService mallService;
+	@Autowired
+	private IActivityJoinRecordService activityJoinRecordService;
+	@Autowired
+	private IBillRecordService billRecordService;
+	@Autowired
+	private IPointChannelService pointChannelService;
+	@Autowired
+	private IChannelUserPointService channelUserPointService;
+	@Autowired
+	private IPointDetailService pointDetailService;
+	@Autowired
+	private IShopYingshouService shopYingshouService;
+	@Autowired
+	private ILoginUserService loginUserService;
+	@Override
+	public BillRecord payBefore(PayDto payDto, LoginUser loginUser, Shop shop) {
+		DecimalFormat decimalFormat = new DecimalFormat("0.00");
+		//生成预订单
+		decimalFormat.setRoundingMode(RoundingMode.CEILING);
+		BillRecord billRecord = new BillRecord();
+		billRecord.setShopId(payDto.getShopId());
+		billRecord.setMallId(shop.getMallId());
+		billRecord.setType(OrderType.USER_PAY.getName());
+		billRecord.setBillsTitle(payDto.getBillsTitle());
+		billRecord.setAppId(payDto.getAppId());
+		billRecord.setOpenId(loginUser.getOpenid());
+		billRecord.setExpireTime(payDto.getExpireTime());
+		billRecord.setPayAmount(decimalFormat.format(payDto.getMoney()));
+		billRecord.setUserId(payDto.getLoginUserId());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecord.setPrice(payDto.getMoney());//总价
+		billRecordService.save(billRecord);
+		billRecord.setSubsidy(BigDecimal.valueOf(1));
+
+		BigDecimal gxServerRate =BigDecimal.valueOf(0); //国信活动服务费
+		BigDecimal scoreServerRate = BigDecimal.valueOf(Double.valueOf(paramService.getValue(CommonConstant.SCORE_SERVIVE_RATE)));//积分服务费
+		Map<String, Member> memberMap = MemberUtil.getMembers(shop,loginUser.getId(),memberService,shopService,mallService);
+
+		Member shopMember = memberMap.get("shopMember");//商店会员
+		Member mallMember = memberMap.get("mallMember");//商场会员
+		Assert.notNull(shopMember,"程序异常");
+		billRecord.setMemberId(shopMember.getId());
+		if(shop.getIsOpenMember() != 1){
+			System.out.println("该商户未开通会员中心");
+			Assert.isTrue(false,"该商户未开通会员中心");
+		}
+
+		//先查询该小B的活动折扣
+		List<ActivityJoinRecord> activityJoinRecords = activityJoinRecordService.getBaseMapper().selectList(new QueryWrapper<>(new ActivityJoinRecord()).lambda()
+			.eq(ActivityJoinRecord::getJoinType, SystemConstant.MALLORSHOP.SHOP.getValue())
+			.eq(ActivityJoinRecord::getJoinId, payDto.getShopId()));
+		if(activityJoinRecords.size()>0){//小B参与了大B的活动
+			//联营折扣
+			billRecord.setSubsidy(activityJoinRecords.get(0).getFinalSupplyPrice().divide(BigDecimal.valueOf(100)));
+			gxServerRate = activityJoinRecords.get(0).getGxRewardSupply().divide(BigDecimal.valueOf(100));
+		}else{//小B没有参加大B的活动,查看小B是否自己有创建活动
+
+		}
+
+
+
+		//用户应付金额 = 商品价格* 小B折扣*大B折扣+国信活动服务费
+		BigDecimal yingfu = payDto.getMoney().multiply(billRecord.getSubsidy().add(gxServerRate));
+		billRecord.setYingfuAmount(yingfu);
+
+
+		//1.查询该大B的积分渠道
+		PointChannel pointChannel = pointChannelService.getBaseMapper().selectOne(new QueryWrapper<>(new PointChannel()).lambda()
+			.eq(PointChannel::getType, SystemConstant.PointChannelType.MALL.getValue())
+			.eq(PointChannel::getRelationId, shop.getMallId()));
+		//2.查询该用户在积分渠道可用积分
+		ChannelUserPoint channelUserPoint = channelUserPointService.getBaseMapper().selectOne(new QueryWrapper<>(new ChannelUserPoint()).lambda()
+			.eq(ChannelUserPoint::getUserId, loginUser.getId()).eq(ChannelUserPoint::getChannelId, pointChannel.getId()));
+
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+
+		Mall mall = mallService.getById(shop.getMallId());
+
+		//1.计算用户大B渠道积分可以抵扣的积分价值,生成用户使用渠道积分支付的记录,状态为待确认
+		//大B渠道国信积分服务费
+		BigDecimal channelGxPointValue = channelUserPoint.getUsablePoint().multiply(gxServerRate);
+		//大B渠道可抵用积分
+		BigDecimal channelEnablePointValue = channelUserPoint.getUsablePoint().multiply(BigDecimal.ONE.subtract(gxServerRate));
+		PointDetail channelPointDetail = new PointDetail();
+		channelPointDetail.setMemberId(mallMember.getId());
+		channelPointDetail.setType(SystemConstant.PointDetailType.USER_PAY.getValue());
+		channelPointDetail.setBillRecordId(billRecord.getId());
+		channelPointDetail.setUserId(payDto.getLoginUserId());
+		channelPointDetail.setGxRewardPointValue(channelGxPointValue);
+		channelPointDetail.setPoint(channelEnablePointValue.multiply(mall.getPoint()).divide(mall.getPointValue()));
+		channelPointDetail.setPointValue(channelEnablePointValue);
+		channelPointDetail.setLogo(mall.getPic());
+		channelPointDetail.setBillRecordStatus(billRecord.getPayStatus());
+		channelPointDetail.setShopId(shop.getId());
+		channelPointDetail.setName(mall.getName());
+		pointDetailService.save(channelPointDetail);
+
+
+
+		//商家应收明细
+		PayUtil.saveShopYingShou(billRecord,pointChannel,channelPointDetail,shop,shopYingshouService);
+
+
+		//还应支付余额
+		yingfu = yingfu.subtract(channelEnablePointValue);
+
+		billRecord.setRealPayAmount(yingfu);
+		billRecord.setPayAmount(decimalFormat.format(yingfu));
+		billRecord.setPayWay(PayWay.MIX.getName());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecordService.updateById(billRecord);
+
+
+		return billRecord;
+	}
+}

+ 194 - 0
src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelZeroRareEnoughStrategy.java

@@ -0,0 +1,194 @@
+package org.springblade.modules.payment.paystrategy.loginuser.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.constant.SystemConstant;
+import org.springblade.common.enums.OrderType;
+import org.springblade.common.enums.PayWay;
+import org.springblade.modules.ldt.activityjoinrecord.entity.ActivityJoinRecord;
+import org.springblade.modules.ldt.activityjoinrecord.service.IActivityJoinRecordService;
+import org.springblade.modules.ldt.billrecord.entity.BillRecord;
+import org.springblade.modules.ldt.billrecord.service.IBillRecordService;
+import org.springblade.modules.ldt.channel.entity.PointChannel;
+import org.springblade.modules.ldt.channel.service.IPointChannelService;
+import org.springblade.modules.ldt.channeluserpoint.entity.ChannelUserPoint;
+import org.springblade.modules.ldt.channeluserpoint.service.IChannelUserPointService;
+import org.springblade.modules.ldt.loginuser.dto.PayDto;
+import org.springblade.modules.ldt.loginuser.entity.LoginUser;
+import org.springblade.modules.ldt.loginuser.service.ILoginUserService;
+import org.springblade.modules.ldt.mall.entity.Mall;
+import org.springblade.modules.ldt.mall.service.IMallService;
+import org.springblade.modules.ldt.member.entity.Member;
+import org.springblade.modules.ldt.member.service.IMemberService;
+import org.springblade.modules.ldt.member.utils.MemberUtil;
+import org.springblade.modules.ldt.pointdetail.entity.PointDetail;
+import org.springblade.modules.ldt.pointdetail.service.IPointDetailService;
+import org.springblade.modules.ldt.shop.entity.Shop;
+import org.springblade.modules.ldt.shop.service.IShopService;
+import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
+import org.springblade.modules.payment.paystrategy.loginuser.IPayStrategy;
+import org.springblade.modules.payment.paystrategy.loginuser.util.PayUtil;
+import org.springblade.modules.system.service.IParamService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created By lidexi in 2021/8/19
+ * 渠道积分为0,用户余额够扣
+ **/
+@Component
+public class ChannelZeroRareEnoughStrategy implements IPayStrategy {
+	@Autowired
+	private IParamService paramService;
+	@Autowired
+	private IMemberService memberService;
+	@Autowired
+	private IShopService shopService;
+	@Autowired
+	private IMallService mallService;
+	@Autowired
+	private IActivityJoinRecordService activityJoinRecordService;
+	@Autowired
+	private IBillRecordService billRecordService;
+	@Autowired
+	private IPointChannelService pointChannelService;
+	@Autowired
+	private IChannelUserPointService channelUserPointService;
+	@Autowired
+	private IPointDetailService pointDetailService;
+	@Autowired
+	private IShopYingshouService shopYingshouService;
+	@Autowired
+	private ILoginUserService loginUserService;
+	@Override
+	public BillRecord payBefore(PayDto payDto, LoginUser loginUser, Shop shop) {
+		DecimalFormat decimalFormat = new DecimalFormat("0.00");
+		//生成预订单
+		decimalFormat.setRoundingMode(RoundingMode.CEILING);
+		BillRecord billRecord = new BillRecord();
+		billRecord.setShopId(payDto.getShopId());
+		billRecord.setMallId(shop.getMallId());
+		billRecord.setType(OrderType.USER_PAY.getName());
+		billRecord.setBillsTitle(payDto.getBillsTitle());
+		billRecord.setAppId(payDto.getAppId());
+		billRecord.setOpenId(loginUser.getOpenid());
+		billRecord.setExpireTime(payDto.getExpireTime());
+		billRecord.setPayAmount(decimalFormat.format(payDto.getMoney()));
+		billRecord.setUserId(payDto.getLoginUserId());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecord.setPrice(payDto.getMoney());//总价
+		billRecordService.save(billRecord);
+		billRecord.setSubsidy(BigDecimal.valueOf(1));
+
+		BigDecimal gxServerRate =BigDecimal.valueOf(0); //国信活动服务费
+		BigDecimal scoreServerRate = BigDecimal.valueOf(Double.valueOf(paramService.getValue(CommonConstant.SCORE_SERVIVE_RATE)));//积分服务费
+		Map<String, Member> memberMap = MemberUtil.getMembers(shop,loginUser.getId(),memberService,shopService,mallService);
+
+		Member shopMember = memberMap.get("shopMember");//商店会员
+		Member mallMember = memberMap.get("mallMember");//商场会员
+		Assert.notNull(shopMember,"程序异常");
+		billRecord.setMemberId(shopMember.getId());
+		if(shop.getIsOpenMember() != 1){
+			System.out.println("该商户未开通会员中心");
+			Assert.isTrue(false,"该商户未开通会员中心");
+		}
+
+		//先查询该小B的活动折扣
+		List<ActivityJoinRecord> activityJoinRecords = activityJoinRecordService.getBaseMapper().selectList(new QueryWrapper<>(new ActivityJoinRecord()).lambda()
+			.eq(ActivityJoinRecord::getJoinType, SystemConstant.MALLORSHOP.SHOP.getValue())
+			.eq(ActivityJoinRecord::getJoinId, payDto.getShopId()));
+		if(activityJoinRecords.size()>0){//小B参与了大B的活动
+			//联营折扣
+			billRecord.setSubsidy(activityJoinRecords.get(0).getFinalSupplyPrice().divide(BigDecimal.valueOf(100)));
+			gxServerRate = activityJoinRecords.get(0).getGxRewardSupply().divide(BigDecimal.valueOf(100));
+		}else{//小B没有参加大B的活动,查看小B是否自己有创建活动
+
+		}
+
+
+
+		//用户应付金额 = 商品价格* 小B折扣*大B折扣+国信活动服务费
+		BigDecimal yingfu = payDto.getMoney().multiply(billRecord.getSubsidy().add(gxServerRate));
+		billRecord.setYingfuAmount(yingfu);
+
+
+		//用户余额够扣,直接扣用户余额
+		billRecord.setRealPayAmount(BigDecimal.ZERO);
+		billRecord.setPayAmount(BigDecimal.ZERO.toString());
+		billRecord.setPayWay(PayWay.POINT.getName());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
+
+		//2.生成用户用积分支付的记录
+		PointDetail pointDetail = new PointDetail();
+		pointDetail.setType(SystemConstant.PointDetailType.USER_PAY.getValue());
+		pointDetail.setBillRecordId(billRecord.getId());
+		pointDetail.setMemberId(shopMember.getId());
+		pointDetail.setUserId(payDto.getLoginUserId());
+		pointDetail.setGxRewardPointValue(yingfu.multiply(gxServerRate));
+		pointDetail.setPoint(yingfu.multiply(shop.getPoint()).divide(shop.getPointValue()));
+		pointDetail.setPointValue(yingfu);
+		pointDetail.setLogo(shop.getCover());
+		pointDetail.setBillRecordStatus(billRecord.getPayStatus());
+		pointDetail.setShopId(shop.getId());
+		pointDetail.setName(shop.getName());
+		pointDetailService.save(pointDetail);
+
+		//3.减少用户可用余额
+		//该用户的余额 = 余额 - 支付的积分价值-国信积分服务费
+		loginUser.setPointValue(loginUser.getPointValue().subtract(pointDetail.getPointValue()).subtract(pointDetail.getGxRewardPointValue()));
+		loginUserService.updateById(loginUser);
+
+		Mall mall = null;
+		if(shop.getMallId() != null){
+			mall = mallService.getById(shop.getMallId());
+		}
+
+		//4.增加商场送积分记录,增加商场积分总价值,增加用户在该渠道的可用积分,增加用户信息的可用总渠道积分价值
+		if(mall != null && mall.getIsOpenMember() == 1){//商场开启会员中心
+
+			//1.查询该大B的积分渠道
+			PointChannel pointChannel = pointChannelService.getBaseMapper().selectOne(new QueryWrapper<>(new PointChannel()).lambda()
+				.eq(PointChannel::getType, SystemConstant.PointChannelType.MALL.getValue())
+				.eq(PointChannel::getRelationId, shop.getMallId()));
+			//2.查询该用户在积分渠道可用积分
+			ChannelUserPoint channelUserPoint = channelUserPointService.getBaseMapper().selectOne(new QueryWrapper<>(new ChannelUserPoint()).lambda()
+				.eq(ChannelUserPoint::getUserId, loginUser.getId()).eq(ChannelUserPoint::getChannelId, pointChannel.getId()));
+			PointDetail mallSendPoint = PayUtil.addMallPointValue(mall, loginUser, billRecord, mallMember, pointDetailService);
+
+
+			//增加该商场的积分总价值
+			mall.setTotalPointValue(mall.getTotalPointValue() != null?mall.getTotalPointValue().add(mallSendPoint.getPointValue()):mallSendPoint.getPointValue());
+			mallService.updateById(mall);
+			//新增该用户在该商场渠道的积分和积分价值
+			channelUserPoint.setUsablePointValue(channelUserPoint.getUsablePointValue().add(mallSendPoint.getPointValue()));
+			channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().add(mallSendPoint.getPoint()));
+			channelUserPoint.setTotalPoint(channelUserPoint.getTotalPoint().add(mallSendPoint.getPoint()));
+			channelUserPointService.updateById(channelUserPoint);
+			//	增加該用戶的渠道总积分价值
+			loginUser.setChannelPointValue(loginUser.getChannelPointValue().add(mallSendPoint.getPointValue()));
+			loginUserService.updateById(loginUser);
+		}
+		//5.新增该用户的积分余额--商家积分成本
+		if(shop.getIsOpenMember() == 1){//判断该商店是否开启会员中心
+			PointDetail shopPointDetail = PayUtil.addShopPointValue(mall,shop,loginUser,billRecord,pointDetailService);
+			shop.setTotalPointValue(shop.getTotalPointValue() != null?shop.getTotalPointValue().add(shopPointDetail.getPointValue()): shopPointDetail.getPointValue());
+			shopService.updateById(shop);
+			//新增用户的余额(积分价值)
+			loginUser.setPointValue(loginUser.getPointValue().add(shopPointDetail.getPointValue()));
+			loginUser.setPoint(loginUser.getPoint().add(shopPointDetail.getPoint()));
+			loginUserService.updateById(loginUser);
+		}
+
+		billRecordService.updateById(billRecord);
+
+		return billRecord;
+
+	}
+}

+ 151 - 0
src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelZeroRareNoEnoughStrategy.java

@@ -0,0 +1,151 @@
+package org.springblade.modules.payment.paystrategy.loginuser.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.constant.SystemConstant;
+import org.springblade.common.enums.OrderType;
+import org.springblade.common.enums.PayWay;
+import org.springblade.modules.ldt.activityjoinrecord.entity.ActivityJoinRecord;
+import org.springblade.modules.ldt.activityjoinrecord.service.IActivityJoinRecordService;
+import org.springblade.modules.ldt.billrecord.entity.BillRecord;
+import org.springblade.modules.ldt.billrecord.service.IBillRecordService;
+import org.springblade.modules.ldt.channel.service.IPointChannelService;
+import org.springblade.modules.ldt.channeluserpoint.service.IChannelUserPointService;
+import org.springblade.modules.ldt.loginuser.dto.PayDto;
+import org.springblade.modules.ldt.loginuser.entity.LoginUser;
+import org.springblade.modules.ldt.loginuser.service.ILoginUserService;
+import org.springblade.modules.ldt.mall.service.IMallService;
+import org.springblade.modules.ldt.member.entity.Member;
+import org.springblade.modules.ldt.member.service.IMemberService;
+import org.springblade.modules.ldt.member.utils.MemberUtil;
+import org.springblade.modules.ldt.pointdetail.entity.PointDetail;
+import org.springblade.modules.ldt.pointdetail.service.IPointDetailService;
+import org.springblade.modules.ldt.shop.entity.Shop;
+import org.springblade.modules.ldt.shop.service.IShopService;
+import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
+import org.springblade.modules.payment.paystrategy.loginuser.IPayStrategy;
+import org.springblade.modules.system.service.IParamService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created By lidexi in 2021/8/19
+ * 渠道积分为0,用户余额不够扣
+ **/
+@Component
+public class ChannelZeroRareNoEnoughStrategy implements IPayStrategy {
+	@Autowired
+	private IParamService paramService;
+	@Autowired
+	private IMemberService memberService;
+	@Autowired
+	private IShopService shopService;
+	@Autowired
+	private IMallService mallService;
+	@Autowired
+	private IActivityJoinRecordService activityJoinRecordService;
+	@Autowired
+	private IBillRecordService billRecordService;
+	@Autowired
+	private IPointChannelService pointChannelService;
+	@Autowired
+	private IChannelUserPointService channelUserPointService;
+	@Autowired
+	private IPointDetailService pointDetailService;
+	@Autowired
+	private IShopYingshouService shopYingshouService;
+	@Autowired
+	private ILoginUserService loginUserService;
+	@Override
+	public BillRecord payBefore(PayDto payDto, LoginUser loginUser, Shop shop) {
+		DecimalFormat decimalFormat = new DecimalFormat("0.00");
+		//生成预订单
+		decimalFormat.setRoundingMode(RoundingMode.CEILING);
+		BillRecord billRecord = new BillRecord();
+		billRecord.setShopId(payDto.getShopId());
+		billRecord.setMallId(shop.getMallId());
+		billRecord.setType(OrderType.USER_PAY.getName());
+		billRecord.setBillsTitle(payDto.getBillsTitle());
+		billRecord.setAppId(payDto.getAppId());
+		billRecord.setOpenId(loginUser.getOpenid());
+		billRecord.setExpireTime(payDto.getExpireTime());
+		billRecord.setPayAmount(decimalFormat.format(payDto.getMoney()));
+		billRecord.setUserId(payDto.getLoginUserId());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecord.setPrice(payDto.getMoney());//总价
+		billRecordService.save(billRecord);
+		billRecord.setSubsidy(BigDecimal.valueOf(1));
+
+		BigDecimal gxServerRate =BigDecimal.valueOf(0); //国信活动服务费
+		BigDecimal scoreServerRate = BigDecimal.valueOf(Double.valueOf(paramService.getValue(CommonConstant.SCORE_SERVIVE_RATE)));//积分服务费
+		Map<String, Member> memberMap = MemberUtil.getMembers(shop,loginUser.getId(),memberService,shopService,mallService);
+
+		Member shopMember = memberMap.get("shopMember");//商店会员
+		Member mallMember = memberMap.get("mallMember");//商场会员
+		Assert.notNull(shopMember,"程序异常");
+		billRecord.setMemberId(shopMember.getId());
+		if(shop.getIsOpenMember() != 1){
+			System.out.println("该商户未开通会员中心");
+			Assert.isTrue(false,"该商户未开通会员中心");
+		}
+
+		//先查询该小B的活动折扣
+		List<ActivityJoinRecord> activityJoinRecords = activityJoinRecordService.getBaseMapper().selectList(new QueryWrapper<>(new ActivityJoinRecord()).lambda()
+			.eq(ActivityJoinRecord::getJoinType, SystemConstant.MALLORSHOP.SHOP.getValue())
+			.eq(ActivityJoinRecord::getJoinId, payDto.getShopId()));
+		if(activityJoinRecords.size()>0){//小B参与了大B的活动
+			//联营折扣
+			billRecord.setSubsidy(activityJoinRecords.get(0).getFinalSupplyPrice().divide(BigDecimal.valueOf(100)));
+			gxServerRate = activityJoinRecords.get(0).getGxRewardSupply().divide(BigDecimal.valueOf(100));
+		}else{//小B没有参加大B的活动,查看小B是否自己有创建活动
+
+		}
+
+
+
+		//用户应付金额 = 商品价格* 小B折扣*大B折扣+国信活动服务费
+		BigDecimal yingfu = payDto.getMoney().multiply(billRecord.getSubsidy().add(gxServerRate));
+		billRecord.setYingfuAmount(yingfu);
+
+		//国信积分服务费
+		BigDecimal gxRewardPointValue = loginUser.getPointValue().multiply(gxServerRate);
+		//可抵扣的余额
+		BigDecimal userEnablePointValue = loginUser.getPointValue().multiply(BigDecimal.ONE.subtract(gxServerRate));
+
+		//用户实际付款 = 应付 - 可用余额
+		billRecord.setRealPayAmount(yingfu.subtract(userEnablePointValue));
+		billRecord.setPayAmount(decimalFormat.format(billRecord.getRealPayAmount()));
+		billRecord.setPayWay(PayWay.MIX.getName());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+
+		//生成用户使用积分余额支付的记录
+		PointDetail pointDetail = new PointDetail();
+		pointDetail.setType(SystemConstant.PointDetailType.USER_PAY.getValue());
+		pointDetail.setBillRecordId(billRecord.getId());
+		pointDetail.setMemberId(shopMember.getId());
+		pointDetail.setUserId(payDto.getLoginUserId());
+		pointDetail.setGxRewardPointValue(gxRewardPointValue);
+		pointDetail.setPoint(userEnablePointValue.multiply(shop.getPoint()).divide(shop.getPointValue()));
+		pointDetail.setPointValue(userEnablePointValue);
+		pointDetail.setLogo(shop.getCover());
+		pointDetail.setBillRecordStatus(billRecord.getPayStatus());
+		pointDetail.setShopId(shop.getId());
+		pointDetail.setName(shop.getName());
+		pointDetailService.save(pointDetail);
+
+		//该用户的余额 = 0 待支付回调后才能扣余额
+//								loginUser.setPointValue(BigDecimal.ZERO);
+//								this.updateById(loginUser);
+
+		billRecordService.updateById(billRecord);
+
+		return billRecord;
+	}
+}

+ 174 - 0
src/main/java/org/springblade/modules/payment/paystrategy/loginuser/impl/ChannelZeroRareZeroStrategy.java

@@ -0,0 +1,174 @@
+package org.springblade.modules.payment.paystrategy.loginuser.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.constant.SystemConstant;
+import org.springblade.common.enums.OrderType;
+import org.springblade.common.enums.PayWay;
+import org.springblade.modules.ldt.activityjoinrecord.entity.ActivityJoinRecord;
+import org.springblade.modules.ldt.activityjoinrecord.service.IActivityJoinRecordService;
+import org.springblade.modules.ldt.billrecord.entity.BillRecord;
+import org.springblade.modules.ldt.billrecord.service.IBillRecordService;
+import org.springblade.modules.ldt.channel.service.IPointChannelService;
+import org.springblade.modules.ldt.channeluserpoint.service.IChannelUserPointService;
+import org.springblade.modules.ldt.loginuser.dto.PayDto;
+import org.springblade.modules.ldt.loginuser.entity.LoginUser;
+import org.springblade.modules.ldt.loginuser.service.ILoginUserService;
+import org.springblade.modules.ldt.mall.entity.Mall;
+import org.springblade.modules.ldt.mall.service.IMallService;
+import org.springblade.modules.ldt.member.entity.Member;
+import org.springblade.modules.ldt.member.service.IMemberService;
+import org.springblade.modules.ldt.member.utils.MemberUtil;
+import org.springblade.modules.ldt.pointdetail.entity.PointDetail;
+import org.springblade.modules.ldt.pointdetail.service.IPointDetailService;
+import org.springblade.modules.ldt.shop.entity.Shop;
+import org.springblade.modules.ldt.shop.service.IShopService;
+import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
+import org.springblade.modules.payment.paystrategy.loginuser.IPayStrategy;
+import org.springblade.modules.system.service.IParamService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created By lidexi in 2021/8/19
+ * 渠道积分为0,用户余额为0
+ **/
+@Component
+public class ChannelZeroRareZeroStrategy implements IPayStrategy {
+	@Autowired
+	private IParamService paramService;
+	@Autowired
+	private IMemberService memberService;
+	@Autowired
+	private IShopService shopService;
+	@Autowired
+	private IMallService mallService;
+	@Autowired
+	private IActivityJoinRecordService activityJoinRecordService;
+	@Autowired
+	private IBillRecordService billRecordService;
+	@Autowired
+	private IPointChannelService pointChannelService;
+	@Autowired
+	private IChannelUserPointService channelUserPointService;
+	@Autowired
+	private IPointDetailService pointDetailService;
+	@Autowired
+	private IShopYingshouService shopYingshouService;
+	@Autowired
+	private ILoginUserService loginUserService;
+
+	@Override
+	public BillRecord payBefore(PayDto payDto, LoginUser loginUser, Shop shop) {
+		DecimalFormat decimalFormat = new DecimalFormat("0.00");
+		//生成预订单
+		decimalFormat.setRoundingMode(RoundingMode.CEILING);
+		BillRecord billRecord = new BillRecord();
+		billRecord.setShopId(payDto.getShopId());
+		billRecord.setMallId(shop.getMallId());
+		billRecord.setType(OrderType.USER_PAY.getName());
+		billRecord.setBillsTitle(payDto.getBillsTitle());
+		billRecord.setAppId(payDto.getAppId());
+		billRecord.setOpenId(loginUser.getOpenid());
+		billRecord.setExpireTime(payDto.getExpireTime());
+		billRecord.setPayAmount(decimalFormat.format(payDto.getMoney()));
+		billRecord.setUserId(payDto.getLoginUserId());
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecord.setPrice(payDto.getMoney());//总价
+		billRecordService.save(billRecord);
+		billRecord.setSubsidy(BigDecimal.valueOf(1));
+
+		BigDecimal gxServerRate = BigDecimal.valueOf(0); //国信活动服务费
+		BigDecimal scoreServerRate = BigDecimal.valueOf(Double.valueOf(paramService.getValue(CommonConstant.SCORE_SERVIVE_RATE)));//积分服务费
+		Map<String, Member> memberMap = MemberUtil.getMembers(shop, loginUser.getId(), memberService, shopService, mallService);
+
+		Member shopMember = memberMap.get("shopMember");//商店会员
+		Member mallMember = memberMap.get("mallMember");//商场会员
+		Assert.notNull(shopMember, "程序异常");
+		billRecord.setMemberId(shopMember.getId());
+		if (shop.getIsOpenMember() != 1) {
+			System.out.println("该商户未开通会员中心");
+			Assert.isTrue(false, "该商户未开通会员中心");
+		}
+
+		//先查询该小B的活动折扣
+		List<ActivityJoinRecord> activityJoinRecords = activityJoinRecordService.getBaseMapper().selectList(new QueryWrapper<>(new ActivityJoinRecord()).lambda()
+			.eq(ActivityJoinRecord::getJoinType, SystemConstant.MALLORSHOP.SHOP.getValue())
+			.eq(ActivityJoinRecord::getJoinId, payDto.getShopId()));
+		if (activityJoinRecords.size() > 0) {//小B参与了大B的活动
+			//联营折扣
+			billRecord.setSubsidy(activityJoinRecords.get(0).getFinalSupplyPrice().divide(BigDecimal.valueOf(100)));
+			gxServerRate = activityJoinRecords.get(0).getGxRewardSupply().divide(BigDecimal.valueOf(100));
+		} else {//小B没有参加大B的活动,查看小B是否自己有创建活动
+
+		}
+
+
+		//用户应付金额 = 商品价格* 小B折扣*大B折扣+国信活动服务费
+		BigDecimal yingfu = payDto.getMoney().multiply(billRecord.getSubsidy().add(gxServerRate));
+		billRecord.setYingfuAmount(yingfu);
+
+		billRecord.setRealPayAmount(yingfu);
+		billRecord.setPayAmount(decimalFormat.format(yingfu));
+		billRecord.setPayWay(PayWay.CASH.getName());//现金支付
+		billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
+		billRecordService.updateById(billRecord);
+
+		Mall mall = null;
+		if (shop.getMallId() != null) {
+			mall = mallService.getById(shop.getMallId());
+			//商场带确认赠送积分
+			PointDetail mallSendPoint = new PointDetail();
+			mallSendPoint.setMemberId(mallMember.getId());
+			mallSendPoint.setMallId(mall.getId());
+			mallSendPoint.setUserId(loginUser.getId());
+			mallSendPoint.setType(SystemConstant.PointDetailType.MALL_SEND.getValue());
+			mallSendPoint.setName(mall.getName());
+			mallSendPoint.setLogo(mall.getPic());
+			mallSendPoint.setPrice(billRecord.getPrice());//总价
+			mallSendPoint.setChannelId(mall.getId());
+			//商场送的积分数 = 总价*商场会员中心每消费一元赠送的积分数
+			mallSendPoint.setPoint(billRecord.getPrice().multiply(mall.getConsumeOnePoint()));
+			//商场赠送的积分价值 = 商场送的积分数*商场会员中心的积分价值/商场会员中心的积分数
+			mallSendPoint.setPointValue(mallSendPoint.getPoint().multiply(mall.getPointValue()).divide(mall.getPoint()));
+			mallSendPoint.setBillRecordId(billRecord.getId());
+			mallSendPoint.setBillRecordStatus(billRecord.getPayStatus());
+			pointDetailService.save(mallSendPoint);
+
+		}
+
+
+		//商户赠送积分待确认
+		PointDetail shopPointDetail = new PointDetail();
+		shopPointDetail.setMallId(mall != null ? mall.getId() : null);
+		shopPointDetail.setShopId(shop.getId());
+		shopPointDetail.setMemberId(shopMember.getId());
+		shopPointDetail.setUserId(loginUser.getId());
+		shopPointDetail.setType(SystemConstant.PointDetailType.SHOP_SEND.getValue());
+		shopPointDetail.setName(shop.getName());
+//						shopPointDetail.setLogo(shop.getShopPic());
+		shopPointDetail.setPrice(billRecord.getPrice());
+		//商家送的积分 = 总价*商家的会议中心每消费一元赠送的积分数
+		shopPointDetail.setPoint(billRecord.getPrice().multiply(shop.getConsumeOnePoint()));
+		//商家赠送的积分价值 = 商家送的积分数*商家会员中心的积分价值/商家会员中心的积分数
+		Assert.isFalse(shop.getIsOpenMember() == 0, "该商户未开启会员中心");
+		Assert.isFalse(shop.getPoint().compareTo(BigDecimal.ZERO) == 0,"会员中心积分数不能为0");
+		shopPointDetail.setPointValue(shopPointDetail.getPoint().multiply(shop.getPointValue()).divide(shop.getPoint()));
+		shopPointDetail.setBillRecordStatus(billRecord.getPayStatus());
+		shopPointDetail.setBillRecordId(billRecord.getId());
+		pointDetailService.save(shopPointDetail);
+
+
+		//用户余额为0时用户需要全额支付,待支付回调成功后才会发放积分
+		return billRecord;
+	}
+
+
+}

+ 103 - 0
src/main/java/org/springblade/modules/payment/paystrategy/loginuser/util/PayUtil.java

@@ -0,0 +1,103 @@
+package org.springblade.modules.payment.paystrategy.loginuser.util;
+
+import org.springblade.common.constant.SystemConstant;
+import org.springblade.modules.ldt.billrecord.entity.BillRecord;
+import org.springblade.modules.ldt.channel.entity.PointChannel;
+
+import org.springblade.modules.ldt.loginuser.entity.LoginUser;
+import org.springblade.modules.ldt.mall.entity.Mall;
+import org.springblade.modules.ldt.member.entity.Member;
+import org.springblade.modules.ldt.pointdetail.entity.PointDetail;
+import org.springblade.modules.ldt.pointdetail.service.IPointDetailService;
+import org.springblade.modules.ldt.shop.entity.Shop;
+import org.springblade.modules.ldt.shopyingshou.entity.ShopYingshou;
+import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
+
+import java.time.LocalDateTime;
+
+/**
+ * Created By lidexi in 2021/8/19
+ **/
+public class PayUtil {
+
+	/**
+	 * 当用户不需要支付时新增商家的积分成本,增加用户的渠道可用积分
+	 * @param mall
+	 * @param loginUser
+	 * @param billRecord
+	 */
+
+	public static PointDetail addMallPointValue(Mall mall, LoginUser loginUser, BillRecord billRecord,
+												Member mallMember, IPointDetailService pointDetailService){
+		PointDetail mallSendPoint = new PointDetail();
+		mallSendPoint.setMallId(mall.getId());
+		mallSendPoint.setMemberId(mallMember.getId());
+		mallSendPoint.setUserId(loginUser.getId());
+		mallSendPoint.setType(SystemConstant.PointDetailType.MALL_SEND.getValue());
+		mallSendPoint.setName(mall.getName());
+		mallSendPoint.setLogo(mall.getPic());
+		mallSendPoint.setPrice(billRecord.getPrice());//总价
+		mallSendPoint.setChannelId(mall.getId());
+		//商场送的积分数 = 总价*商场会员中心每消费一元赠送的积分数
+		mallSendPoint.setPoint(billRecord.getPrice().multiply(mall.getConsumeOnePoint()));
+		//商场赠送的积分价值 = 商场送的积分数*商场会员中心的积分价值/商场会员中心的积分数
+		mallSendPoint.setPointValue(mallSendPoint.getPoint().multiply(mall.getPointValue()).divide(mall.getPoint()));
+		mallSendPoint.setBillRecordId(billRecord.getId());
+		mallSendPoint.setBillRecordStatus(billRecord.getPayStatus());
+		pointDetailService.save(mallSendPoint);
+
+		return mallSendPoint;
+	}
+
+	/**
+	 *  当用户不需要支付时新增商店的积分成本,增加用户的可用积分(余额)
+	 * @param mall
+	 * @param shop
+	 * @param loginUser
+	 * @param billRecord
+	 */
+	public static PointDetail addShopPointValue(Mall mall, Shop shop, LoginUser loginUser, BillRecord billRecord,
+								   IPointDetailService pointDetailService){
+		PointDetail shopPointDetail = new PointDetail();
+		shopPointDetail.setMallId(mall.getId());
+		shopPointDetail.setShopId(shop.getId());
+		shopPointDetail.setUserId(loginUser.getId());
+		shopPointDetail.setType(SystemConstant.PointDetailType.SHOP_SEND.getValue());
+		shopPointDetail.setName(shop.getName());
+//						shopPointDetail.setLogo(shop.getShopPic());
+		shopPointDetail.setPrice(billRecord.getPrice());
+		//商家送的积分 = 总价*商家的会议中心每消费一元赠送的积分数
+		shopPointDetail.setPoint(billRecord.getPrice().multiply(shop.getConsumeOnePoint()));
+		//商家赠送的积分价值 = 商家送的积分数*商家会员中心的积分价值/商家会员中心的积分数
+		shopPointDetail.setPointValue(shopPointDetail.getPoint().multiply(shop.getPointValue()).divide(shop.getPoint()));
+		shopPointDetail.setBillRecordStatus(billRecord.getPayStatus());
+		shopPointDetail.setBillRecordId(billRecord.getId());
+		pointDetailService.save(shopPointDetail);
+		return shopPointDetail;
+
+	}
+
+	/**
+	 * 当用户不需要支付时直接新增商家应收明细
+	 * @param billRecord
+	 * @param pointChannel
+	 * @param pointDetail
+	 * @param shop
+	 */
+	public static void saveShopYingShou(BillRecord billRecord, PointChannel pointChannel, PointDetail pointDetail, Shop shop,
+								  IShopYingshouService shopYingshouService){
+		ShopYingshou shopYingshou = new ShopYingshou();
+		shopYingshou.setBillRecordId(billRecord.getId());
+		shopYingshou.setBillRecordStatus(billRecord.getPayStatus());
+		shopYingshou.setChannelId(pointChannel.getId());
+		shopYingshou.setChannelLogo(pointChannel.getLogo());
+		shopYingshou.setChannelName(pointChannel.getName());
+		shopYingshou.setJsStatus(SystemConstant.JieSuanStatus.jsing.getValue());
+		shopYingshou.setPaymentDays(pointChannel.getPaymentDays());
+		shopYingshou.setJsTime(LocalDateTime.now().plusDays(Long.valueOf(pointChannel.getPaymentDays())));//当前时间加上账期
+		shopYingshou.setPoint(pointDetail.getPoint());
+		shopYingshou.setPointValue(pointDetail.getPointValue());
+		shopYingshou.setShopId(shop.getId());
+		shopYingshouService.save(shopYingshou);
+	}
+}

+ 3 - 3
src/main/java/org/springblade/sms/service/impl/HuaweiSmsServiceImpl.java

@@ -80,9 +80,9 @@ public class HuaweiSmsServiceImpl implements ISmsService {
 		//该手机号码今天获取验证码的次数
 		String redisTimesKey = REDIS_KEY_TIME+phone;
 		String timesValue = redisTemplate.opsForValue().get(redisTimesKey);
-		if(timesValue!=null&&Integer.valueOf(timesValue)>=5){//当天获取验证码次数超过5次
-			return R.data("当天获取验证码次数超过5次");
-		}
+//		if(timesValue!=null&&Integer.valueOf(timesValue)>=5){//当天获取验证码次数超过5次
+//			return R.data("当天获取验证码次数超过5次");
+//		}
 
 		if(timesValue == null){
 			timesValue ="0";