bug修改

This commit is contained in:
zengtao01
2024-07-24 14:21:38 +08:00
parent ee29e19d95
commit 82eb8b56ce
32 changed files with 996 additions and 32 deletions

View File

@ -143,8 +143,8 @@ public class CardController {
@PutMapping("/recharge")
@Operation(summary = "充值")
//@PreAuthorize("@ss.hasPermission('member:card:update')")
public CommonResult<Boolean> recharge(BigDecimal money) {
return success(cardService.recharge(money, CardDO.ADD));
public CommonResult<Boolean> recharge(BigDecimal money,BigDecimal giftMoney) {
return success(cardService.recharge(money, CardDO.ADD,giftMoney));
}
@GetMapping("/getMoney")

View File

@ -99,9 +99,9 @@ public class AppCardController {
@PutMapping("/recharge")
@Operation(summary = "充值")
//@PreAuthorize("@ss.hasPermission('member:card:update')")
public CommonResult<Boolean> recharge(BigDecimal money) {
public CommonResult<Boolean> 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));
}

View File

@ -67,5 +67,11 @@ public class AppDiningPlatesController {
return success(diningPlatesService.getMoney(cId,dishesId));
}
@GetMapping("/getBind")
@Operation(summary = "获取绑定餐盘")
public CommonResult<List<String>> getBind() {
return success(diningPlatesService.getBindDiningPlatesList());
}
}

View File

@ -19,4 +19,6 @@ public class AppUserInfo {
private String dishesName;
private BigDecimal dishesBasePrice;
private BigDecimal orderMoney;
}

View File

@ -63,4 +63,14 @@ public class CardDO extends BaseDO {
*/
private BigDecimal giftAmount;
/**
* 现金金额
*/
private BigDecimal cashAmount;
/**
* 微信充值金额
*/
private BigDecimal wxAmount;
}

View File

@ -67,4 +67,19 @@ public class DishOrderDO extends BaseDO {
* 餐盘编号
*/
private String diningPlatesNum;
/**
* 赠送金额
*/
private BigDecimal giftAmount;
/**
* 现金金额
*/
private BigDecimal cashAmount;
/**
* 微信充值金额
*/
private BigDecimal wxAmount;
}

View File

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

View File

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

View File

@ -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.<CardDO>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.<CardDO>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);
}
}

View File

@ -98,4 +98,9 @@ public interface DiningPlatesService {
AppUserInfo getMoney(String diningPlatesNum, Long dishId);
/**
* 获取绑定餐盘列表
* @return
*/
List<String> getBindDiningPlatesList();
}

View File

@ -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.<DishOrderDO>lambdaUpdate()
.set(DishOrderDO::getOrderStatus,"1")
.eq(DishOrderDO::getId,diningPlatesDO.getOrderId()));
diningPlatesMapper.update(Wrappers.<DiningPlatesDO>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<String> getBindDiningPlatesList() {
List<DiningPlatesDO> diningPlatesDOS = diningPlatesMapper.selectList(Wrappers.<DiningPlatesDO>lambdaQuery()
.isNotNull(DiningPlatesDO::getUserId));
List<String> list = diningPlatesDOS.stream().map(DiningPlatesDO::getDiningPlatesNum).collect(Collectors.toList());
return list;
}
}

View File

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

View File

@ -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, "退款记录不存在");
}

View File

@ -35,5 +35,8 @@ public class DivideSaveReqVO {
@Schema(description = "微信分账单号", example = "3065")
private String orderId;
/**
* 渠道用户编号
*/
private String channelUserId;
}

View File

@ -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<Long> createRefundRecord(@Valid @RequestBody RefundRecordSaveReqVO createReqVO) {
return success(refundRecordService.createRefundRecord(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新退款记录")
@PreAuthorize("@ss.hasPermission('pay:refund-record:update')")
public CommonResult<Boolean> 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<Boolean> 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<RefundRecordRespVO> 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<PageResult<RefundRecordRespVO>> getRefundRecordPage(@Valid RefundRecordPageReqVO pageReqVO) {
PageResult<RefundRecordDO> 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<RefundRecordDO> list = refundRecordService.getRefundRecordPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "退款记录.xls", "数据", RefundRecordRespVO.class,
BeanUtils.toBean(list, RefundRecordRespVO.class));
}
}

View File

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

View File

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

View File

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

View File

@ -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<Boolean> createDivide(@RequestBody DrawMoneyVO drawMoneyVO) {
return success(divideService.drawMoney(drawMoneyVO));
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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<DivideDO> {
.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);
}

View File

@ -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<DivideRecordDO> {
@Select("select * from pay_divide_record where DATE(create_time) = CURDATE()")
List<DivideRecordDO> getList();
}

View File

@ -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<RefundRecordDO> {
default PageResult<RefundRecordDO> selectPage(RefundRecordPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<RefundRecordDO>()
.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));
}
}

View File

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

View File

@ -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<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>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<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>lambdaQuery()
.eq(DivideDO::getStatus, PayDivideStatusRespEnum.WAITING.getStatus())
.ge(DivideDO::getCreateTime,thirtyDaysAgo)
.orderByAsc(DivideDO::getCreateTime));
if(CollectionUtil.isEmpty(divideDOS)){
return 0;
}
List<DivideDO> divideList = new ArrayList<>();
int sum = 0;
for(DivideDO divideDO: divideDOS){
Integer totalPrice = divideDO.getTotalPrice()-divideDO.getCpPrice();
sum = sum+totalPrice;
if(sum<money){
divideDO.setUnPrice(totalPrice);
divideDO.setCpPrice(divideDO.getCpPrice()+totalPrice);
divideList.add(divideDO);
} else if (sum ==money) {
divideDO.setUnPrice(totalPrice);
divideDO.setCpPrice(divideDO.getCpPrice()+totalPrice);
divideList.add(divideDO);
break;
}else {
int leftMoney = money+totalPrice- sum;
divideDO.setUnPrice(leftMoney);
divideDO.setCpPrice(divideDO.getCpPrice()+leftMoney);
divideList.add(divideDO);
break;
}
}
List<DivideRecordDO> 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));
PayDivideRespDto payDivideRespDto = client.unifiedDivide(payDivideUnifiedDto);
if(divideDO.getTotalPrice().equals(divideDO.getCpPrice())) {
payDivideUnifiedDto.setUnfreezeUnsplit(true);
divideDO.setStatus(PayDivideStatusRespEnum.PROGRESS.getStatus());
}
PayDivideRespDto payDivideRespDto = client.unifiedDivide(payDivideUnifiedDto);
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<DivideRecordDO> divideRecordDOList = divideRecordMapper.getList();
if(CollectionUtil.isEmpty(divideRecordDOList)){
return 0;
}
Stream<String> transactionIdList = divideRecordDOList.stream().map(DivideRecordDO::getTransactionId);
Stream<String> OutOrderNoList = divideRecordDOList.stream().map(DivideRecordDO::getOutOrderNo);
List<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>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());
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<DivideDO> divideDOS = divideMapper.selectList(Wrappers.<DivideDO>lambdaQuery()
.eq(DivideDO::getChannelUserId, drawMoneyVO.getChannelUserId())
.eq(DivideDO::getRefundStatus,"0")
.orderByDesc(DivideDO::getCreateTime));
//筛选出未分账的订单
List<DivideDO> unDivideList = divideDOS.stream().filter(vo -> vo.getCpPrice() == 0).collect(Collectors.toList());
//筛选出已分账的订单
List<DivideDO> divideList = divideDOS.stream().filter(vo -> vo.getCpPrice().equals(vo.getTotalPrice())).collect(Collectors.toList());
//剩下的是未分账完 的订单
divideDOS.removeAll(unDivideList);
divideDOS.removeAll(divideList);
//需要回退的订单
List<DivideDO> backList = new ArrayList<>();
//不需要回退的订单
List<DivideDO> 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<money){
for (DivideDO divideDO:divideList){
Integer totalPrice = divideDO.getTotalPrice()-divideDO.getCpPrice();
sum = sum+totalPrice;
if(sum<=money){
divideDO.setRefundPrice(totalPrice);
backList.add(divideDO);
}else {
int leftMoney = money+totalPrice- sum;
divideDO.setRefundPrice(leftMoney);
backList.add(divideDO);
break;
}
}
}
return null;
}
}

View File

@ -305,7 +305,8 @@ public class PayOrderServiceImpl implements PayOrderService {
.setChannelCode(channel.getCode())
.setTotalPrice(payOrderDO.getPrice())
.setNo(no).setStatus(PayDivideStatusRespEnum.WAITING.getStatus())
.setChannelOrderNo(payOrderDO.getChannelOrderNo());
.setChannelOrderNo(payOrderDO.getChannelOrderNo())
.setChannelUserId(payOrderDO.getChannelUserId());
divideService.createDivide(divideSaveReqVO);
}

View File

@ -0,0 +1,55 @@
package cn.iocoder.yudao.module.pay.service.refundrecord;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.pay.controller.admin.refundrecord.vo.RefundRecordPageReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.refundrecord.vo.RefundRecordSaveReqVO;
import cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord.RefundRecordDO;
import javax.validation.Valid;
/**
* 退款记录 Service 接口
*
* @author 管理员
*/
public interface RefundRecordService {
/**
* 创建退款记录
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createRefundRecord(@Valid RefundRecordSaveReqVO createReqVO);
/**
* 更新退款记录
*
* @param updateReqVO 更新信息
*/
void updateRefundRecord(@Valid RefundRecordSaveReqVO updateReqVO);
/**
* 删除退款记录
*
* @param id 编号
*/
void deleteRefundRecord(Long id);
/**
* 获得退款记录
*
* @param id 编号
* @return 退款记录
*/
RefundRecordDO getRefundRecord(Long id);
/**
* 获得退款记录分页
*
* @param pageReqVO 分页查询
* @return 退款记录分页
*/
PageResult<RefundRecordDO> getRefundRecordPage(RefundRecordPageReqVO pageReqVO);
}

View File

@ -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<RefundRecordDO> getRefundRecordPage(RefundRecordPageReqVO pageReqVO) {
return refundRecordMapper.selectPage(pageReqVO);
}
}

View File

@ -30,7 +30,7 @@ public interface CarteenMapper extends BaseMapperX<CarteenDO> {
.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("<script>"+"SELECT\n" +