退款提现

This commit is contained in:
zengtao01
2024-07-26 14:33:43 +08:00
parent 82eb8b56ce
commit 1de2f8a6b7
41 changed files with 1038 additions and 119 deletions

View File

@ -69,6 +69,7 @@ public interface ErrorCodeConstants {
ErrorCode CUSTOMER_TRAFFIC_NOT_EXISTS = new ErrorCode(1_004_013_010, "订单明细不存在"); ErrorCode CUSTOMER_TRAFFIC_NOT_EXISTS = new ErrorCode(1_004_013_010, "订单明细不存在");
ErrorCode DEVICE_WARN_NOT_EXISTS = new ErrorCode(1_004_013_011, "订单明细不存在"); ErrorCode DEVICE_WARN_NOT_EXISTS = new ErrorCode(1_004_013_011, "订单明细不存在");
ErrorCode DISH_STATISTICS_NOT_EXISTS = new ErrorCode(1_004_013_012, "订单明细不存在"); ErrorCode DISH_STATISTICS_NOT_EXISTS = new ErrorCode(1_004_013_012, "订单明细不存在");
ErrorCode CASH_AMOUNT_NOT_ENOUGH = new ErrorCode(1_004_013_002, "现金充值余额不足");
ErrorCode DINING_PLATES_NOT_EXISTS = new ErrorCode(1_004_099_000, "餐盘不存在"); ErrorCode DINING_PLATES_NOT_EXISTS = new ErrorCode(1_004_099_000, "餐盘不存在");
@ -79,6 +80,7 @@ public interface ErrorCodeConstants {
ErrorCode FACE_NOT_BIND_USER = new ErrorCode(1_004_099_005, "人脸未绑定"); ErrorCode FACE_NOT_BIND_USER = new ErrorCode(1_004_099_005, "人脸未绑定");
ErrorCode CARD_NOT_BIND_USER = new ErrorCode(1_004_099_006, "该卡未绑定用户"); ErrorCode CARD_NOT_BIND_USER = new ErrorCode(1_004_099_006, "该卡未绑定用户");
ErrorCode INSUFFICIENT_BALANCE = new ErrorCode(1_004_099_007, "余额不足30元,请充值"); ErrorCode INSUFFICIENT_BALANCE = new ErrorCode(1_004_099_007, "余额不足30元,请充值");
ErrorCode EXIST_TO_COMPLETE_ORDER = new ErrorCode(1_004_099_008, "存在未支付完的订单");
ErrorCode CARD_ALREADY_BIND = new ErrorCode(1_004_099_008, "卡号已绑定"); ErrorCode CARD_ALREADY_BIND = new ErrorCode(1_004_099_008, "卡号已绑定");
ErrorCode ORDER_NOT_COMPLETE = new ErrorCode(1_004_099_009, "订单未完成"); ErrorCode ORDER_NOT_COMPLETE = new ErrorCode(1_004_099_009, "订单未完成");
ErrorCode NEED_ADD_USER = new ErrorCode(1_007_901_004, "请先添加人员"); ErrorCode NEED_ADD_USER = new ErrorCode(1_007_901_004, "请先添加人员");

View File

@ -160,5 +160,17 @@ public class CardController {
return success(cardService.rechargeByAdmin(vo)); return success(cardService.rechargeByAdmin(vo));
} }
@GetMapping("/getCashMoney")
@Operation(summary = "获取现金充值")
public CommonResult<BigDecimal> getCashMoney(Long userId) {
return success(cardService.getCashMoney(userId));
}
@GetMapping("/cashDraw")
@Operation(summary = "现金提现")
public CommonResult<Boolean> cashDraw(Long userId,BigDecimal money) {
return success(cardService.cashDraw(userId,money));
}
} }

View File

@ -17,4 +17,5 @@ public class MemberUserListVO extends PageParam {
@Schema(description = "小组id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "小组id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long groupId; private Long groupId;
private String name; private String name;
private String mobile;
} }

View File

@ -25,7 +25,6 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid; import javax.validation.Valid;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -100,8 +99,8 @@ public class AppCardController {
@Operation(summary = "充值") @Operation(summary = "充值")
//@PreAuthorize("@ss.hasPermission('member:card:update')") //@PreAuthorize("@ss.hasPermission('member:card:update')")
public CommonResult<Boolean> recharge(BigDecimal money,BigDecimal giftMoney) { public CommonResult<Boolean> recharge(BigDecimal money,BigDecimal giftMoney) {
BigDecimal bigDecimal = money.divide(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP); //BigDecimal bigDecimal = money.divide(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
return success(cardService.recharge(bigDecimal,CardDO.ADD,giftMoney)); return success(cardService.recharge(money,CardDO.ADD,giftMoney));
} }

View File

@ -30,6 +30,7 @@ public class DishOrderDO extends BaseDO {
public final static String COMPLETE = "1"; public final static String COMPLETE = "1";
public final static String INCOMPLETE = "0"; public final static String INCOMPLETE = "0";
public final static String TOCOMPLETE = "2";
/** /**

View File

@ -106,6 +106,7 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
// 分页查询 // 分页查询
return selectPage(listVO, new LambdaQueryWrapperX<MemberUserDO>() return selectPage(listVO, new LambdaQueryWrapperX<MemberUserDO>()
.likeIfPresent(MemberUserDO::getNickname, listVO.getName()) .likeIfPresent(MemberUserDO::getNickname, listVO.getName())
.likeIfPresent(MemberUserDO::getMobile,listVO.getMobile())
.notIn(CollectionUtil.isNotEmpty(listVO.getIds()) ,MemberUserDO::getId, listVO.getIds()) .notIn(CollectionUtil.isNotEmpty(listVO.getIds()) ,MemberUserDO::getId, listVO.getIds())
.orderByDesc(MemberUserDO::getId)); .orderByDesc(MemberUserDO::getId));
} }

View File

@ -17,7 +17,9 @@ public enum CostTypeEnum {
NOON("3", "午餐"), NOON("3", "午餐"),
NIGHT("4", "晚餐"), NIGHT("4", "晚餐"),
ADMIN_PAY("5","管理后台充值"), ADMIN_PAY("5","管理后台充值"),
REFUND("6","退款") REFUND("6","退款"),
WITHDRAW("7","微信提现"),
CASH_WITHDRAW("8","现金提现"),
; ;
/** /**

View File

@ -54,7 +54,7 @@ public class BalanceDeductionJob implements JobHandler {
List<DiningPlatesDO> diningPlatesToCharging = platesService.getDiningPlatesToCharging(EXPIRATION_TIME); List<DiningPlatesDO> diningPlatesToCharging = platesService.getDiningPlatesToCharging(EXPIRATION_TIME);
int size = 0; int size = 0;
if(CollectionUtil.isNotEmpty(diningPlatesToCharging)){ if (CollectionUtil.isNotEmpty(diningPlatesToCharging)) {
List<Long> ids = diningPlatesToCharging.stream().map(DiningPlatesDO::getId).collect(Collectors.toList()); List<Long> ids = diningPlatesToCharging.stream().map(DiningPlatesDO::getId).collect(Collectors.toList());
List<Long> orderIds = diningPlatesToCharging.stream().map(DiningPlatesDO::getOrderId).collect(Collectors.toList()); List<Long> orderIds = diningPlatesToCharging.stream().map(DiningPlatesDO::getOrderId).collect(Collectors.toList());
//先更改状态防止重复消费 //先更改状态防止重复消费
@ -74,29 +74,38 @@ public class BalanceDeductionJob implements JobHandler {
BigDecimal money = oldCardDO.getMoney(); BigDecimal money = oldCardDO.getMoney();
BigDecimal wxAmount = oldCardDO.getWxAmount(); BigDecimal wxAmount = oldCardDO.getWxAmount();
BigDecimal giftAmount = oldCardDO.getGiftAmount(); BigDecimal giftAmount = oldCardDO.getGiftAmount();
BigDecimal cashAmount = oldCardDO.getCashAmount(); BigDecimal cashAmount = oldCardDO.getCashAmount();
cardDO.setMoney(money.subtract(total).setScale(2, BigDecimal.ROUND_HALF_UP)); cardDO.setMoney(money.subtract(total).setScale(2, BigDecimal.ROUND_HALF_UP));
if(total.compareTo(wxAmount)<=0){ if (total.compareTo(money) > 0) {
cardDO.setWxAmount(wxAmount.subtract(total).setScale(2, BigDecimal.ROUND_HALF_UP)); dishOrderDO.setOrderStatus(DishOrderDO.TOCOMPLETE);
dishOrderDO.setWxAmount(total); } else {
}else { dishOrderDO.setOrderStatus(DishOrderDO.COMPLETE);
cardDO.setWxAmount(BigDecimal.ZERO); //计算金额
dishOrderDO.setWxAmount(wxAmount); if (total.compareTo(wxAmount) <= 0) {
BigDecimal total1 = total.subtract(wxAmount).setScale(2, BigDecimal.ROUND_HALF_UP); cardDO.setWxAmount(wxAmount.subtract(total).setScale(2, BigDecimal.ROUND_HALF_UP));
if(total1.compareTo(cashAmount)<=0){ dishOrderDO.setWxAmount(total);
cardDO.setCashAmount(cashAmount.subtract(total1).setScale(2, BigDecimal.ROUND_HALF_UP)); } else {
dishOrderDO.setCashAmount(total1); cardDO.setWxAmount(BigDecimal.ZERO);
}else { dishOrderDO.setWxAmount(wxAmount);
cardDO.setCashAmount(BigDecimal.ZERO); BigDecimal total1 = total.subtract(wxAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
dishOrderDO.setCashAmount(cashAmount); if (total1.compareTo(cashAmount) <= 0) {
BigDecimal total2 = total1.subtract(cashAmount).setScale(2, BigDecimal.ROUND_HALF_UP); cardDO.setCashAmount(cashAmount.subtract(total1).setScale(2, BigDecimal.ROUND_HALF_UP));
dishOrderDO.setCashAmount(total1);
} else {
cardDO.setCashAmount(BigDecimal.ZERO);
dishOrderDO.setCashAmount(cashAmount);
BigDecimal total2 = total1.subtract(cashAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
cardDO.setGiftAmount(giftAmount.subtract(total2).setScale(2, BigDecimal.ROUND_HALF_UP)); cardDO.setGiftAmount(giftAmount.subtract(total2).setScale(2, BigDecimal.ROUND_HALF_UP));
dishOrderDO.setGiftAmount(total2); dishOrderDO.setGiftAmount(total2);
}
} }
} }
cardDO.setUserId(userId); cardDO.setUserId(userId);
@ -104,8 +113,8 @@ public class BalanceDeductionJob implements JobHandler {
cardDO.setFlag(CardDO.MINUS); cardDO.setFlag(CardDO.MINUS);
cardService.insertOne(cardDO); cardService.insertOne(cardDO);
list.add(cardDO); list.add(cardDO);
dishOrderDO.setTotalMoney(total); dishOrderDO.setTotalMoney(total);
dishOrderDO.setOrderStatus(DishOrderDO.COMPLETE);
dishOrderDO.setUpdateTime(LocalDateTime.now()); dishOrderDO.setUpdateTime(LocalDateTime.now());
stringRedisTemplate.delete(dishOrderDO.getDiningPlatesNum()); stringRedisTemplate.delete(dishOrderDO.getDiningPlatesNum());
}); });

View File

@ -100,4 +100,8 @@ public interface CardService {
FaceVo getFaceData(String faceId); FaceVo getFaceData(String faceId);
void refund(Long userId,BigDecimal money,Long orderId); void refund(Long userId,BigDecimal money,Long orderId);
BigDecimal getCashMoney(Long userId);
Boolean cashDraw(Long userId,BigDecimal money);
} }

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.service.card;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@ -19,6 +20,7 @@ import cn.iocoder.yudao.module.member.dal.mysql.group.MemberGroupMapper;
import cn.iocoder.yudao.module.member.dal.mysql.order.DishOrderMapper; import cn.iocoder.yudao.module.member.dal.mysql.order.DishOrderMapper;
import cn.iocoder.yudao.module.member.enums.CostTypeEnum; import cn.iocoder.yudao.module.member.enums.CostTypeEnum;
import cn.iocoder.yudao.module.member.util.MemberConstants; import cn.iocoder.yudao.module.member.util.MemberConstants;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -35,8 +37,7 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.CARD_NOT_EXISTS; import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.NEED_ADD_USER;
/** /**
* 余额变动明细 Service 实现类 * 余额变动明细 Service 实现类
@ -115,6 +116,7 @@ public class CardServiceImpl implements CardService {
BigDecimal oldMoney = BigDecimal.ZERO; BigDecimal oldMoney = BigDecimal.ZERO;
BigDecimal wxOldMoney= BigDecimal.ZERO; BigDecimal wxOldMoney= BigDecimal.ZERO;
BigDecimal giftOldMoney= BigDecimal.ZERO; BigDecimal giftOldMoney= BigDecimal.ZERO;
BigDecimal cashAmount= BigDecimal.ZERO;
if (ObjectUtil.isNotEmpty(lastCardDO) && lastCardDO.getMoney() != null) { if (ObjectUtil.isNotEmpty(lastCardDO) && lastCardDO.getMoney() != null) {
oldMoney = lastCardDO.getMoney(); oldMoney = lastCardDO.getMoney();
} }
@ -124,11 +126,24 @@ public class CardServiceImpl implements CardService {
if (ObjectUtil.isNotEmpty(lastCardDO) && lastCardDO.getGiftAmount() != null) { if (ObjectUtil.isNotEmpty(lastCardDO) && lastCardDO.getGiftAmount() != null) {
giftOldMoney = lastCardDO.getGiftAmount(); giftOldMoney = lastCardDO.getGiftAmount();
} }
if (ObjectUtil.isNotEmpty(lastCardDO) && lastCardDO.getGiftAmount() != null) {
cashAmount = lastCardDO.getCashAmount();
}
cardDO.setMoney(oldMoney.add(money).setScale(2, BigDecimal.ROUND_HALF_UP)); cardDO.setMoney(oldMoney.add(money).setScale(2, BigDecimal.ROUND_HALF_UP));
cardDO.setWxAmount(wxOldMoney.add(money).setScale(2, BigDecimal.ROUND_HALF_UP)); cardDO.setCashAmount(cashAmount);
cardDO.setGiftAmount(giftOldMoney.add(giftMoney).setScale(2, BigDecimal.ROUND_HALF_UP)); cardDO.setGiftAmount(giftOldMoney);
return cardMapper.insert(cardDO) > 0; cardDO.setWxAmount(giftOldMoney);
if(cardDO.getMoney().compareTo(BigDecimal.ZERO) >0){
BigDecimal wxAmount = money;
if(giftMoney!=null){
cardDO.setGiftAmount(giftOldMoney.add(giftMoney).setScale(2, BigDecimal.ROUND_HALF_UP));
wxAmount = wxAmount.subtract(giftMoney);
}
cardDO.setWxAmount(wxOldMoney.add(wxAmount).setScale(2, BigDecimal.ROUND_HALF_UP));
}
int i =cardMapper.insert(cardDO);
return i > 0;
} }
@Override @Override
@ -233,10 +248,16 @@ public class CardServiceImpl implements CardService {
add.setType(CostTypeEnum.ADMIN_PAY.getCode()); add.setType(CostTypeEnum.ADMIN_PAY.getCode());
BigDecimal oldMoney = cardDO.getMoney(); BigDecimal oldMoney = cardDO.getMoney();
add.setMoney(oldMoney.add(vo.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP)); add.setMoney(oldMoney.add(vo.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP));
BigDecimal cashOldMoney = cardDO.getCashAmount();
add.setCashAmount(cashOldMoney.add(vo.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP)); if(cardDO.getMoney().compareTo(BigDecimal.ZERO) >0){
BigDecimal cashOldMoney = cardDO.getCashAmount();
add.setCashAmount(cashOldMoney.add(vo.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP));
add.setWxAmount(cardDO.getWxAmount());
add.setGiftAmount(cardDO.getGiftAmount());
}
addList.add(add); addList.add(add);
} }
//添加新的用户金额 //添加新的用户金额
if (CollectionUtil.isNotEmpty(newIds)) { if (CollectionUtil.isNotEmpty(newIds)) {
for (Long id : newIds) { for (Long id : newIds) {
@ -304,4 +325,59 @@ public class CardServiceImpl implements CardService {
} }
cardMapper.insert(cardDO); cardMapper.insert(cardDO);
} }
public BigDecimal checkOrder(Long userId) {
LambdaQueryWrapper<DishOrderDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DishOrderDO::getUserId,userId);
wrapper.eq(DishOrderDO::getOrderStatus,DishOrderDO.TOCOMPLETE);
List<DishOrderDO> dishOrderDOS = dishOrderMapper.selectList(wrapper);
if(CollectionUtil.isNotEmpty(dishOrderDOS)){
BigDecimal reduce = dishOrderDOS.stream().map(DishOrderDO::getTotalMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
return reduce;
}else {
return BigDecimal.ZERO;
}
}
@Override
public BigDecimal getCashMoney(Long userId) {
CardDO lastCardDO = cardMapper.selectOne(Wrappers.<CardDO>lambdaQuery().eq(CardDO::getUserId, userId)
.orderByDesc(CardDO::getCreateTime).last(MemberConstants.LIMIT_ONE));
if(ObjectUtil.isNotEmpty(lastCardDO)){
return lastCardDO.getCashAmount();
}
return BigDecimal.ZERO;
}
@Override
public Boolean cashDraw(Long userId,BigDecimal money) {
CardDO lastCardDO = cardMapper.selectOne(Wrappers.<CardDO>lambdaQuery().eq(CardDO::getUserId, userId)
.orderByDesc(CardDO::getCreateTime).last(MemberConstants.LIMIT_ONE));
if(ObjectUtil.isEmpty(lastCardDO) || lastCardDO.getCashAmount().compareTo(BigDecimal.ZERO)<1
|| money.compareTo(lastCardDO.getCashAmount())>0){
throw exception(CASH_AMOUNT_NOT_ENOUGH);
}
CardDO cardDO = new CardDO();
cardDO.setUserId(userId);
cardDO.setFlag(CardDO.MINUS);
cardDO.setChangeMoney(money);
cardDO.setType(CostTypeEnum.CASH_WITHDRAW.getCode());
BigDecimal oldMoney = lastCardDO.getMoney();
BigDecimal oldWxAmount = lastCardDO.getWxAmount();
BigDecimal oldCashAmount = lastCardDO.getCashAmount();
BigDecimal oldGiftAmount = lastCardDO.getGiftAmount();
cardDO.setWxAmount(oldWxAmount);
cardDO.setGiftAmount(oldGiftAmount);
cardDO.setMoney(oldMoney.subtract(money));
cardDO.setCashAmount(oldCashAmount.subtract(money));
int insert = cardMapper.insert(cardDO);
return insert>0;
}
} }

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.service.diningplates;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender;
@ -167,6 +168,9 @@ public class DiningPlatesServiceImpl implements DiningPlatesService {
.eq(MemberUserDO::getCardId, cardId) .eq(MemberUserDO::getCardId, cardId)
.last(MemberConstants.LIMIT_ONE)); .last(MemberConstants.LIMIT_ONE));
checkMemberUser(memberUserDO, false); checkMemberUser(memberUserDO, false);
//订单验证
checkOrder(memberUserDO.getId());
//余额验证 //余额验证
BigDecimal money = cardService.getMoneyByUserId(memberUserDO.getId()); BigDecimal money = cardService.getMoneyByUserId(memberUserDO.getId());
checkMoney(money); checkMoney(money);
@ -208,6 +212,8 @@ public class DiningPlatesServiceImpl implements DiningPlatesService {
.eq(MemberUserDO::getFaceId, faceId) .eq(MemberUserDO::getFaceId, faceId)
.last(MemberConstants.LIMIT_ONE)); .last(MemberConstants.LIMIT_ONE));
checkMemberUser(memberUserDO, true); checkMemberUser(memberUserDO, true);
//订单验证
checkOrder(memberUserDO.getId());
//余额验证 //余额验证
BigDecimal money = cardService.getMoneyByUserId(memberUserDO.getId()); BigDecimal money = cardService.getMoneyByUserId(memberUserDO.getId());
checkMoney(money); checkMoney(money);
@ -293,6 +299,21 @@ public class DiningPlatesServiceImpl implements DiningPlatesService {
} }
} }
public void checkOrder(Long userId) {
LambdaQueryWrapper<DishOrderDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DishOrderDO::getUserId,userId);
wrapper.eq(DishOrderDO::getOrderStatus,DishOrderDO.TOCOMPLETE);
List<DishOrderDO> dishOrderDOS = dishOrderMapper.selectList(wrapper);
BigDecimal moneyByUserId = cardService.getMoneyByUserId(userId);
ErrorCode code = new ErrorCode(1_004_099_008, "存在未支付完的订单,待支付金额:"+moneyByUserId.abs()+"");
if(CollectionUtil.isNotEmpty(dishOrderDOS)){
throw exception(code);
}
}
@Override @Override
public List<DiningPlatesStoreVO> getDiningPlatesNum(LocalDateTime localDateTime, Integer time) { public List<DiningPlatesStoreVO> getDiningPlatesNum(LocalDateTime localDateTime, Integer time) {

View File

@ -3,33 +3,49 @@ package cn.iocoder.yudao.module.pay.controller.admin.notify;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.PayClient;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import cn.iocoder.yudao.framework.pay.core.enums.divide.PayDivideRefundStatusRespEnum;
import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO;
import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO;
import cn.iocoder.yudao.module.pay.convert.notify.PayNotifyTaskConvert; import cn.iocoder.yudao.module.pay.convert.notify.PayNotifyTaskConvert;
import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.divide.DivideDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord.RefundRecordDO;
import cn.iocoder.yudao.module.pay.dal.mysql.refundrecord.RefundRecordMapper;
import cn.iocoder.yudao.module.pay.service.app.PayAppService; import cn.iocoder.yudao.module.pay.service.app.PayAppService;
import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
import cn.iocoder.yudao.module.pay.service.divide.DivideService;
import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.annotation.security.PermitAll; import javax.annotation.security.PermitAll;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -50,11 +66,17 @@ public class PayNotifyController {
@Resource @Resource
private PayRefundService refundService; private PayRefundService refundService;
@Resource @Resource
private RefundRecordMapper refundRecordMapper;
@Resource
private PayNotifyService notifyService; private PayNotifyService notifyService;
@Resource @Resource
private PayAppService appService; private PayAppService appService;
@Resource @Resource
private PayChannelService channelService; private PayChannelService channelService;
@Resource
private DivideService divideService;
@Resource
private StringRedisTemplate notifyRedisTemplate;
@PostMapping(value = "/order/{channelId}") @PostMapping(value = "/order/{channelId}")
@Operation(summary = "支付渠道的统一【支付】回调") @Operation(summary = "支付渠道的统一【支付】回调")
@ -91,10 +113,37 @@ public class PayNotifyController {
log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId); log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId);
throw exception(CHANNEL_NOT_FOUND); throw exception(CHANNEL_NOT_FOUND);
} }
// 2. 解析通知数据 // 2. 解析通知数据
PayRefundRespDTO notify = payClient.parseRefundNotify(params, body); PayRefundRespDTO notify = payClient.parseRefundNotify(params, body);
refundService.notifyRefund(channelId, notify); RefundRecordDO refundRecordDO = refundRecordMapper.selectOne(Wrappers.<RefundRecordDO>lambdaUpdate()
.eq(RefundRecordDO::getOutRefundNo, notify.getOutRefundNo())
.last("limit 1"));
String status = "";
if(PayRefundStatusRespEnum.SUCCESS.getStatus().equals(notify.getStatus())){
status = PayDivideRefundStatusRespEnum.SUCCESS.getStatus();
}else{
status = PayDivideRefundStatusRespEnum.ABNORMAL.getStatus();
}
refundRecordDO.setStatus(status);
if("0".equals(refundRecordDO.getNotifyStatus()) && "20".equals(refundRecordDO.getStatus())){
//扣除积分
divideService.subtractWx(refundRecordDO.getTotalPrice(),Long.valueOf(refundRecordDO.getUserId()));
//更改订单
String jsonString = notifyRedisTemplate.opsForValue().get("R" + notify.getOutRefundNo());
DivideDO divideDO1 = JsonUtils.parseObject(jsonString, DivideDO.class);
divideService.updateDivideById(divideDO1);
//分账回退
if (divideDO1.getBackPrice()!=0){
ArrayList<DivideDO> divideDOS = new ArrayList<>();
divideDOS.add(divideDO1);
divideService.returnMoney(divideDOS);
}
}
refundRecordDO.setNotifyStatus("1");
refundRecordMapper.updateById(refundRecordDO);
//refundService.notifyRefund(channelId, notify);
return "success"; return "success";
} }

View File

@ -0,0 +1,76 @@
package cn.iocoder.yudao.module.pay.dal.dataobject.card;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.math.BigDecimal;
/**
* 余额变动明细 DO
*
* @author 开发账号
*/
@TableName("member_card")
@KeySequence("member_card_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DivideCardDO extends BaseDO {
public final static String ADD = "1";
public final static String MINUS = "0";
/**
* 编号
*/
@TableId
private Long id;
/**
* 用户Id
*/
private Long userId;
/**
* 余额
*/
private BigDecimal money;
/**
* 加减标志01
*/
private String flag;
/**
* 变动金额
*/
private BigDecimal changeMoney;
/**
* 消费类型
*/
private String type;
/**
* 赠送金额
*/
private BigDecimal giftAmount;
/**
* 现金金额
*/
private BigDecimal cashAmount;
/**
* 微信充值金额
*/
private BigDecimal wxAmount;
}

View File

@ -58,6 +58,11 @@ public class DivideDO extends BaseDO {
* 待分金额,单位:分 * 待分金额,单位:分
*/ */
private Integer unPrice; private Integer unPrice;
/**
* 待退款金额,单位:分
*/
private Integer unRePrice;
/** /**
* 分账状态 * 分账状态
*/ */
@ -68,6 +73,11 @@ public class DivideDO extends BaseDO {
*/ */
private String refundStatus; private String refundStatus;
/**
* 是否解冻
*/
private String unfreezeStatus;
/** /**
* 商户分账单号 * 商户分账单号
*/ */
@ -82,7 +92,17 @@ public class DivideDO extends BaseDO {
private String orderId; private String orderId;
/** /**
* 退款金额 * 已用于退款金额
*/ */
private Integer refundPrice; private Integer refundPrice;
/**
* 分账回退金额
*/
private Integer backPrice;
/**
* 用于分账的金额
*/
private Integer psPrice;
} }

View File

@ -39,6 +39,11 @@ public class DivideInfoDO extends BaseDO {
* 商户分账单号 * 商户分账单号
*/ */
private String outOrderNo; private String outOrderNo;
/**
* 微信分账单号
*/
private String orderId;
/** /**
* 分账个人接收方姓名 * 分账个人接收方姓名
*/ */

View File

@ -1,11 +1,15 @@
package cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord; package cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
/** /**
* 退款记录 DO * 退款记录 DO
@ -68,4 +72,9 @@ public class RefundRecordDO extends BaseDO {
*/ */
private String refundId; private String refundId;
/**
* 是否回调
*/
private String notifyStatus;
} }

View File

@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.pay.dal.mysql.card;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.pay.dal.dataobject.card.DivideCardDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 余额变动明细 Mapper
*
* @author 开发账号
*/
@Mapper
public interface DivideCardMapper extends BaseMapperX<DivideCardDO> {
}

View File

@ -41,7 +41,4 @@ public interface DivideMapper extends BaseMapperX<DivideDO> {
int orderCount(Long userId); int orderCount(Long userId);
} }

View File

@ -1,13 +1,11 @@
package cn.iocoder.yudao.module.pay.dal.mysql.refundrecord; package cn.iocoder.yudao.module.pay.dal.mysql.refundrecord;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.pay.controller.admin.refundrecord.vo.RefundRecordPageReqVO;
import cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord.RefundRecordDO; import cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord.RefundRecordDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.pay.controller.admin.refundrecord.vo.*;
/** /**
* 退款记录 Mapper * 退款记录 Mapper

View File

@ -4,6 +4,8 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.extra.spring.SpringUtil; import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@ -204,4 +206,9 @@ public class WalletPayClient extends AbstractPayClient<NonePayClientConfig> {
return null; return null;
} }
@Override
protected PayDivideBackRespDto doUnifiedDivideback(PayDivideBackUnifiedDto reqDTO) throws Throwable {
return null;
}
} }

View File

@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.pay.controller.app.divide.vo.DrawMoneyVO;
import cn.iocoder.yudao.module.pay.dal.dataobject.divide.DivideDO; import cn.iocoder.yudao.module.pay.dal.dataobject.divide.DivideDO;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.List;
/** /**
* 分账单 Service 接口 * 分账单 Service 接口
@ -70,7 +71,20 @@ public interface DivideService {
/** /**
* 解冻剩余资金 * 提现(退款)
*/ */
Boolean drawMoney( DrawMoneyVO drawMoneyVO); Boolean drawMoney( DrawMoneyVO drawMoneyVO);
/**
* 扣除wx充值
*/
void subtractWx(Integer amount,Long userId);
/**
* 分账回退
*/
void returnMoney(List<DivideDO> backList);
void updateDivideById(DivideDO divideDO);
} }

View File

@ -4,20 +4,31 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.PayClient;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.enums.divide.PayDivideRefundStatusRespEnum;
import cn.iocoder.yudao.framework.pay.core.enums.divide.PayDivideStatusRespEnum; import cn.iocoder.yudao.framework.pay.core.enums.divide.PayDivideStatusRespEnum;
import cn.iocoder.yudao.module.pay.controller.admin.divide.vo.DividePageReqVO; import cn.iocoder.yudao.module.pay.controller.admin.divide.vo.DividePageReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.divide.vo.DivideSaveReqVO; import cn.iocoder.yudao.module.pay.controller.admin.divide.vo.DivideSaveReqVO;
import cn.iocoder.yudao.module.pay.controller.app.divide.vo.DrawMoneyVO; import cn.iocoder.yudao.module.pay.controller.app.divide.vo.DrawMoneyVO;
import cn.iocoder.yudao.module.pay.dal.dataobject.card.DivideCardDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.divide.DivideDO; import cn.iocoder.yudao.module.pay.dal.dataobject.divide.DivideDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.dividecompany.DivideCompanyDO; import cn.iocoder.yudao.module.pay.dal.dataobject.dividecompany.DivideCompanyDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.divideinfo.DivideInfoDO; import cn.iocoder.yudao.module.pay.dal.dataobject.divideinfo.DivideInfoDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.dividerecord.DivideRecordDO; import cn.iocoder.yudao.module.pay.dal.dataobject.dividerecord.DivideRecordDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord.RefundRecordDO;
import cn.iocoder.yudao.module.pay.dal.mysql.card.DivideCardMapper;
import cn.iocoder.yudao.module.pay.dal.mysql.divide.DivideMapper; import cn.iocoder.yudao.module.pay.dal.mysql.divide.DivideMapper;
import cn.iocoder.yudao.module.pay.dal.mysql.dividerecord.DivideRecordMapper; import cn.iocoder.yudao.module.pay.dal.mysql.dividerecord.DivideRecordMapper;
import cn.iocoder.yudao.module.pay.dal.mysql.refundrecord.RefundRecordMapper;
import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO;
import cn.iocoder.yudao.module.pay.framework.pay.config.PayProperties; import cn.iocoder.yudao.module.pay.framework.pay.config.PayProperties;
import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
@ -26,6 +37,8 @@ import cn.iocoder.yudao.module.pay.service.divideinfo.DivideInfoService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingV3Request; import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingV3Request;
import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingV3Result; import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingV3Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -34,9 +47,9 @@ import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
@ -48,6 +61,7 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
*/ */
@Service @Service
@Validated @Validated
@Slf4j
public class DivideServiceImpl implements DivideService { public class DivideServiceImpl implements DivideService {
@Resource @Resource
@ -70,6 +84,14 @@ public class DivideServiceImpl implements DivideService {
@Resource @Resource
private DivideRecordMapper divideRecordMapper; private DivideRecordMapper divideRecordMapper;
@Resource
private RefundRecordMapper refundRecordMapper;
@Resource
private DivideCardMapper divideCardMapper;
@Resource
private StringRedisTemplate divideRedisTemplate;
@Override @Override
@ -150,6 +172,11 @@ public class DivideServiceImpl implements DivideService {
public int startDivide() { public int startDivide() {
BigDecimal today = divideMapper.getToday(); BigDecimal today = divideMapper.getToday();
if (today == null) {
return 0;
}
int money = today.multiply(new BigDecimal("100")).intValue(); int money = today.multiply(new BigDecimal("100")).intValue();
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
LocalDateTime thirtyDaysAgo = now.minusDays(30); LocalDateTime thirtyDaysAgo = now.minusDays(30);
@ -157,32 +184,41 @@ public class DivideServiceImpl implements DivideService {
List<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>lambdaQuery() List<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>lambdaQuery()
.eq(DivideDO::getStatus, PayDivideStatusRespEnum.WAITING.getStatus()) .eq(DivideDO::getStatus, PayDivideStatusRespEnum.WAITING.getStatus())
.ge(DivideDO::getCreateTime,thirtyDaysAgo) .eq(DivideDO::getUnfreezeStatus,"0")
.ge(DivideDO::getCreateTime, thirtyDaysAgo)
.orderByAsc(DivideDO::getCreateTime)); .orderByAsc(DivideDO::getCreateTime));
if(CollectionUtil.isEmpty(divideDOS)){ if (CollectionUtil.isEmpty(divideDOS)) {
return 0; return 0;
} }
List<DivideDO> divideList = new ArrayList<>(); List<DivideDO> divideList = new ArrayList<>();
int sum = 0; int sum = 0;
for(DivideDO divideDO: divideDOS){ for (DivideDO divideDO : divideDOS) {
Integer totalPrice = divideDO.getTotalPrice()-divideDO.getCpPrice(); Integer totalPrice = divideDO.getTotalPrice() - divideDO.getCpPrice();
sum = sum+totalPrice; if(totalPrice == 0){
if(sum<money){ continue;
}
sum = sum + totalPrice;
if (sum < money) {
divideDO.setUnPrice(totalPrice); divideDO.setUnPrice(totalPrice);
divideDO.setCpPrice(divideDO.getCpPrice()+totalPrice); divideDO.setCpPrice(divideDO.getCpPrice() + totalPrice);
divideDO.setPsPrice(divideDO.getPsPrice()+totalPrice);
divideList.add(divideDO); divideList.add(divideDO);
} else if (sum ==money) { } else if (sum == money) {
divideDO.setUnPrice(totalPrice); divideDO.setUnPrice(totalPrice);
divideDO.setCpPrice(divideDO.getCpPrice()+totalPrice); divideDO.setCpPrice(divideDO.getCpPrice() + totalPrice);
divideDO.setPsPrice(divideDO.getPsPrice()+totalPrice);
divideList.add(divideDO); divideList.add(divideDO);
break; break;
}else { } else {
int leftMoney = money+totalPrice- sum; int leftMoney = money + totalPrice - sum;
divideDO.setUnPrice(leftMoney); divideDO.setUnPrice(leftMoney);
divideDO.setCpPrice(divideDO.getCpPrice()+leftMoney); divideDO.setCpPrice(divideDO.getCpPrice() + leftMoney);
divideDO.setPsPrice(divideDO.getPsPrice()+leftMoney);
divideList.add(divideDO); divideList.add(divideDO);
break; break;
} }
@ -198,7 +234,7 @@ public class DivideServiceImpl implements DivideService {
.setUnfreezeUnsplit(false) .setUnfreezeUnsplit(false)
.setReceivers(createDivideInfo(divideDO)); .setReceivers(createDivideInfo(divideDO));
if(divideDO.getTotalPrice().equals(divideDO.getCpPrice())) { if (divideDO.getTotalPrice().equals(divideDO.getCpPrice())) {
payDivideUnifiedDto.setUnfreezeUnsplit(true); payDivideUnifiedDto.setUnfreezeUnsplit(true);
divideDO.setStatus(PayDivideStatusRespEnum.PROGRESS.getStatus()); divideDO.setStatus(PayDivideStatusRespEnum.PROGRESS.getStatus());
} }
@ -222,9 +258,11 @@ public class DivideServiceImpl implements DivideService {
} }
} }
} }
divideMapper.updateBatch(divideDOS); if(CollectionUtil.isNotEmpty(divideRecordDOList)){
divideRecordMapper.insertBatch(divideRecordDOList); divideMapper.updateBatch(divideDOS);
return divideDOS.size(); divideRecordMapper.insertBatch(divideRecordDOList);
}
return divideRecordDOList.size();
} }
@ -232,18 +270,18 @@ public class DivideServiceImpl implements DivideService {
public int getDivideResult() { public int getDivideResult() {
List<DivideRecordDO> divideRecordDOList = divideRecordMapper.getList(); List<DivideRecordDO> divideRecordDOList = divideRecordMapper.getList();
if(CollectionUtil.isEmpty(divideRecordDOList)){ if (CollectionUtil.isEmpty(divideRecordDOList)) {
return 0; return 0;
} }
Stream<String> transactionIdList = divideRecordDOList.stream().map(DivideRecordDO::getTransactionId); List<String> transactionIdList = divideRecordDOList.stream().map(DivideRecordDO::getTransactionId).collect(Collectors.toList());
Stream<String> OutOrderNoList = divideRecordDOList.stream().map(DivideRecordDO::getOutOrderNo); List<String> OutOrderNoList = divideRecordDOList.stream().map(DivideRecordDO::getOutOrderNo).collect(Collectors.toList());
List<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>lambdaQuery() List<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>lambdaQuery()
.in(DivideDO::getChannelOrderNo, transactionIdList) .in(DivideDO::getChannelOrderNo, transactionIdList)
.in(DivideDO::getNo,OutOrderNoList)); .in(DivideDO::getNo, OutOrderNoList));
if(CollectionUtil.isEmpty(divideDOS)){ if (CollectionUtil.isEmpty(divideDOS)) {
return 0; return 0;
} }
@ -254,11 +292,11 @@ public class DivideServiceImpl implements DivideService {
payDivideUnifiedDto.setTransactionId(divideDO.getChannelOrderNo()) payDivideUnifiedDto.setTransactionId(divideDO.getChannelOrderNo())
.setOutOrderNo(divideDO.getNo()); .setOutOrderNo(divideDO.getNo());
PayDivideRespDto payDivideRespDto = client.unifiedDivideResult(payDivideUnifiedDto); PayDivideRespDto payDivideRespDto = client.unifiedDivideResult(payDivideUnifiedDto);
updateDivideInfo(payDivideRespDto.getReceivers(),divideDO.getNo()); updateDivideInfo(payDivideRespDto.getReceivers(), divideDO.getNo(),payDivideRespDto.getOrderId());
if(divideDO.getTotalPrice().equals(divideDO.getCpPrice())) { if (divideDO.getTotalPrice().equals(divideDO.getCpPrice())) {
divideDO.setStatus(PayDivideStatusRespEnum.COMPLETE.getStatus()); divideDO.setStatus(PayDivideStatusRespEnum.COMPLETE.getStatus());
}else{ } else {
divideDO.setNo(noRedisDAO.generate(payProperties.getOrderNoPrefix())); divideDO.setNo(noRedisDAO.generate(payProperties.getOrderNoPrefix()));
} }
} }
@ -266,15 +304,24 @@ public class DivideServiceImpl implements DivideService {
return divideDOS.size(); return divideDOS.size();
} }
void updateDivideInfo(List<ProfitSharingV3Result.Receiver> receivers,String outOrderNo){ void updateDivideInfo(List<ProfitSharingV3Result.Receiver> receivers, String outOrderNo,String orderId) {
List<DivideInfoDO> list = new ArrayList<>(); List<DivideCompanyDO> list1 = divideCompanyService.getList();
for (ProfitSharingV3Result.Receiver receiver:receivers){ List<String> accountList = list1.stream().map(DivideCompanyDO::getAccount).collect(Collectors.toList());
List<DivideInfoDO> list = new ArrayList<>();
for (ProfitSharingV3Result.Receiver receiver : receivers) {
if(!accountList.contains(receiver.getAccount())){
continue;
}
DivideInfoDO divideInfo = divideInfoService.getDivideInfo(outOrderNo, receiver.getAccount()); DivideInfoDO divideInfo = divideInfoService.getDivideInfo(outOrderNo, receiver.getAccount());
divideInfo.setResult(receiver.getResult()) divideInfo.setResult(receiver.getResult())
.setFailReason(receiver.getFailReason()) .setFailReason(receiver.getFailReason())
.setDetailId(receiver.getDetailId()) .setDetailId(receiver.getDetailId())
.setDCreateTime(receiver.getCreateTime()) .setDCreateTime(receiver.getCreateTime())
.setDFinishTime(receiver.getFinishTime()); .setDFinishTime(receiver.getFinishTime())
.setOrderId(orderId);
list.add(divideInfo); list.add(divideInfo);
} }
divideInfoService.updateList(list); divideInfoService.updateList(list);
@ -284,14 +331,14 @@ public class DivideServiceImpl implements DivideService {
public int getDivideFreeze() { public int getDivideFreeze() {
List<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>lambdaQuery() List<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>lambdaQuery()
.eq(DivideDO::getStatus, PayDivideStatusRespEnum.COMPLETE.getStatus())); .eq(DivideDO::getStatus, PayDivideStatusRespEnum.COMPLETE.getStatus()));
if(CollectionUtil.isEmpty(divideDOS)){ if (CollectionUtil.isEmpty(divideDOS)) {
return 0; return 0;
} }
for (DivideDO divideDO : divideDOS) { for (DivideDO divideDO : divideDOS) {
PayClient client = channelService.getPayClient(divideDO.getChannelId()); PayClient client = channelService.getPayClient(divideDO.getChannelId());
PayDivideUnifiedDto payDivideUnifiedDto = new PayDivideUnifiedDto(); PayDivideUnifiedDto payDivideUnifiedDto = new PayDivideUnifiedDto();
if(checkSuccess(divideDO.getNo())){ if (checkSuccess(divideDO.getNo())) {
payDivideUnifiedDto.setTransactionId(divideDO.getChannelOrderNo()) payDivideUnifiedDto.setTransactionId(divideDO.getChannelOrderNo())
.setOutOrderNo(divideDO.getNo()); .setOutOrderNo(divideDO.getNo());
client.unifiedDivideFreeze(payDivideUnifiedDto); client.unifiedDivideFreeze(payDivideUnifiedDto);
@ -302,10 +349,10 @@ public class DivideServiceImpl implements DivideService {
return divideDOS.size(); return divideDOS.size();
} }
boolean checkSuccess(String outOrderNo){ boolean checkSuccess(String outOrderNo) {
List<DivideInfoDO> divideList = divideInfoService.getDivideList(outOrderNo); List<DivideInfoDO> divideList = divideInfoService.getDivideList(outOrderNo);
for (DivideInfoDO divideInfoDO:divideList){ for (DivideInfoDO divideInfoDO : divideList) {
if(!"SUCCESS".equals(divideInfoDO.getResult())){ if (!"SUCCESS".equals(divideInfoDO.getResult())) {
return false; return false;
} }
} }
@ -317,32 +364,41 @@ public class DivideServiceImpl implements DivideService {
//判断订单是否完成 //判断订单是否完成
int i = divideMapper.orderCount(drawMoneyVO.getUserId()); int i = divideMapper.orderCount(drawMoneyVO.getUserId());
if(i>0){ if (i > 0) {
throw new ServiceException(ORDER_NOT_COMPLETE); throw new ServiceException(ORDER_NOT_COMPLETE);
} }
//判断是否有金额可退款 //判断是否有金额可退款
BigDecimal wxAmount = divideMapper.getWxAmount(drawMoneyVO.getUserId()); BigDecimal wxAmount = divideMapper.getWxAmount(drawMoneyVO.getUserId());
int money = wxAmount.multiply(new BigDecimal("100")).intValue(); if(wxAmount == null){
if(money<=0){
throw new ServiceException(WX_ACCOUNT_NO); throw new ServiceException(WX_ACCOUNT_NO);
} }
int money = wxAmount.multiply(new BigDecimal("100")).intValue();
if (money <= 0) {
throw new ServiceException(WX_ACCOUNT_NO);
}
LocalDateTime now = LocalDateTime.now(); // 获取当前时间
LocalDateTime threeYearsAgo = now.minusDays(365);
//查询最近的充值订单,时间倒序退款 //查询最近的充值订单,时间倒序退款
List<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>lambdaQuery() List<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>lambdaQuery()
.eq(DivideDO::getChannelUserId, drawMoneyVO.getChannelUserId()) .eq(DivideDO::getChannelUserId, drawMoneyVO.getChannelUserId())
.eq(DivideDO::getRefundStatus,"0") .eq(DivideDO::getRefundStatus, "0")
.ge(DivideDO::getCreateTime,threeYearsAgo)
.orderByDesc(DivideDO::getCreateTime)); .orderByDesc(DivideDO::getCreateTime));
//筛选出未分账的订单 //筛选出未分账的订单
List<DivideDO> unDivideList = divideDOS.stream().filter(vo -> vo.getCpPrice() == 0).collect(Collectors.toList()); List<DivideDO> unDivideList = divideDOS.stream().filter(vo -> vo.getPsPrice() == 0).collect(Collectors.toList());
//筛选出已分账的订单 //筛选出已分账的订单
List<DivideDO> divideList = divideDOS.stream().filter(vo -> vo.getCpPrice().equals(vo.getTotalPrice())).collect(Collectors.toList()); List<DivideDO> divideCpList = divideDOS.stream().filter(vo -> vo.getPsPrice() != 0).collect(Collectors.toList());
//筛选出分账完的订单
List<DivideDO> divideList = divideCpList.stream().filter(vo -> vo.getTotalPrice().equals(vo.getCpPrice())).collect(Collectors.toList());
//剩下的是未分账完 的订单 //剩下的是未分账完 的订单
divideDOS.removeAll(unDivideList); divideCpList.removeAll(divideList);
divideDOS.removeAll(divideList);
//需要回退的订单 //需要回退的订单
List<DivideDO> backList = new ArrayList<>(); List<DivideDO> backList = new ArrayList<>();
@ -353,54 +409,329 @@ public class DivideServiceImpl implements DivideService {
//先从未分账的订单计算 //先从未分账的订单计算
for (DivideDO divideDO: unDivideList){ for (DivideDO divideDO : unDivideList) {
Integer totalPrice = divideDO.getTotalPrice()-divideDO.getCpPrice(); Integer totalPrice = divideDO.getTotalPrice() - divideDO.getCpPrice();
sum = sum + totalPrice;
sum = sum+totalPrice; if (sum < money) {
divideDO.setUnRePrice(totalPrice);
if(sum<=money){ divideDO.setRefundPrice(totalPrice+divideDO.getCpPrice());
divideDO.setRefundPrice(totalPrice); divideDO.setCpPrice(divideDO.getCpPrice() + totalPrice);
divideDO.setCpPrice(divideDO.getCpPrice()+totalPrice);
noBackList.add(divideDO); noBackList.add(divideDO);
}else { } else if (sum == money) {
int leftMoney = money+totalPrice- sum; divideDO.setUnRePrice(totalPrice);
divideDO.setRefundPrice(leftMoney); divideDO.setRefundPrice(totalPrice+divideDO.getCpPrice());
divideDO.setCpPrice(divideDO.getCpPrice()+leftMoney); divideDO.setCpPrice(divideDO.getCpPrice() + totalPrice);
noBackList.add(divideDO);
break;
} else {
int leftMoney = money + totalPrice - sum;
divideDO.setUnRePrice(leftMoney);
divideDO.setRefundPrice(divideDO.getCpPrice() + leftMoney);
divideDO.setCpPrice(divideDO.getCpPrice() + leftMoney);
noBackList.add(divideDO); noBackList.add(divideDO);
break; break;
} }
} }
//从分账完的订单进行退款 //从分账完的订单进行退款
if(sum<money){ if (sum < money) {
for (DivideDO divideDO : divideList) {
Integer totalPrice = divideDO.getTotalPrice()-divideDO.getRefundPrice();
for (DivideDO divideDO:divideList){ sum = sum + totalPrice;
Integer totalPrice = divideDO.getTotalPrice()-divideDO.getCpPrice();
sum = sum+totalPrice; if (sum < money) {
divideDO.setUnRePrice(totalPrice);
if(sum<=money){ divideDO.setRefundPrice(divideDO.getTotalPrice());
divideDO.setRefundPrice(totalPrice); divideDO.setBackPrice(totalPrice);
divideDO.setPsPrice(0);
backList.add(divideDO); backList.add(divideDO);
}else { } else if (sum == money) {
int leftMoney = money+totalPrice- sum; divideDO.setUnRePrice(totalPrice);
divideDO.setRefundPrice(leftMoney); divideDO.setRefundPrice(divideDO.getTotalPrice());
divideDO.setBackPrice(totalPrice);
divideDO.setPsPrice(0);
backList.add(divideDO);
break;
} else {
int leftMoney = money + totalPrice - sum;
divideDO.setUnRePrice(leftMoney);
divideDO.setRefundPrice(leftMoney+divideDO.getRefundPrice());
divideDO.setBackPrice(leftMoney);
divideDO.setPsPrice(divideDO.getPsPrice()-leftMoney);
backList.add(divideDO); backList.add(divideDO);
break; break;
} }
} }
} }
//从部分分账完的订单进行退款,由于分账的特性只会存在一条未分账完全的资金
if (sum < money) {
for (DivideDO divideDO : divideCpList) {
//剩余未解冻的资金
Integer totalPrice = divideDO.getTotalPrice() - divideDO.getCpPrice();
sum = sum + totalPrice;
if (sum < money) {
if("0".equals(divideDO.getUnfreezeStatus())){
//先解冻剩余资金
String unFreeNo = noRedisDAO.generate(payProperties.getOrderNoPrefix());
PayClient client = channelService.getPayClient(divideDO.getChannelId());
PayDivideUnifiedDto payDivideUnifiedDto = new PayDivideUnifiedDto();
payDivideUnifiedDto.setTransactionId(divideDO.getChannelOrderNo())
.setOutOrderNo(unFreeNo);
client.unifiedDivideFreeze(payDivideUnifiedDto);
DivideDO unfree = new DivideDO();
unfree.setUnfreezeStatus("1").setId(divideDO.getId());
divideMapper.updateById(unfree);
String state = "";
do {
try {
//等待解冻成功
TimeUnit.SECONDS.sleep(15);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
PayDivideUnifiedDto resultDto = new PayDivideUnifiedDto();
resultDto.setTransactionId(divideDO.getChannelOrderNo())
.setOutOrderNo(unFreeNo);
PayDivideRespDto payDivideRespDto = client.unifiedDivideResult(resultDto);
state = payDivideRespDto.getState();
}while ("PROCESSING".equals(state));
return null; }
//计算退款资金
//可用于退款的资金
Integer psPrice = divideDO.getTotalPrice()- divideDO.getRefundPrice();
sum = sum - totalPrice+psPrice;
if (sum <= money){
divideDO.setUnRePrice(psPrice);
divideDO.setRefundPrice(divideDO.getTotalPrice());
divideDO.setBackPrice(divideDO.getPsPrice());
divideDO.setPsPrice(0);
}else{
int left = money-sum+psPrice;
divideDO.setUnRePrice(left);
divideDO.setRefundPrice(divideDO.getRefundPrice()+left);
//分账回退金额
int back = left-totalPrice;
divideDO.setBackPrice(back);
divideDO.setPsPrice(divideDO.getPsPrice()-back);
}
backList.add(divideDO);
divideDO.setCpPrice(divideDO.getTotalPrice());
} else {
//计算使用资金
Integer useMoney = sum - money;
divideDO.setUnRePrice(useMoney);
divideDO.setRefundPrice(useMoney+divideDO.getRefundPrice());
divideDO.setCpPrice(divideDO.getCpPrice() + useMoney);
noBackList.add(divideDO);
}
break;
}
}
//退款记录
List<RefundRecordDO> list = new ArrayList();
int failNum = 0;
//调用退款接口
if(CollectionUtil.isNotEmpty(noBackList)){
for (DivideDO divideDO : noBackList) {
String outRefundNo = noRedisDAO.generate(payProperties.getRefundNoPrefix());
RefundRecordDO refundRecordDO = new RefundRecordDO();
refundRecordDO.setOutTradeNo(divideDO.getNo());
refundRecordDO.setOutRefundNo(outRefundNo);
refundRecordDO.setTransactionId(divideDO.getChannelOrderNo());
refundRecordDO.setChannelId(divideDO.getChannelId());
refundRecordDO.setChannelUserId(divideDO.getChannelUserId());
refundRecordDO.setChannelCode(divideDO.getChannelCode());
refundRecordDO.setUserId(String.valueOf(drawMoneyVO.getUserId()));
refundRecordDO.setTotalPrice(divideDO.getUnRePrice());
PayChannelDO channel = channelService.validPayChannel(divideDO.getChannelId());
PayClient client = channelService.getPayClient(divideDO.getChannelId());
PayRefundUnifiedReqDTO payRefundUnifiedReqDTO = new PayRefundUnifiedReqDTO();
payRefundUnifiedReqDTO.setTransactionId(divideDO.getChannelOrderNo())
.setReason("提现").setRefundPrice(divideDO.getUnRePrice())
.setOutRefundNo(outRefundNo).setPayPrice(divideDO.getTotalPrice())
.setNotifyUrl(genChannelRefundNotifyUrl(channel));
PayRefundRespDTO payRefundRespDTO = client.unifiedRefund(payRefundUnifiedReqDTO);
String channelRefundNo = payRefundRespDTO.getChannelRefundNo();
refundRecordDO.setRefundId(channelRefundNo);
if(cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum.WAITING.getStatus().equals(payRefundRespDTO.getStatus())){
refundRecordDO.setStatus(PayDivideRefundStatusRespEnum.PROCESSING.getStatus());
} else if (cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum.SUCCESS.getStatus().equals(payRefundRespDTO.getStatus())) {
refundRecordDO.setStatus(PayDivideRefundStatusRespEnum.SUCCESS.getStatus());
}else {
failNum++;
refundRecordDO.setStatus(PayDivideRefundStatusRespEnum.ABNORMAL.getStatus());
}
refundRecordMapper.insert(refundRecordDO);
if(divideDO.getRefundPrice().equals(divideDO.getTotalPrice())){
divideDO.setRefundStatus("1");
}
if(divideDO.getTotalPrice().equals(divideDO.getCpPrice())){
divideDO.setStatus(PayDivideStatusRespEnum.CASH.getStatus());
}
String jsonString = JsonUtils.toJsonString(divideDO);
//DivideDO divideDO1 = JsonUtils.parseObject(jsonString, DivideDO.class);
divideRedisTemplate.opsForValue().set("R"+outRefundNo,jsonString);
//divideMapper.updateById(divideDO);
//list.add(refundRecordDO);
}
}
//调用退款接口
if(CollectionUtil.isNotEmpty(backList)){
for (DivideDO divideDO : backList) {
String outRefundNo = noRedisDAO.generate(payProperties.getRefundNoPrefix());
RefundRecordDO refundRecordDO = new RefundRecordDO();
refundRecordDO.setOutTradeNo(divideDO.getNo());
refundRecordDO.setOutRefundNo(outRefundNo);
refundRecordDO.setTransactionId(divideDO.getChannelOrderNo());
refundRecordDO.setChannelId(divideDO.getChannelId());
refundRecordDO.setChannelUserId(divideDO.getChannelUserId());
refundRecordDO.setChannelCode(divideDO.getChannelCode());
refundRecordDO.setUserId(String.valueOf(drawMoneyVO.getUserId()));
refundRecordDO.setTotalPrice(divideDO.getUnRePrice());
PayChannelDO channel = channelService.validPayChannel(divideDO.getChannelId());
PayClient client = channelService.getPayClient(divideDO.getChannelId());
PayRefundUnifiedReqDTO payRefundUnifiedReqDTO = new PayRefundUnifiedReqDTO();
payRefundUnifiedReqDTO.setTransactionId(divideDO.getChannelOrderNo())
.setReason("提现").setRefundPrice(divideDO.getUnRePrice())
.setOutRefundNo(outRefundNo).setPayPrice(divideDO.getTotalPrice())
.setNotifyUrl(genChannelRefundNotifyUrl(channel));
PayRefundRespDTO payRefundRespDTO = client.unifiedRefund(payRefundUnifiedReqDTO);
String channelRefundNo = payRefundRespDTO.getChannelRefundNo();
refundRecordDO.setRefundId(channelRefundNo);
if(cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum.WAITING.getStatus().equals(payRefundRespDTO.getStatus())){
refundRecordDO.setStatus(PayDivideRefundStatusRespEnum.PROCESSING.getStatus());
} else if (cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum.SUCCESS.getStatus().equals(payRefundRespDTO.getStatus())) {
refundRecordDO.setStatus(PayDivideRefundStatusRespEnum.SUCCESS.getStatus());
}else {
failNum++;
refundRecordDO.setStatus(PayDivideRefundStatusRespEnum.ABNORMAL.getStatus());
}
//list.add(refundRecordDO);
refundRecordMapper.insert(refundRecordDO);
if(divideDO.getRefundPrice().equals(divideDO.getTotalPrice())){
divideDO.setRefundStatus("1");
}
if(divideDO.getTotalPrice().equals(divideDO.getCpPrice())){
divideDO.setStatus(PayDivideStatusRespEnum.CASH.getStatus());
}
String jsonString = JsonUtils.toJsonString(divideDO);
//DivideDO divideDO1 = JsonUtils.parseObject(jsonString, DivideDO.class);
divideRedisTemplate.opsForValue().set("R"+outRefundNo,jsonString);
//divideMapper.updateById(divideDO);
}
}
//分账回退
//if(CollectionUtil.isNotEmpty(backList)){
// returnMoney(backList);
//}
//refundRecordMapper.insertBatch(list);
// todo清空
return failNum>0?false:true;
} }
private String genChannelRefundNotifyUrl(PayChannelDO channel) {
return payProperties.getRefundNotifyUrl() + "/" + channel.getId();
}
@Override
public void returnMoney(List<DivideDO> backList){
List<DivideCompanyDO> companyList = divideCompanyService.getList();
Map<String, DivideCompanyDO> companyMap = companyList.stream().collect(Collectors.toMap(DivideCompanyDO::getName, vo -> vo));
for(DivideDO divideDO:backList){
PayClient client = channelService.getPayClient(divideDO.getChannelId());
//查询出分账的具体条数
List<DivideInfoDO> divideListByTi = divideInfoService.getDivideListByTi(divideDO.getChannelOrderNo());
//全部回退
if(divideDO.getRefundPrice().equals(divideDO.getTotalPrice())){
for(DivideInfoDO divideInfoDO : divideListByTi){
doReturn(client,divideInfoDO,companyMap.get(divideInfoDO.getName()).getAccount());
}
}else{
Integer refundPrice = divideDO.getRefundPrice();
//算出每个公司应回退的金额
for(DivideCompanyDO companyDO:companyList){
int backmoney = (int) Math.ceil(refundPrice* Double.valueOf(companyDO.getProportion()));
List<DivideInfoDO> baList = divideListByTi.stream().filter(vo -> vo.getName().equals(companyDO.getName())).collect(Collectors.toList());
int sum = 0;
for (DivideInfoDO infoDO : baList){
sum = sum+infoDO.getAmount();
if(sum<backmoney){
doReturn(client,infoDO,companyDO.getAccount());
}else if (sum==backmoney){
doReturn(client,infoDO,companyDO.getAccount());
break;
}else{
int left = backmoney+infoDO.getAmount()-sum;
infoDO.setAmount(left);
doReturn(client,infoDO,companyDO.getAccount());
break;
}
}
}
}
}
}
void doReturn(PayClient client ,DivideInfoDO divideInfoDO ,String account){
PayDivideBackUnifiedDto payDivideBackUnifiedDto = new PayDivideBackUnifiedDto();
payDivideBackUnifiedDto.setAmount(divideInfoDO.getAmount().longValue());
payDivideBackUnifiedDto.setDescription("分账回退");
payDivideBackUnifiedDto.setOrderId(divideInfoDO.getOrderId());
payDivideBackUnifiedDto.setReturnMchid(account);
payDivideBackUnifiedDto.setOutOrderNo(divideInfoDO.getOutOrderNo());
payDivideBackUnifiedDto.setOutReturnNo(noRedisDAO.generate(payProperties.getOrderNoPrefix()));
PayDivideBackRespDto payDivideBackRespDto = client.unifiedDivideback(payDivideBackUnifiedDto);
log.info("订单:"+payDivideBackRespDto.getOrderId()+"回退结果:"+payDivideBackRespDto.getResult());
}
@Override
public void subtractWx(Integer amount, Long userId) {
DivideCardDO lastCardDO = divideCardMapper.selectOne(Wrappers.<DivideCardDO>lambdaQuery()
.eq(DivideCardDO::getUserId, userId)
.orderByDesc(DivideCardDO::getCreateTime)
.last("limit 1"));
BigDecimal changeMoney = new BigDecimal(amount).divide(new BigDecimal("100"));
//获取最新余额
DivideCardDO cardDO = new DivideCardDO();
cardDO.setUserId(userId);
cardDO.setFlag(DivideCardDO.MINUS);
cardDO.setChangeMoney(changeMoney);
cardDO.setType("7");
BigDecimal oldMoney = lastCardDO.getMoney();
BigDecimal wxOldMoney= lastCardDO.getWxAmount();
cardDO.setMoney(oldMoney.subtract(changeMoney).setScale(2, BigDecimal.ROUND_HALF_UP));
cardDO.setWxAmount(wxOldMoney.subtract(changeMoney).setScale(2, BigDecimal.ROUND_HALF_UP));
cardDO.setGiftAmount(lastCardDO.getGiftAmount());
divideCardMapper.insert(cardDO);
}
@Override
public void updateDivideById(DivideDO divideDO) {
divideMapper.updateById(divideDO);
}
} }

View File

@ -60,4 +60,6 @@ public interface DivideInfoService {
List<DivideInfoDO> getDivideList(String outOrderNo); List<DivideInfoDO> getDivideList(String outOrderNo);
void updateList(List<DivideInfoDO> list); void updateList(List<DivideInfoDO> list);
List<DivideInfoDO> getDivideListByTi(String transactionId);
} }

View File

@ -105,4 +105,10 @@ public class DivideInfoServiceImpl implements DivideInfoService {
return divideInfoMapper.selectList(Wrappers.<DivideInfoDO>lambdaQuery() return divideInfoMapper.selectList(Wrappers.<DivideInfoDO>lambdaQuery()
.eq(DivideInfoDO::getOutOrderNo, outOrderNo)); .eq(DivideInfoDO::getOutOrderNo, outOrderNo));
} }
@Override
public List<DivideInfoDO> getDivideListByTi(String transactionId) {
return divideInfoMapper.selectList(Wrappers.<DivideInfoDO>lambdaQuery()
.eq(DivideInfoDO::getTransactionId, transactionId));
}
} }

View File

@ -380,6 +380,7 @@ public class PayOrderServiceImpl implements PayOrderService {
//3.添加分账 //3.添加分账
order.setChannelOrderNo(notify.getChannelOrderNo()); order.setChannelOrderNo(notify.getChannelOrderNo());
order.setChannelUserId(notify.getChannelUserId());
addDivide(channel,order); addDivide(channel,order);
return false; return false;
} }

View File

@ -52,4 +52,5 @@ public interface RefundRecordService {
*/ */
PageResult<RefundRecordDO> getRefundRecordPage(RefundRecordPageReqVO pageReqVO); PageResult<RefundRecordDO> getRefundRecordPage(RefundRecordPageReqVO pageReqVO);
} }

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.framework.pay.core.client; package cn.iocoder.yudao.framework.pay.core.client;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@ -125,4 +127,13 @@ public interface PayClient {
PayDivideRespDto unifiedDivideFreeze(PayDivideUnifiedDto reqDTO); PayDivideRespDto unifiedDivideFreeze(PayDivideUnifiedDto reqDTO);
/**
* 分账回退
*
* @param reqDTO 分账参数
* @return 分账
*/
PayDivideBackRespDto unifiedDivideback(PayDivideBackUnifiedDto reqDTO);
} }

View File

@ -0,0 +1,51 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.divide;
import lombok.Data;
/**
* @author zt
* @description <description class purpose>
* @since 2024/7/17
*/
@Data
public class PayDivideBackRespDto {
private String subMchId;
private String orderId;
private String outOrderNo;
private String outReturnNo;
private String returnId;
private String returnMchid;
private Long amount;
private String description;
private String result;
private String failReason;
private String createTime;
private String finishTime;
private String channelErrorCode;
/**
* 调用渠道报错时,错误信息
*/
private String channelErrorMsg;
/**
* 原始的异步通知结果
*/
private Object rawData;
/**
* 创建【FAILURE】状态的退款返回
*/
public static PayDivideBackRespDto failureOf(String channelErrorCode, String channelErrorMsg,
String transactionId, Object rawData) {
PayDivideBackRespDto respDTO = new PayDivideBackRespDto();
//respDTO.status = PayRefundStatusRespEnum.FAILURE.getStatus();
respDTO.channelErrorCode = channelErrorCode;
respDTO.channelErrorMsg = channelErrorMsg;
// 相对通用的字段
respDTO.orderId = transactionId;
respDTO.rawData = rawData;
return respDTO;
}
}

View File

@ -0,0 +1,47 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.divide;
import lombok.Data;
/**
* @author zt
* @description <description class purpose>
* @since 2024/7/17
*/
@Data
public class PayDivideBackUnifiedDto {
/**
* 应用ID
*/
private String appid;
/**
* 微信分账单号
*/
private String orderId;
/**
* 商户分账单号
*/
private String outOrderNo;
/**
* 商户回退单号
*/
private String outReturnNo;
/**
* 回退商户号
*/
private String returnMchid;
/**
* 回退金额
*/
private Long amount;
/**
* 回退描述
*/
private String description;
}

View File

@ -28,9 +28,12 @@ public class PayRefundUnifiedReqDTO {
* *
* 对应 PayOrderExtensionDO 的 no 字段 * 对应 PayOrderExtensionDO 的 no 字段
*/ */
@NotEmpty(message = "外部订单编号不能为空") //@NotEmpty(message = "外部订单编号不能为空")
private String outTradeNo; private String outTradeNo;
@NotEmpty(message = "微信订单编号不能为空")
private String transactionId;
/** /**
* 外部退款号 * 外部退款号
* *

View File

@ -4,6 +4,8 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.PayClient;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@ -313,4 +315,26 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
} }
protected abstract PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) protected abstract PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO)
throws Throwable; throws Throwable;
@Override
public PayDivideBackRespDto unifiedDivideback(PayDivideBackUnifiedDto reqDTO) {
ValidationUtils.validate(reqDTO);
// 执行统一下单
PayDivideBackRespDto resp;
try {
resp = doUnifiedDivideback(reqDTO);
} catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
throw ex;
} catch (Throwable ex) {
// 系统异常,则包装成 PayException 异常抛出
log.error("[unifiedOrder][客户端({}) request({}) 发起支付异常]",
getId(), toJsonString(reqDTO), ex);
throw buildPayException(ex);
}
return resp;
}
protected abstract PayDivideBackRespDto doUnifiedDivideback(PayDivideBackUnifiedDto reqDTO)
throws Throwable;
} }

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@ -73,4 +75,9 @@ public class AlipayAppPayClient extends AbstractAlipayPayClient {
protected PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) throws Throwable { protected PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) throws Throwable {
return null; return null;
} }
@Override
protected PayDivideBackRespDto doUnifiedDivideback(PayDivideBackUnifiedDto reqDTO) throws Throwable {
return null;
}
} }

View File

@ -3,6 +3,8 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@ -99,4 +101,9 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient {
protected PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) throws Throwable { protected PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) throws Throwable {
return null; return null;
} }
@Override
protected PayDivideBackRespDto doUnifiedDivideback(PayDivideBackUnifiedDto reqDTO) throws Throwable {
return null;
}
} }

View File

@ -2,6 +2,8 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.Method; import cn.hutool.http.Method;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@ -83,4 +85,9 @@ public class AlipayPcPayClient extends AbstractAlipayPayClient {
protected PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) throws Throwable { protected PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) throws Throwable {
return null; return null;
} }
@Override
protected PayDivideBackRespDto doUnifiedDivideback(PayDivideBackUnifiedDto reqDTO) throws Throwable {
return null;
}
} }

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@ -80,4 +82,9 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient {
protected PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) throws Throwable { protected PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) throws Throwable {
return null; return null;
} }
@Override
protected PayDivideBackRespDto doUnifiedDivideback(PayDivideBackUnifiedDto reqDTO) throws Throwable {
return null;
}
} }

View File

@ -1,6 +1,8 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.http.Method; import cn.hutool.http.Method;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@ -73,4 +75,9 @@ public class AlipayWapPayClient extends AbstractAlipayPayClient {
protected PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) throws Throwable { protected PayDivideRespDto dounifiedDivideFreeze(PayDivideUnifiedDto reqDTO) throws Throwable {
return null; return null;
} }
@Override
protected PayDivideBackRespDto doUnifiedDivideback(PayDivideBackUnifiedDto reqDTO) throws Throwable {
return null;
}
} }

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.mock; package cn.iocoder.yudao.framework.pay.core.client.impl.mock;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@ -94,4 +96,9 @@ public class MockPayClient extends AbstractPayClient<NonePayClientConfig> {
return null; return null;
} }
@Override
protected PayDivideBackRespDto doUnifiedDivideback(PayDivideBackUnifiedDto reqDTO) throws Throwable {
return null;
}
} }

View File

@ -8,6 +8,8 @@ import cn.hutool.core.date.TemporalAccessorUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.io.FileUtils; import cn.iocoder.yudao.framework.common.util.io.FileUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideRespDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto; import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@ -23,8 +25,10 @@ import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingReturnV3Request;
import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingUnfreezeV3Request; import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingUnfreezeV3Request;
import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingV3Request; import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingV3Request;
import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingReturnV3Result;
import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingUnfreezeV3Result; import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingUnfreezeV3Result;
import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingV3Result; import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingV3Result;
import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest; import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest;
@ -314,7 +318,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
private PayRefundRespDTO doUnifiedRefundV3(PayRefundUnifiedReqDTO reqDTO) throws Throwable { private PayRefundRespDTO doUnifiedRefundV3(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
// 1. 构建 WxPayRefundRequest 请求 // 1. 构建 WxPayRefundRequest 请求
WxPayRefundV3Request request = new WxPayRefundV3Request() WxPayRefundV3Request request = new WxPayRefundV3Request()
.setOutTradeNo(reqDTO.getOutTradeNo()) .setTransactionId(reqDTO.getTransactionId())
.setOutRefundNo(reqDTO.getOutRefundNo()) .setOutRefundNo(reqDTO.getOutRefundNo())
.setAmount(new WxPayRefundV3Request.Amount().setRefund(reqDTO.getRefundPrice()) .setAmount(new WxPayRefundV3Request.Amount().setRefund(reqDTO.getRefundPrice())
.setTotal(reqDTO.getPayPrice()).setCurrency("CNY")) .setTotal(reqDTO.getPayPrice()).setCurrency("CNY"))
@ -610,4 +614,44 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
BeanUtil.copyProperties(response,payDivideRespDto); BeanUtil.copyProperties(response,payDivideRespDto);
return payDivideRespDto; return payDivideRespDto;
} }
@Override
protected PayDivideBackRespDto doUnifiedDivideback(PayDivideBackUnifiedDto reqDTO) throws Throwable {
try {
switch (config.getApiVersion()) {
case API_VERSION_V2:
return doUnifiedDividebackV2(reqDTO);
case WxPayClientConfig.API_VERSION_V3:
return doUnifiedDividebackV3(reqDTO);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
} catch (WxPayException e) {
String errorCode = getErrorCode(e);
String errorMessage = getErrorMessage(e);
return PayDivideBackRespDto.failureOf(errorCode, errorMessage,
reqDTO.getOrderId(), e.getXmlString());
}
}
private PayDivideBackRespDto doUnifiedDividebackV2(PayDivideBackUnifiedDto reqDTO) throws Throwable {
throw new UnsupportedOperationException("待实现");
}
private PayDivideBackRespDto doUnifiedDividebackV3(PayDivideBackUnifiedDto reqDTO) throws Throwable {
// 1. 构建 WxPayRefundRequest 请求
ProfitSharingReturnV3Request request = new ProfitSharingReturnV3Request();
request.setOrderId(reqDTO.getOrderId());
request.setOutOrderNo(reqDTO.getOutOrderNo());
request.setOutReturnNo(reqDTO.getOutReturnNo());
request.setReturnMchid(reqDTO.getReturnMchid());
request.setAmount(reqDTO.getAmount());
request.setDescription(reqDTO.getDescription());
// 2.1 执行请求
ProfitSharingReturnV3Result response = client.getProfitSharingService().profitSharingReturnV3(request);
PayDivideBackRespDto payDivideRespDto = new PayDivideBackRespDto();
BeanUtil.copyProperties(response,payDivideRespDto);
return payDivideRespDto;
}
} }

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.framework.pay.core.enums.divide;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 渠道的退款状态枚举
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum PayDivideRefundStatusRespEnum {
PROCESSING("10", "退款处理中"),
SUCCESS("20", "退款成功"),
CLOSED("30", "退款关闭"),
ABNORMAL("40", "退款异常"),
;
private final String status;
private final String name;
}

View File

@ -16,6 +16,8 @@ public enum PayDivideStatusRespEnum {
PROGRESS("10", "分账进行中"), PROGRESS("10", "分账进行中"),
COMPLETE("20", "分账完成"), COMPLETE("20", "分账完成"),
FINISH("30", "分账结束"), FINISH("30", "分账结束"),
CASH("40", "提现"),
; ;
private final String status; private final String status;

View File

@ -84,6 +84,17 @@ public class DishesServiceImpl implements DishesService {
validateDishesExists(updateReqVO.getId()); validateDishesExists(updateReqVO.getId());
// 更新 // 更新
DishesDO updateObj = BeanUtils.toBean(updateReqVO, DishesDO.class); DishesDO updateObj = BeanUtils.toBean(updateReqVO, DishesDO.class);
//计算每g多少钱
BigDecimal dishesSumPrice = updateObj.getDishesSumPrice();
BigDecimal dishesNumber = updateObj.getDishesNumber();
BigDecimal div = NumberUtil.div(dishesSumPrice, dishesNumber, 2);
//避免计算出每克价格约 为0
if(div.floatValue() <= 0.00f){
updateObj.setDishesBasePrice(new BigDecimal("0.01"));
}else{
updateObj.setDishesBasePrice(div);
}
dishesMapper.updateById(updateObj); dishesMapper.updateById(updateObj);
List<DishesNutritionSaveReqVO> list = updateReqVO.getDishesNutritionList(); List<DishesNutritionSaveReqVO> list = updateReqVO.getDishesNutritionList();
List<DishesRawSaveReqVO> dishesRawList = updateReqVO.getDishesRawList(); List<DishesRawSaveReqVO> dishesRawList = updateReqVO.getDishesRawList();