瀏覽代碼

积分核销

july 4 年之前
父節點
當前提交
5c29bedf08

+ 22 - 15
src/main/java/org/springblade/ldt/bills/controller/PointBillsController.java

@@ -23,13 +23,16 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.ldt.bills.entity.PointBills;
 import org.springblade.ldt.bills.service.IPointBillsService;
+import org.springblade.ldt.bills.vo.PointBillCensusVO;
 import org.springblade.ldt.bills.vo.PointBillsVO;
 import org.springblade.ldt.bills.wrapper.PointBillsWrapper;
 import org.springblade.ldt.mall.service.IMallService;
@@ -39,15 +42,14 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
 import java.util.Date;
-import java.util.List;
-import java.util.Map;
 
 /**
- *  控制器
+ * 控制器
  *
  * @author BladeX
  * @since 2021-09-23
  */
+@Slf4j
 @RestController
 @AllArgsConstructor
 @RequestMapping("ldt_bills/pointbills")
@@ -55,11 +57,8 @@ import java.util.Map;
 public class PointBillsController extends BladeController {
 
 	private final IPointBillsService pointBillsService;
-
 	private final ILoginUserService loginUserService;
-
 	private final IShopService shopService;
-
 	private final IMallService mallService;
 
 	/**
@@ -70,7 +69,7 @@ public class PointBillsController extends BladeController {
 	@ApiOperation(value = "详情", notes = "传入pointBills")
 	public R<PointBillsVO> detail(PointBills pointBills) {
 		PointBills detail = pointBillsService.getOne(Condition.getQueryWrapper(pointBills));
-		return R.data(PointBillsWrapper.build(loginUserService,shopService,mallService).entityVO(detail));
+		return R.data(PointBillsWrapper.build(loginUserService, shopService, mallService).entityVO(detail));
 	}
 
 	/**
@@ -82,12 +81,12 @@ public class PointBillsController extends BladeController {
 	public R<IPage<PointBillsVO>> list(PointBills pointBills, Query query, Date createTimeStart, Date createTimeEnd) {
 		QueryWrapper<PointBills> queryWrapper = Condition.getQueryWrapper(pointBills);
 		//添加创建时间条件
-		if(createTimeStart!=null && createTimeEnd!=null){
-			queryWrapper.lambda().between(PointBills::getCreateTime,createTimeStart,createTimeEnd);
+		if (createTimeStart != null && createTimeEnd != null) {
+			queryWrapper.lambda().between(PointBills::getCreateTime, createTimeStart, createTimeEnd);
 		}
 
 		//循环查询
-		return R.data(PointBillsWrapper.build(loginUserService,shopService,mallService).pageVO(pointBillsService.page(Condition.getPage(query), queryWrapper)));
+		return R.data(PointBillsWrapper.build(loginUserService, shopService, mallService).pageVO(pointBillsService.page(Condition.getPage(query), queryWrapper)));
 	}
 
 
@@ -147,12 +146,20 @@ public class PointBillsController extends BladeController {
 	 * 统计金额
 	 */
 	@GetMapping("/censusPrice")
-	@ApiOperationSupport(order =8)
+	@ApiOperationSupport(order = 8)
 	@ApiOperation(value = "统计金额", notes = "统计金额")
-	public R<List<Map<String,Object>>> censusPrice() {
-		return R.data(pointBillsService.listMaps(new QueryWrapper<PointBills>()
-			.select("sum(price) as price,type as type")
-			.lambda().groupBy(PointBills::getType)));
+	public R<PointBillCensusVO> censusPrice(BladeUser bladeUser) {
+		return R.data(pointBillsService.censusData(bladeUser));
+	}
+
+	/**
+	 * 删除
+	 */
+	@PostMapping("/handlePointBills")
+	@ApiOperationSupport(order = 9)
+	@ApiOperation(value = "积分核销", notes = "传入ids")
+	public R handlePointBills(@ApiParam(value = "主键集合", required = true) @RequestParam String ids, BladeUser bladeUser) {
+		return R.status(pointBillsService.handlePointBills(Func.toLongList(ids), bladeUser));
 	}
 
 }

+ 16 - 3
src/main/java/org/springblade/ldt/bills/service/IPointBillsService.java

@@ -16,13 +16,17 @@
  */
 package org.springblade.ldt.bills.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.ldt.bills.entity.PointBills;
+import org.springblade.ldt.bills.vo.PointBillCensusVO;
 import org.springblade.ldt.bills.vo.PointBillsVO;
-import org.springblade.core.mp.base.BaseService;
-import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.util.List;
 
 /**
- *  服务类
+ * 服务类
  *
  * @author BladeX
  * @since 2021-09-23
@@ -38,4 +42,13 @@ public interface IPointBillsService extends BaseService<PointBills> {
 	 */
 	IPage<PointBillsVO> selectPointBillsPage(IPage<PointBillsVO> page, PointBillsVO pointBills);
 
+	/**
+	 * 统计核销数据
+	 */
+	PointBillCensusVO censusData(BladeUser bladeUser);
+
+	/**
+	 * 核销积分账单
+	 */
+	boolean handlePointBills(List<Long> ids, BladeUser bladeUser);
 }

+ 167 - 4
src/main/java/org/springblade/ldt/bills/service/impl/PointBillsServiceImpl.java

@@ -16,26 +16,189 @@
  */
 package org.springblade.ldt.bills.service.impl;
 
+import cn.hutool.core.util.IdUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+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.enums.AppConstant;
+import org.springblade.common.enums.OrderType;
+import org.springblade.common.enums.PaymentScene;
+import org.springblade.common.enums.PaymentType;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.ldt.bills.entity.Bills;
 import org.springblade.ldt.bills.entity.PointBills;
-import org.springblade.ldt.bills.vo.PointBillsVO;
 import org.springblade.ldt.bills.mapper.PointBillsMapper;
+import org.springblade.ldt.bills.service.IBillsService;
 import org.springblade.ldt.bills.service.IPointBillsService;
-import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.ldt.bills.vo.PointBillCensusVO;
+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.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 com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springframework.util.Assert;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Objects;
 
 /**
- *  服务实现类
+ * 服务实现类
  *
  * @author BladeX
  * @since 2021-09-23
  */
+@AllArgsConstructor
 @Service
 public class PointBillsServiceImpl extends BaseServiceImpl<PointBillsMapper, PointBills> implements IPointBillsService {
 
+	private IMallService mallService;
+	private YeepaySaasService yeepaySaasService;
+	private YeePayConst yeePayConst;
+	private IBillsService billsService;
+
 	@Override
 	public IPage<PointBillsVO> selectPointBillsPage(IPage<PointBillsVO> page, PointBillsVO pointBills) {
 		return page.setRecords(baseMapper.selectPointBillsPage(page, pointBills));
 	}
 
+	@Override
+	public PointBillCensusVO censusData(BladeUser bladeUser) {
+		Mall mall = mallService.getOne(Wrappers.<Mall>lambdaQuery().select(Mall::getMerchantNo).eq(Mall::getTenantId, bladeUser.getTenantId()));
+
+		PointBillCensusVO result = new PointBillCensusVO();
+		//易宝余额
+		YeePayAccountBalanceVO balanceVO = getYeePayAccountBalance(mall.getMerchantNo());
+		result.setYeePayBalance(balanceVO.getBalance());
+
+		//总金额
+		QueryWrapper<PointBills> queryWrapper = new QueryWrapper<>();
+		queryWrapper.select("sum(total_price) as totalPrice");
+		result.setAccountsPayable(getData(queryWrapper));
+
+		//已核销
+		QueryWrapper<PointBills> queryYes = new QueryWrapper<>();
+		queryYes.select("sum(total_price) as totalPrice").lambda().eq(PointBills::getIsCheak, "1");
+		result.setHandledAmount(getData(queryYes));
+
+		//未核销
+		QueryWrapper<PointBills> queryNo = new QueryWrapper<>();
+		queryNo.select("sum(total_price) as totalPrice").lambda().eq(PointBills::getIsCheak, "0");
+		result.setUntreatedAmount(getData(queryNo));
+
+		return result;
+	}
+
+	private String getData(QueryWrapper<PointBills> queryWrapper) {
+		return ObjectUtil.isEmpty(getOne(queryWrapper)) ? "0.00" : getOne(queryWrapper).getTotalPrice().toPlainString();
+	}
+
+	@Override
+	public boolean handlePointBills(List<Long> ids, BladeUser bladeUser) {
+		Mall mall = mallService.getOne(Wrappers.<Mall>lambdaQuery().select(Mall::getMerchantNo).eq(Mall::getTenantId, bladeUser.getTenantId()));
+
+		YeePayAccountBalanceVO yeePayAccountBalance = getYeePayAccountBalance(mall.getMerchantNo());
+		if (ObjectUtil.isEmpty(yeePayAccountBalance) || ObjectUtil.isEmpty(yeePayAccountBalance.getBalance())) {
+			throw new ServiceException("余额不足,请充值处理!");
+		}
+		BigDecimal balance = BigDecimal.valueOf(Long.parseLong(yeePayAccountBalance.getBalance()));
+
+		QueryWrapper<PointBills> query = new QueryWrapper<>();
+		query.select("sum(total_price) as totalPrice").lambda()
+			.eq(PointBills::getIsCheak, "0")
+			.in(PointBills::getId, ids);
+
+		PointBills pointBills = getOne(query);
+		if (ObjectUtil.isEmpty(pointBills) && ObjectUtil.isEmpty(pointBills.getTotalPrice())) {
+			throw new ServiceException("未找到记录!");
+		}
+
+		BigDecimal amount = pointBills.getTotalPrice();
+		//判断余额是否可以进行核销操作
+		if (balance.subtract(amount).compareTo(BigDecimal.ZERO) < 0) {
+			throw new ServiceException("余额不足,请充值处理!");
+		}
+
+		String requestNo = IdUtil.simpleUUID();
+
+		//余额充足调取易宝的转账接口进行转账操作
+		transfer(mall, amount, requestNo);
+
+		//保存转账信息
+		saveBills(bladeUser, amount, requestNo, ids, mall.getId());
+		return true;
+	}
+
+	/**
+	 * 保存积分核销转账信息
+	 */
+	private void saveBills(BladeUser bladeUser, BigDecimal amount, String requestNo, List<Long> ids, long mallId) {
+		Bills bills = new Bills();
+		bills.setPointNum(BigDecimal.ZERO);
+		bills.setFee(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.setPayway(PaymentScene.TRANSFER.name());
+		bills.setCost(BigDecimal.ZERO);
+		bills.setType(OrderType.MALL_CHARGE.name());
+		bills.setDiscount(BigDecimal.ONE);
+		bills.setPayId(bladeUser.getUserId());
+		bills.setThirdOrderId(requestNo);
+		bills.setBillDesc(JSON.toJSONString(ids));
+		bills.setTenantId(bills.getTenantId());
+		bills.setMallId(mallId);
+		Assert.isTrue(billsService.saveOrUpdate(bills), () -> {
+			throw new ServiceException("订单异常!");
+		});
+	}
+
+	/**
+	 * 积分核销,向易宝发起商户或商场账户扣费
+	 */
+	private void transfer(Mall mall, BigDecimal amount, String requestNo) {
+		TransferOrderDto transferOrderDto = TransferOrderDto.builder()
+			.fromMerchantNo(mall.getMerchantNo())
+			.toMerchantNo(yeePayConst.getParentMerchantNo())
+			.orderAmount(amount.toPlainString())
+			.requestNo(requestNo)
+			.usage("积分交易核销!")
+			.feeChargeSide(YeepayApiConstant.feeChargeSide.INSIDE)
+			.notifyUrl(yeePayConst.getServiceUrl() + "/payment/callback/" + OrderType.MALL_CHARGE)
+			.build();
+
+		YopResponse yopResponse = yeepaySaasService.transferOrder(transferOrderDto);
+		JSONObject res = JSON.parseObject(yopResponse.getStringResult());
+		if (!Objects.equals(res.getString("returnCode"), "UA00000")) {
+			throw new ServiceException(res.getString("returnMsg"));
+		}
+	}
+
+	/**
+	 * 获取易宝余额信息
+	 */
+	private YeePayAccountBalanceVO getYeePayAccountBalance(String merchantNo) {
+		YeePayAccountBalanceVO balanceVO = new YeePayAccountBalanceVO();
+		YopResponse yopResponse = yeepaySaasService.accountBalanceQuery(merchantNo);
+		if (ObjectUtil.isNotEmpty(yopResponse)) {
+			balanceVO = JSON.parseObject(yopResponse.getStringResult(), YeePayAccountBalanceVO.class);
+		}
+		return balanceVO;
+	}
 }

+ 51 - 0
src/main/java/org/springblade/ldt/bills/vo/PointBillCensusVO.java

@@ -0,0 +1,51 @@
+/*
+ *      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 io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springblade.ldt.bills.entity.PointBills;
+
+/**
+ * @author July
+ * @description 积分明细统计数据VO
+ * @createdTime 2021/9/28 14:17
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@Data
+@ApiModel(value = "积分明细统计数据VO", description = "积分明细统计数据VO")
+public class PointBillCensusVO {
+	private static final long serialVersionUID = 1L;
+
+	@ApiModelProperty(value = "易宝余额")
+	private String yeePayBalance;
+
+	@ApiModelProperty(value = "应付总额")
+	private String accountsPayable;
+
+	@ApiModelProperty(value = "已核销")
+	private String handledAmount;
+
+	@ApiModelProperty(value = "未核销")
+	private String untreatedAmount;
+}

+ 43 - 0
src/main/java/org/springblade/ldt/bills/vo/YeePayAccountBalanceVO.java

@@ -0,0 +1,43 @@
+/*
+ *      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 lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @author July
+ * @description 易宝账户余额VO
+ * @createdTime 2021/9/28 14:17
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@Data
+public class YeePayAccountBalanceVO {
+	private String returnCode;
+	private String returnMsg;
+	private String accountNo;
+	private String merchantNo;
+	private String balance;
+	private String accountCreateTime;
+	private String accountStatus;
+}

+ 55 - 1
src/main/java/org/springblade/payment/callback/trade/MallChargeCallback.java

@@ -1,25 +1,79 @@
 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;
+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.entity.PointBills;
+import org.springblade.ldt.bills.service.IBillsService;
+import org.springblade.ldt.bills.service.IPointBillsService;
 import org.springblade.payment.entity.SuccessParams;
 import org.springblade.payment.event.MallChargeEvent;
 import org.springframework.context.event.EventListener;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
+
+import java.util.List;
 
 /**
  * @author: lianghanqiang
  * @description: 代理付款回调
  * @since: 8/5/21 -- 3:01 PM
  */
+@AllArgsConstructor
 @Component
 public class MallChargeCallback {
 
+	private IBillsService billsService;
+	private IPointBillsService pointBillsService;
+
 
 	@EventListener
 	@Async
 	@Transactional
-	public void PaySuccess(MallChargeEvent mallChargeEvent){
+	public void PaySuccess(MallChargeEvent mallChargeEvent) {
 		SuccessParams successParams = mallChargeEvent.getSuccessParams();
+		String requestNo = successParams.getRes().getString("requestNo");
+
+		Bills bills = billsService.getOne(new QueryWrapper<Bills>().lambda().eq(Bills::getThirdOrderId, requestNo));
+
+		String transferStatus = successParams.getRes().getString("transferStatus");
+		if (transferStatus.equals("FAIL")) {
+			handleBills(bills, successParams.getRes(), AppConstant.BillPayStatus.取消付款);
+		} else if (transferStatus.equals("SUCCESS")) {
+			handleBills(bills, successParams.getRes(), AppConstant.BillPayStatus.付款成功);
+
+			handlePointBills(bills.getBillDesc());
+
+		}
 	}
+
+	/**
+	 * 更新账单信息
+	 */
+	private void handleBills(Bills bills, JSONObject res, AppConstant.BillPayStatus status) {
+		bills.setFee(res.getBigDecimal("fee"));
+		bills.setPayStatus(status.name());
+		bills.setThirdOrderId(res.getString("orderNo"));
+		Assert.isTrue(billsService.saveOrUpdate(bills), () -> {
+			throw new ServiceException("更新付款账单信息异常!");
+		});
+	}
+
+	/**
+	 * 将积分明细修改未已核销
+	 */
+	private void handlePointBills(String idStr) {
+		List<Long> ids = JSON.parseArray(idStr, Long.class);
+		Assert.isTrue(pointBillsService.update(Wrappers.<PointBills>lambdaUpdate().set(PointBills::getIsCheak, 1).in(PointBills::getId, ids)), () -> {
+			throw new ServiceException("更新渠道积分账户异常!");
+		});
+	}
+
 }