فهرست منبع

Merge branch 'master' of http://192.168.1.218:3000/lianghanqiang/ldt

lianghanqiang 4 سال پیش
والد
کامیت
e77f154197
31فایلهای تغییر یافته به همراه901 افزوده شده و 188 حذف شده
  1. 4 1
      src/main/java/org/springblade/common/aop/TenantIgnoreAop.java
  2. 44 24
      src/main/java/org/springblade/common/cache/PaymentCache.java
  3. 3 0
      src/main/java/org/springblade/common/enums/PaymentScene.java
  4. 23 0
      src/main/java/org/springblade/common/enums/TransferStatus.java
  5. 39 0
      src/main/java/org/springblade/flow/activity/listener/ActivityPlatformCompleteListener.java
  6. 12 2
      src/main/java/org/springblade/gateway/mall_gateway/controller/MallYeePayProductController.java
  7. 15 5
      src/main/java/org/springblade/gateway/shop_gateway/controller/AppShopController.java
  8. 12 2
      src/main/java/org/springblade/gateway/shop_gateway/controller/ShopYeePayProduceController.java
  9. 12 2
      src/main/java/org/springblade/gateway/shop_gateway/service/IAppShopService.java
  10. 53 16
      src/main/java/org/springblade/gateway/shop_gateway/service/impl/AppShopServiceImpl.java
  11. 8 5
      src/main/java/org/springblade/gateway/web_gateway/controller/CensusController.java
  12. 2 0
      src/main/java/org/springblade/gateway/web_gateway/service/ICensusService.java
  13. 6 1
      src/main/java/org/springblade/gateway/web_gateway/service/impl/ICensusServiceImpl.java
  14. 24 0
      src/main/java/org/springblade/ldt/activity/vo/ActivityVO.java
  15. 49 0
      src/main/java/org/springblade/ldt/activity/wrapper/ActivityWrapper.java
  16. 6 21
      src/main/java/org/springblade/ldt/agent/controller/AgentRecordController.java
  17. 7 3
      src/main/java/org/springblade/ldt/agent/service/impl/AgentRecordServiceImpl.java
  18. 87 0
      src/main/java/org/springblade/ldt/bills/entity/TransferRec.java
  19. 3 0
      src/main/java/org/springblade/ldt/bills/entity/WithdrawRec.java
  20. 42 0
      src/main/java/org/springblade/ldt/bills/mapper/TransferRecMapper.java
  21. 36 0
      src/main/java/org/springblade/ldt/bills/mapper/TransferRecMapper.xml
  22. 41 0
      src/main/java/org/springblade/ldt/bills/service/ITransferRecService.java
  23. 41 37
      src/main/java/org/springblade/ldt/bills/service/impl/PointBillsServiceImpl.java
  24. 41 0
      src/main/java/org/springblade/ldt/bills/service/impl/TransferRecServiceImpl.java
  25. 36 0
      src/main/java/org/springblade/ldt/bills/vo/TransferRecVO.java
  26. 45 26
      src/main/java/org/springblade/ldt/mall/service/impl/MallServiceImpl.java
  27. 27 12
      src/main/java/org/springblade/payment/callback/trade/MallChargeCallback.java
  28. 21 2
      src/main/java/org/springblade/payment/callback/trade/MallRechargeCallback.java
  29. 8 5
      src/main/java/org/springblade/payment/callback/trade/UserPointTransferWithdrawCallback.java
  30. 22 0
      src/main/java/org/springblade/payment/handle/entity/HandleTransferData.java
  31. 132 24
      src/main/java/org/springblade/payment/plugin/YeePayPlugin.java

+ 4 - 1
src/main/java/org/springblade/common/aop/TenantIgnoreAop.java

@@ -12,6 +12,7 @@ import org.springblade.core.mp.base.BaseEntity;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tenant.BladeTenantHolder;
+import org.springblade.core.tool.api.R;
 import org.springblade.gateway.web_gateway.service.ICensusService;
 import org.springblade.ldt.agent.entity.AgentBills;
 import org.springblade.ldt.agent.entity.AgentRecord;
@@ -94,8 +95,10 @@ public class TenantIgnoreAop{
 						((Shop)arg).setAgenter(agentUserId);
 					}
 				}
+				return pjp.proceed();
+			}else{
+				return R.fail("该账号未绑定代理,不允许使用");
 			}
-			return pjp.proceed();
 		}finally {
 			BladeTenantHolder.clear();
 		}

+ 44 - 24
src/main/java/org/springblade/common/cache/PaymentCache.java

@@ -2,22 +2,15 @@ package org.springblade.common.cache;
 
 
 import com.alibaba.fastjson.JSON;
-import org.springblade.common.enums.ResCode;
-import org.springblade.common.utils.RSASecretUtil;
 import org.springblade.core.cache.utils.CacheUtil;
-import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.tool.utils.SpringUtil;
 import org.springblade.payment.entity.SuccessParams;
 import org.springblade.payment.handle.entity.HandleDivideData;
-import org.springblade.yeePay.entity.saas.trade.DivideCompleteDto;
-import org.springframework.data.redis.core.RedisTemplate;
+import org.springblade.payment.handle.entity.HandleTransferData;
 
-import java.nio.channels.AcceptPendingException;
 import java.time.Duration;
-import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 
 /**
  * @author: lianghanqiang
@@ -36,8 +29,8 @@ public class PaymentCache {
 
 	private static BladeRedis bladeRedis;
 
-	static   {
-		 bladeRedis = SpringUtil.getBean("bladeRedis");
+	static {
+		bladeRedis = SpringUtil.getBean("bladeRedis");
 	}
 
 	/**
@@ -46,9 +39,9 @@ public class PaymentCache {
 	 * @param md5Str MD5
 	 * @return T 信息实体
 	 */
-	public static <T> T getCodeInfo(String md5Str,Class<T> clazz) {
-		String content = (String) CacheUtil.get(CacheNames.PAYMENT,":"+PAY_INFO,md5Str);
-		return JSON.parseObject(content,clazz);
+	public static <T> T getCodeInfo(String md5Str, Class<T> clazz) {
+		String content = (String) CacheUtil.get(CacheNames.PAYMENT, ":" + PAY_INFO, md5Str);
+		return JSON.parseObject(content, clazz);
 	}
 
 	/**
@@ -57,19 +50,19 @@ public class PaymentCache {
 	 * @param md5Str MD5
 	 * @return
 	 */
-	public static void putCodeInfo(String md5Str,Object object) {
-		CacheUtil.put(CacheNames.PAYMENT,":"+PAY_INFO,md5Str, JSON.toJSONString(object));
+	public static void putCodeInfo(String md5Str, Object object) {
+		CacheUtil.put(CacheNames.PAYMENT, ":" + PAY_INFO, md5Str, JSON.toJSONString(object));
 	}
 
 	/**
 	 * MD5 缓存 二维码信息 key:MD5 ,value: JSON
 	 *
-	 * @param md5Str MD5
+	 * @param md5Str     MD5
 	 * @param expireTime 过期时间
 	 * @return
 	 */
-	public static void putCodeInfoWithEx(String md5Str,Object object,Long expireTime) {
-		bladeRedis.setEx(CacheNames.PAYMENT+":"+PAY_INFO+md5Str,JSON.toJSONString(object),expireTime);
+	public static void putCodeInfoWithEx(String md5Str, Object object, Long expireTime) {
+		bladeRedis.setEx(CacheNames.PAYMENT + ":" + PAY_INFO + md5Str, JSON.toJSONString(object), expireTime);
 	}
 
 //
@@ -103,26 +96,29 @@ public class PaymentCache {
 //		return JSON.parseObject(text,BillRecord.class);
 //	}
 //
+
 	/**
-	 *	缓存订单回调信息
-	 * @param billId 订单id
+	 * 缓存订单回调信息
+	 *
+	 * @param billId        订单id
 	 * @param successParams 回调参数
 	 * @return
 	 */
 	public static void putSuccessParams(String billId, SuccessParams successParams) {
-		bladeRedis.setEx(CacheNames.PAYMENT.concat(ORDER_INFO).concat(billId), JSON.toJSONString(successParams),Duration.ofDays(1L));
+		bladeRedis.setEx(CacheNames.PAYMENT.concat(ORDER_INFO).concat(billId), JSON.toJSONString(successParams), Duration.ofDays(1L));
 //		CacheUtil.put(CacheNames.PAYMENT, ORDER_INFO, billId, JSON.toJSONString(successParams),false);
 	}
 
 	/**
-	 *	获取订单回调信息
+	 * 获取订单回调信息
+	 *
 	 * @param billId 订单id
 	 * @return
 	 */
 	public static SuccessParams getSuccessParams(String billId) {
 //		String params =  CacheUtil.get(CacheNames.PAYMENT, ORDER_INFO, billId,String.class,false);
-		String params =  bladeRedis.get(CacheNames.PAYMENT.concat(ORDER_INFO).concat(billId));
-		return JSON.parseObject(params,SuccessParams.class);
+		String params = bladeRedis.get(CacheNames.PAYMENT.concat(ORDER_INFO).concat(billId));
+		return JSON.parseObject(params, SuccessParams.class);
 	}
 
 
@@ -149,4 +145,28 @@ public class PaymentCache {
 	public static void completeApply(HandleDivideData... data) {
 		bladeRedis.sRem(CacheNames.PAYMENT + ":" + ACCOUNT_APPLY_PREFIX, data);
 	}
+
+	/***
+	 * 	转账申请队列--添加申请
+	 *
+	 * @param data*/
+	public static void addTransferApply(HandleTransferData data) {
+		bladeRedis.sAdd(CacheNames.PAYMENT + ":" + ACCOUNT_APPLY_PREFIX, data);
+	}
+
+	/***
+	 * 	获取-- 转账申请队列
+	 *
+	 * @return*/
+	public static Set<HandleTransferData> getTransferApplyList() {
+		Set<HandleTransferData> authList = bladeRedis.sMembers(CacheNames.PAYMENT + ":" + ACCOUNT_APPLY_PREFIX);
+		return authList;
+	}
+
+	/***
+	 * 	转账申请队列--完成申请
+	 * */
+	public static void completeTransferApply(HandleTransferData... data) {
+		bladeRedis.sRem(CacheNames.PAYMENT + ":" + ACCOUNT_APPLY_PREFIX, data);
+	}
 }

+ 3 - 0
src/main/java/org/springblade/common/enums/PaymentScene.java

@@ -19,6 +19,9 @@ public enum PaymentScene {
 	/* 对公转账 */
 	TRANSFER("transfer"),
 
+	/* 充值 */
+	RECHARGE("recharge"),
+
 	/* 收款码支付 */
 	PAY_CODE("payCode"),
 

+ 23 - 0
src/main/java/org/springblade/common/enums/TransferStatus.java

@@ -0,0 +1,23 @@
+package org.springblade.common.enums;
+
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 租户类型
+ */
+@AllArgsConstructor
+@Getter
+public enum TransferStatus {
+	REQUEST_RECEIVE("WAITING", "转账申请中"),
+	SUCCESS("DONE", "转账已完成"),
+	FAIL("FAIL", "转账失败");
+
+	@EnumValue
+	private String value;
+	@JsonValue
+	private String dec;
+}

+ 39 - 0
src/main/java/org/springblade/flow/activity/listener/ActivityPlatformCompleteListener.java

@@ -4,13 +4,22 @@ import cn.hutool.core.convert.Convert;
 import lombok.NoArgsConstructor;
 import org.flowable.engine.delegate.TaskListener;
 import org.flowable.task.service.delegate.DelegateTask;
+import org.springblade.common.enums.AppConstant;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.tool.utils.SpringUtil;
 import org.springblade.flow.activity.entity.ActivityEnum;
 import org.springblade.ldt.activity.entity.Activity;
+import org.springblade.ldt.activity.entity.JoinRecord;
 import org.springblade.ldt.activity.service.IActivityService;
+import org.springblade.ldt.activity.service.IJoinRecordService;
+import org.springblade.ldt.mall.entity.Mall;
+import org.springblade.ldt.mall.service.IMallService;
+import org.springblade.ldt.shop.entity.Shop;
+import org.springblade.ldt.shop.service.IShopService;
 import org.springframework.util.Assert;
 
+import java.util.Optional;
+
 /**
  * @author: lianghanqiang
  * @description: 平台审核完毕处理
@@ -20,9 +29,15 @@ import org.springframework.util.Assert;
 public class ActivityPlatformCompleteListener implements TaskListener {
 
 	private IActivityService activityService;
+	private IJoinRecordService joinRecordService;
+	private IShopService shopService;
+	private IMallService mallService;
 
 	{
 		activityService = SpringUtil.getBean(IActivityService.class);
+		joinRecordService = SpringUtil.getBean(IJoinRecordService.class);
+		shopService = SpringUtil.getBean(IShopService.class);
+		mallService = SpringUtil.getBean(IMallService.class);
 	}
 
 	@Override
@@ -33,8 +48,32 @@ public class ActivityPlatformCompleteListener implements TaskListener {
 
 		Activity activity = activityService.getById(businessId);
 
+		this.joinActivity(activity);
+
 		activity.setAuditStatus(pass? ActivityEnum.PASS.name():ActivityEnum.FAIL.name());
 
 		Assert.isTrue(activityService.saveOrUpdate(activity),()->{throw  new ServiceException("活动审核: 平台审核完毕处理异常");});
 	}
+
+	/**
+	 * 参与活动
+	 * @param activity
+	 */
+	private void joinActivity(Activity activity){
+		JoinRecord joinRecord = new JoinRecord();
+		joinRecord.setActivityId(activity.getId());
+		joinRecord.setJoinId(activity.getLaunchId());
+		joinRecord.setJoinType(activity.getLaunchType());
+		if (activity.getLaunchType().equals(AppConstant.PLATFORM.SHOP.name())) {
+			Shop shop = shopService.getById(activity.getLaunchId());
+			joinRecord.setJoinName(Optional.ofNullable(shop).map(Shop::getName).orElse("暂无名称"));
+			joinRecord.setJoinLogo(Optional.ofNullable(shop).map(Shop::getCover).orElse(""));
+		} else if (activity.getLaunchType().equals(AppConstant.PLATFORM.MALL.name())) {
+			Mall mall = mallService.getById(activity.getLaunchId());
+			joinRecord.setJoinName(Optional.ofNullable(mall).map(Mall::getMallName).orElse("暂无名称"));
+			joinRecord.setJoinLogo(Optional.ofNullable(mall).map(Mall::getLogo).orElse(""));
+		}
+		joinRecord.setDiscount(activity.getDiscount());
+		joinRecordService.saveOrUpdate(joinRecord);
+	}
 }

+ 12 - 2
src/main/java/org/springblade/gateway/mall_gateway/controller/MallYeePayProductController.java

@@ -8,8 +8,10 @@ import com.yeepay.yop.sdk.service.common.response.YopResponse;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.tenant.annotation.TenantIgnore;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.ldt.fee.entity.ProductFee;
@@ -35,6 +37,7 @@ import java.util.UUID;
 @RequestMapping("/mall/yeepay/product/fee")
 @Api(tags = "大B商户易宝费率控制")
 @AllArgsConstructor
+@Slf4j
 public class MallYeePayProductController {
 	private final IMallService mallService;
 
@@ -95,8 +98,10 @@ public class MallYeePayProductController {
 
 	@ApiOperation("产品费率变更通知")
 	@PostMapping("modifyProductFeeNotify")
+	@TenantIgnore
 	public void modifyProductFeeNotify(HttpServletRequest request){
 		JSONObject jsonObject = yeePayService.deCodeNotifyData(request.getParameterMap().get("cipherText")[0]);
+		log.info("产品费率变更通知内容:{}",jsonObject);
 		Assert.notNull(jsonObject,"产品费率变更通知回调信息为空");
 		ProductFee productFee = jsonObject.toJavaObject(ProductFee.class);
 		ProductFee oldProductFee = productFeeService.getOne(Wrappers.<ProductFee>lambdaQuery()
@@ -104,8 +109,13 @@ public class MallYeePayProductController {
 			.eq(ProductFee::getMerchantNo, productFee.getMerchantNo())
 			.eq(ProductFee::getApplicationNo, productFee.getApplicationNo()));
 		if(oldProductFee!=null){
-			BeanUtil.copyProperties(productFee,oldProductFee);
-			productFeeService.updateById(oldProductFee);
+			log.error("旧数据:{}",oldProductFee);
+			oldProductFee.setRequestNo(productFee.getApplicationStatus());
+			oldProductFee.setAgreementSignUrl(productFee.getAgreementSignUrl());
+			oldProductFee.setAuditOpinion(productFee.getAuditOpinion());
+			oldProductFee.setProgressDescription(productFee.getProgressDescription());
+			productFeeService.update(oldProductFee,Wrappers.<ProductFee>lambdaQuery()
+				.eq(ProductFee::getId,oldProductFee.getId()));
 		}
 	}
 

+ 15 - 5
src/main/java/org/springblade/gateway/shop_gateway/controller/AppShopController.java

@@ -29,9 +29,9 @@ import org.springblade.ldt.shop.vo.ShopVO;
 import org.springblade.ldt.shop.wrapper.ShopWrapper;
 import org.springblade.ldt.user.entity.Member;
 import org.springblade.ldt.user.service.IMemberService;
+import org.springblade.yeePay.common.YeepayApiConstant;
 import org.springframework.web.bind.annotation.*;
 
-import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.util.Date;
 import java.util.Map;
@@ -80,16 +80,18 @@ public class AppShopController {
 
 	@PostMapping("userBalanceWithdraw")
 	@ApiOperation(value = "用户余额提现(结算)")
-	public R settleSelfSettleApply(@RequestBody WithdrawRec withdrawRec) {
+	public R userBalanceWithdraw(@RequestBody WithdrawRec withdrawRec) {
 		withdrawRec.setType(WithdrawType.BALANCE_WITHDRAW);
-		return R.data(appShopService.userWithdraw(withdrawRec));
+		withdrawRec.setReceiveType(YeepayApiConstant.receiveType.REAL_TIME.name());
+		return R.data(appShopService.userBalanceWithdraw(withdrawRec));
 	}
 
 	@PostMapping("userPointWithdraw")
 	@ApiOperation(value = "用户积分提现")
 	public R userPointWithdraw(@RequestBody WithdrawRec withdrawRec) {
 		withdrawRec.setType(WithdrawType.POINT_WITHDRAW);
-		return R.data(appShopService.userWithdraw(withdrawRec));
+		withdrawRec.setReceiveType(YeepayApiConstant.receiveType.REAL_TIME.name());
+		return R.data(appShopService.userPointWithdraw(withdrawRec));
 	}
 
 	@GetMapping("indexInfo")
@@ -122,8 +124,16 @@ public class AppShopController {
 				.or()
 				.eq(Bills::getPayStatus, AppConstant.BillPayStatus.已完结.name())));
 
+
+		BalanceAccountInfoVO balanceAccountInfoVO = appShopService.queryBalance(shopId);
+		//今日现金收益
+		BigDecimal todayBalance = Convert.toBigDecimal(balanceAccountInfoVO.getTodayNum());
+		//今日积分收益
+		BigDecimal todayPoint = this.getTodayPoint(shopId);
+		//渠道积分今日收益
+		BigDecimal todayChannel = this.getTodayCharge(shopId);
 		//今日营收
-		BigDecimal todayCharge = this.todayRevenue(shopId);
+		BigDecimal todayCharge = BigDecimal.ZERO.add(todayBalance).add(todayPoint).add(todayChannel);
 
 		return R.data(
 			IndexVO.builder()

+ 12 - 2
src/main/java/org/springblade/gateway/shop_gateway/controller/ShopYeePayProduceController.java

@@ -7,9 +7,11 @@ import com.yeepay.yop.sdk.service.common.response.YopResponse;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.tenant.annotation.TenantIgnore;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.ldt.fee.entity.ProductFee;
@@ -35,6 +37,7 @@ import java.util.UUID;
 @RequestMapping("/shop/yeepay/product/fee")
 @Api(tags = "小B商户易宝费率控制")
 @AllArgsConstructor
+@Slf4j
 public class ShopYeePayProduceController {
 	private final IShopService shopService;
 
@@ -94,8 +97,10 @@ public class ShopYeePayProduceController {
 
 	@ApiOperation("产品费率变更通知")
 	@PostMapping("modifyProductFeeNotify")
+	@TenantIgnore
 	public void modifyProductFeeNotify(HttpServletRequest request){
 		JSONObject jsonObject = yeePayService.deCodeNotifyData(request.getParameterMap().get("cipherText")[0]);
+		log.info("产品费率变更通知内容:{}",jsonObject);
 		Assert.notNull(jsonObject,"产品费率变更通知回调信息为空");
 		ProductFee productFee = jsonObject.toJavaObject(ProductFee.class);
 		ProductFee oldProductFee = productFeeService.getOne(Wrappers.<ProductFee>lambdaQuery()
@@ -103,8 +108,13 @@ public class ShopYeePayProduceController {
 			.eq(ProductFee::getMerchantNo, productFee.getMerchantNo())
 			.eq(ProductFee::getApplicationNo, productFee.getApplicationNo()));
 		if(oldProductFee!=null){
-			BeanUtil.copyProperties(productFee,oldProductFee);
-			productFeeService.updateById(oldProductFee);
+			log.error("旧数据:{}",oldProductFee);
+			oldProductFee.setRequestNo(productFee.getApplicationStatus());
+			oldProductFee.setAgreementSignUrl(productFee.getAgreementSignUrl());
+			oldProductFee.setAuditOpinion(productFee.getAuditOpinion());
+			oldProductFee.setProgressDescription(productFee.getProgressDescription());
+			productFeeService.update(oldProductFee,Wrappers.<ProductFee>lambdaQuery()
+				.eq(ProductFee::getId,oldProductFee.getId()));
 		}
 	}
 

+ 12 - 2
src/main/java/org/springblade/gateway/shop_gateway/service/IAppShopService.java

@@ -53,15 +53,25 @@ public interface IAppShopService extends IService<Shop> {
 	 * @param withdrawRec: 提现信息
 	 * @Return void
 	 * @Author July
-	 * @Description 用户提现(积分 / 余额)
+	 * @Description 用户余额提现
 	 * @Date 2021/10/19 16:14
 	 */
-	Long userWithdraw(WithdrawRec withdrawRec);
+	Long userBalanceWithdraw(WithdrawRec withdrawRec);
 
 	/**
 	 * 查询商户余额
+	 *
 	 * @param shopId
 	 * @return
 	 */
 	BalanceAccountInfoVO queryBalance(Long shopId);
+
+	/**
+	 * @param withdrawRec: 提现信息
+	 * @Return Long
+	 * @Author July
+	 * @Description 用户积分提现
+	 * @Date 2021/10/22 9:22
+	 */
+	Long userPointWithdraw(WithdrawRec withdrawRec);
 }

+ 53 - 16
src/main/java/org/springblade/gateway/shop_gateway/service/impl/AppShopServiceImpl.java

@@ -24,6 +24,7 @@ import org.apache.commons.lang3.ObjectUtils;
 import org.springblade.common.cache.PlatformCache;
 import org.springblade.common.config.entity.PlatformConfig;
 import org.springblade.common.enums.AppConstant;
+import org.springblade.common.enums.TransferStatus;
 import org.springblade.common.enums.WithdrawStatus;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.tool.api.R;
@@ -33,7 +34,9 @@ import org.springblade.flow.shop.service.impl.AuditShopService;
 import org.springblade.gateway.shop_gateway.entity.dto.ShopAuditDto;
 import org.springblade.gateway.shop_gateway.entity.vo.BalanceAccountInfoVO;
 import org.springblade.gateway.shop_gateway.service.IAppShopService;
+import org.springblade.ldt.bills.entity.TransferRec;
 import org.springblade.ldt.bills.entity.WithdrawRec;
+import org.springblade.ldt.bills.service.ITransferRecService;
 import org.springblade.ldt.bills.service.IWithdrawRecService;
 import org.springblade.ldt.mall.entity.Mall;
 import org.springblade.ldt.mall.service.IMallService;
@@ -43,7 +46,6 @@ import org.springblade.ldt.shop.mapper.ShopMapper;
 import org.springblade.ldt.shop.service.IAuditService;
 import org.springblade.ldt.user.entity.LoginUser;
 import org.springblade.ldt.user.service.ILoginUserService;
-import org.springblade.ldt.user.service.IUserBankService;
 import org.springblade.wx.config.ConfigForClient;
 import org.springblade.wx.config.ConfigForMall;
 import org.springblade.wx.config.ConfigForShop;
@@ -83,6 +85,7 @@ public class AppShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements
 	private ConfigForMall configForMall;
 	private ConfigForShop configForShop;
 	private IWithdrawRecService withdrawRecService;
+	private ITransferRecService transferRecService;
 	private YeepaySaasService yeepaySaasService;
 
 
@@ -171,8 +174,7 @@ public class AppShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements
 	}
 
 	@Override
-	@Transactional
-	public Long userWithdraw(WithdrawRec withdrawRec) {
+	public Long userBalanceWithdraw(WithdrawRec withdrawRec) {
 		if (ObjectUtils.isEmpty(withdrawRec) || ObjectUtils.isEmpty(withdrawRec.getOwnerId())) {
 			throw new ServiceException(ResultCode.PARAM_MISS);
 		}
@@ -180,9 +182,53 @@ public class AppShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements
 		if (ObjectUtils.isEmpty(shop)) {
 			throw new ServiceException(ResultCode.NOT_FOUND);
 		}
+
+		BigDecimal feeRate = getFeeRate(withdrawRec.getPrice());
+		//国信手续费
+		BigDecimal fee = withdrawRec.getPrice().multiply(feeRate);
+		withdrawRec.setPlatformFee(fee);
+		//实际提现金额
+		BigDecimal actualPrice = withdrawRec.getPrice().subtract(fee);
+		withdrawRec.setActualPrice(actualPrice);
 		withdrawRec.setWithdrawStatus(WithdrawStatus.WAITING.getValue());
+		withdrawRecService.saveOrUpdate(withdrawRec);
+
+		return withdrawRec.getId();
+	}
+
+	@Override
+	public Long userPointWithdraw(WithdrawRec withdrawRec) {
+		//1.保存提现记录
+		Long withdrawId = userBalanceWithdraw(withdrawRec);
+
+		//2.转账金额 = 提现金额 - 提现金额 * 国信手续费率
+		BigDecimal fee = withdrawRec.getPrice().multiply(getFeeRate(withdrawRec.getPrice()));
+		BigDecimal actualPrice = withdrawRec.getPrice().subtract(fee);
+
+		//3.保存转账记录
+		TransferRec transferRec = new TransferRec();
+		transferRec.setChannel(withdrawRec.getChannel());
+		transferRec.setTransferStatus(TransferStatus.REQUEST_RECEIVE);
+		transferRec.setOwnerId(withdrawRec.getOwnerId());
+		transferRec.setPrice(actualPrice);
+		transferRec.setActualPrice(actualPrice);
+		transferRec.setFeeChargeSide(YeepayApiConstant.feeChargeSide.OUTSIDE);
+		transferRec.setPlatformFee(BigDecimal.ZERO);//转账平台暂时不收取手续费
+		transferRec.setWithdrawId(withdrawId);//提现记录id
+		transferRec.setTenantId(withdrawRec.getTenantId());
+		transferRecService.saveOrUpdate(transferRec);
+
+		return transferRec.getId();
+	}
+
+	/**
+	 * 提现处理国信手续费
+	 *
+	 * @param amount 提现金额
+	 * @return 手续费率
+	 */
+	private BigDecimal getFeeRate(BigDecimal amount) {
 
-		//积分提现处理国信手续费
 		PlatformConfig platformConfig = PlatformCache.platFormConfig();
 		Assert.notNull(platformConfig, "提现异常,请联系管理员!");
 		List<PlatformConfig.WithdrawConfig> items = platformConfig.getWithdrawConfigList();
@@ -192,27 +238,18 @@ public class AppShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements
 			BigDecimal min = BigDecimal.valueOf(item.getMinBalance());
 			BigDecimal max = BigDecimal.valueOf(item.getMaxBalance());
 			//最小提现金额 <= 提现金额 <= 最大提现金额
-			boolean flag = withdrawRec.getPrice().compareTo(min) >= 0 && withdrawRec.getPrice().compareTo(max) <= 0;
+			boolean flag = amount.compareTo(min) >= 0 && amount.compareTo(max) <= 0;
 			if (flag) {
 				feeRate = BigDecimal.valueOf(item.getRate());
 			}
 		}
-		//国信手续费
-		BigDecimal fee = withdrawRec.getPrice().multiply(feeRate);
-		withdrawRec.setPlatformFee(fee);
-
-		//实际提现手续费
-		BigDecimal actualPrice = withdrawRec.getPrice().subtract(fee);
-		withdrawRec.setActualPrice(actualPrice);
-		withdrawRecService.saveOrUpdate(withdrawRec);
-
-		return withdrawRec.getId();
+		return feeRate;
 	}
 
 	@Override
 	public BalanceAccountInfoVO queryBalance(Long shopId) {
 		Shop shop = this.getById(shopId);
-		SettleBalanceQueryDto settleBalanceQueryDto = new SettleBalanceQueryDto(YeepayApiConstant.operatePeriod.ALL.name(),null);
+		SettleBalanceQueryDto settleBalanceQueryDto = new SettleBalanceQueryDto(YeepayApiConstant.operatePeriod.ALL.name(), null);
 		settleBalanceQueryDto.setMerchantNo(shop.getMerchantNo());
 		settleBalanceQueryDto.setParentMerchantNo(yeePayConst.getPlatformServiceNo());
 		JSONObject settleBalance = JSON.parseObject(yeepaySaasService.settleBalanceQuery(settleBalanceQueryDto).getStringResult());

+ 8 - 5
src/main/java/org/springblade/gateway/web_gateway/controller/CensusController.java

@@ -10,6 +10,8 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import lombok.SneakyThrows;
+import org.springblade.common.aop.core.TenantAop;
+import org.springblade.common.constant.Agent;
 import org.springblade.common.enums.AppConstant;
 import org.springblade.common.enums.OrderType;
 import org.springblade.core.log.exception.ServiceException;
@@ -18,10 +20,10 @@ import org.springblade.core.tenant.annotation.TenantIgnore;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.ObjectUtil;
-import org.springblade.gateway.web_gateway.entity.vo.YeePayInfoVO;
 import org.springblade.gateway.web_gateway.entity.vo.TenantCensusAddTrendVo;
 import org.springblade.gateway.web_gateway.entity.vo.TenantCensusBillsTrendVo;
 import org.springblade.gateway.web_gateway.entity.vo.TenantCensusVo;
+import org.springblade.gateway.web_gateway.entity.vo.YeePayInfoVO;
 import org.springblade.gateway.web_gateway.service.ICensusService;
 import org.springblade.ldt.agent.entity.AgentBills;
 import org.springblade.ldt.agent.entity.AgentRecord;
@@ -176,6 +178,7 @@ public class CensusController {
 	@GetMapping("/getAgentInfo")
 	@ApiOperationSupport(order = 8)
 	@ApiOperation(value = "代理商信息")
+	@TenantAop(agent = Agent.roleName)
 	public R<AgentInfoVO> agentInfo(BladeUser bladeUser) {
 		return R.data(agentRecordService.getAgentInfo(bladeUser.getUserId()));
 	}
@@ -197,7 +200,7 @@ public class CensusController {
 
 	@GetMapping("/getAgentTenantCensusCount")
 	@ApiOperation(value = "获取代理租户数据数量统计")
-	@TenantIgnore
+	@TenantAop(agent = Agent.roleName)
 	public R getAgentTenantCensusCount(BladeUser bladeUser) {
 		Long userId = censusService.getAgentUserId(bladeUser);
 		Map<String, Object> map = agentBillsService.getMap(new QueryWrapper<AgentBills>()
@@ -211,7 +214,7 @@ public class CensusController {
 
 	@GetMapping("/getAgentTenantTodayCensusCount")
 	@ApiOperation(value = "获取今日代理租户数据数量统计")
-	@TenantIgnore
+	@TenantAop(agent = Agent.roleName)
 	public R getAgentTenantTodayCensusCount(BladeUser bladeUser) {
 		Long userId = censusService.getAgentUserId(bladeUser);
 		String date = DateUtil.format(new Date(), DateUtil.PATTERN_DATE);
@@ -229,7 +232,7 @@ public class CensusController {
 
 	@GetMapping("/getTenantAgentBills")
 	@ApiOperation(value = "获取租户平台代理收益统计")
-	@TenantIgnore
+	@TenantAop(agent = Agent.roleName)
 	public R getTenantAgentBills(@RequestParam Date time, BladeUser bladeUser) {
 		Long userId = censusService.getAgentUserId(bladeUser);
 		return R.data(new TenantCensusBillsTrendVo()
@@ -243,7 +246,7 @@ public class CensusController {
 
 	@GetMapping("/getAgentTenantAddTrend")
 	@ApiOperation(value = "获取代理租户平台新增趋势统计")
-	@TenantIgnore
+	@TenantAop(agent = Agent.roleName)
 	public R getAgentTenantAddTrend(@RequestParam Date time, BladeUser bladeUser) {
 		Long userId = censusService.getAgentUserId(bladeUser);
 		return R.data(new TenantCensusAddTrendVo()

+ 2 - 0
src/main/java/org/springblade/gateway/web_gateway/service/ICensusService.java

@@ -4,4 +4,6 @@ import org.springblade.core.secure.BladeUser;
 
 public interface ICensusService {
     Long getAgentUserId(BladeUser bladeUser);
+
+    Long getAgentUserId(Long userId);
 }

+ 6 - 1
src/main/java/org/springblade/gateway/web_gateway/service/impl/ICensusServiceImpl.java

@@ -15,9 +15,14 @@ public class ICensusServiceImpl implements ICensusService {
 
 	@Override
 	public Long getAgentUserId(BladeUser bladeUser) {
+		return getAgentUserId(bladeUser.getUserId());
+	}
+
+	@Override
+	public Long getAgentUserId(Long userId) {
 		AgentRecord agentRecord = agentRecordService.getOne(Wrappers.<AgentRecord>lambdaQuery()
 			.select(AgentRecord::getAccountId) //只查询代理的id
-			.eq(AgentRecord::getUserId, bladeUser.getUserId()) //根据用户id去查询代理id
+			.eq(AgentRecord::getUserId, userId) //根据用户id去查询代理id
 			.last("limit 0,1")); //如果有多个默认取第一个
 		if(agentRecord!=null){
 			return agentRecord.getAccountId();

+ 24 - 0
src/main/java/org/springblade/ldt/activity/vo/ActivityVO.java

@@ -16,6 +16,7 @@
  */
 package org.springblade.ldt.activity.vo;
 
+import io.swagger.annotations.ApiModelProperty;
 import org.springblade.ldt.activity.entity.Activity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -33,4 +34,27 @@ import io.swagger.annotations.ApiModel;
 public class ActivityVO extends Activity {
 	private static final long serialVersionUID = 1L;
 
+	@ApiModelProperty(value = "商户名称")
+	private String shopName;
+
+	@ApiModelProperty(value = "主体信息")
+	private String entity;
+
+	@ApiModelProperty(value = "法人姓名")
+	private String legalPerson;
+
+	@ApiModelProperty(value = "具体地址")
+	private String address;
+
+	@ApiModelProperty(value = "身份证号")
+	private String idCard;
+
+	@ApiModelProperty(value = "身份证-正面")
+	private String idCardFront;
+
+	@ApiModelProperty(value = "身份证-反面")
+	private String idCardContrary;
+
+	@ApiModelProperty(value = "营业执照")
+	private String businessLicense;
 }

+ 49 - 0
src/main/java/org/springblade/ldt/activity/wrapper/ActivityWrapper.java

@@ -16,10 +16,23 @@
  */
 package org.springblade.ldt.activity.wrapper;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springblade.common.enums.AppConstant;
+import org.springblade.common.utils.SpringContextHolder;
+import org.springblade.common.utils.TenantIgnoreUtil;
 import org.springblade.core.mp.support.BaseEntityWrapper;
 import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.ldt.activity.entity.Activity;
 import org.springblade.ldt.activity.vo.ActivityVO;
+import org.springblade.ldt.mall.entity.Mall;
+import org.springblade.ldt.mall.service.IMallService;
+import org.springblade.ldt.shop.entity.Audit;
+import org.springblade.ldt.shop.entity.Shop;
+import org.springblade.ldt.shop.service.IAuditService;
+import org.springblade.ldt.shop.service.IShopService;
+
 import java.util.Objects;
 
 /**
@@ -30,6 +43,14 @@ import java.util.Objects;
  */
 public class ActivityWrapper extends BaseEntityWrapper<Activity, ActivityVO>  {
 
+	private static IShopService shopService = SpringContextHolder.getBean(IShopService.class);
+
+	private static IMallService mallService = SpringContextHolder.getBean(IMallService.class);
+
+	private static IAuditService auditService = SpringContextHolder.getBean(IAuditService.class);
+
+	private static TenantIgnoreUtil tenantIgnoreUtil = SpringContextHolder.getBean(TenantIgnoreUtil.class);
+
 	public static ActivityWrapper build() {
 		return new ActivityWrapper();
  	}
@@ -38,11 +59,39 @@ public class ActivityWrapper extends BaseEntityWrapper<Activity, ActivityVO>  {
 	public ActivityVO entityVO(Activity activity) {
 		ActivityVO activityVO = Objects.requireNonNull(BeanUtil.copy(activity, ActivityVO.class));
 
+		if(ObjectUtils.isNotEmpty(activityVO)){
+			//获取审核数据
+			Audit audit = (Audit) tenantIgnoreUtil.getOne(auditService, Wrappers.<Audit>lambdaQuery().eq(Audit::getEntityId, activityVO.getLaunchId()));
+			if(ObjectUtils.isNotEmpty(audit)){
+				activityVO.setEntity(audit.getEntity());
+				activityVO.setIdCard(audit.getIdCard());
+				activityVO.setIdCardFront(audit.getIdCardFront());
+				activityVO.setIdCardContrary(audit.getIdCardContrary());
+				activityVO.setBusinessLicense(audit.getBusinessLicense());
+			}
+			//查询商户信息
+			if(StringUtils.equals(activityVO.getLaunchType(), AppConstant.PLATFORM.SHOP.getName())){
+				Shop shop = (Shop) tenantIgnoreUtil.getById(shopService, activityVO.getLaunchId());
+				if(ObjectUtils.isNotEmpty(shop)){
+					activityVO.setShopName(shop.getName());
+					activityVO.setLegalPerson(shop.getPersonName());
+					activityVO.setAddress(shop.getAddress());
+				}
+			}else if(StringUtils.equals(activityVO.getLaunchType(), AppConstant.PLATFORM.MALL.getName())){ //查询商场信息
+				Mall mall = (Mall) tenantIgnoreUtil.getById(mallService, activityVO.getLaunchId());
+				if(ObjectUtils.isNotEmpty(mall)){
+					activityVO.setShopName(mall.getMallName());
+					activityVO.setLegalPerson(mall.getPersonName());
+					activityVO.setAddress(mall.getAddress());
+				}
+			}
+		}
 		//User createUser = UserCache.getUser(activity.getCreateUser());
 		//User updateUser = UserCache.getUser(activity.getUpdateUser());
 		//activityVO.setCreateUserName(createUser.getName());
 		//activityVO.setUpdateUserName(updateUser.getName());
 
+
 		return activityVO;
 	}
 

+ 6 - 21
src/main/java/org/springblade/ldt/agent/controller/AgentRecordController.java

@@ -54,23 +54,15 @@ public class AgentRecordController extends BladeController {
 
 	private final IAgentRecordService agentRecordService;
 
-	private final TenantIgnoreUtil tenantIgnoreUtil;
-
 	/**
 	 * 详情
 	 */
 	@GetMapping("/detail")
 	@ApiOperationSupport(order = 1)
 	@ApiOperation(value = "详情", notes = "传入agentRecord")
-	public R<AgentRecordVO> detail(AgentRecord agentRecord,BladeUser bladeUser) {
-		AgentRecord detail;
-		if(Salesman.isSalesman(bladeUser)){
-			agentRecord.setCreateUser(bladeUser.getUserId());
-			detail = (AgentRecord) tenantIgnoreUtil.getOne(agentRecordService,Condition.getQueryWrapper(agentRecord));
-		}else{
-			detail = agentRecordService.getOne(Condition.getQueryWrapper(agentRecord));
-		}
-		return R.data(AgentRecordWrapper.build().entityVO(detail));
+	@TenantAop(salesman = Salesman.roleName,agent = Agent.roleName)
+	public R<AgentRecordVO> detail(AgentRecord agentRecord) {
+		return R.data(AgentRecordWrapper.build().entityVO(agentRecordService.getOne(Condition.getQueryWrapper(agentRecord))));
 	}
 
 	/**
@@ -79,16 +71,9 @@ public class AgentRecordController extends BladeController {
 	@GetMapping("/list")
 	@ApiOperationSupport(order = 2)
 	@ApiOperation(value = "分页", notes = "传入agentRecord")
-	@TenantAop(agent = Agent.roleName)
-	public R<IPage<AgentRecordVO>> list(AgentRecord agentRecord, Query query, BladeUser bladeUser) {
-		IPage<AgentRecord> pages;
-		if(Salesman.isSalesman(bladeUser)){
-			agentRecord.setCreateUser(bladeUser.getUserId());
-			pages = tenantIgnoreUtil.page(agentRecordService,Condition.getPage(query), Condition.getQueryWrapper(agentRecord));
-		}else{
-			pages = agentRecordService.page(Condition.getPage(query), Condition.getQueryWrapper(agentRecord));
-		}
-		return R.data(AgentRecordWrapper.build().pageVO(pages));
+	@TenantAop(salesman = Salesman.roleName,agent = Agent.roleName)
+	public R<IPage<AgentRecordVO>> list(AgentRecord agentRecord, Query query) {
+		return R.data(AgentRecordWrapper.build().pageVO(agentRecordService.page(Condition.getPage(query), Condition.getQueryWrapper(agentRecord))));
 	}
 
 

+ 7 - 3
src/main/java/org/springblade/ldt/agent/service/impl/AgentRecordServiceImpl.java

@@ -21,6 +21,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.tenant.annotation.TenantIgnore;
 import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.gateway.web_gateway.service.ICensusService;
 import org.springblade.ldt.agent.entity.AgentRecord;
 import org.springblade.ldt.agent.mapper.AgentRecordMapper;
 import org.springblade.ldt.agent.service.IAgentRecordService;
@@ -42,6 +43,9 @@ public class AgentRecordServiceImpl extends BaseServiceImpl<AgentRecordMapper, A
 	@Autowired
 	private ILoginUserService loginUserService;
 
+	@Autowired
+	private ICensusService censusService;
+
 	@Override
 	public IPage<AgentRecordVO> selectAgentRecordPage(IPage<AgentRecordVO> page, AgentRecordVO agentRecord) {
 		return page.setRecords(baseMapper.selectAgentRecordPage(page, agentRecord));
@@ -51,10 +55,10 @@ public class AgentRecordServiceImpl extends BaseServiceImpl<AgentRecordMapper, A
 	@TenantIgnore
 	public AgentInfoVO getAgentInfo(Long userId) {
 		AgentInfoVO agentInfoVO = new AgentInfoVO();
-		AgentRecord agentRecord = getOne(Wrappers.<AgentRecord>lambdaQuery().eq(AgentRecord::getUserId, userId));
+		Long agentUserId = censusService.getAgentUserId(userId);
 		LoginUser loginUser = null;
-		if (ObjectUtil.isNotEmpty(agentRecord)) {
-			loginUser = loginUserService.getById(agentRecord.getAccountId());
+		if (ObjectUtil.isNotEmpty(agentUserId)) {
+			loginUser = loginUserService.getById(agentUserId);
 		}
 		if (loginUser != null) {
 			agentInfoVO.setTotalBalance(loginUser.getTotalBalance());

+ 87 - 0
src/main/java/org/springblade/ldt/bills/entity/TransferRec.java

@@ -0,0 +1,87 @@
+/*
+ *      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.ldt.bills.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.common.enums.TransferStatus;
+import org.springblade.common.enums.WithdrawStatus;
+import org.springblade.core.tenant.mp.TenantEntity;
+import org.springblade.yeePay.common.YeepayApiConstant;
+
+import java.math.BigDecimal;
+
+/**
+ * 实体类
+ *
+ * @author BladeX
+ * @since 2021-09-23
+ */
+@Data
+@TableName("ldt_transfer_rec")
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "TransferRec对象", description = "TransferRec对象")
+public class TransferRec extends TenantEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	@ApiModelProperty(value = "转账商户用户id")
+	private Long ownerId;
+
+	@ApiModelProperty(value = "转账金额")
+	private BigDecimal price;
+
+	@ApiModelProperty(value = "实际转账金额")
+	private BigDecimal actualPrice;
+
+	@ApiModelProperty(value = "手续费承担方向")
+	private YeepayApiConstant.feeChargeSide feeChargeSide;
+
+	@ApiModelProperty(value = "平台手续费")
+	private BigDecimal platformFee;
+
+	@ApiModelProperty(value = "第三方转账手续费")
+	private BigDecimal fee;
+
+	@ApiModelProperty(value = "REQUEST_RECEIVE:正在处理中 SUCCESS:转账成功 FAIL:失败")
+	private TransferStatus transferStatus;
+
+	@ApiModelProperty(value = "转账渠道:yeePay(易宝支付)")
+	private String channel;
+
+	@ApiModelProperty(value = "转账到账的金额")
+	private BigDecimal receiveAmount;
+
+	@ApiModelProperty(value = "失败原因")
+	private String failReason;
+
+	@ApiModelProperty(value = "第三方返回的结果集")
+	private String responseJson;
+
+	@ApiModelProperty(value = "第三方平台id")
+	private String thirdOrderId;
+
+	@ApiModelProperty(value = "商户请求号")
+	private String requestNo;
+
+	@ApiModelProperty(value = "提现id")
+	private Long withdrawId;
+
+}

+ 3 - 0
src/main/java/org/springblade/ldt/bills/entity/WithdrawRec.java

@@ -144,4 +144,7 @@ public class WithdrawRec extends TenantEntity {
 	@ApiModelProperty(value = "提现类型(1:余额提现   2:积分提现)")
 	private WithdrawType type;
 
+	@ApiModelProperty(value = "商户请求号")
+	private String requestNo;
+
 }

+ 42 - 0
src/main/java/org/springblade/ldt/bills/mapper/TransferRecMapper.java

@@ -0,0 +1,42 @@
+/*
+ *      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.ldt.bills.mapper;
+
+import org.springblade.ldt.bills.entity.TransferRec;
+import org.springblade.ldt.bills.vo.TransferRecVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 转账记录表 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2021-10-21
+ */
+public interface TransferRecMapper extends BaseMapper<TransferRec> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param transferRec
+	 * @return
+	 */
+	List<TransferRecVO> selectTransferRecPage(IPage page, TransferRecVO transferRec);
+
+}

+ 36 - 0
src/main/java/org/springblade/ldt/bills/mapper/TransferRecMapper.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.ldt.bills.mapper.TransferRecMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="transferRecResultMap" type="org.springblade.ldt.bills.entity.TransferRec">
+        <result column="id" property="id"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_dept" property="createDept"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="status" property="status"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="owner_id" property="ownerId"/>
+        <result column="price" property="price"/>
+        <result column="actual_price" property="actualPrice"/>
+        <result column="fee_change_side" property="feeChangeSide"/>
+        <result column="platform_fee" property="platformFee"/>
+        <result column="fee" property="fee"/>
+        <result column="transfer_status" property="transferStatus"/>
+        <result column="order_id" property="orderId"/>
+        <result column="channel" property="channel"/>
+        <result column="receive_amount" property="receiveAmount"/>
+        <result column="fail_reason" property="failReason"/>
+        <result column="response_json" property="responseJson"/>
+        <result column="third_order_id" property="thirdOrderId"/>
+        <result column="request_no" property="requestNo"/>
+    </resultMap>
+
+
+    <select id="selectTransferRecPage" resultMap="transferRecResultMap">
+        select * from ldt_transfer_rec where is_deleted = 0
+    </select>
+
+</mapper>

+ 41 - 0
src/main/java/org/springblade/ldt/bills/service/ITransferRecService.java

@@ -0,0 +1,41 @@
+/*
+ *      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.ldt.bills.service;
+
+import org.springblade.ldt.bills.entity.TransferRec;
+import org.springblade.ldt.bills.vo.TransferRecVO;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 转账记录表 服务类
+ *
+ * @author BladeX
+ * @since 2021-10-21
+ */
+public interface ITransferRecService extends BaseService<TransferRec> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param transferRec
+	 * @return
+	 */
+	IPage<TransferRecVO> selectTransferRecPage(IPage<TransferRecVO> page, TransferRecVO transferRec);
+
+}

+ 41 - 37
src/main/java/org/springblade/ldt/bills/service/impl/PointBillsServiceImpl.java

@@ -16,6 +16,7 @@
  */
 package org.springblade.ldt.bills.service.impl;
 
+import cn.hutool.core.convert.Convert;
 import cn.hutool.core.util.IdUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
@@ -24,6 +25,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.yeepay.yop.sdk.service.common.response.YopResponse;
 import lombok.AllArgsConstructor;
+import org.springblade.common.cache.PaymentCache;
 import org.springblade.common.enums.AppConstant;
 import org.springblade.common.enums.OrderType;
 import org.springblade.common.enums.PaymentScene;
@@ -42,12 +44,13 @@ import org.springblade.ldt.bills.vo.PointBillsVO;
 import org.springblade.ldt.bills.vo.YeePayAccountBalanceVO;
 import org.springblade.ldt.mall.entity.Mall;
 import org.springblade.ldt.mall.service.IMallService;
+import org.springblade.payment.entity.SuccessParams;
 import org.springblade.yeePay.common.YeePayConst;
 import org.springblade.yeePay.common.YeepayApiConstant;
 import org.springblade.yeePay.entity.saas.account.TransferOrderDto;
 import org.springblade.yeePay.service.YeepaySaasService;
 import org.springframework.stereotype.Service;
-import org.springframework.util.Assert;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.util.List;
@@ -108,6 +111,7 @@ public class PointBillsServiceImpl extends BaseServiceImpl<PointBillsMapper, Poi
 	}
 
 	@Override
+	@Transactional
 	public boolean handlePointBills(List<Long> ids, BladeUser bladeUser) {
 		Mall mall = mallService.getOne(Wrappers.<Mall>lambdaQuery().select(Mall::getMerchantNo).eq(Mall::getTenantId, bladeUser.getTenantId()));
 
@@ -137,52 +141,43 @@ public class PointBillsServiceImpl extends BaseServiceImpl<PointBillsMapper, Poi
 			throw new ServiceException("余额不足,请充值处理!");
 		}
 
-		String requestNo = IdUtil.simpleUUID();
-		//余额充足调取易宝的转账接口进行转账操作
-		JSONObject res = transfer(mall, amount, requestNo);
-		String transferStatus = res.getString("transferStatus");
-		if (ObjectUtil.isNotEmpty(transferStatus) && !transferStatus.equals("FAIL")) {
-			//保存转账信息
-			Bills bills = new Bills();
-			bills.setPointNum(BigDecimal.ZERO);
-			bills.setFee(res.getBigDecimal("fee"));
-			bills.setPointFee(BigDecimal.ZERO);
-			bills.setBalanceNum(BigDecimal.ZERO);
-			bills.setPrice(amount);
-			bills.setTotalPrice(amount);
-			bills.setCost(amount);
-			bills.setPayPlugin(PaymentType.YEE_PAY.name());
-			bills.setTitle("积分核销");
-			bills.setPayStatus(AppConstant.BillPayStatus.待付款.name());
-			bills.setPayScene(PaymentScene.TRANSFER.name());
-			bills.setCost(BigDecimal.ZERO);
-			bills.setType(OrderType.MALL_CHARGE.name());
-			bills.setDiscount(BigDecimal.ONE);
-			bills.setPayId(bladeUser.getUserId());
-			bills.setThirdOrderId(res.getString("orderNo"));
-			bills.setBillDesc(JSON.toJSONString(ids));
-			bills.setTenantId(bladeUser.getTenantId());
-			bills.setMallId(mall.getId());
-			Assert.isTrue(billsService.saveOrUpdate(bills), () -> {
-				throw new ServiceException("订单异常!");
-			});
-		}
-
+		//保存账单记录
+		Bills bills = new Bills();
+		bills.setPointNum(BigDecimal.ZERO);
+		bills.setPointFee(BigDecimal.ZERO);
+		bills.setBalanceNum(BigDecimal.ZERO);
+		bills.setPrice(amount);
+		bills.setTotalPrice(amount);
+		bills.setCost(amount);
+		bills.setPayPlugin(PaymentType.YEE_PAY.name());
+		bills.setTitle("积分核销");
+		bills.setPayStatus(AppConstant.BillPayStatus.待付款.name());
+		bills.setPayScene(PaymentScene.TRANSFER.name());
+		bills.setType(OrderType.MALL_CHARGE.name());
+		bills.setDiscount(BigDecimal.ONE);
+		bills.setPayId(bladeUser.getUserId());
+		bills.setBillDesc(JSON.toJSONString(ids));//暂时存放需要核销的积分记录id
+		bills.setTenantId(bladeUser.getTenantId());
+		bills.setMallId(mall.getId());
+		billsService.saveOrUpdate(bills);
+
+		transfer(bills, mall);
 		return true;
 	}
 
 	/**
 	 * 积分核销,向易宝发起商户或商场账户扣费
 	 */
-	private JSONObject transfer(Mall mall, BigDecimal amount, String requestNo) {
+	private void transfer(Bills bills, Mall mall) {
+		String requestNo = IdUtil.simpleUUID();
 		TransferOrderDto transferOrderDto = TransferOrderDto.builder()
 			.fromMerchantNo(mall.getMerchantNo())
-			.toMerchantNo(yeePayConst.getParentMerchantNo())
-			.orderAmount(amount.toPlainString())
+			.toMerchantNo(yeePayConst.getPlatformServiceNo())
+			.orderAmount(bills.getPrice().toPlainString())
 			.requestNo(requestNo)
 			.usage("积分交易核销!")
 			.feeChargeSide(YeepayApiConstant.feeChargeSide.INSIDE)
-			.notifyUrl(yeePayConst.getServiceUrl() + "/payment/callback/" + OrderType.MALL_CHARGE)
+			.notifyUrl(yeePayConst.getServiceUrl() + "/payment/callback/YEE_PAY")
 			.build();
 
 		YopResponse yopResponse = yeepaySaasService.transferOrder(transferOrderDto);
@@ -190,7 +185,16 @@ public class PointBillsServiceImpl extends BaseServiceImpl<PointBillsMapper, Poi
 		if (!Objects.equals(res.getString("returnCode"), "UA00000")) {
 			throw new ServiceException(res.getString("returnMsg"));
 		}
-		return res;
+
+		//支付参数
+		SuccessParams successParams  = SuccessParams.builder()
+			.orderType(OrderType.MALL_CHARGE.name())
+			.status(AppConstant.BillPayStatus.待付款.name())
+			.bills(bills)
+			.res(res)
+			.build();
+
+		PaymentCache.putSuccessParams(Convert.toStr(successParams.getBills().getId()), successParams);
 	}
 
 	/**

+ 41 - 0
src/main/java/org/springblade/ldt/bills/service/impl/TransferRecServiceImpl.java

@@ -0,0 +1,41 @@
+/*
+ *      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.ldt.bills.service.impl;
+
+import org.springblade.ldt.bills.entity.TransferRec;
+import org.springblade.ldt.bills.vo.TransferRecVO;
+import org.springblade.ldt.bills.mapper.TransferRecMapper;
+import org.springblade.ldt.bills.service.ITransferRecService;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 转账记录表 服务实现类
+ *
+ * @author BladeX
+ * @since 2021-10-21
+ */
+@Service
+public class TransferRecServiceImpl extends BaseServiceImpl<TransferRecMapper, TransferRec> implements ITransferRecService {
+
+	@Override
+	public IPage<TransferRecVO> selectTransferRecPage(IPage<TransferRecVO> page, TransferRecVO transferRec) {
+		return page.setRecords(baseMapper.selectTransferRecPage(page, transferRec));
+	}
+
+}

+ 36 - 0
src/main/java/org/springblade/ldt/bills/vo/TransferRecVO.java

@@ -0,0 +1,36 @@
+/*
+ *      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.ldt.bills.vo;
+
+import org.springblade.ldt.bills.entity.TransferRec;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * 转账记录表视图实体类
+ *
+ * @author BladeX
+ * @since 2021-10-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "TransferRecVO对象", description = "转账记录表")
+public class TransferRecVO extends TransferRec {
+	private static final long serialVersionUID = 1L;
+
+}

+ 45 - 26
src/main/java/org/springblade/ldt/mall/service/impl/MallServiceImpl.java

@@ -16,6 +16,7 @@
  */
 package org.springblade.ldt.mall.service.impl;
 
+import cn.hutool.core.convert.Convert;
 import cn.hutool.core.util.IdUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
@@ -23,6 +24,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.yeepay.yop.sdk.service.common.response.YopResponse;
 import lombok.AllArgsConstructor;
+import org.springblade.common.cache.PaymentCache;
 import org.springblade.common.enums.AppConstant;
 import org.springblade.common.enums.OrderType;
 import org.springblade.common.enums.PaymentScene;
@@ -37,12 +39,12 @@ import org.springblade.ldt.mall.entity.Mall;
 import org.springblade.ldt.mall.mapper.MallMapper;
 import org.springblade.ldt.mall.service.IMallService;
 import org.springblade.ldt.mall.vo.MallVO;
+import org.springblade.payment.entity.SuccessParams;
 import org.springblade.yeePay.common.YeePayConst;
 import org.springblade.yeePay.common.YeepayApiConstant;
 import org.springblade.yeePay.entity.saas.account.BankRechargeOrderDto;
 import org.springblade.yeePay.service.YeepaySaasService;
 import org.springframework.stereotype.Service;
-import org.springframework.util.Assert;
 
 import java.math.BigDecimal;
 import java.util.Objects;
@@ -71,24 +73,6 @@ public class MallServiceImpl extends BaseServiceImpl<MallMapper, Mall> implement
 
 		Mall mall = getOne(Wrappers.<Mall>lambdaQuery().select(Mall::getMerchantNo).eq(Mall::getTenantId, bladeUser.getTenantId()));
 
-		String requestNo = IdUtil.simpleUUID();
-
-		BankRechargeOrderDto dto = BankRechargeOrderDto.builder()
-			.merchantNo(mall.getMerchantNo())
-			.amount(bankRechargeOrderDto.getAmount())
-			.parentMerchantNo(yeePayConst.getParentMerchantNo())
-			.requestNo(requestNo)
-			.payType(YeepayApiConstant.payType.BANK_TRANSFER)
-			.notifyUrl(yeePayConst.getServiceUrl() + "/payment/callback/" + OrderType.MALL_RECHARGE)
-			.remark(bankRechargeOrderDto.getRemark())
-			.build();
-
-		YopResponse yopResponse = yeepaySaasService.bankRechargeOrder(dto);
-		JSONObject res = JSON.parseObject(yopResponse.getStringResult());
-		if (!Objects.equals(res.getString("returnCode"), "UA00000")) {
-			throw new ServiceException(res.getString("returnMsg"));
-		}
-		String remitComment = res.getString("remitComment");
 		//保存转账信息
 		Bills bills = new Bills();
 		bills.setPointNum(BigDecimal.ZERO);
@@ -101,19 +85,54 @@ public class MallServiceImpl extends BaseServiceImpl<MallMapper, Mall> implement
 		bills.setPayPlugin(PaymentType.YEE_PAY.name());
 		bills.setTitle("商场充值");
 		bills.setPayStatus(AppConstant.BillPayStatus.待付款.name());
-		bills.setPayStatus(PaymentScene.TRANSFER.name());
-		bills.setCost(BigDecimal.ZERO);
+		bills.setPayScene(PaymentScene.RECHARGE.name());
 		bills.setType(OrderType.MALL_RECHARGE.name());
 		bills.setDiscount(BigDecimal.ONE);
 		bills.setPayId(bladeUser.getUserId());
-		bills.setThirdOrderId(res.getString("orderNo"));
 		bills.setTenantId(bills.getTenantId());
 		bills.setMallId(mall.getId());
-		bills.setBillDesc(remitComment);
-		Assert.isTrue(billsService.saveOrUpdate(bills), () -> {
-			throw new ServiceException("订单异常!");
-		});
+		bills.setBillDesc(bankRechargeOrderDto.getRemark());
+		billsService.saveOrUpdate(bills);
+
+		return bankRechargeOrder(bills, mall);
+
+	}
+
+	/**
+	 * @param :
+	 * @Return void
+	 * @Author July
+	 * @Description 充值-银行汇款下单
+	 * @Date 2021/10/22 13:48
+	 */
+	private JSONObject bankRechargeOrder(Bills bills, Mall mall) {
+		String requestNo = IdUtil.simpleUUID();
+
+		BankRechargeOrderDto dto = BankRechargeOrderDto.builder()
+			.merchantNo(mall.getMerchantNo())
+			.amount(bills.getPrice())
+			.parentMerchantNo(yeePayConst.getParentMerchantNo())
+			.requestNo(requestNo)
+			.payType(YeepayApiConstant.payType.BANK_TRANSFER)
+			.notifyUrl(yeePayConst.getServiceUrl() + "/payment/callback/YEE_PAY")
+			.remark(bills.getBillDesc())
+			.build();
+
+		YopResponse yopResponse = yeepaySaasService.bankRechargeOrder(dto);
+		JSONObject res = JSON.parseObject(yopResponse.getStringResult());
+		if (!Objects.equals(res.getString("returnCode"), "UA00000")) {
+			throw new ServiceException(res.getString("returnMsg"));
+		}
+
+		//支付参数
+		SuccessParams successParams = SuccessParams.builder()
+			.orderType(OrderType.MALL_RECHARGE.name())
+			.status(AppConstant.BillPayStatus.待付款.name())
+			.bills(bills)
+			.res(res)
+			.build();
 
+		PaymentCache.putSuccessParams(Convert.toStr(successParams.getBills().getId()), successParams);
 		return res;
 	}
 

+ 27 - 12
src/main/java/org/springblade/payment/callback/trade/MallChargeCallback.java

@@ -1,6 +1,7 @@
 package org.springblade.payment.callback.trade;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
@@ -10,6 +11,8 @@ import org.springblade.ldt.bills.entity.Bills;
 import org.springblade.ldt.bills.entity.PointBills;
 import org.springblade.ldt.bills.service.IBillsService;
 import org.springblade.ldt.bills.service.IPointBillsService;
+import org.springblade.ldt.mall.entity.Mall;
+import org.springblade.ldt.mall.service.IMallService;
 import org.springblade.payment.entity.SuccessParams;
 import org.springblade.payment.event.MallChargeEvent;
 import org.springframework.context.event.EventListener;
@@ -31,6 +34,7 @@ public class MallChargeCallback {
 
 	private IBillsService billsService;
 	private IPointBillsService pointBillsService;
+	private IMallService mallService;
 
 
 	@EventListener
@@ -38,27 +42,24 @@ public class MallChargeCallback {
 	@Transactional
 	public void PaySuccess(MallChargeEvent mallChargeEvent) {
 		SuccessParams successParams = mallChargeEvent.getSuccessParams();
-		String orderNo = successParams.getRes().getString("orderNo");
-
-		Bills bills = billsService.getOne(new QueryWrapper<Bills>().lambda().eq(Bills::getThirdOrderId, orderNo));
-
-		handleBills(bills);
+		Bills bills = billsService.getOne(new QueryWrapper<Bills>().lambda().eq(Bills::getId, successParams.getBills().getId()));
+		//*.先更新积分记录
 		handlePointBills(bills);
+		handleBills(bills, successParams.getRes());
+		handleMall(bills);
 
 	}
 
-	/**
-	 * 更新账单信息
-	 */
-	private void handleBills(Bills bills) {
-		bills.setPayStatus(AppConstant.BillPayStatus.付款成功.name());
+	private void handleMall(Bills bills) {
+		Mall mall = mallService.getById(bills.getMallId());
+		mall.setBalance(mall.getBalance().subtract(bills.getPrice()));
 		Assert.isTrue(billsService.saveOrUpdate(bills), () -> {
-			throw new ServiceException("更新付款账单信息异常!");
+			throw new ServiceException("更新商场余额异常!");
 		});
 	}
 
 	/**
-	 * 将积分明细修改已核销
+	 * 将积分明细修改已核销
 	 */
 	private void handlePointBills(Bills bills) {
 		List<Long> ids = JSON.parseArray(bills.getBillDesc(), Long.class);
@@ -67,4 +68,18 @@ public class MallChargeCallback {
 		});
 	}
 
+	/**
+	 * 更新账单信息
+	 */
+	private void handleBills(Bills bills, JSONObject res) {
+		bills.setFee(res.getBigDecimal("fee"));
+		bills.setThirdOrderId(res.getString("orderNo"));
+		bills.setReceiveNumYp(res.getBigDecimal("receiveAmount"));
+		bills.setPayStatus(AppConstant.BillPayStatus.付款成功.name());
+		Assert.isTrue(billsService.saveOrUpdate(bills), () -> {
+			throw new ServiceException("更新付款账单信息异常!");
+		});
+	}
+
+
 }

+ 21 - 2
src/main/java/org/springblade/payment/callback/trade/MallRechargeCallback.java

@@ -1,11 +1,14 @@
 package org.springblade.payment.callback.trade;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import lombok.AllArgsConstructor;
 import org.springblade.common.enums.AppConstant;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.ldt.bills.entity.Bills;
 import org.springblade.ldt.bills.service.IBillsService;
+import org.springblade.ldt.mall.entity.Mall;
+import org.springblade.ldt.mall.service.IMallService;
 import org.springblade.payment.entity.SuccessParams;
 import org.springblade.payment.event.MallRechargeEvent;
 import org.springframework.context.event.EventListener;
@@ -24,15 +27,31 @@ import org.springframework.util.Assert;
 public class MallRechargeCallback {
 
 	private IBillsService billsService;
+	private IMallService mallService;
 
 	@EventListener
 	@Async
 	@Transactional
 	public void PaySuccess(MallRechargeEvent mallRechargeEvent) {
 		SuccessParams successParams = mallRechargeEvent.getSuccessParams();
-		String orderNo = successParams.getRes().getString("orderNo");
-		Bills bills = billsService.getOne(new QueryWrapper<Bills>().lambda().eq(Bills::getThirdOrderId, orderNo));
+		JSONObject res = successParams.getRes();
+		Bills bills = billsService.getOne(new QueryWrapper<Bills>().lambda().eq(Bills::getId, successParams.getBills().getId()));
+		handleBills(res, bills);
+		handleMall(bills);
+	}
+
+	private void handleMall(Bills bills) {
+		Mall mall = mallService.getById(bills.getMallId());
+		mall.setBalance(mall.getBalance().add(bills.getPrice()));
+		Assert.isTrue(billsService.saveOrUpdate(bills), () -> {
+			throw new ServiceException("更新商场充值余额异常!");
+		});
+	}
+
+	private void handleBills(JSONObject res, Bills bills) {
 		bills.setPayStatus(AppConstant.BillPayStatus.付款成功.name());
+		bills.setBillDesc(res.getString("remitComment"));
+		bills.setThirdOrderId(res.getString("orderNo"));
 		Assert.isTrue(billsService.saveOrUpdate(bills), () -> {
 			throw new ServiceException("更新付款账单信息异常!");
 		});

+ 8 - 5
src/main/java/org/springblade/payment/callback/trade/UserPointTransferWithdrawCallback.java

@@ -55,15 +55,18 @@ public class UserPointTransferWithdrawCallback {
 		//接收到转账回调后进行用户提现操作
 		Shop shop = shopService.getById(withdrawRec.getOwnerId());
 
+		String requestNo = IdUtil.simpleUUID();
 		WithdrawOrderDto withdrawOrderDto = WithdrawOrderDto.builder()
-			.parentMerchantNo(yeePayConst.getParentMerchantNo())
-			.requestNo(IdUtil.simpleUUID())
+			.parentMerchantNo(yeePayConst.getPlatformServiceNo())
+			.requestNo(requestNo)
 			.merchantNo(shop.getMerchantNo())
 			.bankAccountNo(withdrawRec.getReceiverAccountNo())
 			.receiveType(YeepayApiConstant.receiveType.valueOf(withdrawRec.getReceiveType()))
-			.orderAmount(withdrawRec.getActualPrice().toPlainString())
+			.orderAmount(successParams.getTotalPrice().toPlainString())
 			.notifyUrl(yeePayConst.getServiceUrl() + "/payment/callback/YEE_PAY")
 			.build();
+		withdrawRec.setRequestNo(requestNo);
+		withdrawRecService.saveOrUpdate(withdrawRec);
 
 		YopResponse yopResponse = yeepaySaasService.withdrawOrder(withdrawOrderDto);
 		JSONObject res = JSON.parseObject(yopResponse.getStringResult());
@@ -72,7 +75,7 @@ public class UserPointTransferWithdrawCallback {
 		}
 
 		//支付参数
-		SuccessParams notifySuccessParams  = SuccessParams.builder()
+		SuccessParams notifySuccessParams = SuccessParams.builder()
 			.orderType(OrderType.USER_POINT_WITHDRAW.name())
 			.status(WithdrawStatus.WAITING.getValue())
 			.userId(withdrawRec.getOwnerId())
@@ -82,6 +85,6 @@ public class UserPointTransferWithdrawCallback {
 			.withdrawRecId(withdrawRec.getId())
 			.build();
 
-		PaymentCache.putSuccessParams(Convert.toStr(notifySuccessParams.getWithdrawRecId()),successParams);
+		PaymentCache.putSuccessParams(Convert.toStr(notifySuccessParams.getWithdrawRecId()), notifySuccessParams);
 	}
 }

+ 22 - 0
src/main/java/org/springblade/payment/handle/entity/HandleTransferData.java

@@ -0,0 +1,22 @@
+package org.springblade.payment.handle.entity;
+
+import lombok.Builder;
+import lombok.Data;
+import org.springblade.ldt.bills.entity.TransferRec;
+import org.springblade.ldt.shop.entity.Shop;
+
+/**
+ * @author July
+ * @version 1.0.0
+ * @ClassName HandleTransferData.java
+ * @Description 待处理的转账数据
+ * @createTime 2021年10月21日 17:53:00
+ */
+@Builder
+@Data
+public class HandleTransferData {
+
+	TransferRec transferRec;
+
+	String requestNo;
+}

+ 132 - 24
src/main/java/org/springblade/payment/plugin/YeePayPlugin.java

@@ -3,6 +3,7 @@ package org.springblade.payment.plugin;
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -10,37 +11,45 @@ import com.yeepay.yop.sdk.service.common.response.YopResponse;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springblade.common.cache.PaymentCache;
-import org.springblade.common.enums.AppConstant;
 import org.springblade.common.enums.OrderType;
 import org.springblade.common.enums.PaymentType;
+import org.springblade.common.enums.TransferStatus;
 import org.springblade.common.enums.WithdrawStatus;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.ldt.bills.entity.Bills;
+import org.springblade.ldt.bills.entity.TransferRec;
 import org.springblade.ldt.bills.entity.WithdrawRec;
 import org.springblade.ldt.bills.service.IBillsService;
+import org.springblade.ldt.bills.service.ITransferRecService;
 import org.springblade.ldt.bills.service.IWithdrawRecService;
 import org.springblade.ldt.shop.entity.Shop;
 import org.springblade.ldt.shop.service.IShopService;
 import org.springblade.ldt.user.service.ILoginUserService;
 import org.springblade.payment.entity.PayParam;
 import org.springblade.payment.entity.SuccessParams;
+import org.springblade.payment.event.UserPointTransferWithdrawEvent;
+import org.springblade.payment.handle.entity.HandleTransferData;
 import org.springblade.payment.service.impl.PaymentService;
 import org.springblade.yeePay.common.YeePayConst;
 import org.springblade.yeePay.common.YeepayApiConstant;
 import org.springblade.yeePay.entity.InitOrderDto;
 import org.springblade.yeePay.entity.MerchantInfo;
 import org.springblade.yeePay.entity.saas.PayLinkOrderDto;
+import org.springblade.yeePay.entity.saas.account.TransferB2bQueryDto;
 import org.springblade.yeePay.entity.saas.account.TransferOrderDto;
 import org.springblade.yeePay.entity.saas.settlement.SettleSelfSettleApplyDto;
 import org.springblade.yeePay.service.YeePayService;
 import org.springblade.yeePay.service.YeepaySaasService;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.Objects;
+import java.util.Set;
 
 
 /**
@@ -61,6 +70,8 @@ public class YeePayPlugin implements Payment {
 	IWithdrawRecService withdrawRecService;
 	YeePayConst yeePayConst;
 	IShopService shopService;
+	ApplicationEventPublisher eventPublisher;
+	ITransferRecService transferRecService;
 
 
 	@Override
@@ -190,48 +201,102 @@ public class YeePayPlugin implements Payment {
 	@Override
 	@Transactional
 	public R userPointWithdraw(PayParam payParam) {
-		WithdrawRec withdrawRec = withdrawRecService.getById(payParam.getOrderId());
-		Assert.notNull(withdrawRec, "订单查询失败,无此订单信息!");
-
-		//从平台转账实际提现金额到用户的易宝商户账号中
-		Shop shop = shopService.getById(withdrawRec.getOwnerId());
+		TransferRec transferRec = transferRecService.getById(payParam.getOrderId());
+		Assert.notNull(transferRec, "订单查询失败,无此订单信息!");
 
+		//从平台转账到用户的易宝商户账号中
+		Shop shop = shopService.getById(transferRec.getOwnerId());
 		String requestNo = IdUtil.simpleUUID();
-
 		TransferOrderDto transferOrderDto = TransferOrderDto.builder()
 			.fromMerchantNo(yeePayConst.getPlatformServiceNo())
 			.toMerchantNo(shop.getMerchantNo())
-			.orderAmount(withdrawRec.getActualPrice().toPlainString())
+			.orderAmount(transferRec.getPrice().toPlainString())
 			.requestNo(requestNo)
-			.usage("用户积分提现!")
-			.feeChargeSide(YeepayApiConstant.feeChargeSide.OUTSIDE)
+			.usage("用户积分提现转账!")
+			.feeChargeSide(transferRec.getFeeChargeSide())
 			.notifyUrl(callbackUrl(PaymentType.YEE_PAY.name()))
 			.build();
 		transferOrderDto.setParentMerchantNo(yeePayConst.getPlatformServiceNo());
 		YopResponse yopResponse = yeepaySaasService.transferOrder(transferOrderDto);
 		JSONObject res = JSON.parseObject(yopResponse.getStringResult());
 		if (!Objects.equals(res.getString("returnCode"), "UA00000")) {
-
-			withdrawRec.setWithdrawStatus(WithdrawStatus.FAIL.getValue());
-			withdrawRec.setResponseJson(res.toJSONString());
-			withdrawRecService.saveOrUpdate(withdrawRec);
-
+			userPointWithdrawFail(transferRec, res);
 			throw new ServiceException(res.getString("returnMsg"));
 		}
 
+		String transferStatus = res.getString("transferStatus");
+		switch (transferStatus) {
+			case "SUCCESS":
+				userPointWithdrawSuccess(res, transferRec, requestNo);
+				break;
+			case "REQUEST_RECEIVE":
+				PaymentCache.addTransferApply(HandleTransferData.builder()
+					.transferRec(transferRec)
+					.requestNo(requestNo)
+					.build());
+				break;
+			default:
+				userPointWithdrawFail(transferRec, res);
+				break;
+		}
+
+		return R.data(res);
+	}
+
+	/**
+	 * @param transferRec: 转账信息
+	 * @param res:         易宝返回数据
+	 * @Return void
+	 * @Author July
+	 * @Description 处理转账申请失败
+	 * @Date 2021/10/21 17:42
+	 */
+	private void userPointWithdrawFail(TransferRec transferRec, JSONObject res) {
+		//更新提现记录
+		WithdrawRec withdrawRec = withdrawRecService.getById(transferRec.getWithdrawId());
+		withdrawRec.setWithdrawStatus(WithdrawStatus.FAIL.getValue());
+		withdrawRec.setResponseJson(res.toJSONString());
+		withdrawRecService.saveOrUpdate(withdrawRec);
+
+		//更新转账记录
+		transferRec.setTransferStatus(TransferStatus.FAIL);
+		withdrawRec.setFailReason(res.toJSONString());
+		transferRecService.saveOrUpdate(transferRec);
+	}
+
+	/**
+	 * @param requestNo:   商户请求号
+	 * @param transferRec: 转账信息
+	 * @param res:         易宝返回数据
+	 * @Author July
+	 * @Description 处理转账成功发起提现申请
+	 * @Date 2021/10/21 17:42
+	 */
+	private void userPointWithdrawSuccess(JSONObject res, TransferRec transferRec, String requestNo) {
+
+		//更新转账记录
+		transferRec.setFee(res.getBigDecimal("fee"));
+		transferRec.setTransferStatus(TransferStatus.SUCCESS);
+		transferRec.setReceiveAmount(res.getBigDecimal("receiveAmount"));
+		transferRec.setRequestNo(requestNo);
+		transferRec.setResponseJson(res.toJSONString());
+		transferRec.setThirdOrderId(res.getString("orderNo"));
+		transferRecService.saveOrUpdate(transferRec);
+
 		//支付参数
-		SuccessParams successParams  = SuccessParams.builder()
+		SuccessParams successParams = SuccessParams.builder()
 			.orderType(OrderType.USER_POINT_TRANSFER_WITHDRAW.name())
 			.status(WithdrawStatus.WAITING.getValue())
-			.userId(withdrawRec.getOwnerId())
-			.totalPrice(withdrawRec.getActualPrice())
-			.shopId(shop.getId())
-			.tenantId(shop.getTenantId())
-			.withdrawRecId(withdrawRec.getId())
+			.userId(transferRec.getOwnerId())
+			.totalPrice(transferRec.getReceiveAmount())
+			.shopId(transferRec.getOwnerId())
+			.tenantId(transferRec.getTenantId())
+			.withdrawRecId(transferRec.getWithdrawId())
 			.build();
+		PaymentCache.putSuccessParams(Convert.toStr(successParams.getWithdrawRecId()), successParams);
+
+		eventPublisher.publishEvent(new UserPointTransferWithdrawEvent(successParams));
 
-		PaymentCache.putSuccessParams(Convert.toStr(successParams.getWithdrawRecId()),successParams);
-		return R.data(res);
 	}
 
 
@@ -239,7 +304,7 @@ public class YeePayPlugin implements Payment {
 		switch (orderType) {
 			case WECHAT_PAY:
 			case USER_PAY:
-				if(merchantInfo instanceof InitOrderDto){
+				if (merchantInfo instanceof InitOrderDto) {
 					InitOrderDto initOrderDto = (InitOrderDto) merchantInfo;
 					//
 //				//营销信息(商户赠送的用户积分以及单笔 交易的国信服务费通过分账的形式到国信账户)
@@ -263,4 +328,47 @@ public class YeePayPlugin implements Payment {
 			default:
 		}
 	}
+
+	/**
+	 * @Author July
+	 * @Description 处理用户积分提现的转账结果
+	 * @Date 2021/10/22 10:29
+	 */
+	@Scheduled(cron = "0 */1 * * * ?")
+	public void handleUserPointWithdrawTransferResult() {
+		Set<HandleTransferData> queue = PaymentCache.getTransferApplyList();
+		if (ObjectUtil.isNotEmpty(queue) && queue.size() > 0) {
+			log.info("定时任务开始,查询队列中的待处理的转账记录!,队列数:{}", queue.size());
+			queue.forEach(handleTransferData -> {
+				//查询分账结果
+				log.info("进行转账结果查询:{}", handleTransferData.getTransferRec().getId());
+				TransferRec transferRec = transferRecService.getById(handleTransferData.getTransferRec().getId());
+				Assert.notNull(transferRec, "转账订单查询失败,无此订单信息!" + transferRec.getId());
+
+				TransferB2bQueryDto transferB2bQueryDto = TransferB2bQueryDto.builder()
+					.parentMerchantNo(yeePayConst.getPlatformServiceNo())
+					.requestNo(handleTransferData.getRequestNo())
+					.build();
+				YopResponse yopResponse = yeepaySaasService.transferB2bQuery(transferB2bQueryDto);
+				JSONObject res = JSON.parseObject(yopResponse.getStringResult());
+				if (!Objects.equals(res.getString("returnCode"), "UA00000")) {
+					userPointWithdrawFail(transferRec, res);
+					throw new ServiceException(res.getString("returnMsg"));
+				}
+
+				String transferStatus = res.getString("transferStatus");
+				switch (transferStatus) {
+					case "SUCCESS":
+						userPointWithdrawSuccess(res, transferRec, handleTransferData.getRequestNo());
+						PaymentCache.completeTransferApply(handleTransferData);
+						break;
+					case "FAIL":
+						userPointWithdrawFail(transferRec, res);
+						break;
+					default:
+						break;
+				}
+			});
+		}
+	}
 }