Răsfoiți Sursa

钱包接口及业务实现和中台接口实现和拓展

xucaiqin 2 ani în urmă
părinte
comite
81c9ca9b82
16 a modificat fișierele cu 1059 adăugiri și 107 ștergeri
  1. 155 4
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/controller/WalletController.java
  2. 54 0
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/constant/CashEnum.java
  3. 9 1
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/constant/PayCenterEnum.java
  4. 53 0
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/constant/RefundEnum.java
  5. 7 2
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/CashPageReq.java
  6. 41 0
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/PrePay.java
  7. 23 0
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/PrePayCheck.java
  8. 1 1
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/PrePayPage.java
  9. 41 0
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/Refund.java
  10. 4 2
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/RefundReq.java
  11. 41 0
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/TransferReq.java
  12. 27 6
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/res/FundVo.java
  13. 34 0
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/res/MorePageRes.java
  14. 3 1
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/res/WalletDetail.java
  15. 131 8
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/service/PayCenterService.java
  16. 435 82
      sckw-modules/sckw-payment/src/main/java/com/sckw/payment/service/WalletService.java

+ 155 - 4
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/controller/WalletController.java

@@ -1,13 +1,12 @@
 package com.sckw.payment.controller;
 
 import com.sckw.core.web.response.HttpResult;
-import com.sckw.payment.model.vo.req.WalletDetailReq;
+import com.sckw.payment.model.vo.req.*;
 import com.sckw.payment.service.WalletService;
 import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 /**
  * 钱包
@@ -42,4 +41,156 @@ public class WalletController {
         return HttpResult.ok(walletService.walletDetail(walletDetailReq));
     }
 
+    /**
+     * 新增账目
+     *
+     * @param addWalletReq
+     * @return
+     */
+    @PostMapping("add")
+    public HttpResult add(@RequestBody @Valid AddWalletReq addWalletReq) {
+        return HttpResult.ok(walletService.addWallet(addWalletReq));
+    }
+
+    /**
+     * 账目充值
+     *
+     * @param addWalletReq
+     * @return
+     */
+    @PostMapping("recharge")
+    public HttpResult recharge(@RequestBody @Valid AddWalletReq addWalletReq) {
+        return HttpResult.ok(walletService.addWalletMoney(addWalletReq));
+    }
+
+    /**
+     * 提现
+     *
+     * @param cashWalletReq
+     * @return
+     */
+    @PostMapping("cashOUt")
+    public HttpResult cashOUt(@RequestBody @Valid CashWalletReq cashWalletReq) {
+        return HttpResult.ok(walletService.cashOUt(cashWalletReq));
+    }
+
+    /**
+     * 重新提现
+     *
+     * @param cashWalletReq
+     * @return
+     */
+    @PostMapping("reCashOUt")
+    public HttpResult reCashOUt(@RequestBody @Valid CashWalletReq cashWalletReq) {
+        return HttpResult.ok(walletService.reCashOUt(cashWalletReq));
+    }
+
+    /**
+     * 转账
+     *
+     * @param transferReq
+     * @return
+     */
+    @PostMapping("transfer")
+    public HttpResult transfer(TransferReq transferReq) {
+        return HttpResult.ok(walletService.transfer(transferReq));
+    }
+
+    /**
+     * 提现记录
+     *
+     * @param cashPageReq
+     * @return
+     */
+    @GetMapping("cashList")
+    public HttpResult cashList(CashPageReq cashPageReq) {
+        return HttpResult.ok(walletService.cashList(cashPageReq));
+    }
+
+    /**
+     * 提现记录 分类统计
+     *
+     * @param cashPageReq
+     * @return
+     */
+    @GetMapping("cashCount")
+    public HttpResult cashCount(CashPageReq cashPageReq) {
+        return HttpResult.ok(walletService.cashCount(cashPageReq));
+    }
+
+    /**
+     * 预付列表
+     *
+     * @param prePayPage
+     * @return
+     */
+    @GetMapping("prePayList")
+    public HttpResult prePayList(PrePayPage prePayPage) {
+        return HttpResult.ok(walletService.prePayList(prePayPage));
+    }
+
+    /**
+     * 预收列表
+     *
+     * @param prePayPage
+     * @return
+     */
+    @GetMapping("preReceiveList")
+    public HttpResult preReceiveList(PrePayPage prePayPage) {
+        return HttpResult.ok(walletService.preReceiveList(prePayPage));
+    }
+
+    /**
+     * 预付校验
+     *
+     * @param prePayCheck
+     * @return
+     */
+    @PostMapping("prePayCheck")
+    public HttpResult prePayCheck(@RequestBody @Valid PrePayCheck prePayCheck) {
+        return HttpResult.ok(walletService.prePayCheck(prePayCheck));
+    }
+
+    /**
+     * 新增预付
+     *
+     * @param prePay
+     * @return
+     */
+    @PostMapping("addPrePay")
+    public HttpResult addPrePay(@RequestBody @Valid PrePay prePay) {
+        return HttpResult.ok(walletService.addPrePay(prePay));
+    }
+
+    /**
+     * 预付追加
+     *
+     * @param prePay
+     * @return
+     */
+    @PostMapping("prePayAppend")
+    public HttpResult prePayAppend(@RequestBody @Valid PrePay prePay) {
+        return HttpResult.ok(walletService.prePayAppend(prePay));
+    }
+
+    /**
+     * 申请退款
+     *
+     * @param refundReq
+     * @return
+     */
+    @PostMapping("applyRefund")
+    public HttpResult applyRefund(@RequestBody @Valid RefundReq refundReq) {
+        return HttpResult.ok(walletService.applyRefund(refundReq));
+    }
+    /**
+     * 退款
+     *
+     * @param refundReq
+     * @return
+     */
+    @PostMapping("refund")
+    public HttpResult refund(@RequestBody @Valid RefundReq refundReq) {
+        return HttpResult.ok(walletService.launchRefund(refundReq));
+    }
 }

+ 54 - 0
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/constant/CashEnum.java

@@ -0,0 +1,54 @@
+package com.sckw.payment.model.constant;
+
+import java.util.Objects;
+
+/**
+ * 物流、贸易
+ * 对账单状态枚举
+ *
+ * @author xucaiqin
+ * @date 2023-07-11 12:00:52
+ */
+public enum CashEnum {
+    ALL(-1, "全部", "-1"),
+    FAIL(0, "提现失败", "0"),
+    SUCCESS(1, "提现成功", "1"),
+    LOAD(2, "提现中", "2"),
+    WAIT(3, "等待提现", "3");
+
+    private final int status;
+    private final String desc;
+    private final String label;
+
+    CashEnum(int status, String desc, String label) {
+        this.status = status;
+        this.label = label;
+        this.desc = desc;
+    }
+
+    public static String getDesc(Integer status) {
+        if (Objects.isNull(status)) {
+            return "";
+        }
+        for (CashEnum value : values()) {
+            if (status == value.getStatus()) {
+                return value.getDesc();
+            }
+        }
+        return "";
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+
+    public String getDesc() {
+        return desc;
+    }
+
+}

+ 9 - 1
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/constant/PayCenterEnum.java

@@ -12,8 +12,13 @@ import lombok.Getter;
 public enum PayCenterEnum {
     MEMBER_DETAIL("/v1/member/detail", "会员详情"),
     MEMBER_WALLET("/v1/member/wallet", "钱包清单"),
+    MEMBER_WALLET_V2("/v2/member/wallet", "钱包清单"),
+    MEMBER_GENERAL("/v2/wallet/general", "总览信息"),
+
     WITHDRAW_DETAIL("/v1/wallet/withdraw/detail", "提现详情"),
-    WITHDRAW_INDEX("/v1/wallet/withdraw/index", "提现清单"),
+    //    WITHDRAW_INDEX("/v1/wallet/withdraw/index", "提现清单"), 原接口
+    WITHDRAW_INDEX("/v2/wallet/withdraw/index", "提现清单"),
+    WITHDRAW_CATEGORY("/v2/wallet/withdraw/categories", "提现清单分类"),
     WITHDRAW_STATUS("/v1/wallet/withdraw/status", "订单状态"),
     WITHDRAW_CANCEL("/v1/wallet/withdraw/cancel", "取消提现"),
     WITHDRAW_TAKE("/v1/wallet/withdraw/take", "申请提现"),
@@ -27,6 +32,8 @@ public enum PayCenterEnum {
     ADVANCE_PAY_DETAIL("/v1/wallet/advancepay/detail", "预付订单详情"),
     ADVANCE_PAY_APPLY("/v1/wallet/advancepay/apply", "发起预付"),
     ADVANCE_PAY_INDEX("/v1/wallet/advancepay/index", "预付订单清单"),
+    ADVANCE_PAY_WALLETS("/v2/advancepay/wallets", "钱包预付列表"),
+    ADVANCE_PAY_RECEIVE("/v2/advancepay/receives", "钱包预收列表"),
     ADVANCE_PAY_STATUS("/v1/wallet/advancepay/statusCategory", "预付订单状态"),
     INDEX("/v1/index/index", "获取通道清单"),
     MEMBER_PAY_INDEX("/v1/member/pay/index", "订单记录"),
@@ -35,6 +42,7 @@ public enum PayCenterEnum {
     WALLET_FREEZE("/v1/wallet/freeze", "冻结资金"),
     WALLET_UNFREEZE("/v1/wallet/unfreeze", "解冻金额"),
     PAY_AGENT_PAY("/v1/pay/agent_pay", "清分"),
+    PAY_AGENT_PAY_V2("/v2/pay/agent_pay", "清分"),
     WALLET_INDEX("/v1/wallet/index", "创建钱包");
     private final String addr;
     private final String desc;

+ 53 - 0
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/constant/RefundEnum.java

@@ -0,0 +1,53 @@
+package com.sckw.payment.model.constant;
+
+import java.util.Objects;
+
+/**
+ * 钱包退款枚举类
+ * 1-申请退款 2-退款中 3-退款失败 4-退款驳回
+ * @author xucaiqin
+ * @date 2023-07-11 12:00:52
+ */
+public enum RefundEnum {
+    ALL(0, "全部", "0"),
+    APPLY(1, "申请退款", "1"),
+    REFUNDING(2, "退款中", "2"),
+    FAILED(3, "退款失败", "3"),
+    BACK(4, "退款驳回", "4");
+
+    private final int status;
+    private final String desc;
+    private final String label;
+
+    RefundEnum(int status, String desc, String label) {
+        this.status = status;
+        this.label = label;
+        this.desc = desc;
+    }
+
+    public static String getDesc(Integer status) {
+        if (Objects.isNull(status)) {
+            return "";
+        }
+        for (RefundEnum value : values()) {
+            if (status == value.getStatus()) {
+                return value.getDesc();
+            }
+        }
+        return "";
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+
+    public String getDesc() {
+        return desc;
+    }
+
+}

+ 7 - 2
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/CashPageReq.java

@@ -1,6 +1,7 @@
 package com.sckw.payment.model.vo.req;
 
 import com.sckw.core.model.vo.BasePara;
+import com.sckw.payment.model.constant.CashEnum;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -17,7 +18,11 @@ public class CashPageReq extends BasePara {
      * 支付通道 huifu
      */
     private String channel;
-
-    private String entName;
+    /**
+     * 提现状态
+     *
+     * @see CashEnum
+     */
+    private String status;
 
 }

+ 41 - 0
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/PrePay.java

@@ -0,0 +1,41 @@
+package com.sckw.payment.model.vo.req;
+
+import com.sckw.payment.model.vo.res.MoneyChange;
+import jakarta.validation.constraints.Digits;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.Size;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 新增预付参数
+ *
+ * @author xucaiqin
+ * @date 2023-08-29 09:14:04
+ */
+@Getter
+@Setter
+public class PrePay implements MoneyChange {
+    /**
+     * 支付通道 huifu
+     */
+    @NotBlank(message = "支付通道不能为空")
+    private String channel;
+
+    @NotBlank(message = "uid不能为空")
+    private String uid;
+
+    @NotBlank(message = "filter不能为空")
+    private String filter;
+
+    @Positive(message = "提现金额必须大于0")
+    @Digits(message = "小数位数过长或金额过大", integer = 10, fraction = 2)
+    private BigDecimal money;
+
+    @Size(message = "备注不能超过200字")
+    private String remark;
+
+}

+ 23 - 0
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/PrePayCheck.java

@@ -0,0 +1,23 @@
+package com.sckw.payment.model.vo.req;
+
+import jakarta.validation.constraints.NotBlank;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 预付钱包可用余额校验
+ *
+ * @author xucaiqin
+ * @date 2023-08-29 09:14:04
+ */
+@Getter
+@Setter
+public class PrePayCheck {
+    /**
+     * 支付通道 huifu
+     */
+    @NotBlank(message = "支付通道不能为空")
+    private String channel;
+    @NotBlank(message = "filter不能为空")
+    private String filter;
+}

+ 1 - 1
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/PrePayReq.java → sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/PrePayPage.java

@@ -12,7 +12,7 @@ import lombok.Setter;
  */
 @Getter
 @Setter
-public class PrePayReq extends BasePara {
+public class PrePayPage extends BasePara {
     /**
      * 支付通道 1
      */

+ 41 - 0
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/Refund.java

@@ -0,0 +1,41 @@
+package com.sckw.payment.model.vo.req;
+
+import com.sckw.payment.model.vo.res.MoneyChange;
+import jakarta.validation.constraints.Digits;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.Size;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 退款
+ *
+ * @author xucaiqin
+ * @date 2023-08-29 09:14:04
+ */
+@Getter
+@Setter
+public class Refund implements MoneyChange {
+    /**
+     * 支付通道 huifu
+     */
+    @NotBlank(message = "支付通道不能为空")
+    private String channel;
+
+    @NotBlank(message = "uid不能为空")
+    private String uid;
+
+    @NotBlank(message = "filter不能为空")
+    private String filter;
+
+    @Positive(message = "提现金额必须大于0")
+    @Digits(message = "小数位数过长或金额过大", integer = 10, fraction = 2)
+    private BigDecimal money;
+
+    @Size(message = "备注不能超过200字")
+    private String remark;
+
+}

+ 4 - 2
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/RefundReq.java

@@ -18,7 +18,9 @@ import java.math.BigDecimal;
  */
 @Getter
 @Setter
-public class RefundReq  implements MoneyChange {
+public class RefundReq implements MoneyChange {
+    @NotBlank(message = "当前企业不能为空")
+    private String uid;
     /**
      * 支付通道字典值
      */
@@ -26,7 +28,7 @@ public class RefundReq  implements MoneyChange {
     private String channel;
 
     @NotBlank(message = "合作企业不能为空")
-    private String entId;
+    private String filter;
 
     @Positive(message = "提现金额必须大于0")
     @Digits(message = "小数位数过长或金额过大", integer = 10, fraction = 2)

+ 41 - 0
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/req/TransferReq.java

@@ -0,0 +1,41 @@
+package com.sckw.payment.model.vo.req;
+
+import com.sckw.payment.model.vo.res.MoneyChange;
+import jakarta.validation.constraints.Digits;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.Size;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 转账
+ *
+ * @author xucaiqin
+ * @date 2023-08-29 09:14:04
+ */
+@Getter
+@Setter
+public class TransferReq implements MoneyChange {
+    /**
+     * 支付通道 huifu
+     */
+    @NotBlank(message = "支付通道不能为空")
+    private String channel;
+
+    @NotBlank(message = "uid不能为空")
+    private String uid;
+
+    @NotBlank(message = "filter不能为空")
+    private String filter;
+
+    @Positive(message = "提现金额必须大于0")
+    @Digits(message = "小数位数过长或金额过大", integer = 10, fraction = 2)
+    private BigDecimal money;
+
+    @Size(message = "备注不能超过200字")
+    private String remark;
+
+}

+ 27 - 6
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/res/FundVo.java

@@ -37,17 +37,38 @@ public class FundVo implements Serializable {
      * 往来单位名称
      */
     private String filterName;
-
-    private Long payMoney;
-    private Long cashMoney;
-    private Long refundMoney;
+    /**
+     * 充值中金额
+     */
+    private String chargingMoney;
+    /**
+     * 提现中金额
+     */
+    private String withdrawingMoney;
+    /**
+     * 退款中金额
+     */
+    private String refundMoney;
     /**
      * 可用余额
      */
-    private Long money;
+    private String money;
     /**
-     * 更新时间
+     * 总金额
+     */
+    private String totalMoney;
+    /**
+     * 操作
+     */
+    private String action;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间 todo-xcq 自我维护
      */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private LocalDateTime updateTime;
+
 }

+ 34 - 0
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/res/MorePageRes.java

@@ -0,0 +1,34 @@
+package com.sckw.payment.model.vo.res;
+
+import com.sckw.core.model.page.PageRes;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 返回的分页数据中,有额外需要返回的参数
+ *
+ * @author Aick Spt
+ * @date 2023-07-25 17:31
+ */
+@Getter
+@Setter
+public class MorePageRes<T> extends PageRes<T> {
+    private String money;
+
+    public MorePageRes(int page, int pageSize, long size, int pages, List<T> list, String money) {
+        super(page, pageSize, size, pages, list);
+        this.money = money;
+    }
+
+    public MorePageRes(int page, int pageSize, List<T> list, String money) {
+        this.page = page;
+        this.pageSize = pageSize;
+        this.size = list.size();
+        this.pages = list.size() / pageSize + 1;
+        this.money = money;
+        this.list = list.stream().skip((long) (page - 1) * pageSize).limit(pageSize).toList();
+    }
+
+}

+ 3 - 1
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/model/vo/res/WalletDetail.java

@@ -1,10 +1,12 @@
 package com.sckw.payment.model.vo.res;
 
+import java.util.List;
+
 /**
  * 钱包信息
  *
  * @author xucaiqin
  * @date 2023-08-28 15:43:49
  */
-public record WalletDetail(String entName, String money, String moneyYuan, int channel) {
+public record WalletDetail(String entName, String money, String moneyYuan, int channel, List<String> channels) {
 }

+ 131 - 8
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/service/PayCenterService.java

@@ -12,6 +12,7 @@ import com.sckw.payment.api.model.dto.common.BusinessNo;
 import com.sckw.payment.api.model.dto.common.R;
 import com.sckw.payment.api.model.dto.page.CashPage;
 import com.sckw.payment.api.model.dto.page.PrePayIndexPage;
+import com.sckw.payment.api.model.dto.page.PrePayWalletPage;
 import com.sckw.payment.api.model.dto.page.RecordPage;
 import com.sckw.payment.model.constant.PayCenterEnum;
 import jakarta.validation.constraints.NotBlank;
@@ -53,7 +54,7 @@ public class PayCenterService {
     }
 
     private String getHttp(PayCenterEnum payCenterEnum, Map<String, Object> para) {
-        log.info("{}入参->{}", payCenterEnum.getDesc(), JSONObject.toJSONString(para));
+        log.debug("{}入参->{}", payCenterEnum.getDesc(), JSONObject.toJSONString(para));
         OkHttpUtils okHttpUtils = OkHttpUtils.builder().url(payCenterAddr + payCenterEnum.getAddr());
         if (!CollectionUtils.isEmpty(para)) {
             for (Map.Entry<String, Object> p : para.entrySet()) {
@@ -88,12 +89,12 @@ public class PayCenterService {
             log.error("中台服务异常", e.getCause());
             throw new RuntimeException("支付服务异常!");
         }
-        log.info("{}返回值->{}", payCenterEnum.getDesc(), sync);
+        log.debug("{}返回值->{}", payCenterEnum.getDesc(), sync);
         return changeRes(sync);
     }
 
     private String postHttp(PayCenterEnum payCenterEnum, Map<String, Object> para) {
-        log.info("{}入参->{}", payCenterEnum.getDesc(), JSONObject.toJSONString(para));
+        log.debug("{}入参->{}", payCenterEnum.getDesc(), JSONObject.toJSONString(para));
         OkHttpUtils okHttpUtils = OkHttpUtils.builder().url(payCenterAddr + payCenterEnum.getAddr());
         if (!CollectionUtils.isEmpty(para)) {
             for (Map.Entry<String, Object> p : para.entrySet()) {
@@ -127,7 +128,7 @@ public class PayCenterService {
             log.error("中台服务异常", e.getCause());
             throw new RuntimeException("支付服务异常!");
         }
-        log.info("{}返回值->{}", payCenterEnum.getDesc(), sync);
+        log.debug("{}返回值->{}", payCenterEnum.getDesc(), sync);
         return changeRes(sync);
     }
 
@@ -159,6 +160,21 @@ public class PayCenterService {
         });
     }
 
+
+    /**
+     * 总览信息
+     *
+     * @param uid
+     * @return
+     */
+    public R<WalletOverview> general(String uid) {
+        String sync = getHttp(PayCenterEnum.MEMBER_GENERAL, new HashMap<>() {{
+            put("uid", uid);
+        }});
+        return JSONObject.parseObject(sync, new TypeReference<>() {
+        });
+    }
+
     /**
      * 钱包清单
      *
@@ -179,6 +195,27 @@ public class PayCenterService {
         return parseArray(sync, WalletDto.class);
     }
 
+    /**
+     * 钱包清单 v2
+     *
+     * @param uid
+     * @param channel
+     * @param filter
+     * @return
+     */
+    public R<Wallet> walletSum(@NotNull String uid, ChannelEnum channel, String filter) {
+        if (StringUtils.isBlank(uid)) {
+            throw new BusinessException("提现用户不能为空");
+        }
+        String sync = getHttp(PayCenterEnum.MEMBER_WALLET_V2, new HashMap<>() {{
+            put("uid", uid);
+            put("channel", Objects.isNull(channel) ? "" : channel);
+            put("filter", filter);
+        }});
+        return JSONObject.parseObject(sync, new TypeReference<>() {
+        });
+    }
+
     /**
      * 提现详情
      *
@@ -212,13 +249,10 @@ public class PayCenterService {
      * @param pageSize
      * @return
      */
-    public R<CashPage> withdrawIndex(String uid, ChannelEnum channel, Integer page, Integer pageSize) {
+    public R<CashPage> withdrawIndex(String uid, ChannelEnum channel, String status, Integer page, Integer pageSize) {
         if (StringUtils.isBlank(uid)) {
             throw new BusinessException("用户不能为空");
         }
-        if (Objects.isNull(channel)) {
-            throw new BusinessException("支付渠道不能为空");
-        }
         if (Objects.isNull(page)) {
             page = 1;
         }
@@ -232,11 +266,29 @@ public class PayCenterService {
             put("channel", channel);
             put("page", finalPage);
             put("pageSize", finalPageSize);
+            put("status", status);
         }});
         return JSONObject.parseObject(sync, new TypeReference<>() {
         });
     }
 
+    /**
+     * 提现类型分类统计
+     *
+     * @param uid
+     * @return
+     */
+    public R<List<CashCount>> withdrawCategory(String uid, ChannelEnum channel) {
+        if (StringUtils.isBlank(uid)) {
+            throw new BusinessException("用户不能为空");
+        }
+        String sync = getHttp(PayCenterEnum.WITHDRAW_CATEGORY, new HashMap<>() {{
+            put("uid", uid);
+            put("channel", channel);
+        }});
+        return parseArray(sync, CashCount.class);
+    }
+
     /**
      * 订单状态
      *
@@ -518,6 +570,50 @@ public class PayCenterService {
         });
     }
 
+    /**
+     * 钱包预付统计列表
+     *
+     * @param uid
+     * @param channel
+     * @param filter
+     * @param page
+     * @param pageSize
+     * @return
+     */
+    public R<PrePayWalletPage> advancePayWALLET(String uid, ChannelEnum channel, String filter, Integer page, Integer pageSize) {
+        String sync = getHttp(PayCenterEnum.ADVANCE_PAY_WALLETS, new HashMap<>() {{
+            put("uid", uid);
+            put("channel", channel);
+            put("filter", filter);
+            put("page", page);
+            put("pageSize", pageSize);
+        }});
+        return JSONObject.parseObject(sync, new TypeReference<>() {
+        });
+    }
+
+    /**
+     * 钱包预收列表
+     *
+     * @param uid
+     * @param channel
+     * @param filter
+     * @param page
+     * @param pageSize
+     * @return
+     */
+    public R<PrePayWalletPage> advancePayReceive(String uid, ChannelEnum channel, String filter, Integer page, Integer pageSize) {
+        String sync = getHttp(PayCenterEnum.ADVANCE_PAY_RECEIVE, new HashMap<>() {{
+            put("uid", uid);
+            put("channel", channel);
+            put("filter", filter);
+            put("page", page);
+            put("pageSize", pageSize);
+        }});
+        return JSONObject.parseObject(sync, new TypeReference<>() {
+        });
+    }
+
     /**
      * 预付订单状态
      *
@@ -639,6 +735,7 @@ public class PayCenterService {
      * 清分
      * 中台逻辑:
      * 先从预付金额中进行扣除,然后金额不够的情况下在调用三方接口进行清分,然后进行记账
+     * 因为预付业务实际就是真实的清分业务,所以先判断预付金额是否足够
      *
      * @param buyUid
      * @param sellUid
@@ -661,6 +758,32 @@ public class PayCenterService {
         });
     }
 
+    /**
+     * 清分
+     *
+     * @param buyUid 付款方uid
+     * @param sellUid 收款方
+     * @param channel
+     * @param money 总清分金额
+     * @param batchPayList 收款方集合
+     * @param businessNo 流水号
+     * @param payType 支付类型 0-默认 1-仅预付支付 2-仅余额支付
+     * @return
+     */
+    public R<BusinessNo> payAgentPayV2(String buyUid, String sellUid, ChannelEnum channel, Long money, List<PatchPay> batchPayList, String businessNo, String payType) {
+        String sync = postHttp(PayCenterEnum.PAY_AGENT_PAY_V2, new HashMap<>() {{
+            put("buy_uid", buyUid);
+            put("sell_uid", sellUid);
+            put("channel", channel);
+            put("money", money);
+            put("batch_pay_list", JSONObject.toJSONString(batchPayList));
+            put("business_no", businessNo);
+            put("pay_type", payType);
+        }});
+        return JSONObject.parseObject(sync, new TypeReference<>() {
+        });
+    }
+
     /**
      * 创建钱包
      *

+ 435 - 82
sckw-modules/sckw-payment/src/main/java/com/sckw/payment/service/WalletService.java

@@ -1,17 +1,29 @@
 package com.sckw.payment.service;
 
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.sckw.core.common.enums.NumberConstant;
 import com.sckw.core.exception.BusinessException;
 import com.sckw.core.model.page.PageRes;
 import com.sckw.core.utils.CollectionUtils;
+import com.sckw.core.utils.IdWorker;
+import com.sckw.core.utils.OrderUtils;
 import com.sckw.core.web.context.LoginUserHolder;
+import com.sckw.manage.api.RemoteManageService;
+import com.sckw.manage.api.model.dto.res.FindEntCooperateResVo;
 import com.sckw.payment.api.model.constant.ChannelEnum;
-import com.sckw.payment.api.model.dto.Order;
-import com.sckw.payment.api.model.dto.WalletDto;
+import com.sckw.payment.api.model.dto.*;
+import com.sckw.payment.api.model.dto.common.BusinessNo;
 import com.sckw.payment.api.model.dto.common.R;
 import com.sckw.payment.api.model.dto.page.CashPage;
-import com.sckw.payment.api.model.dto.page.PrePayIndexPage;
+import com.sckw.payment.api.model.dto.page.PrePayWalletPage;
+import com.sckw.payment.dao.KwpWalletRefundMapper;
+import com.sckw.payment.job.AsyncPool;
+import com.sckw.payment.model.KwpWalletRefund;
+import com.sckw.payment.model.constant.RefundEnum;
 import com.sckw.payment.model.vo.req.*;
 import com.sckw.payment.model.vo.res.FundVo;
+import com.sckw.payment.model.vo.res.MorePageRes;
 import com.sckw.payment.model.vo.res.WalletDetail;
 import com.sckw.system.api.RemoteSystemService;
 import com.sckw.system.api.model.dto.res.EntCacheResDto;
@@ -19,15 +31,17 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
+import java.text.DecimalFormat;
+import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * 钱包
@@ -41,12 +55,84 @@ import java.util.concurrent.TimeUnit;
 public class WalletService {
     private final PayCenterService payCenterService;
     private final KwpWalletRelationService walletRelationService;
-    private final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 2, TimeUnit.MINUTES, new LinkedBlockingQueue<>(12));
+    private final KwpWalletRefundMapper kwpWalletRefundMapper;
     @DubboReference(version = "1.0.0", group = "design", check = false)
     private RemoteSystemService remoteSystemService;
+    @DubboReference(version = "1.0.0", group = "design", check = false)
+    private RemoteManageService remoteManageService;
+
+    /**
+     * 通过中台用户id转为企业名称
+     *
+     * @param id 中台用户id
+     * @return
+     */
+    private String getFirmName(String id) {
+        if (StringUtils.isBlank(id)) {
+            return "";
+        }
+        Long ent = walletRelationService.getEnt(id);
+        if (Objects.nonNull(ent)) {
+            EntCacheResDto entCacheResDto = remoteSystemService.queryEntCacheById(ent);
+            if (Objects.nonNull(entCacheResDto)) {
+                return entCacheResDto.getFirmName();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 通过企业名称查询关联的中台用户id
+     *
+     * @param entName
+     * @return
+     */
+    private List<String> findFilter(String entName) {
+        if (StringUtils.isNotBlank(entName)) {
+            Long entId = LoginUserHolder.getEntId();
+            List<FindEntCooperateResVo> allCooperateEnt = remoteManageService.findAllCooperateEnt(entId);
+            if (!CollectionUtils.isEmpty(allCooperateEnt)) {
+                List<Long> collect = allCooperateEnt.stream().filter(a -> StringUtils.contains(a.getEntName(), entName)).map(FindEntCooperateResVo::getEntId).collect(Collectors.toList());
+                List<String> res = new ArrayList<>();
+                for (Long aLong : collect) {
+                    String relation = walletRelationService.getRelation(aLong);
+                    if (StringUtils.isNotBlank(relation) && !res.contains(relation)) {
+                        res.add(relation);
+                    }
+                }
+                return res;
+            }
+        }
+        return new ArrayList<>();
+    }
+
+    /**
+     * 通过企业名称查询关联的中台用户id
+     *
+     * @param entName
+     * @return "uid,uid,uid"
+     */
+    private String findFilterStr(String entName) {
+        List<String> filter = findFilter(entName);
+        return StringUtils.join(filter, ",");
+    }
+
+    /**
+     * 金额转元并转字符串
+     *
+     * @param money
+     * @return
+     */
+    private String dfMoney(Long money) {
+        if (Objects.isNull(money)) {
+            return "0.00";
+        }
+        DecimalFormat df = new DecimalFormat("0.00");
+        return df.format(money / 100.0D);
+    }
 
     /**
-     * 查询企业钱包总览信息
+     * 钱包总览信息
      *
      * @return
      */
@@ -56,15 +142,12 @@ public class WalletService {
         if (StringUtils.isBlank(relation)) {
             throw new BusinessException("暂未开通电子钱包");
         }
-        R<List<WalletDto>> wallet = payCenterService.wallet(relation, null, "");
-        long sum = 0;
+        R<WalletOverview> wallet = payCenterService.general(relation);
         if (wallet.getStatus()) {
-            List<WalletDto> data = CollectionUtils.isEmpty(wallet.getData()) ? new ArrayList<>() : wallet.getData();
-            for (WalletDto datum : data) {
-                sum += datum.getMoney();
-            }
+            WalletOverview data = wallet.getData();
+            return new WalletDetail(LoginUserHolder.getEntName(), String.valueOf(data.getTotalMoney()), String.valueOf(data.getTotalMoney() / 100D), data.getChannelTotal(), data.getChannels());
         }
-        return new WalletDetail(LoginUserHolder.getEntName(), String.valueOf(sum), String.valueOf(sum / 100.0D), 0);
+        return new WalletDetail(LoginUserHolder.getEntName(), "-", "-", 0, new ArrayList<>());
     }
 
     /**
@@ -73,9 +156,13 @@ public class WalletService {
      * @return
      */
     public Object walletDetail(WalletDetailReq walletDetailReq) {
+        log.info("查询资金明细:{}", JSONObject.toJSONString(walletDetailReq));
         Long entId = LoginUserHolder.getEntId();
-        String entName = walletDetailReq.getEntName();
-        //todo-xcq 确认下拉选规则参数
+        //查询我方企业开通的渠道
+        String relation = walletRelationService.getRelation(entId);
+        if (StringUtils.isBlank(relation)) {
+            return PageRes.handPage(walletDetailReq.getPage(), walletDetailReq.getPageSize(), new ArrayList<>());
+        }
         ChannelEnum channelEnum = null;
         if (StringUtils.isNotBlank(walletDetailReq.getChannel())) {
             channelEnum = ChannelEnum.getByValue(walletDetailReq.getChannel());
@@ -83,40 +170,40 @@ public class WalletService {
                 throw new BusinessException("支付通道不存在");
             }
         }
-        //查询我方企业开通的渠道
-        String relation = walletRelationService.getRelation(entId);
-        if (StringUtils.isBlank(relation)) {
-            throw new BusinessException("暂未开通电子钱包");
-        }
         List<WalletDto> res = new ArrayList<>();
-        List<Long> list = new ArrayList<>();
-        //筛选企业名称
+        long sum = 0L;
+        //筛选企业
+        String entName = walletDetailReq.getEntName();
         if (StringUtils.isNotBlank(entName)) {
-            List<EntCacheResDto> entCacheResDto = remoteSystemService.queryEntCacheByName(entName);
+            List<String> filterList = findFilter(entName);
             //未筛选出数据
-            if (CollectionUtils.isEmpty(entCacheResDto)) {
+            if (CollectionUtils.isEmpty(filterList)) {
                 return PageRes.handPage(walletDetailReq.getPage(), walletDetailReq.getPageSize(), new ArrayList<>());
             }
-            list = entCacheResDto.stream().map(EntCacheResDto::getId).toList();
-        }
-
-        //搜索指定往来单位
-        if (!CollectionUtils.isEmpty(list)) {
-            for (Long aLong : list) {
-                R<List<WalletDto>> wallet = payCenterService.wallet(relation, channelEnum, String.valueOf(aLong));
-                if (wallet.getStatus()) {
-                    List<WalletDto> data = wallet.getData();
-                    res.addAll(data);
+            for (String filter : filterList) {
+                R<Wallet> walletR = payCenterService.walletSum(relation, channelEnum, filter);
+                if (walletR.getStatus()) {
+                    Wallet data = walletR.getData();
+                    sum += data.getTotalMoney();
+                    List<WalletDto> rows = data.getRows();
+                    if (CollectionUtils.isEmpty(rows)) {
+                        continue;
+                    }
+                    res.addAll(rows);
                 }
             }
         } else {
             //不搜索往来单位
-            R<List<WalletDto>> wallet = payCenterService.wallet(relation, channelEnum, "");
+            R<Wallet> wallet = payCenterService.walletSum(relation, channelEnum, "");
             if (wallet.getStatus()) {
-                List<WalletDto> data = wallet.getData();
-                res.addAll(data);
+                Wallet data = wallet.getData();
+                sum += data.getTotalMoney();
+                if (!CollectionUtils.isEmpty(data.getRows())) {
+                    res.addAll(data.getRows());
+                }
             }
         }
+
         List<FundVo> vo = new ArrayList<>();
         FundVo fundVo;
 
@@ -125,9 +212,17 @@ public class WalletService {
             fundVo = new FundVo();
             BeanUtils.copyProperties(re, fundVo);
             fundVo.setChannelLabel(ChannelEnum.getDesc(re.getChannel()));
+            fundVo.setUidName(getFirmName(re.getUid()));
+            fundVo.setFilterName(getFirmName(re.getFilter()));
+            fundVo.setMoney(dfMoney(re.getMoney()));
+            fundVo.setWithdrawingMoney(dfMoney(re.getWithdrawingMoney()));
+            fundVo.setChargingMoney(dfMoney(re.getChargingMoney()));
+            fundVo.setTotalMoney(dfMoney(re.getTotalMoney()));
+//            fundVo.setRefundMoney(dfMoney(re.getMoney()));
             vo.add(fundVo);
         }
-        return PageRes.handPage(walletDetailReq.getPage(), walletDetailReq.getPageSize(), vo);
+        DecimalFormat df = new DecimalFormat("0.00");
+        return new MorePageRes<>(walletDetailReq.getPage(), walletDetailReq.getPageSize(), vo, df.format(sum / 100.0D));
     }
 
 
@@ -137,6 +232,7 @@ public class WalletService {
      * @return
      */
     public Object addWallet(AddWalletReq addWalletReq) {
+        log.info("新增账目:{}", JSONObject.toJSONString(addWalletReq));
         Long entId1 = LoginUserHolder.getEntId();
         String uid = walletRelationService.getRelation(entId1);
         if (StringUtils.isBlank(uid)) {
@@ -147,22 +243,23 @@ public class WalletService {
         if (StringUtils.isBlank(filter)) {
             throw new BusinessException("合作单位暂未开通电子钱包");
         }
-        ChannelEnum channelEnum = ChannelEnum.getByValue(addWalletReq.getChannel());
+        ChannelEnum channelEnum = ChannelEnum.getByChannel(addWalletReq.getChannel());
         if (Objects.isNull(channelEnum)) {
-            throw new BusinessException("支付通道不能为空");
+            throw new BusinessException("支付通道不存在");
         }
-
         //1.开通钱包
         R<Object> objectR = payCenterService.walletIndex(uid, channelEnum, filter, "");
+        log.info("新增账目-开通钱包:{}", JSONObject.toJSONString(objectR));
         if (!objectR.getStatus()) {
             throw new BusinessException(StringUtils.isBlank(objectR.getMsg()) ? "钱包开通失败" : objectR.getMsg());
         }
-        //2.发起预支付
-        R<Order> orderR = payCenterService.advancePayApply("", channelEnum, filter, addWalletReq.bigMoney(addWalletReq.getMoney()));
-        if (!orderR.getStatus()) {
-            throw new BusinessException(StringUtils.isBlank(orderR.getMsg()) ? "预支付失败" : orderR.getMsg());
+        //2.发起充值
+        R<PayIndex> payIndexR = payCenterService.payIndex(uid, filter, channelEnum, addWalletReq.bigMoney(addWalletReq.getMoney()));
+        log.info("新增账目-发起充值:{}", JSONObject.toJSONString(payIndexR));
+        if (!payIndexR.getStatus()) {
+            throw new BusinessException(StringUtils.isBlank(payIndexR.getMsg()) ? "充值失败" : payIndexR.getMsg());
         }
-        return orderR.getData();
+        return payIndexR.getData();
     }
 
     /**
@@ -171,6 +268,7 @@ public class WalletService {
      * @return
      */
     public Object addWalletMoney(AddWalletReq addWalletReq) {
+        log.info("账目充值:{}", JSONObject.toJSONString(addWalletReq));
         Long entId1 = LoginUserHolder.getEntId();
         String uid = walletRelationService.getRelation(entId1);
         if (StringUtils.isBlank(uid)) {
@@ -183,31 +281,63 @@ public class WalletService {
         }
         ChannelEnum channelEnum = ChannelEnum.getByValue(addWalletReq.getChannel());
         if (Objects.isNull(channelEnum)) {
-            throw new BusinessException("支付通道不能为空");
+            throw new BusinessException("支付通道不存在");
         }
-        //发起预支付
-        R<Order> orderR = payCenterService.advancePayApply(uid, channelEnum, filter, addWalletReq.bigMoney(addWalletReq.getMoney()));
-        if (!orderR.getStatus()) {
-            throw new BusinessException(StringUtils.isBlank(orderR.getMsg()) ? "预支付失败" : orderR.getMsg());
+        //发起充值
+        R<PayIndex> payIndexR = payCenterService.payIndex(uid, filter, channelEnum, addWalletReq.bigMoney(addWalletReq.getMoney()));
+        log.info("账目充值-发起充值:{}", JSONObject.toJSONString(payIndexR));
+        if (!payIndexR.getStatus()) {
+            throw new BusinessException(StringUtils.isBlank(payIndexR.getMsg()) ? "充值失败" : payIndexR.getMsg());
         }
-        return orderR.getData();
+        return payIndexR.getData();
     }
 
     /**
      * 提现
+     * 重新提现:只针对汇付
      * 1.余额转出
      * 2.申请提现
      *
      * @return
      */
     public Object cashOUt(CashWalletReq cashWalletReq) {
+        log.info("提现:{}", JSONObject.toJSONString(cashWalletReq));
         ChannelEnum byChannel = ChannelEnum.getByChannel(cashWalletReq.getChannel());
+        if (Objects.isNull(byChannel)) {
+            throw new BusinessException("支付通道不存在");
+        }
         //余额转出
         R<Object> transfer = payCenterService.transfer(cashWalletReq.getUid(), cashWalletReq.getFilter(), byChannel, cashWalletReq.bigMoney(cashWalletReq.getMoney()));
+        log.info("提现-余额转出:{}", JSONObject.toJSONString(transfer));
         if (!transfer.getStatus()) {
             throw new BusinessException(StringUtils.isNotBlank(transfer.getMsg()) ? transfer.getMsg() : "提现异常");
         }
+        //申请提现
         R<Order> orderR = payCenterService.withdrawTake(cashWalletReq.getUid(), byChannel, cashWalletReq.bigMoney(cashWalletReq.getMoney()), cashWalletReq.getRemark());
+        log.info("提现-申请提现:{}", JSONObject.toJSONString(orderR));
+        if (!orderR.getStatus()) {
+            throw new BusinessException(StringUtils.isNotBlank(orderR.getMsg()) ? orderR.getMsg() : "申请提现异常");
+        }
+        return orderR.getData();
+    }
+
+    /**
+     * 重新提现
+     * 重新提现:只针对汇付
+     * 1.余额转出
+     * 2.申请提现
+     *
+     * @return
+     */
+    public Object reCashOUt(CashWalletReq cashWalletReq) {
+        log.info("重新提现:{}", JSONObject.toJSONString(cashWalletReq));
+        ChannelEnum byChannel = ChannelEnum.getByChannel(cashWalletReq.getChannel());
+        if (Objects.isNull(byChannel)) {
+            throw new BusinessException("支付通道不存在");
+        }
+        //申请提现
+        R<Order> orderR = payCenterService.withdrawTake(cashWalletReq.getUid(), byChannel, cashWalletReq.bigMoney(cashWalletReq.getMoney()), cashWalletReq.getRemark());
+        log.info("重新提现-申请提现:{}", JSONObject.toJSONString(orderR));
         if (!orderR.getStatus()) {
             throw new BusinessException(StringUtils.isNotBlank(orderR.getMsg()) ? orderR.getMsg() : "申请提现异常");
         }
@@ -219,8 +349,24 @@ public class WalletService {
      *
      * @return
      */
-    public Object transfer() {
-        return null;
+    public Object transfer(TransferReq transferReq) {
+        log.info("转账:{}", JSONObject.toJSONString(transferReq));
+        ChannelEnum channelEnum = ChannelEnum.getByChannel(transferReq.getChannel());
+        if (Objects.isNull(channelEnum)) {
+            throw new BusinessException("支付通道不存在");
+        }
+        List<PatchPay> list = new ArrayList<>();
+        PatchPay patchPay = new PatchPay();
+        patchPay.setUid(transferReq.getFilter());
+        patchPay.setMoney(transferReq.bigMoney(transferReq.getMoney()));
+        patchPay.setRemark(transferReq.getRemark());
+        list.add(patchPay);
+        R<BusinessNo> businessNoR1 = payCenterService.payAgentPayV2(transferReq.getUid(), transferReq.getFilter(),
+                channelEnum, transferReq.bigMoney(transferReq.getMoney()), list, OrderUtils.generateOrderNo("TF"), "2");
+        if (!businessNoR1.getStatus()) {
+            throw new BusinessException(StringUtils.isNotBlank(businessNoR1.getMsg()) ? businessNoR1.getMsg() : "转账失败");
+        }
+        return businessNoR1.getData();
     }
 
 
@@ -230,30 +376,54 @@ public class WalletService {
      * @return
      */
     public Object cashList(CashPageReq cashPageReq) {
+        log.info("提现记录:{}", JSONObject.toJSONString(cashPageReq));
         Long entId = LoginUserHolder.getEntId();
         String uid = walletRelationService.getRelation(entId);
         if (StringUtils.isBlank(uid)) {
-            return null;
+            return PageRes.handPage(cashPageReq.getPage(), cashPageReq.getPageSize(), new ArrayList<>());
         }
         ChannelEnum channelEnum = null;
         if (StringUtils.isNotBlank(cashPageReq.getChannel())) {
             channelEnum = ChannelEnum.getByValue(cashPageReq.getChannel());
             if (Objects.isNull(channelEnum)) {
-                throw new BusinessException("选择渠道异常");
+                throw new BusinessException("支付通道不存在");
             }
         }
-        String entName = cashPageReq.getEntName();
-        if (StringUtils.isNotBlank(entName)) {
-            //todo 转换企业名称为filter
-
-        }
         //查询中台接口
-        R<CashPage> cashPageR = payCenterService.withdrawIndex(uid, channelEnum, cashPageReq.getPage(), cashPageReq.getPageSize());
+        R<CashPage> cashPageR = payCenterService.withdrawIndex(uid, channelEnum, cashPageReq.getStatus(), cashPageReq.getPage(), cashPageReq.getPageSize());
         if (!cashPageR.getStatus()) {
-            return null;
+            return new MorePageRes<>(cashPageReq.getPage(), cashPageReq.getPageSize(), 0, 0, new ArrayList<>(), "0.00");
         }
+        CashPage data = cashPageR.getData();
         //组装数据
-        return cashPageR.getData();
+        return new MorePageRes<>(cashPageReq.getPage(), cashPageReq.getPageSize(), data.getTotal(), (int) (data.getTotal() / cashPageReq.getPageSize() + 1), data.getRows(), String.valueOf(Long.parseLong(data.getTotalWithdrawMoney()) / 100.0D));
+    }
+
+    /**
+     * 提现分类页签统计
+     *
+     * @param cashPageReq
+     * @return
+     */
+    public Object cashCount(CashPageReq cashPageReq) {
+        log.info("提现分类页签统计:{}", JSONObject.toJSONString(cashPageReq));
+        Long entId = LoginUserHolder.getEntId();
+        String uid = walletRelationService.getRelation(entId);
+        if (StringUtils.isBlank(uid)) {
+            return null;
+        }
+        ChannelEnum channelEnum = null;
+        if (StringUtils.isNotBlank(cashPageReq.getChannel())) {
+            channelEnum = ChannelEnum.getByValue(cashPageReq.getChannel());
+            if (Objects.isNull(channelEnum)) {
+                throw new BusinessException("支付通道不存在");
+            }
+        }
+        R<List<CashCount>> listR = payCenterService.withdrawCategory(uid, channelEnum);
+        if (listR.getStatus()) {
+            return listR.getData();
+        }
+        return new ArrayList<>();
     }
 
     /**
@@ -261,28 +431,93 @@ public class WalletService {
      *
      * @return
      */
-    public Object prePayList(PrePayReq prePayReq) {
+    public Object prePayList(PrePayPage prePayPage) {
         Long entId = LoginUserHolder.getEntId();
         String uid = walletRelationService.getRelation(entId);
         if (StringUtils.isBlank(uid)) {
             return null;
         }
         ChannelEnum channelEnum = null;
-        if (StringUtils.isNotBlank(prePayReq.getChannel())) {
-            channelEnum = ChannelEnum.getByValue(prePayReq.getChannel());
+        if (StringUtils.isNotBlank(prePayPage.getChannel())) {
+            channelEnum = ChannelEnum.getByValue(prePayPage.getChannel());
             if (Objects.isNull(channelEnum)) {
-                throw new BusinessException("选择渠道异常");
+                throw new BusinessException("支付通道异常");
             }
         }
-        String entName = prePayReq.getEntName();
+        String entName = prePayPage.getEntName();
+        String filter = "";
+        //筛选企业名称
         if (StringUtils.isNotBlank(entName)) {
-            //todo 转换企业名称为 filter
+            filter = findFilterStr(entName);
+        }
+        // 查询预付数据
+        R<PrePayWalletPage> prePayIndexPageR = payCenterService.advancePayWALLET(uid, channelEnum, filter, prePayPage.getPage(), prePayPage.getPageSize());
+        if (prePayIndexPageR.getStatus()) {
+            PrePayWalletPage data = prePayIndexPageR.getData();
+            return new PageRes<>(prePayPage.getPage(), prePayPage.getPageSize(), data.getTotal(), (int) (data.getTotal() / prePayPage.getPageSize() + 1), data.getRows());
+        }
+        return new PageRes<>(prePayPage.getPage(), prePayPage.getPageSize(), 0, 0, new ArrayList<>());
+
+    }
 
+    /**
+     * 预收列表
+     *
+     * @param prePayPage
+     * @return
+     */
+    public Object preReceiveList(PrePayPage prePayPage) {
+        Long entId = LoginUserHolder.getEntId();
+        String uid = walletRelationService.getRelation(entId);
+        if (StringUtils.isBlank(uid)) {
+            return null;
+        }
+        ChannelEnum channelEnum = null;
+        if (StringUtils.isNotBlank(prePayPage.getChannel())) {
+            channelEnum = ChannelEnum.getByValue(prePayPage.getChannel());
+            if (Objects.isNull(channelEnum)) {
+                throw new BusinessException("支付通道异常");
+            }
+        }
+        String entName = prePayPage.getEntName();
+        String filter = "";
+        //筛选企业名称
+        if (StringUtils.isNotBlank(entName)) {
+            filter = findFilterStr(entName);
         }
-        //
-        R<PrePayIndexPage> prePayIndexPageR = payCenterService.advancePayIndex(uid, channelEnum, "", prePayReq.getPage(), prePayReq.getPageSize());
+        // 预收列表
+        R<PrePayWalletPage> prePayIndexPageR = payCenterService.advancePayReceive(uid, channelEnum, filter, prePayPage.getPage(), prePayPage.getPageSize());
+        if (prePayIndexPageR.getStatus()) {
+            PrePayWalletPage data = prePayIndexPageR.getData();
+            return new PageRes<>(prePayPage.getPage(), prePayPage.getPageSize(), data.getTotal(), (int) (data.getTotal() / prePayPage.getPageSize() + 1), data.getRows());
+        }
+        return new PageRes<>(prePayPage.getPage(), prePayPage.getPageSize(), 0, 0, new ArrayList<>());
+    }
 
-        return null;
+    /**
+     * 预付校验
+     *
+     * @param prePayCheck
+     * @return
+     */
+    public Object prePayCheck(PrePayCheck prePayCheck) {
+        String uid = walletRelationService.getRelation(LoginUserHolder.getEntId());
+        if (StringUtils.isBlank(uid)) {
+            throw new BusinessException("您暂未开通电子钱包");
+        }
+        ChannelEnum channelEnum = ChannelEnum.getByValue(prePayCheck.getChannel());
+        if (Objects.isNull(channelEnum)) {
+            throw new BusinessException("支付通道不存在");
+        }
+        R<WalletInfo> walletInfoR = payCenterService.totalInfo(uid, channelEnum, prePayCheck.getFilter());
+        if (!walletInfoR.getStatus()) {
+            throw new BusinessException(StringUtils.isNotBlank(walletInfoR.getMsg()) ? walletInfoR.getMsg() : "未找到交易方");
+        }
+        WalletInfo data = walletInfoR.getData();
+        if (Objects.isNull(data)) {
+            throw new BusinessException("不存在交易");
+        }
+        return data;
     }
 
     /**
@@ -290,8 +525,21 @@ public class WalletService {
      *
      * @return
      */
-    public Object addPrePay() {
-        return null;
+    public Object addPrePay(PrePay prePay) {
+        String uid = walletRelationService.getRelation(LoginUserHolder.getEntId());
+        if (StringUtils.isBlank(uid)) {
+            throw new BusinessException("您暂未开通电子钱包");
+        }
+        ChannelEnum channelEnum = ChannelEnum.getByValue(prePay.getChannel());
+        if (Objects.isNull(channelEnum)) {
+            throw new BusinessException("支付通道不存在");
+        }
+
+        R<Order> orderR = payCenterService.advancePayApply(prePay.getUid(), channelEnum, prePay.getFilter(), prePay.bigMoney(prePay.getMoney()));
+        if (!orderR.getStatus()) {
+            throw new BusinessException(StringUtils.isNotBlank(orderR.getMsg()) ? orderR.getMsg() : "预付失败");
+        }
+        return orderR.getData();
     }
 
     /**
@@ -299,8 +547,21 @@ public class WalletService {
      *
      * @return
      */
-    public Object prePayAppend() {
-        return null;
+    public Object prePayAppend(PrePay prePay) {
+        String uid = walletRelationService.getRelation(LoginUserHolder.getEntId());
+        if (StringUtils.isBlank(uid)) {
+            throw new BusinessException("您暂未开通电子钱包");
+        }
+        ChannelEnum channelEnum = ChannelEnum.getByValue(prePay.getChannel());
+        if (Objects.isNull(channelEnum)) {
+            throw new BusinessException("支付通道不存在");
+        }
+
+        R<Order> orderR = payCenterService.advancePayApply(prePay.getUid(), channelEnum, prePay.getFilter(), prePay.bigMoney(prePay.getMoney()));
+        if (!orderR.getStatus()) {
+            throw new BusinessException(StringUtils.isNotBlank(orderR.getMsg()) ? orderR.getMsg() : "预付失败");
+        }
+        return orderR.getData();
     }
 
     /**
@@ -309,16 +570,108 @@ public class WalletService {
      * @return
      */
     public Object applyRefund(RefundReq refundReq) {
-        return null;
+        LambdaQueryWrapper<KwpWalletRefund> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(KwpWalletRefund::getChannel, refundReq.getChannel());
+        wrapper.eq(KwpWalletRefund::getUid, refundReq.getUid()).eq(KwpWalletRefund::getFilter, refundReq.getFilter()).eq(KwpWalletRefund::getStatus, RefundEnum.APPLY.getStatus()).last("limit 1");
+        KwpWalletRefund kwpWalletRefund = kwpWalletRefundMapper.selectOne(wrapper);
+        if (Objects.nonNull(kwpWalletRefund)) {
+            throw new BusinessException("存在未完成的退款订单");
+        }
+        ChannelEnum channelEnum = ChannelEnum.getByChannel(refundReq.getChannel());
+        if (Objects.isNull(channelEnum)) {
+            throw new BusinessException("支付通道不存在");
+        }
+        KwpWalletRefund kwpWalletRefundAdd = new KwpWalletRefund();
+        kwpWalletRefundAdd.setId(new IdWorker(NumberConstant.ONE).nextId());
+        kwpWalletRefundAdd.setOrderNo(OrderUtils.generateOrderNo("RF"));
+        kwpWalletRefundAdd.setUid(refundReq.getUid());
+        kwpWalletRefundAdd.setFromEnt(walletRelationService.getEnt(refundReq.getUid()));
+        kwpWalletRefundAdd.setFilter(refundReq.getFilter());
+        kwpWalletRefundAdd.setToEnt(walletRelationService.getEnt(refundReq.getFilter()));
+        kwpWalletRefundAdd.setChannel(refundReq.getChannel());
+        kwpWalletRefundAdd.setMoney(refundReq.getMoney());
+        kwpWalletRefundAdd.setRemark(refundReq.getRemark());
+        kwpWalletRefundAdd.setCreateBy(LoginUserHolder.getUserId());
+        kwpWalletRefundAdd.setCreateTime(LocalDateTime.now());
+        kwpWalletRefundAdd.setUpdateBy(LoginUserHolder.getUserId());
+        kwpWalletRefundAdd.setUpdateTime(LocalDateTime.now());
+        kwpWalletRefundAdd.setDelFlag(0);
+        kwpWalletRefundAdd.setStatus(RefundEnum.APPLY.getStatus());
+        kwpWalletRefundMapper.insert(kwpWalletRefundAdd);
+        return "提交成功";
     }
 
     /**
      * 发起退款
+     * 中台逻辑:
+     * 预付 A->B 100元
+     * 退款50元,调用2次清分。
+     * 1. 清分 A->B 50元
+     * 2. 清分 B->A 50元
      *
      * @return
      */
-    public Object launchRefund() {
-        return null;
+    public Object launchRefund(RefundReq refundReq) {
+        LambdaQueryWrapper<KwpWalletRefund> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(KwpWalletRefund::getChannel, refundReq.getChannel());
+        wrapper.eq(KwpWalletRefund::getUid, refundReq.getUid()).eq(KwpWalletRefund::getFilter, refundReq.getFilter()).eq(KwpWalletRefund::getStatus, RefundEnum.APPLY.getStatus()).last("limit 1");
+        KwpWalletRefund kwpWalletRefund = kwpWalletRefundMapper.selectOne(wrapper);
+        if (Objects.isNull(kwpWalletRefund)) {
+            throw new BusinessException("未找到待完成的退款订单");
+        }
+        ChannelEnum channelEnum = ChannelEnum.getByChannel(refundReq.getChannel());
+        if (Objects.isNull(channelEnum)) {
+            throw new BusinessException("支付通道不存在");
+        }
+        // 1.记账
+        List<PatchPay> list = new ArrayList<>();
+        PatchPay patchPay = new PatchPay();
+        patchPay.setUid(refundReq.getFilter());
+        patchPay.setMoney(refundReq.bigMoney(refundReq.getMoney()));
+        patchPay.setRemark(refundReq.getRemark());
+        list.add(patchPay);
+        R<BusinessNo> businessNoR = payCenterService.payAgentPayV2(refundReq.getUid(), refundReq.getFilter(), channelEnum, refundReq.bigMoney(refundReq.getMoney()), list, kwpWalletRefund.getOrderNo(), "1");
+        if (!businessNoR.getStatus()) {
+            throw new BusinessException(StringUtils.isNotBlank(businessNoR.getMsg()) ? businessNoR.getMsg() : "退款失败");
+        }
+        Long userId = LoginUserHolder.getUserId();
+        //异步提交清分退款任务
+        AsyncPool.addTask(new Refund(refundReq, kwpWalletRefund, payCenterService, kwpWalletRefundMapper, userId));
+        return businessNoR;
+    }
+
+    /**
+     * 退款处理
+     *
+     * @param refundReq
+     * @param kwpWalletRefund
+     * @param payCenterService
+     * @param kwpWalletRefundMapper
+     * @param userId
+     */
+    private record Refund(RefundReq refundReq, KwpWalletRefund kwpWalletRefund, PayCenterService payCenterService,
+                          KwpWalletRefundMapper kwpWalletRefundMapper, Long userId) implements Runnable {
+        private final static Logger log = LoggerFactory.getLogger(Refund.class);
+
+        @Override
+        public void run() {
+            ChannelEnum channelEnum = ChannelEnum.getByChannel(refundReq.getChannel());
+            List<PatchPay> list = new ArrayList<>();
+            PatchPay patchPay = new PatchPay();
+            patchPay.setUid(refundReq.getFilter());
+            patchPay.setMoney(refundReq.bigMoney(refundReq.getMoney()));
+            patchPay.setRemark(refundReq.getRemark());
+            list.add(patchPay);
+            log.info("异步提交清分退款任务");
+            R<BusinessNo> businessNoR1 = payCenterService.payAgentPayV2(refundReq.getFilter(), refundReq.getUid(), channelEnum, refundReq.bigMoney(refundReq.getMoney()), list, kwpWalletRefund.getOrderNo(), "2");
+            if (businessNoR1.getStatus()) {
+                kwpWalletRefund.setActualMoney(refundReq.getMoney());
+                kwpWalletRefund.setUpdateBy(userId);
+                kwpWalletRefund.setUpdateTime(LocalDateTime.now());
+                kwpWalletRefund.setStatus(RefundEnum.REFUNDING.getStatus());
+                kwpWalletRefundMapper.updateById(kwpWalletRefund);
+            }
+        }
     }
 
 }