bug修改
This commit is contained in:
@ -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, "退款记录不存在");
|
||||
|
||||
}
|
||||
|
@ -35,5 +35,8 @@ public class DivideSaveReqVO {
|
||||
|
||||
@Schema(description = "微信分账单号", example = "3065")
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
* 渠道用户编号
|
||||
*/
|
||||
private String channelUserId;
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
@ -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));
|
||||
|
||||
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<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());
|
||||
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<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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user