From 82eb8b56ceae150d3ed11c85e13b25198a77078c Mon Sep 17 00:00:00 2001 From: zengtao01 Date: Wed, 24 Jul 2024 14:21:38 +0800 Subject: [PATCH] =?UTF-8?q?bug=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/card/CardController.java | 4 +- .../app/card/AppCardController.java | 4 +- .../AppDiningPlatesController.java | 6 + .../app/diningplates/vo/AppUserInfo.java | 2 + .../member/dal/dataobject/card/CardDO.java | 10 + .../dal/dataobject/order/DishOrderDO.java | 15 ++ .../member/job/BalanceDeductionJob.java | 31 ++- .../member/service/card/CardService.java | 5 +- .../member/service/card/CardServiceImpl.java | 62 +++++- .../diningplates/DiningPlatesService.java | 5 + .../diningplates/DiningPlatesServiceImpl.java | 17 +- .../service/refund/RefundServiceImpl.java | 2 +- .../module/pay/enums/ErrorCodeConstants.java | 3 + .../admin/divide/vo/DivideSaveReqVO.java | 5 +- .../refundrecord/RefundRecordController.java | 95 +++++++++ .../vo/RefundRecordPageReqVO.java | 52 +++++ .../refundrecord/vo/RefundRecordRespVO.java | 64 ++++++ .../vo/RefundRecordSaveReqVO.java | 47 +++++ .../app/divide/AppDivideController.java | 33 +++ .../controller/app/divide/vo/DrawMoneyVO.java | 20 ++ .../pay/dal/dataobject/divide/DivideDO.java | 25 +++ .../dividerecord/DivideRecordDO.java | 43 ++++ .../refundrecord/RefundRecordDO.java | 71 +++++++ .../pay/dal/mysql/divide/DivideMapper.java | 22 +- .../dividerecord/DivideRecordMapper.java | 20 ++ .../refundrecord/RefundRecordMapper.java | 36 ++++ .../pay/service/divide/DivideService.java | 7 + .../pay/service/divide/DivideServiceImpl.java | 188 +++++++++++++++++- .../service/order/PayOrderServiceImpl.java | 3 +- .../refundrecord/RefundRecordService.java | 55 +++++ .../refundrecord/RefundRecordServiceImpl.java | 74 +++++++ .../dal/mysql/carteen/CarteenMapper.java | 2 +- 32 files changed, 996 insertions(+), 32 deletions(-) create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/RefundRecordController.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordPageReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordRespVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordSaveReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/divide/AppDivideController.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/divide/vo/DrawMoneyVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/dividerecord/DivideRecordDO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refundrecord/RefundRecordDO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/dividerecord/DivideRecordMapper.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refundrecord/RefundRecordMapper.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refundrecord/RefundRecordService.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refundrecord/RefundRecordServiceImpl.java diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/card/CardController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/card/CardController.java index f2ebb33e..b037b469 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/card/CardController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/card/CardController.java @@ -143,8 +143,8 @@ public class CardController { @PutMapping("/recharge") @Operation(summary = "充值") //@PreAuthorize("@ss.hasPermission('member:card:update')") - public CommonResult recharge(BigDecimal money) { - return success(cardService.recharge(money, CardDO.ADD)); + public CommonResult recharge(BigDecimal money,BigDecimal giftMoney) { + return success(cardService.recharge(money, CardDO.ADD,giftMoney)); } @GetMapping("/getMoney") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/card/AppCardController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/card/AppCardController.java index 5b618abf..bf7f8c20 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/card/AppCardController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/card/AppCardController.java @@ -99,9 +99,9 @@ public class AppCardController { @PutMapping("/recharge") @Operation(summary = "充值") //@PreAuthorize("@ss.hasPermission('member:card:update')") - public CommonResult recharge(BigDecimal money) { + public CommonResult recharge(BigDecimal money,BigDecimal giftMoney) { BigDecimal bigDecimal = money.divide(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP); - return success(cardService.recharge(bigDecimal,CardDO.ADD)); + return success(cardService.recharge(bigDecimal,CardDO.ADD,giftMoney)); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/diningplates/AppDiningPlatesController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/diningplates/AppDiningPlatesController.java index 2e48060f..31f101ab 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/diningplates/AppDiningPlatesController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/diningplates/AppDiningPlatesController.java @@ -67,5 +67,11 @@ public class AppDiningPlatesController { return success(diningPlatesService.getMoney(cId,dishesId)); } + @GetMapping("/getBind") + @Operation(summary = "获取绑定餐盘") + public CommonResult> getBind() { + return success(diningPlatesService.getBindDiningPlatesList()); + } + } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/diningplates/vo/AppUserInfo.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/diningplates/vo/AppUserInfo.java index 6e9e15d7..8d662e4f 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/diningplates/vo/AppUserInfo.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/diningplates/vo/AppUserInfo.java @@ -19,4 +19,6 @@ public class AppUserInfo { private String dishesName; private BigDecimal dishesBasePrice; + + private BigDecimal orderMoney; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/card/CardDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/card/CardDO.java index c4413410..8da7c222 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/card/CardDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/card/CardDO.java @@ -63,4 +63,14 @@ public class CardDO extends BaseDO { */ private BigDecimal giftAmount; + /** + * 现金金额 + */ + private BigDecimal cashAmount; + + /** + * 微信充值金额 + */ + private BigDecimal wxAmount; + } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/order/DishOrderDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/order/DishOrderDO.java index ff814fe5..f079ba08 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/order/DishOrderDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/order/DishOrderDO.java @@ -67,4 +67,19 @@ public class DishOrderDO extends BaseDO { * 餐盘编号 */ private String diningPlatesNum; + + /** + * 赠送金额 + */ + private BigDecimal giftAmount; + + /** + * 现金金额 + */ + private BigDecimal cashAmount; + + /** + * 微信充值金额 + */ + private BigDecimal wxAmount; } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/job/BalanceDeductionJob.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/job/BalanceDeductionJob.java index 7407e7e2..3cda3228 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/job/BalanceDeductionJob.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/job/BalanceDeductionJob.java @@ -70,8 +70,35 @@ public class BalanceDeductionJob implements JobHandler { Long userId = dishOrderDO.getUserId(); CardDO cardDO = new CardDO(); cardDO.setType(TimePeriodEnum.getTimePeriod(LocalDateTime.now())); - BigDecimal oldMoney = cardService.getMoneyByUserId(userId); - cardDO.setMoney(oldMoney.subtract(total).setScale(2, BigDecimal.ROUND_HALF_UP)); + CardDO oldCardDO = cardService.getCardDoByUserId(userId); + + + BigDecimal money = oldCardDO.getMoney(); + BigDecimal wxAmount = oldCardDO.getWxAmount(); + BigDecimal giftAmount = oldCardDO.getGiftAmount(); + BigDecimal cashAmount = oldCardDO.getCashAmount(); + cardDO.setMoney(money.subtract(total).setScale(2, BigDecimal.ROUND_HALF_UP)); + + if(total.compareTo(wxAmount)<=0){ + cardDO.setWxAmount(wxAmount.subtract(total).setScale(2, BigDecimal.ROUND_HALF_UP)); + dishOrderDO.setWxAmount(total); + }else { + cardDO.setWxAmount(BigDecimal.ZERO); + dishOrderDO.setWxAmount(wxAmount); + BigDecimal total1 = total.subtract(wxAmount).setScale(2, BigDecimal.ROUND_HALF_UP); + if(total1.compareTo(cashAmount)<=0){ + 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)); + dishOrderDO.setGiftAmount(total2); + } + } + cardDO.setUserId(userId); cardDO.setChangeMoney(total); cardDO.setFlag(CardDO.MINUS); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/card/CardService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/card/CardService.java index 0992f331..248f9ff5 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/card/CardService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/card/CardService.java @@ -69,7 +69,7 @@ public interface CardService { /** * 余额变动 */ - Boolean recharge(BigDecimal money, String flag); + Boolean recharge(BigDecimal money, String flag,BigDecimal giftMoney); /** * 获取余额 @@ -81,6 +81,7 @@ public interface CardService { */ BigDecimal getMoneyByUserId(Long userId); + CardDO getCardDoByUserId(Long userId); /** * 批量扣款 */ @@ -98,5 +99,5 @@ public interface CardService { FaceVo getFaceData(String faceId); - void refund(Long userId,BigDecimal money); + void refund(Long userId,BigDecimal money,Long orderId); } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/card/CardServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/card/CardServiceImpl.java index e36e49e9..0aeda7bd 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/card/CardServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/card/CardServiceImpl.java @@ -13,8 +13,10 @@ import cn.iocoder.yudao.module.member.controller.app.card.vo.AppCardMonthVO; import cn.iocoder.yudao.module.member.controller.app.card.vo.AppCardPageReqVO; import cn.iocoder.yudao.module.member.controller.app.card.vo.FaceVo; import cn.iocoder.yudao.module.member.dal.dataobject.card.CardDO; +import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO; import cn.iocoder.yudao.module.member.dal.mysql.card.CardMapper; 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.enums.CostTypeEnum; import cn.iocoder.yudao.module.member.util.MemberConstants; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -50,6 +52,9 @@ public class CardServiceImpl implements CardService { @Resource private MemberGroupMapper memberGroupMapper; + @Resource + private DishOrderMapper dishOrderMapper; + @Override public Long createCard(CardSaveReqVO createReqVO) { // 插入 @@ -99,7 +104,7 @@ public class CardServiceImpl implements CardService { @Override - public Boolean recharge(BigDecimal money, String flag) { + public Boolean recharge(BigDecimal money, String flag,BigDecimal giftMoney) { //获取最新余额 CardDO lastCardDO = getLastCardDO(); CardDO cardDO = new CardDO(); @@ -108,14 +113,21 @@ public class CardServiceImpl implements CardService { cardDO.setChangeMoney(money); cardDO.setType(CostTypeEnum.WX_PAY.getCode()); BigDecimal oldMoney = BigDecimal.ZERO; + BigDecimal wxOldMoney= BigDecimal.ZERO; + BigDecimal giftOldMoney= BigDecimal.ZERO; if (ObjectUtil.isNotEmpty(lastCardDO) && lastCardDO.getMoney() != null) { oldMoney = lastCardDO.getMoney(); } - if (CardDO.ADD.equals(flag)) { - cardDO.setMoney(oldMoney.add(money).setScale(2, BigDecimal.ROUND_HALF_UP)); - } else { - cardDO.setMoney(oldMoney.subtract(money).setScale(2, BigDecimal.ROUND_HALF_UP)); + if (ObjectUtil.isNotEmpty(lastCardDO) && lastCardDO.getWxAmount() != null) { + wxOldMoney = lastCardDO.getWxAmount(); } + if (ObjectUtil.isNotEmpty(lastCardDO) && lastCardDO.getGiftAmount() != null) { + giftOldMoney = lastCardDO.getGiftAmount(); + } + + cardDO.setMoney(oldMoney.add(money).setScale(2, BigDecimal.ROUND_HALF_UP)); + cardDO.setWxAmount(wxOldMoney.add(money).setScale(2, BigDecimal.ROUND_HALF_UP)); + cardDO.setGiftAmount(giftOldMoney.add(giftMoney).setScale(2, BigDecimal.ROUND_HALF_UP)); return cardMapper.insert(cardDO) > 0; } @@ -138,6 +150,14 @@ public class CardServiceImpl implements CardService { return lastCardDO.getMoney(); } + @Override + public CardDO getCardDoByUserId(Long userId) { + CardDO lastCardDO = cardMapper.selectOne(Wrappers.lambdaQuery().eq(CardDO::getUserId, userId) + .orderByDesc(CardDO::getCreateTime).last(MemberConstants.LIMIT_ONE)); + + return lastCardDO; + } + /** * 获取当前用户最新余额明细 * @@ -213,6 +233,8 @@ public class CardServiceImpl implements CardService { add.setType(CostTypeEnum.ADMIN_PAY.getCode()); BigDecimal oldMoney = cardDO.getMoney(); 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)); addList.add(add); } //添加新的用户金额 @@ -224,6 +246,7 @@ public class CardServiceImpl implements CardService { add.setChangeMoney(vo.getMoney()); add.setType(CostTypeEnum.ADMIN_PAY.getCode()); add.setMoney(vo.getMoney()); + add.setCashAmount(vo.getMoney()); addList.add(add); } } @@ -238,20 +261,47 @@ public class CardServiceImpl implements CardService { } @Override - public void refund(Long userId,BigDecimal money) { + public void refund(Long userId,BigDecimal money,Long orderId) { //获取最新余额 + CardDO lastCardDO = cardMapper.selectOne(Wrappers.lambdaQuery().eq(CardDO::getUserId, userId) .orderByDesc(CardDO::getCreateTime).last(MemberConstants.LIMIT_ONE)); + DishOrderDO dishOrderDO = dishOrderMapper.selectById(orderId); + CardDO cardDO = new CardDO(); cardDO.setUserId(userId); cardDO.setFlag(CardDO.ADD); cardDO.setChangeMoney(money); cardDO.setType(CostTypeEnum.REFUND.getCode()); + BigDecimal oldMoney = BigDecimal.ZERO; if (ObjectUtil.isNotEmpty(lastCardDO) && lastCardDO.getMoney() != null) { oldMoney = lastCardDO.getMoney(); } cardDO.setMoney(oldMoney.add(money).setScale(2, BigDecimal.ROUND_HALF_UP)); + + BigDecimal wxAmount = lastCardDO.getWxAmount(); + BigDecimal cashAmount = lastCardDO.getCashAmount(); + BigDecimal giftAmount = lastCardDO.getGiftAmount(); + + BigDecimal dishWxAmount = dishOrderDO.getWxAmount(); + BigDecimal dishCashAmount = dishOrderDO.getCashAmount(); + BigDecimal dishGiftAmount = dishOrderDO.getGiftAmount(); + + if(money.compareTo(dishGiftAmount)<=0){ + cardDO.setGiftAmount(giftAmount.add(money).setScale(2, BigDecimal.ROUND_HALF_UP)); + }else { + cardDO.setGiftAmount(giftAmount.add(dishGiftAmount).setScale(2, BigDecimal.ROUND_HALF_UP)); + BigDecimal money1 = money.subtract(dishGiftAmount).setScale(2, BigDecimal.ROUND_HALF_UP); + + if(money1.compareTo(dishCashAmount)<=0){ + cardDO.setCashAmount(cashAmount.add(money1).setScale(2, BigDecimal.ROUND_HALF_UP)); + }else { + cardDO.setCashAmount(cashAmount.add(dishCashAmount).setScale(2, BigDecimal.ROUND_HALF_UP)); + BigDecimal money2 = money1.subtract(dishCashAmount).setScale(2, BigDecimal.ROUND_HALF_UP); + cardDO.setWxAmount(wxAmount.add(money2).setScale(2, BigDecimal.ROUND_HALF_UP)); + } + } cardMapper.insert(cardDO); } } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/diningplates/DiningPlatesService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/diningplates/DiningPlatesService.java index 493ebe1a..aa63c132 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/diningplates/DiningPlatesService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/diningplates/DiningPlatesService.java @@ -98,4 +98,9 @@ public interface DiningPlatesService { AppUserInfo getMoney(String diningPlatesNum, Long dishId); + /** + * 获取绑定餐盘列表 + * @return + */ + List getBindDiningPlatesList(); } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/diningplates/DiningPlatesServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/diningplates/DiningPlatesServiceImpl.java index 20a81cb3..2411d6aa 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/diningplates/DiningPlatesServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/diningplates/DiningPlatesServiceImpl.java @@ -38,6 +38,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*; @@ -349,6 +350,7 @@ public class DiningPlatesServiceImpl implements DiningPlatesService { } @Override + @Transactional(rollbackFor = Exception.class) public void unbind(String diningPlatesNum) { String money = stringRedisTemplate.opsForValue().get(diningPlatesNum); @@ -363,6 +365,9 @@ public class DiningPlatesServiceImpl implements DiningPlatesService { .eq(DiningPlatesDO::getDiningPlatesNum, diningPlatesNum) .last("limit 1")); + dishOrderMapper.update(Wrappers.lambdaUpdate() + .set(DishOrderDO::getOrderStatus,"1") + .eq(DishOrderDO::getId,diningPlatesDO.getOrderId())); diningPlatesMapper.update(Wrappers.lambdaUpdate() .set(DiningPlatesDO::getPayFlag, DiningPlatesDO.TO_PAY) .set(DiningPlatesDO::getStatus, DiningPlatesDO.FREE) @@ -370,6 +375,8 @@ public class DiningPlatesServiceImpl implements DiningPlatesService { .set(DiningPlatesDO::getBindingTime, null) .set(DiningPlatesDO::getOrderId, null) .eq(DiningPlatesDO::getId,diningPlatesDO.getId())); + + } @Override @@ -386,9 +393,15 @@ public class DiningPlatesServiceImpl implements DiningPlatesService { appUserInfo.setNickname(memberUserDO.getNickname()) .setDishesName(dish.getDishesName()) .setDishesBasePrice(dish.getDishesBasePrice()) - .setMoney(moneyByUserId); + .setMoney(moneyByUserId).setOrderMoney(new BigDecimal(stringRedisTemplate.opsForValue().get(diningPlatesNum))); return appUserInfo; } - + @Override + public List getBindDiningPlatesList() { + List diningPlatesDOS = diningPlatesMapper.selectList(Wrappers.lambdaQuery() + .isNotNull(DiningPlatesDO::getUserId)); + List list = diningPlatesDOS.stream().map(DiningPlatesDO::getDiningPlatesNum).collect(Collectors.toList()); + return list; + } } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/refund/RefundServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/refund/RefundServiceImpl.java index db8c9e21..36010a3d 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/refund/RefundServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/refund/RefundServiceImpl.java @@ -50,7 +50,7 @@ public class RefundServiceImpl implements RefundService { RefundDO updateObj = BeanUtils.toBean(updateReqVO, RefundDO.class); refundMapper.updateById(updateObj); if(RefundStatusEnum.SUCCESS.getCode().equals(updateReqVO.getStatus())){ - cardService.refund(updateReqVO.getUserId(),updateReqVO.getMoney()); + cardService.refund(updateReqVO.getUserId(),updateReqVO.getMoney(),updateReqVO.getOrderId()); } } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index 642f7054..47290c0d 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -91,11 +91,14 @@ public interface ErrorCodeConstants { ErrorCode DEMO_TRANSFER_FAIL_PRICE_NOT_MATCH = new ErrorCode(1_007_901_003, "转账失败,转账单金额不匹配"); ErrorCode DIVIDE_NOT_EXISTS = new ErrorCode(1_007_902_001, "分账单不存在"); + ErrorCode ORDER_NOT_COMPLETE = new ErrorCode(1_007_902_002, "还有订单尚未结算"); + ErrorCode WX_ACCOUNT_NO = new ErrorCode(1_007_902_002, "微信充值金额已用完"); ErrorCode DIVIDE_COMPANY_NOT_EXISTS = new ErrorCode(1_007_903_001, "分账公司不存在"); ErrorCode DIVIDE_INFO_NOT_EXISTS = new ErrorCode(1_007_904_001, "分账明细不存在"); + ErrorCode REFUND_RECORD_NOT_EXISTS = new ErrorCode(1_007_905_001, "退款记录不存在"); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/divide/vo/DivideSaveReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/divide/vo/DivideSaveReqVO.java index ded2261b..7808b355 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/divide/vo/DivideSaveReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/divide/vo/DivideSaveReqVO.java @@ -35,5 +35,8 @@ public class DivideSaveReqVO { @Schema(description = "微信分账单号", example = "3065") private String orderId; - + /** + * 渠道用户编号 + */ + private String channelUserId; } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/RefundRecordController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/RefundRecordController.java new file mode 100644 index 00000000..ced4ad10 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/RefundRecordController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refundrecord; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.pay.controller.admin.refundrecord.vo.*; +import cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord.RefundRecordDO; +import cn.iocoder.yudao.module.pay.service.refundrecord.RefundRecordService; + +@Tag(name = "管理后台 - 退款记录") +@RestController +@RequestMapping("/pay/refund-record") +@Validated +public class RefundRecordController { + + @Resource + private RefundRecordService refundRecordService; + + @PostMapping("/create") + @Operation(summary = "创建退款记录") + @PreAuthorize("@ss.hasPermission('pay:refund-record:create')") + public CommonResult createRefundRecord(@Valid @RequestBody RefundRecordSaveReqVO createReqVO) { + return success(refundRecordService.createRefundRecord(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新退款记录") + @PreAuthorize("@ss.hasPermission('pay:refund-record:update')") + public CommonResult updateRefundRecord(@Valid @RequestBody RefundRecordSaveReqVO updateReqVO) { + refundRecordService.updateRefundRecord(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除退款记录") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('pay:refund-record:delete')") + public CommonResult deleteRefundRecord(@RequestParam("id") Long id) { + refundRecordService.deleteRefundRecord(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得退款记录") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('pay:refund-record:query')") + public CommonResult getRefundRecord(@RequestParam("id") Long id) { + RefundRecordDO refundRecord = refundRecordService.getRefundRecord(id); + return success(BeanUtils.toBean(refundRecord, RefundRecordRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得退款记录分页") + @PreAuthorize("@ss.hasPermission('pay:refund-record:query')") + public CommonResult> getRefundRecordPage(@Valid RefundRecordPageReqVO pageReqVO) { + PageResult pageResult = refundRecordService.getRefundRecordPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, RefundRecordRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出退款记录 Excel") + @PreAuthorize("@ss.hasPermission('pay:refund-record:export')") + @OperateLog(type = EXPORT) + public void exportRefundRecordExcel(@Valid RefundRecordPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = refundRecordService.getRefundRecordPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "退款记录.xls", "数据", RefundRecordRespVO.class, + BeanUtils.toBean(list, RefundRecordRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordPageReqVO.java new file mode 100644 index 00000000..d28cca9b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordPageReqVO.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refundrecord.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 退款记录分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class RefundRecordPageReqVO extends PageParam { + + @Schema(description = "渠道编号", example = "13125") + private Long channelId; + + @Schema(description = "渠道编码") + private String channelCode; + + @Schema(description = "渠道用户编号", example = "19090") + private String channelUserId; + + @Schema(description = "会员编号", example = "21945") + private String userId; + + @Schema(description = "总金额,单位:分", example = "11049") + private Integer totalPrice; + + @Schema(description = "退款状态", example = "1") + private String status; + + @Schema(description = "商户订单号") + private String outTradeNo; + + @Schema(description = "微信订单号", example = "26320") + private String transactionId; + + @Schema(description = "微信退款单号") + private String outRefundNo; + + @Schema(description = "微信支付退款单号", example = "8006") + private String refundId; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordRespVO.java new file mode 100644 index 00000000..e41f8a11 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordRespVO.java @@ -0,0 +1,64 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refundrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 退款记录 Response VO") +@Data +@ExcelIgnoreUnannotated +public class RefundRecordRespVO { + + @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "8454") + @ExcelProperty("主键") + private Long id; + + @Schema(description = "渠道编号", example = "13125") + @ExcelProperty("渠道编号") + private Long channelId; + + @Schema(description = "渠道编码") + @ExcelProperty("渠道编码") + private String channelCode; + + @Schema(description = "渠道用户编号", example = "19090") + @ExcelProperty("渠道用户编号") + private String channelUserId; + + @Schema(description = "会员编号", example = "21945") + @ExcelProperty("会员编号") + private String userId; + + @Schema(description = "总金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "11049") + @ExcelProperty("总金额,单位:分") + private Integer totalPrice; + + @Schema(description = "退款状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty("退款状态") + private String status; + + @Schema(description = "商户订单号") + @ExcelProperty("商户订单号") + private String outTradeNo; + + @Schema(description = "微信订单号", example = "26320") + @ExcelProperty("微信订单号") + private String transactionId; + + @Schema(description = "微信退款单号") + @ExcelProperty("微信退款单号") + private String outRefundNo; + + @Schema(description = "微信支付退款单号", example = "8006") + @ExcelProperty("微信支付退款单号") + private String refundId; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordSaveReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordSaveReqVO.java new file mode 100644 index 00000000..f0b43c47 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refundrecord/vo/RefundRecordSaveReqVO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refundrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 退款记录新增/修改 Request VO") +@Data +public class RefundRecordSaveReqVO { + + @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "8454") + private Long id; + + @Schema(description = "渠道编号", example = "13125") + private Long channelId; + + @Schema(description = "渠道编码") + private String channelCode; + + @Schema(description = "渠道用户编号", example = "19090") + private String channelUserId; + + @Schema(description = "会员编号", example = "21945") + private String userId; + + @Schema(description = "总金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "11049") + @NotNull(message = "总金额,单位:分不能为空") + private Integer totalPrice; + + @Schema(description = "退款状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotEmpty(message = "退款状态不能为空") + private String status; + + @Schema(description = "商户订单号") + private String outTradeNo; + + @Schema(description = "微信订单号", example = "26320") + private String transactionId; + + @Schema(description = "微信退款单号") + private String outRefundNo; + + @Schema(description = "微信支付退款单号", example = "8006") + private String refundId; + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/divide/AppDivideController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/divide/AppDivideController.java new file mode 100644 index 00000000..3e378151 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/divide/AppDivideController.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.pay.controller.app.divide; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.pay.controller.app.divide.vo.DrawMoneyVO; +import cn.iocoder.yudao.module.pay.service.divide.DivideService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +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.RestController; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 分账单") +@RestController +@RequestMapping("/pay/divide") +@Validated +public class AppDivideController { + + @Resource + private DivideService divideService; + + @PostMapping("/drawMoney") + @Operation(summary = "提现") + public CommonResult createDivide(@RequestBody DrawMoneyVO drawMoneyVO) { + return success(divideService.drawMoney(drawMoneyVO)); + } + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/divide/vo/DrawMoneyVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/divide/vo/DrawMoneyVO.java new file mode 100644 index 00000000..f04e467e --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/divide/vo/DrawMoneyVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.pay.controller.app.divide.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 分账单新增/修改 Request VO") +@Data +public class DrawMoneyVO { + + @Schema(description = "用户编号") + private Long userId; + + @Schema(description = "总金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "30938") + //@NotNull(message = "总金额,单位:分不能为空") + private Integer totalPrice; + /** + * 渠道用户编号 + */ + private String channelUserId; +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/divide/DivideDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/divide/DivideDO.java index a01a5573..c366f3b8 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/divide/DivideDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/divide/DivideDO.java @@ -43,10 +43,31 @@ public class DivideDO extends BaseDO { * 总金额,单位:分 */ private Integer totalPrice; + + /** + * 已分金额,单位:分 + */ + private Integer cpPrice; + + /** + * 渠道用户编号 + */ + private String channelUserId; + + /** + * 待分金额,单位:分 + */ + private Integer unPrice; /** * 分账状态 */ private String status; + + /** + * 是否退款 + */ + private String refundStatus; + /** * 商户分账单号 */ @@ -60,4 +81,8 @@ public class DivideDO extends BaseDO { */ private String orderId; + /** + * 退款金额 + */ + private Integer refundPrice; } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/dividerecord/DivideRecordDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/dividerecord/DivideRecordDO.java new file mode 100644 index 00000000..5e92ef4c --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/dividerecord/DivideRecordDO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.pay.dal.dataobject.dividerecord; + +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 + * + * @author 管理员 + */ +@TableName("pay_divide_record") +@KeySequence("pay_divide_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DivideRecordDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + /** + * 商户分账单号 + */ + private String outOrderNo; + /** + * 微信订单号 + */ + private String transactionId; + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refundrecord/RefundRecordDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refundrecord/RefundRecordDO.java new file mode 100644 index 00000000..3b4621ea --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refundrecord/RefundRecordDO.java @@ -0,0 +1,71 @@ +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; + +/** + * 退款记录 DO + * + * @author 管理员 + */ +@TableName("pay_refund_record") +@KeySequence("pay_refund_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class RefundRecordDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + /** + * 渠道编号 + */ + private Long channelId; + /** + * 渠道编码 + */ + private String channelCode; + /** + * 渠道用户编号 + */ + private String channelUserId; + /** + * 会员编号 + */ + private String userId; + /** + * 总金额,单位:分 + */ + private Integer totalPrice; + /** + * 退款状态 + */ + private String status; + /** + * 商户订单号 + */ + private String outTradeNo; + /** + * 微信订单号 + */ + private String transactionId; + /** + * 微信退款单号 + */ + private String outRefundNo; + /** + * 微信支付退款单号 + */ + private String refundId; + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/divide/DivideMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/divide/DivideMapper.java index f35910d7..604be72d 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/divide/DivideMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/divide/DivideMapper.java @@ -1,13 +1,14 @@ package cn.iocoder.yudao.module.pay.dal.mysql.divide; -import java.util.*; - 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.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.pay.controller.admin.divide.vo.DividePageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.divide.DivideDO; import org.apache.ibatis.annotations.Mapper; -import cn.iocoder.yudao.module.pay.controller.admin.divide.vo.*; +import org.apache.ibatis.annotations.Select; + +import java.math.BigDecimal; /** * 分账单 Mapper @@ -30,4 +31,17 @@ public interface DivideMapper extends BaseMapperX { .orderByDesc(DivideDO::getId)); } + @Select("select sum(total_money) from member_dish_order where DATE(create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)") + BigDecimal getToday(); + + @Select("select wx_amount from member_card where user_id = #{userId} order by create_time desc limit 1") + BigDecimal getWxAmount(Long userId); + + @Select("select count(1) from member_dish_order where user_id = #{userId} and order_status = '0'") + int orderCount(Long userId); + + + + + } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/dividerecord/DivideRecordMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/dividerecord/DivideRecordMapper.java new file mode 100644 index 00000000..958a06b0 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/dividerecord/DivideRecordMapper.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.dividerecord; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.pay.dal.dataobject.dividerecord.DivideRecordDO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * 分账记录 Mapper + * + * @author 管理员 + */ +@Mapper +public interface DivideRecordMapper extends BaseMapperX { + + @Select("select * from pay_divide_record where DATE(create_time) = CURDATE()") + List getList(); +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refundrecord/RefundRecordMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refundrecord/RefundRecordMapper.java new file mode 100644 index 00000000..e28c6763 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refundrecord/RefundRecordMapper.java @@ -0,0 +1,36 @@ +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.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord.RefundRecordDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.pay.controller.admin.refundrecord.vo.*; + +/** + * 退款记录 Mapper + * + * @author 管理员 + */ +@Mapper +public interface RefundRecordMapper extends BaseMapperX { + + default PageResult selectPage(RefundRecordPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(RefundRecordDO::getChannelId, reqVO.getChannelId()) + .eqIfPresent(RefundRecordDO::getChannelCode, reqVO.getChannelCode()) + .eqIfPresent(RefundRecordDO::getChannelUserId, reqVO.getChannelUserId()) + .eqIfPresent(RefundRecordDO::getUserId, reqVO.getUserId()) + .eqIfPresent(RefundRecordDO::getTotalPrice, reqVO.getTotalPrice()) + .eqIfPresent(RefundRecordDO::getStatus, reqVO.getStatus()) + .eqIfPresent(RefundRecordDO::getOutTradeNo, reqVO.getOutTradeNo()) + .eqIfPresent(RefundRecordDO::getTransactionId, reqVO.getTransactionId()) + .eqIfPresent(RefundRecordDO::getOutRefundNo, reqVO.getOutRefundNo()) + .eqIfPresent(RefundRecordDO::getRefundId, reqVO.getRefundId()) + .betweenIfPresent(RefundRecordDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(RefundRecordDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/divide/DivideService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/divide/DivideService.java index 150824cc..a03d9fff 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/divide/DivideService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/divide/DivideService.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.service.divide; import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.app.divide.vo.DrawMoneyVO; import cn.iocoder.yudao.module.pay.dal.dataobject.divide.DivideDO; import javax.validation.Valid; @@ -66,4 +67,10 @@ public interface DivideService { * 解冻剩余资金 */ int getDivideFreeze(); + + + /** + * 解冻剩余资金 + */ + Boolean drawMoney( DrawMoneyVO drawMoneyVO); } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/divide/DivideServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/divide/DivideServiceImpl.java index 11c95680..0279ee25 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/divide/DivideServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/divide/DivideServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.service.divide; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; +import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.pay.core.client.PayClient; @@ -10,10 +11,15 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto 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.DivideSaveReqVO; +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.dividecompany.DivideCompanyDO; 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.mysql.divide.DivideMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.dividerecord.DivideRecordMapper; +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.service.channel.PayChannelService; import cn.iocoder.yudao.module.pay.service.dividecompany.DivideCompanyService; import cn.iocoder.yudao.module.pay.service.divideinfo.DivideInfoService; @@ -24,12 +30,16 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +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.module.pay.enums.ErrorCodeConstants.DIVIDE_NOT_EXISTS; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; /** * 分账单 Service 实现类 @@ -52,6 +62,16 @@ public class DivideServiceImpl implements DivideService { @Resource private PayChannelService channelService; + @Resource + private PayNoRedisDAO noRedisDAO; + + @Resource + private PayProperties payProperties; + @Resource + private DivideRecordMapper divideRecordMapper; + + + @Override public Long createDivide(DivideSaveReqVO createReqVO) { // 插入 @@ -105,7 +125,7 @@ public class DivideServiceImpl implements DivideService { for (DivideCompanyDO divideCompanyDO : companyList) { DivideInfoDO divideInfoDO = new DivideInfoDO(); - int money = (int) Math.ceil(divideDO.getTotalPrice() * Double.valueOf(divideCompanyDO.getProportion())); + int money = (int) Math.ceil(divideDO.getUnPrice() * Double.valueOf(divideCompanyDO.getProportion())); divideInfoDO.setTransactionId(divideDO.getChannelOrderNo()) .setOutOrderNo(divideDO.getNo()) .setName(divideCompanyDO.getName()) @@ -128,14 +148,48 @@ public class DivideServiceImpl implements DivideService { @Override public int startDivide() { - List divideDOS = divideMapper.selectList(Wrappers.lambdaQuery() - .eq(DivideDO::getStatus, PayDivideStatusRespEnum.WAITING.getStatus())); + BigDecimal today = divideMapper.getToday(); + int money = today.multiply(new BigDecimal("100")).intValue(); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime thirtyDaysAgo = now.minusDays(30); + + + List divideDOS = divideMapper.selectList(Wrappers.lambdaQuery() + .eq(DivideDO::getStatus, PayDivideStatusRespEnum.WAITING.getStatus()) + .ge(DivideDO::getCreateTime,thirtyDaysAgo) + .orderByAsc(DivideDO::getCreateTime)); if(CollectionUtil.isEmpty(divideDOS)){ return 0; } + + List divideList = new ArrayList<>(); + + int sum = 0; + for(DivideDO divideDO: divideDOS){ + Integer totalPrice = divideDO.getTotalPrice()-divideDO.getCpPrice(); + + sum = sum+totalPrice; + if(sum divideRecordDOList = new ArrayList<>(); int counter = 0; - for (DivideDO divideDO : divideDOS) { + for (DivideDO divideDO : divideList) { PayClient client = channelService.getPayClient(divideDO.getChannelId()); PayDivideUnifiedDto payDivideUnifiedDto = new PayDivideUnifiedDto(); @@ -143,8 +197,19 @@ public class DivideServiceImpl implements DivideService { .setOutOrderNo(divideDO.getNo()) .setUnfreezeUnsplit(false) .setReceivers(createDivideInfo(divideDO)); + + if(divideDO.getTotalPrice().equals(divideDO.getCpPrice())) { + payDivideUnifiedDto.setUnfreezeUnsplit(true); + divideDO.setStatus(PayDivideStatusRespEnum.PROGRESS.getStatus()); + } PayDivideRespDto payDivideRespDto = client.unifiedDivide(payDivideUnifiedDto); - divideDO.setStatus(PayDivideStatusRespEnum.PROGRESS.getStatus()); + + DivideRecordDO divideRecordDO = new DivideRecordDO(); + divideRecordDO.setTransactionId(divideDO.getChannelOrderNo()) + .setOutOrderNo(divideDO.getNo()); + divideRecordDOList.add(divideRecordDO); + + divideDO.setOrderId(payDivideRespDto.getOrderId()); // 每执行250次,休息一分钟 @@ -158,14 +223,26 @@ public class DivideServiceImpl implements DivideService { } } divideMapper.updateBatch(divideDOS); + divideRecordMapper.insertBatch(divideRecordDOList); return divideDOS.size(); } @Override public int getDivideResult() { + List divideRecordDOList = divideRecordMapper.getList(); + + if(CollectionUtil.isEmpty(divideRecordDOList)){ + return 0; + } + + Stream transactionIdList = divideRecordDOList.stream().map(DivideRecordDO::getTransactionId); + Stream OutOrderNoList = divideRecordDOList.stream().map(DivideRecordDO::getOutOrderNo); + List divideDOS = divideMapper.selectList(Wrappers.lambdaQuery() - .eq(DivideDO::getStatus, PayDivideStatusRespEnum.PROGRESS.getStatus())); + .in(DivideDO::getChannelOrderNo, transactionIdList) + .in(DivideDO::getNo,OutOrderNoList)); + if(CollectionUtil.isEmpty(divideDOS)){ return 0; } @@ -178,7 +255,12 @@ public class DivideServiceImpl implements DivideService { .setOutOrderNo(divideDO.getNo()); PayDivideRespDto payDivideRespDto = client.unifiedDivideResult(payDivideUnifiedDto); updateDivideInfo(payDivideRespDto.getReceivers(),divideDO.getNo()); - divideDO.setStatus(PayDivideStatusRespEnum.COMPLETE.getStatus()); + + if(divideDO.getTotalPrice().equals(divideDO.getCpPrice())) { + divideDO.setStatus(PayDivideStatusRespEnum.COMPLETE.getStatus()); + }else{ + divideDO.setNo(noRedisDAO.generate(payProperties.getOrderNoPrefix())); + } } divideMapper.updateBatch(divideDOS); return divideDOS.size(); @@ -230,5 +312,95 @@ public class DivideServiceImpl implements DivideService { return true; } + @Override + public Boolean drawMoney(DrawMoneyVO drawMoneyVO) { + + //判断订单是否完成 + int i = divideMapper.orderCount(drawMoneyVO.getUserId()); + if(i>0){ + throw new ServiceException(ORDER_NOT_COMPLETE); + } + + //判断是否有金额可退款 + BigDecimal wxAmount = divideMapper.getWxAmount(drawMoneyVO.getUserId()); + int money = wxAmount.multiply(new BigDecimal("100")).intValue(); + if(money<=0){ + throw new ServiceException(WX_ACCOUNT_NO); + } + + //查询最近的充值订单,时间倒序退款 + List divideDOS = divideMapper.selectList(Wrappers.lambdaQuery() + .eq(DivideDO::getChannelUserId, drawMoneyVO.getChannelUserId()) + .eq(DivideDO::getRefundStatus,"0") + .orderByDesc(DivideDO::getCreateTime)); + + //筛选出未分账的订单 + List unDivideList = divideDOS.stream().filter(vo -> vo.getCpPrice() == 0).collect(Collectors.toList()); + + //筛选出已分账的订单 + List divideList = divideDOS.stream().filter(vo -> vo.getCpPrice().equals(vo.getTotalPrice())).collect(Collectors.toList()); + + //剩下的是未分账完 的订单 + divideDOS.removeAll(unDivideList); + divideDOS.removeAll(divideList); + + //需要回退的订单 + List backList = new ArrayList<>(); + //不需要回退的订单 + List noBackList = new ArrayList<>(); + + int sum = 0; + + //先从未分账的订单计算 + + for (DivideDO divideDO: unDivideList){ + Integer totalPrice = divideDO.getTotalPrice()-divideDO.getCpPrice(); + + sum = sum+totalPrice; + + if(sum<=money){ + divideDO.setRefundPrice(totalPrice); + divideDO.setCpPrice(divideDO.getCpPrice()+totalPrice); + noBackList.add(divideDO); + }else { + int leftMoney = money+totalPrice- sum; + divideDO.setRefundPrice(leftMoney); + divideDO.setCpPrice(divideDO.getCpPrice()+leftMoney); + noBackList.add(divideDO); + break; + } + } + //从分账完的订单进行退款 + if(sum getRefundRecordPage(RefundRecordPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refundrecord/RefundRecordServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refundrecord/RefundRecordServiceImpl.java new file mode 100644 index 00000000..6bfb3c7d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refundrecord/RefundRecordServiceImpl.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.pay.service.refundrecord; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.pay.controller.admin.refundrecord.vo.*; +import cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord.RefundRecordDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.pay.dal.mysql.refundrecord.RefundRecordMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; + +/** + * 退款记录 Service 实现类 + * + * @author 管理员 + */ +@Service +@Validated +public class RefundRecordServiceImpl implements RefundRecordService { + + @Resource + private RefundRecordMapper refundRecordMapper; + + @Override + public Long createRefundRecord(RefundRecordSaveReqVO createReqVO) { + // 插入 + RefundRecordDO refundRecord = BeanUtils.toBean(createReqVO, RefundRecordDO.class); + refundRecordMapper.insert(refundRecord); + // 返回 + return refundRecord.getId(); + } + + @Override + public void updateRefundRecord(RefundRecordSaveReqVO updateReqVO) { + // 校验存在 + validateRefundRecordExists(updateReqVO.getId()); + // 更新 + RefundRecordDO updateObj = BeanUtils.toBean(updateReqVO, RefundRecordDO.class); + refundRecordMapper.updateById(updateObj); + } + + @Override + public void deleteRefundRecord(Long id) { + // 校验存在 + validateRefundRecordExists(id); + // 删除 + refundRecordMapper.deleteById(id); + } + + private void validateRefundRecordExists(Long id) { + if (refundRecordMapper.selectById(id) == null) { + throw exception(REFUND_RECORD_NOT_EXISTS); + } + } + + @Override + public RefundRecordDO getRefundRecord(Long id) { + return refundRecordMapper.selectById(id); + } + + @Override + public PageResult getRefundRecordPage(RefundRecordPageReqVO pageReqVO) { + return refundRecordMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/carteen/CarteenMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/carteen/CarteenMapper.java index e56284a0..67d0ae6f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/carteen/CarteenMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/carteen/CarteenMapper.java @@ -30,7 +30,7 @@ public interface CarteenMapper extends BaseMapperX { .eqIfPresent(CarteenDO::getAccountOrder, reqVO.getAccountOrder()) .eqIfPresent(CarteenDO::getPhone, reqVO.getPhone()) .betweenIfPresent(CarteenDO::getCreateTime, reqVO.getCreateTime()) - .last(" and FIND_IN_SET("+userId+",serial_number) order by id desc") + .orderByDesc(CarteenDO::getId) ); } @Select("