/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.ldt.loginuser.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
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.common.enums.PaymentType;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DigestUtil;
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.LoginUserDTO;
import org.springblade.modules.ldt.loginuser.dto.PayDto;
import org.springblade.modules.ldt.loginuser.entity.LoginUser;
import org.springblade.modules.ldt.loginuser.vo.LoginUserVO;
import org.springblade.modules.ldt.loginuser.mapper.LoginUserMapper;
import org.springblade.modules.ldt.loginuser.service.ILoginUserService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.ldt.mall.entity.Mall;
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.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.system.service.IParamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;

import javax.net.ssl.SNIHostName;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.SQLOutput;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  服务实现类
 *
 * @author BladeX
 * @since 2021-07-28
 */
@Service
public class LoginUserServiceImpl extends BaseServiceImpl<LoginUserMapper, LoginUser> implements ILoginUserService {

	@Autowired
	private  IActivityJoinRecordService activityJoinRecordService;
	@Autowired
	private  IMemberService memberService;
	@Autowired
	private IBillRecordService billRecordService;
	@Autowired
	private IPointDetailService pointDetailService;
	@Autowired
	private IChannelUserPointService channelUserPointService;
	@Autowired
	private IPointChannelService pointChannelService;
	@Autowired
	private IParamService paramService;
	@Autowired
	private IMallService mallService;
	@Autowired
	private IShopYingshouService shopYingshouService;
	@Autowired
	private IShopService shopService;



	@Override
	public IPage<LoginUserVO> selectLoginUserPage(IPage<LoginUserVO> page, LoginUserVO loginUser) {
		return page.setRecords(baseMapper.selectLoginUserPage(page, loginUser));
	}

	@Override
	public LoginUser login(LoginUserDTO loginUserDTO) {
		//通过openid获取用户信息
		LoginUser loginUser = this.getOne(Condition.getQueryWrapper(new LoginUser()).lambda()
			.eq(LoginUser::getOpenid, loginUserDTO.getOpenid()));
		if (loginUser == null) {
			//新用户,保存到数据库
			this.save(loginUserDTO);
			return loginUserDTO;
		}
		return loginUser;
	}

	@Override
	@Transactional
	public BillRecord payBefore(LoginUser loginUser,Shop shop, PayDto payDto) {
		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 = this.getMembers(shop,payDto);
		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;

				if(channelScoreEnough){//大B渠道的积分足够支付
					billRecord.setRealPayAmount(BigDecimal.ZERO);
					billRecord.setPayAmount(BigDecimal.ZERO.toString());
					billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
					billRecord.setPayWay(PayWay.POINT.getName());//全部由积分支付

					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);

					//扣除该用户在该大B渠道的积分价值
					channelUserPoint.setUsedPoint(channelUserPoint.getUsedPoint().add(pointDetail.getPoint()).add(pointDetail.getGxRewardPointValue()));
					channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().subtract(pointDetail.getPoint()).subtract(pointDetail.getGxRewardPointValue()));
					channelUserPointService.updateById(channelUserPoint);


					billRecordService.updateById(billRecord);
					//商家应收明细
					this.saveShopYingShou(billRecord,pointChannel,pointDetail,shop);

					//商场积分成本
					if(mall.getIsOpenMember() == 1){//商场开启会员中心
						this.addMallPointValue(mall,loginUser,billRecord,channelUserPoint);
					}
					//新增该用户的积分余额--商家积分成本
					if(shop.getIsOpenMember() == 1){//判断该商店是否开启会员中心
						this.addShopPointValue(mall,shop,loginUser,billRecord);
					}

					return billRecord;
				}else{//大B渠道的积分不足支付，
					if(channelPointValue.compareTo(BigDecimal.ZERO) == 0){//大B渠道积分价值为零，扣用户余额
						if(loginUser.getPointValue().compareTo(BigDecimal.ZERO) == 0){//用户余额为0
							billRecord.setRealPayAmount(yingfu);
							billRecord.setPayAmount(decimalFormat.format(yingfu));
							billRecord.setPayWay(PayWay.CASH.getName());//现金支付
							billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
							billRecordService.updateById(billRecord);

							//商场带确认赠送积分
							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);

							//商户赠送积分待确认
							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()));
							//商家赠送的积分价值 = 商家送的积分数*商家会员中心的积分价值/商家会员中心的积分数
							if(shop.getIsOpenMember() != 1){
								Assert.isTrue(false,"该商户未开启会员中心");
							}
							shopPointDetail.setPointValue(shopPointDetail.getPoint().multiply(shop.getPointValue()).divide(shop.getPoint()));
							shopPointDetail.setBillRecordStatus(billRecord.getPayStatus());
							shopPointDetail.setBillRecordId(billRecord.getId());
							pointDetailService.save(shopPointDetail);


							//用户余额为0时用户需要全额支付，待支付回调成功后才会发放积分
							return billRecord;
						}else{//余额不为0
							boolean userAccoutEnough = yingfu.subtract(loginUser.getPointValue().multiply(BigDecimal.ONE.add(gxServerRate))).compareTo(BigDecimal.ZERO) > 0 ? false : true;
							if(userAccoutEnough){//余额够扣
								//直接扣余额
								billRecord.setRealPayAmount(BigDecimal.ZERO);
								billRecord.setPayAmount(BigDecimal.ZERO.toString());
								billRecord.setPayWay(PayWay.POINT.getName());
								billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.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(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);

								//该用户的余额 = 余额 - 支付的积分价值-国信积分服务费
								loginUser.setPointValue(loginUser.getPointValue().subtract(pointDetail.getPointValue()).subtract(pointDetail.getGxRewardPointValue()));
								this.updateById(loginUser);

								//商场积分成本
								if(mall.getIsOpenMember() == 1){//商场开启会员中心
									this.addMallPointValue(mall,loginUser,billRecord,channelUserPoint);
								}
								//新增该用户的积分余额--商家积分成本
								if(shop.getIsOpenMember() == 1){//判断该商店是否开启会员中心
									this.addShopPointValue(mall,shop,loginUser,billRecord);
								}

								billRecordService.updateById(billRecord);

								return billRecord;
							}else{//余额不够扣
								//国信积分服务费
								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;
							}
						}
					}else{ //大B渠道积分不为0且不够扣，先扣大B渠道积分价值，再扣用户余额
						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);

						//扣除该用户在该大B渠道的积分价值
						channelUserPoint.setUsedPoint(channelUserPoint.getUsedPoint().add(channelPointDetail.getPoint()).add(channelPointDetail.getGxRewardPointValue()));
						channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().subtract(channelPointDetail.getPoint()).subtract(channelPointDetail.getGxRewardPointValue()));
						channelUserPointService.updateById(channelUserPoint);
						//修改该用户的渠道积分
						loginUser.setChannelPointValue(loginUser.getChannelPointValue().subtract(channelPointDetail.getPointValue()));
						this.updateById(loginUser);
						//商家应收明细
						this.saveShopYingShou(billRecord,pointChannel,channelPointDetail,shop);


						//还应支付余额
						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){//用户余额够扣，扣用户余额即可
								billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
								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);

								//该用户的余额 = 余额 - 支付的积分价值-国信积分服务费
								loginUser.setPointValue(loginUser.getPointValue().subtract(pointDetail.getPointValue()).subtract(pointDetail.getGxRewardPointValue()));
								this.updateById(loginUser);

								//商场积分成本
								if(mall.getIsOpenMember() == 1){//商场开启会员中心
									this.addMallPointValue(mall,loginUser,billRecord,channelUserPoint);
								}
								//新增该用户的积分余额--商家积分成本
								if(shop.getIsOpenMember() == 1){//判断该商店是否开启会员中心
									this.addShopPointValue(mall,shop,loginUser,billRecord);
								}



								billRecordService.updateById(billRecord);

								return billRecord;

							}else{//余额不够扣，先扣除余额，再支付
								//国信积分服务费
								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;
							}
						}else{//用户无余额可扣
							billRecord.setRealPayAmount(yingfu);
							billRecord.setPayAmount(decimalFormat.format(yingfu));
							billRecord.setPayWay(PayWay.MIX.getName());
							billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
							billRecordService.updateById(billRecord);
							return billRecord;
						}
					}
				}
			}


		}else{//该商户没有大B

		}


		boolean scoreEnough =  yingfu.subtract(
			loginUser.getPointValue().multiply(BigDecimal.ONE.add(BigDecimal.valueOf(0.005)))).compareTo(BigDecimal.ZERO) > 0 ?false : true;

		if(scoreEnough){//积分足够扣
			billRecord.setRealPayAmount(BigDecimal.ZERO);

		}else{//积分不够支付
			billRecord.setRealPayAmount(yingfu.subtract(loginUser.getPointValue()));
		}

		//积分明细(从积分渠道中先扣)
		PointDetail pointDetail = new PointDetail();
		pointDetail.setBillRecordId(billRecord.getId());
		pointDetail.setType(SystemConstant.PointDetailType.USER_PAY.getValue());
		pointDetail.setMallId(shop.getMallId());
		pointDetail.setMemberId(shopMember.getId());
		pointDetail.setUserId(loginUser.getId());
		//用户实际支付积分价值
		pointDetail.setPointValue(yingfu);
		//国信服务费
		pointDetail.setGxRewardPointValue(yingfu.subtract(yingfu.multiply(BigDecimal.valueOf(0.005))));
		pointDetail.setPrice(yingfu);
		pointDetailService.save(pointDetail);

		//扣除用户积分价值
//		loginUser.setPointValue(loginUser.getPointValue().subtract(yingfu));
//		this.updateById(loginUser);
		return billRecord;
	}


	/**
	 * 获取用户在该店该商场的会员信息
	 */

	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);
				}
			}

		}

		return memberMap;
	}

	/**
	 * 当用户不需要支付时新增商家的积分成本，增加用户的渠道可用积分
	 * @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);
	}

	/**
	 *  当用户不需要支付时新增商店的积分成本，增加用户的可用积分（余额）
	 * @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);
	}

	/**
	 * 当用户不需要支付时直接新增商家应收明细
	 * @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);
	}



}
