2 Commits bfafb23a1c ... 4885f73997

Tác giả SHA1 Thông báo Ngày
  wujiefeng 4885f73997 初始化 11 tháng trước cách đây
  wujiefeng cae31989ae 初始化 11 tháng trước cách đây
91 tập tin đã thay đổi với 3680 bổ sung0 xóa
  1. 65 0
      RewardClient/pom.xml
  2. 12 0
      RewardClient/src/main/java/com/zhongshu/reward/client/config/RewardClientConfiguration.java
  3. 8 0
      RewardClient/src/main/java/com/zhongshu/reward/client/config/RewardServerConfiguration.java
  4. 35 0
      RewardClient/src/main/java/com/zhongshu/reward/client/model/InviteReceiptsRoleModel.java
  5. 16 0
      RewardClient/src/main/java/com/zhongshu/reward/client/model/TotalStatisticsModel.java
  6. 21 0
      RewardClient/src/main/java/com/zhongshu/reward/client/model/param/QueryTransferParam.java
  7. 40 0
      RewardClient/src/main/java/com/zhongshu/reward/client/model/param/WalletReceiptsParam.java
  8. 25 0
      RewardClient/src/main/java/com/zhongshu/reward/client/model/param/WalletTransferParam.java
  9. 43 0
      RewardClient/src/main/java/com/zhongshu/reward/client/model/wallet/TransferModel.java
  10. 42 0
      RewardClient/src/main/java/com/zhongshu/reward/client/model/wallet/TransferStatusModel.java
  11. 51 0
      RewardClient/src/main/java/com/zhongshu/reward/client/model/wallet/WalletModel.java
  12. 55 0
      RewardClient/src/main/java/com/zhongshu/reward/client/model/wallet/WalletReceiptsModel.java
  13. 89 0
      RewardClient/src/main/java/com/zhongshu/reward/client/model/wallet/WxTransferBatchModel.java
  14. 41 0
      RewardClient/src/main/java/com/zhongshu/reward/client/ret/CommentException.java
  15. 92 0
      RewardClient/src/main/java/com/zhongshu/reward/client/ret/ResultContent.java
  16. 33 0
      RewardClient/src/main/java/com/zhongshu/reward/client/ret/ResultException.java
  17. 11 0
      RewardClient/src/main/java/com/zhongshu/reward/client/ret/ResultMessage.java
  18. 39 0
      RewardClient/src/main/java/com/zhongshu/reward/client/ret/ResultState.java
  19. 19 0
      RewardClient/src/main/java/com/zhongshu/reward/client/type/ComputationType.java
  20. 19 0
      RewardClient/src/main/java/com/zhongshu/reward/client/type/DataState.java
  21. 21 0
      RewardClient/src/main/java/com/zhongshu/reward/client/type/ReceiptsStatus.java
  22. 17 0
      RewardClient/src/main/java/com/zhongshu/reward/client/type/ReceiptsType.java
  23. 11 0
      RewardClient/src/main/java/com/zhongshu/reward/client/type/TimeUnitType.java
  24. 10 0
      RewardClient/src/main/java/com/zhongshu/reward/client/type/TransferChannel.java
  25. 28 0
      RewardClient/src/main/java/com/zhongshu/reward/client/type/TransferStatus.java
  26. 12 0
      RewardClient/src/main/java/com/zhongshu/reward/client/type/WalletType.java
  27. BIN
      RewardClient/target/classes/com/zhongshu/reward/client/config/RewardClientConfiguration.class
  28. BIN
      RewardClient/target/classes/com/zhongshu/reward/client/config/RewardServerConfiguration.class
  29. 166 0
      RewardServer/pom.xml
  30. 21 0
      RewardServer/src/main/java/com/zhongshu/reward/server/RewardServerApplication.java
  31. 11 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/AuthConfig.java
  32. 10 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/ClientConfig.java
  33. 14 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/MVCConfig.java
  34. 13 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/MongoConfig.java
  35. 37 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/PaymentConfig.java
  36. 9 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/PushConfig.java
  37. 26 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/RedisConfig.java
  38. 27 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/SchedulingConfig.java
  39. 31 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/SnowFlakeConfig.java
  40. 46 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/SwagerConfig.java
  41. 15 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/VipConfig.java
  42. 65 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/WeChatConfig.java
  43. 15 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/feign/ZswlCloudBdbConfig.java
  44. 11 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/config/feign/ZswlCloudShopConfig.java
  45. 54 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/controller/wallet/WalletController.java
  46. 36 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/Impl/WalletDaoImpl.java
  47. 106 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/Impl/WxTransferBatchDaoImpl.java
  48. 14 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/InviteReceiptsRoleDao.java
  49. 12 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/TransferRulerDao.java
  50. 17 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/WalletDao.java
  51. 17 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/WalletReceiptsDao.java
  52. 20 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/WxTransferBatchDao.java
  53. 10 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/extend/WalletDaoExtend.java
  54. 22 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/extend/WxTransferBatchDaoExtend.java
  55. 43 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/InviteReceiptsRole.java
  56. 86 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/TransferRuler.java
  57. 59 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/Wallet.java
  58. 62 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/WalletReceipts.java
  59. 109 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/WxTransferBatch.java
  60. 42 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/WxTransferScene.java
  61. 23 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/listener/VipEventListener.java
  62. 117 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/service/ChatTransferBatchService.java
  63. 8 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/service/Impl/WalletFeignServiceImpl.java
  64. 65 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/service/InviteReceiptsRoleService.java
  65. 98 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/service/WalletReceiptsService.java
  66. 58 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/service/WalletService.java
  67. 226 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/service/WxTransferService.java
  68. 56 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/timer/WalletTimer.java
  69. 156 0
      RewardServer/src/main/java/com/zhongshu/reward/server/core/util/DateUtils.java
  70. 41 0
      RewardServer/src/main/resources/application-dev.yml
  71. 64 0
      RewardServer/src/main/resources/application.yml
  72. 23 0
      RewardServer/src/main/resources/bootstrap.yml
  73. 402 0
      RewardServer/src/test/java/com/zhongshu/payment/server/ServerApplicationTests.java
  74. 113 0
      RewardServer/target/classes/META-INF/spring-configuration-metadata.json
  75. 41 0
      RewardServer/target/classes/application-dev.yml
  76. 64 0
      RewardServer/target/classes/application.yml
  77. 23 0
      RewardServer/target/classes/bootstrap.yml
  78. BIN
      RewardServer/target/classes/com/zhongshu/payment/server/core/config/MVCConfig.class
  79. BIN
      RewardServer/target/classes/com/zhongshu/payment/server/core/config/PaymentConfig.class
  80. BIN
      RewardServer/target/classes/com/zhongshu/payment/server/core/config/RedisConfig.class
  81. BIN
      RewardServer/target/classes/com/zhongshu/reward/server/RewardServerApplication.class
  82. BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/AuthConfig.class
  83. BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/ClientConfig.class
  84. BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/MongoConfig.class
  85. BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/PushConfig.class
  86. BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/SchedulingConfig.class
  87. BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/SnowFlakeConfig.class
  88. BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/SwagerConfig.class
  89. BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/WeChatConfig.class
  90. BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/feign/ZswlCloudShopConfig.class
  91. 21 0
      pom.xml

+ 65 - 0
RewardClient/pom.xml

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>com.github.microservice</groupId>
+		<artifactId>PParent</artifactId>
+		<version>1.0.0-SNAPSHOT</version>
+		<relativePath>../../../super/PParent</relativePath>
+	</parent>
+
+
+	<groupId>com.zhongshu</groupId>
+	<artifactId>RewardClient</artifactId>
+	<name>RewardClient</name>
+	<properties>
+		<java.version>11</java.version>
+	</properties>
+	<dependencies>
+
+
+		<dependency>
+			<groupId>com.github.microservice</groupId>
+			<artifactId>PCore</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<!--应用中心客户端-->
+		<dependency>
+			<groupId>com.github.microservice.components</groupId>
+			<artifactId>ApplicationClient</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+
+		<dependency>
+			<groupId>com.github.microservice.auth</groupId>
+			<artifactId>AuthClient</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.github.xiaoymin</groupId>
+			<artifactId>knife4j-spring-boot-starter</artifactId>
+			<version>3.0.3</version>
+		</dependency>
+
+		<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
+		<dependency>
+			<groupId>cn.hutool</groupId>
+			<artifactId>hutool-all</artifactId>
+			<version>5.8.20</version>
+		</dependency>
+
+
+		<dependency>
+			<groupId>com.github.wechatpay-apiv3</groupId>
+			<artifactId>wechatpay-java</artifactId>
+			<version>0.2.12</version>
+		</dependency>
+
+	</dependencies>
+
+
+</project>

+ 12 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/config/RewardClientConfiguration.java

@@ -0,0 +1,12 @@
+package com.zhongshu.reward.client.config;
+
+
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableFeignClients("com.zhongshu.reward.client.service")
+@ComponentScan({"com.zhongshu.reward.client"})
+public class RewardClientConfiguration {
+}

+ 8 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/config/RewardServerConfiguration.java

@@ -0,0 +1,8 @@
+package com.zhongshu.reward.client.config;
+
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class RewardServerConfiguration {
+}

+ 35 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/model/InviteReceiptsRoleModel.java

@@ -0,0 +1,35 @@
+package com.zhongshu.reward.client.model;
+
+import com.zhongshu.reward.client.type.ComputationType;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author wjf
+ * @date 2024/8/7
+ */
+@Data
+public class InviteReceiptsRoleModel {
+
+    private String id;
+
+    @ApiModelProperty("规则名称")
+    private String roleName;
+
+    @ApiModelProperty("套餐id")
+    private String setMealId;
+
+    @ApiModelProperty("计算规则:固定、百分比")
+    private ComputationType computation;
+
+    @ApiModelProperty("金额额度")
+    private BigDecimal baseTotal;
+
+    @ApiModelProperty("生效状态")
+    private boolean disable;
+
+    @ApiModelProperty("生效范围是否所有")
+    private boolean isALL = true;
+}

+ 16 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/model/TotalStatisticsModel.java

@@ -0,0 +1,16 @@
+package com.zhongshu.reward.client.model;
+
+import lombok.Data;
+
+/**
+ * @author wjf
+ * @date 2024/7/31
+ */
+
+@Data
+public class TotalStatisticsModel {
+
+    private String id;
+
+    private Integer totalAmount;
+}

+ 21 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/model/param/QueryTransferParam.java

@@ -0,0 +1,21 @@
+package com.zhongshu.reward.client.model.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * @author wjf
+ * @date 2024/7/29
+ */
+@Data
+public class QueryTransferParam {
+
+    @Schema(name = "walletId", description = "钱包id")
+    private String walletId;
+
+    @Schema(name = "year", description = "年")
+    private Integer year;
+
+    @Schema(name = "month", description = "月")
+    private Integer month;
+}

+ 40 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/model/param/WalletReceiptsParam.java

@@ -0,0 +1,40 @@
+package com.zhongshu.reward.client.model.param;
+
+
+import com.zhongshu.reward.client.type.ReceiptsType;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author wjf
+ * @date 2024/8/6
+ */
+@Data
+public class WalletReceiptsParam {
+
+    /**
+     * 钱包
+     */
+    private String userId;
+
+    /**
+     * 预计到账时间
+     */
+    private Long estimatedTime;
+
+    /**
+     * 到账类型
+     */
+    private ReceiptsType receiptsType;
+
+    /**
+     * 到账金额
+     */
+    private BigDecimal total = BigDecimal.ZERO;
+
+    /**
+     * 外部订单号
+     */
+    private String outTradeNo;
+}

+ 25 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/model/param/WalletTransferParam.java

@@ -0,0 +1,25 @@
+package com.zhongshu.reward.client.model.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 钱包提现参数
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Data
+public class WalletTransferParam {
+
+    @Schema(name = "walletId", description = "钱包id")
+    private String walletId;
+
+    @Schema(name = "total", description = "提现金额")
+    private BigDecimal total = BigDecimal.ZERO;
+
+    @Schema(name = "openid", description = "微信openid")
+    private String openid;
+
+}

+ 43 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/model/wallet/TransferModel.java

@@ -0,0 +1,43 @@
+package com.zhongshu.reward.client.model.wallet;
+
+import com.google.gson.annotations.SerializedName;
+import com.wechat.pay.java.core.cipher.Encryption;
+import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TransferModel {
+
+
+//    @SerializedName("appid")
+//    private String appid;
+//    /** 商家批次单号 说明:商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一 */
+    @SerializedName("out_batch_no")
+    private String outBatchNo;
+    /** 批次名称 说明:该笔批量转账的名称 */
+    @SerializedName("batch_name")
+    private String batchName;
+    /** 批次备注 说明:转账说明,UTF8编码,最多允许32个字符 */
+    @SerializedName("batch_remark")
+    private String batchRemark;
+    /** 转账总金额 说明:转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作 */
+    @SerializedName("total_amount")
+    private Long totalAmount;
+    /** 转账总笔数 说明:一个转账批次单最多发起一千笔转账。转账总笔数必须与批次内所有明细之和保持一致,否则无法发起转账操作 */
+    @SerializedName("total_num")
+    private Integer totalNum;
+    /** 转账明细列表 说明:发起批量转账的明细列表,最多一千笔 */
+    @Encryption
+    @SerializedName("transfer_detail_list")
+    private List<TransferDetailInput> transferDetailList = new ArrayList<TransferDetailInput>();
+    /** 转账场景ID 说明:该批次转账使用的转账场景,如不填写则使用商家的默认场景,如无默认场景可为空,可前往“商家转账到零钱-前往功能”中申请。 如:1001-现金营销 */
+    @SerializedName("transfer_scene_id")
+    private String transferSceneId;
+}

+ 42 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/model/wallet/TransferStatusModel.java

@@ -0,0 +1,42 @@
+package com.zhongshu.reward.client.model.wallet;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TransferStatusModel {
+    @SerializedName("batch_id")
+    @Expose(
+            serialize = false
+    )
+    private String batchId;
+    @SerializedName("need_query_detail")
+    @Expose(
+            serialize = false
+    )
+    private Boolean needQueryDetail;
+    @SerializedName("offset")
+    @Expose(
+            serialize = false
+    )
+    private Integer offset;
+    @SerializedName("limit")
+    @Expose(
+            serialize = false
+    )
+    private Integer limit;
+    @SerializedName("detail_status")
+    @Expose(
+            serialize = false
+    )
+    private String detailStatus;
+}

+ 51 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/model/wallet/WalletModel.java

@@ -0,0 +1,51 @@
+package com.zhongshu.reward.client.model.wallet;
+
+import com.zhongshu.reward.client.type.DataState;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Data
+public class WalletModel {
+
+    private String id;
+
+    private Long createTime;
+
+    private Long updateTime;;
+
+    /**
+     * 用户id
+     */
+    private String userId;
+
+    /**
+     * 商铺id
+     */
+    private String shopId;
+
+
+    /**
+     * 账户余额(可提现金额)
+     */
+    private BigDecimal amount;
+
+    /**
+     * 未结算金额
+     */
+    private BigDecimal waitAmount;
+
+    /**
+     * 今日已提现金额
+     */
+    private BigDecimal todayTransferAmount;
+
+    /**
+     * 钱包状态
+     */
+    private DataState dataState;
+}

+ 55 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/model/wallet/WalletReceiptsModel.java

@@ -0,0 +1,55 @@
+package com.zhongshu.reward.client.model.wallet;
+
+import com.zhongshu.reward.client.type.ReceiptsStatus;
+import com.zhongshu.reward.client.type.ReceiptsType;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author wjf
+ * @date 2024/8/6
+ */
+@Data
+public class WalletReceiptsModel {
+
+    private String id;
+
+    private Long createTime;
+
+    private Long updateTime;;
+    /**
+     * 钱包
+     */
+    private String walletId;
+
+    /**
+     * 预计到账时间
+     */
+    private Long estimatedTime;
+
+    /**
+     * 实际到账时间
+     */
+    private Long receiptsTime;
+
+    /**
+     * 到账类型
+     */
+    private ReceiptsType receiptsType;
+
+    /**
+     * 到账金额
+     */
+    private BigDecimal total = BigDecimal.ZERO;
+
+    /**
+     * 状态
+     */
+    private ReceiptsStatus status;
+
+    /**
+     * 外部订单号
+     */
+    private String outTradeNo;
+}

+ 89 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/model/wallet/WxTransferBatchModel.java

@@ -0,0 +1,89 @@
+package com.zhongshu.reward.client.model.wallet;
+
+import com.zhongshu.reward.client.type.TransferChannel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxTransferBatchModel {
+
+    private String id;
+
+    private Long createTime;
+
+    private Long updateTime;
+
+    /**
+     * 内部批次单号
+     */
+    private String batchNo;
+
+    /**
+     * (内部)提现明细单号
+     */
+    private String detailNo;
+
+    /**
+     * 提现钱包
+     */
+    private String walletId;
+
+    /**
+     * 提现金额
+     */
+    private BigDecimal total;
+
+    /**
+     * 提现渠道
+     */
+    private TransferChannel channel;
+
+//    /**
+//     * 提现前账户信息
+//     */
+//    private Wallet beforeWalletInfo;
+
+//    /**
+//     * 到账时间
+//     */
+//    private Long tradeTime;
+
+    /**
+     * 批次状态
+     */
+    private String batchStatus;
+
+    /**
+     * 明细状态
+     */
+    private String detailStatus;
+
+    /**
+     * wx批次单号
+     */
+    private String wxBatchId;
+
+    /**
+     * wx批次单号
+     */
+    private String wxDetailId;
+
+    /**
+     * openid
+     */
+    private String openid;
+
+    /**
+     * 异常原因
+     */
+    private String exceptionReason;
+}

+ 41 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/ret/CommentException.java

@@ -0,0 +1,41 @@
+package com.zhongshu.reward.client.ret;
+
+/**
+ * @Author: wy
+ * @Date: 2023/6/6 16:43
+ */
+public class CommentException extends RuntimeException {
+
+    private ResultState resultState;
+
+    private String message;
+
+    /**
+     * 参数校验异常构造方法
+     */
+    public CommentException(String message) {
+        this.message = message;
+    }
+
+    public CommentException(ResultState resultState, String message) {
+        this.resultState = resultState;
+        this.message = message;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public ResultState getResultState() {
+        return resultState;
+    }
+
+    public void setResultState(ResultState resultState) {
+        this.resultState = resultState;
+    }
+}

+ 92 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/ret/ResultContent.java

@@ -0,0 +1,92 @@
+package com.zhongshu.reward.client.ret;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.*;
+
+import java.util.Optional;
+
+/**
+ * 结果
+ *
+ * @param <T>
+ */
+@Builder
+@ToString(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@AllArgsConstructor
+@NoArgsConstructor
+public class ResultContent<T> {
+
+    //内容
+    @Getter
+    @Setter
+    private T content;
+
+    //状态
+    @Getter
+    @Setter
+    private ResultState state;
+
+    //文本
+    @Getter
+    @Setter
+    private String msg;
+
+
+    //异常
+    @Getter
+    @Setter
+    private ResultException exception;
+
+
+    /**
+     * 获取内容
+     *
+     * @return
+     */
+    public Optional<T> optionalContent() {
+        return Optional.ofNullable(this.content);
+    }
+
+    public static <T> ResultContent build(ResultState state, T content) {
+        return ResultContent.builder().state(state).content(content).msg(state.getRemark()).build();
+    }
+
+    public static <T> ResultContent build(boolean bool) {
+        return build(bool ? ResultState.Success : ResultState.Fail, null);
+    }
+
+    public static <T> ResultContent build(ResultState state) {
+        return build(state, null);
+    }
+
+    public static <T> ResultContent buildContent(T content) {
+        return build(content == null ? ResultState.Fail : ResultState.Success, content);
+    }
+
+    public static <T> ResultContent buildFail(String msg) {
+        return ResultContent.builder().state(ResultState.Fail).msg(msg).build();
+    }
+
+    public static <T> ResultContent buildSuccess(String msg) {
+        return build(ResultState.Success, msg);
+    }
+
+    public static <T> ResultContent buildSuccess(T content) {
+        return build(ResultState.Success, content);
+    }
+
+    public static <T> ResultContent buildSuccess() {
+        return build(ResultState.Success, ResultState.Success.getRemark());
+    }
+
+    public boolean isSuccess()
+    {
+        return ResultState.Success.equals(this.state);
+    }
+
+    public boolean isFailed()
+    {
+        return !ResultState.Success.equals(this.state);
+    }
+}

+ 33 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/ret/ResultException.java

@@ -0,0 +1,33 @@
+package com.zhongshu.reward.client.ret;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 结果集异常
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ResultException {
+
+    private String type;
+    private String cls;
+    private String message;
+
+
+    /**
+     * 创建异常对象
+     *
+     * @param e
+     * @return
+     */
+    public static ResultException build(Exception e) {
+        ResultException exception = new ResultException();
+        exception.type = e.getClass().getSimpleName();
+        exception.cls = e.getClass().getName();
+        exception.message = e.getMessage();
+        return exception;
+    }
+}

+ 11 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/ret/ResultMessage.java

@@ -0,0 +1,11 @@
+package com.zhongshu.reward.client.ret;
+
+/**
+ * @author TRX
+ * @date 2024/5/31
+ */
+public class ResultMessage {
+    public static final String DATA_NOT_EXIST = "数据不存在:%s";
+
+    public static final String NAME_EXIST = "名称已存在:%s";
+}

+ 39 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/ret/ResultState.java

@@ -0,0 +1,39 @@
+package com.zhongshu.reward.client.ret;
+
+import lombok.Getter;
+
+/**
+ * 结果状态模板
+ */
+public enum ResultState {
+
+    Success("成功"),
+    Fail("失败"),
+    Error("错误"),
+    Exception("异常"),
+    Robot("机器验证"),
+
+    UserExit("用户存在"),
+    UserNotExit("用户不存在"),
+    UserOrPassWordError("用户名或密码错误"),
+
+    NOT_TOKEN_ERROR("token获取失败"),
+    NOT_AUTH_ERROR("需要授权"),
+    EXPIRE_ERROR( "token已过期"),
+    INVALID_TOKEN("无效token"),
+    LOGIN_REQUIRED("需要登录"),
+    CODE_ERROR("验证码错误"),
+
+    AccountNotNull("账户不能为空"),
+    AccountExists("用户存在"),
+    AccountNotExists("账户不存在"),
+    NOT_WECHAT_AUTH("用户微信未授权"),
+    ;
+
+    @Getter
+    private String remark;
+
+    ResultState(String remark) {
+        this.remark = remark;
+    }
+}

+ 19 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/type/ComputationType.java

@@ -0,0 +1,19 @@
+package com.zhongshu.reward.client.type;
+
+/**
+ * 返利计算方式
+ * @author wjf
+ * @date 2024/8/7
+ */
+public enum ComputationType {
+
+    /**
+     * 固定金额
+     */
+    FIXED,
+
+    /**
+     * 百分比
+     */
+    RATIO;
+}

+ 19 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/type/DataState.java

@@ -0,0 +1,19 @@
+package com.zhongshu.reward.client.type;
+
+import lombok.Getter;
+
+/**
+ * 数据状态
+ */
+public enum DataState {
+    Enable("启用"),
+    Disable("已停用"),
+    ;
+
+    @Getter
+    private String remark;
+
+    DataState(String remark) {
+        this.remark = remark;
+    }
+}

+ 21 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/type/ReceiptsStatus.java

@@ -0,0 +1,21 @@
+package com.zhongshu.reward.client.type;
+
+/**
+ * @author wjf
+ * @date 2024/8/6
+ */
+public enum ReceiptsStatus {
+
+    /**
+     * 未结算
+     */
+    WAIT,
+    /**
+     * 已结算
+     */
+    RECEIPTS,
+    /**
+     * 无返利
+     */
+    CANCEL
+}

+ 17 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/type/ReceiptsType.java

@@ -0,0 +1,17 @@
+package com.zhongshu.reward.client.type;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public enum ReceiptsType {
+
+    /**
+     * 返利
+     */
+    REBATE,
+    /**
+     * 佣金
+     */
+    COMMISSION,
+}

+ 11 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/type/TimeUnitType.java

@@ -0,0 +1,11 @@
+package com.zhongshu.reward.client.type;
+
+/**
+ * @author wjf
+ * @date 2024/8/7
+ */
+public enum TimeUnitType {
+
+    MONTH,
+    DAY
+}

+ 10 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/type/TransferChannel.java

@@ -0,0 +1,10 @@
+package com.zhongshu.reward.client.type;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public enum TransferChannel {
+
+    WeChat
+}

+ 28 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/type/TransferStatus.java

@@ -0,0 +1,28 @@
+package com.zhongshu.reward.client.type;
+
+import lombok.Getter;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public enum TransferStatus {
+
+    PROCESSING("提现处理中"),
+
+    SUCCESS("已成功"),
+
+    FAIL("失败"),
+
+    CLOSE("已关闭")
+    ;
+
+
+
+    @Getter
+    private String remark;
+
+    TransferStatus(String remark){
+        this.remark =remark;
+    }
+}

+ 12 - 0
RewardClient/src/main/java/com/zhongshu/reward/client/type/WalletType.java

@@ -0,0 +1,12 @@
+package com.zhongshu.reward.client.type;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public enum WalletType {
+
+    USER,
+
+    SHOP
+}

BIN
RewardClient/target/classes/com/zhongshu/reward/client/config/RewardClientConfiguration.class


BIN
RewardClient/target/classes/com/zhongshu/reward/client/config/RewardServerConfiguration.class


+ 166 - 0
RewardServer/pom.xml

@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>com.github.microservice</groupId>
+		<artifactId>PParent</artifactId>
+		<version>1.0.0-SNAPSHOT</version>
+		<relativePath>../../../super/PParent</relativePath>
+	</parent>
+
+
+	<groupId>com.zhongshu</groupId>
+	<artifactId>RewardServer</artifactId>
+	<name>RewardServer</name>
+	<description>返利中心</description>
+	<properties>
+		<java.version>11</java.version>
+	</properties>
+	<dependencies>
+
+
+		<dependency>
+			<groupId>com.github.microservice</groupId>
+			<artifactId>PCore</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<!--应用中心客户端-->
+		<dependency>
+			<groupId>com.github.microservice.components</groupId>
+			<artifactId>ApplicationClient</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+
+		<dependency>
+			<groupId>com.zswl.cloud.bdb</groupId>
+			<artifactId>zswl-cloud-bdb-client</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.zswl.cloud.shop</groupId>
+			<artifactId>zswl-cloud-shop-client</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.zhongshu</groupId>
+			<artifactId>VipClient</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+
+		<dependency>
+			<groupId>com.github.microservice.components</groupId>
+			<artifactId>MongodbData</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.github.microservice.components</groupId>
+			<artifactId>RedisData</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>fastjson</artifactId>
+			<version>2.0.38</version>
+		</dependency>
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.14.0</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.zhongshu</groupId>
+            <artifactId>RewardClient</artifactId>
+			<version>${project.version}</version>
+        </dependency>
+
+		<dependency>
+			<groupId>com.github.microservice.netdisk</groupId>
+			<artifactId>NetDiskClient</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+            <version>2.0.38</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+            <version>2.0.38</version>
+        </dependency>
+
+		<dependency>
+			<groupId>com.github.microservice.components</groupId>
+			<artifactId>PushCenterClient</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+
+<!--		<dependency>-->
+<!--			<groupId>org.redisson</groupId>-->
+<!--			<artifactId>redisson-spring-boot-starter</artifactId>-->
+<!--			<version>3.17.1</version> &lt;!&ndash; 请根据实际情况选择版本 &ndash;&gt;-->
+<!--		</dependency>-->
+
+
+    </dependencies>
+
+	<build>
+
+
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<configuration>
+					<fork>true</fork>
+				</configuration>
+				<executions>
+					<execution>
+						<goals>
+							<goal>repackage</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<excludes>
+						<!-- This is where the exclusion occurs -->
+						<exclude>**/application-*.yml</exclude>
+					</excludes>
+				</configuration>
+			</plugin>
+
+		</plugins>
+
+		<!-- properties 取 pom 配置 -->
+		<resources>
+			<resource>
+				<directory>src/main/java</directory>
+				<includes>
+					<include>**/*.xml</include>
+				</includes>
+			</resource>
+			<resource>
+				<directory>src/main/resources</directory>
+				<filtering>true</filtering>
+			</resource>
+		</resources>
+
+	</build>
+</project>

+ 21 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/RewardServerApplication.java

@@ -0,0 +1,21 @@
+package com.zhongshu.reward.server;
+
+import com.github.microservice.app.annotation.EnableApplicationClient;
+import com.github.microservice.core.boot.ApplicationBootSuper;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+
+@SpringBootApplication
+@EnableApplicationClient
+@EnableScheduling
+@ComponentScan("com.zhongshu.reward.server.core")
+public class RewardServerApplication extends ApplicationBootSuper {
+
+	public static void main(String[] args) {
+		SpringApplication.run(RewardServerApplication.class, args);
+	}
+
+}

+ 11 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/AuthConfig.java

@@ -0,0 +1,11 @@
+package com.zhongshu.reward.server.core.config;
+
+import com.github.microservice.auth.config.AuthClientConfiguration;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+
+@Configuration
+@Import(AuthClientConfiguration.class)
+public class AuthConfig {
+}

+ 10 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/ClientConfig.java

@@ -0,0 +1,10 @@
+package com.zhongshu.reward.server.core.config;
+
+import com.zhongshu.reward.client.config.RewardServerConfiguration;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+@Configuration
+@Import(RewardServerConfiguration.class)
+public class ClientConfig {
+}

+ 14 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/MVCConfig.java

@@ -0,0 +1,14 @@
+package com.zhongshu.reward.server.core.config;
+
+import com.github.microservice.core.mvc.MVCConfiguration;
+import com.github.microservice.core.mvc.MVCResponseConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+@Import({MVCConfiguration.class, MVCResponseConfiguration.class})
+@Configuration
+public class MVCConfig {
+
+}

+ 13 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/MongoConfig.java

@@ -0,0 +1,13 @@
+package com.zhongshu.reward.server.core.config;
+
+
+import com.github.microservice.components.data.mongo.mongo.config.MongoConfiguration;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+@Configuration
+@Import(MongoConfiguration.class)
+@EnableMongoRepositories("com.zhongshu.reward.server.core.dao")
+public class MongoConfig {
+}

+ 37 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/PaymentConfig.java

@@ -0,0 +1,37 @@
+package com.zhongshu.reward.server.core.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "payment")
+public class PaymentConfig {
+
+    private String mer_no;
+
+    private String tid;
+
+    private String accesser_id;
+
+    private String key;
+
+    private String h5_page_url;
+
+    private String pc_page_url;
+
+    private String interface_url;
+
+    private String pay_key;
+
+    private String pay_url;
+
+    private String withdrawals_url;
+
+    private String withdrawals_key;
+
+    private String notifyUrl;
+
+
+}

+ 9 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/PushConfig.java

@@ -0,0 +1,9 @@
+package com.zhongshu.reward.server.core.config;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan("com.github.microservice.components.push")
+public class PushConfig {
+}

+ 26 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/RedisConfig.java

@@ -0,0 +1,26 @@
+package com.zhongshu.reward.server.core.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Configuration
+public class RedisConfig {
+    /**
+     * 自定义Key为String类型Value为Object类型的Redis操作模板
+     */
+    @Bean(name = "redisTemplate")
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
+        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+        redisTemplate.setConnectionFactory(redisConnectionFactory);
+
+        // key采用String的序列化方式
+        redisTemplate.setKeySerializer(new StringRedisSerializer());
+        // hash的key也采用String的序列化方式
+        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+ 
+        return redisTemplate;
+    }
+}

+ 27 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/SchedulingConfig.java

@@ -0,0 +1,27 @@
+package com.zhongshu.reward.server.core.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+@Configuration
+@EnableScheduling
+public class SchedulingConfig implements SchedulingConfigurer {
+
+    @Bean
+    public ThreadPoolTaskScheduler taskScheduler() {
+        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+        scheduler.setPoolSize(5); // 设置线程池大小
+        scheduler.setThreadNamePrefix("scheduled-task-");
+        scheduler.setRemoveOnCancelPolicy(true);
+        return scheduler;
+    }
+
+    @Override
+    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+        taskRegistrar.setTaskScheduler(taskScheduler());
+    }
+}

+ 31 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/SnowFlakeConfig.java

@@ -0,0 +1,31 @@
+package com.zhongshu.reward.server.core.config;
+
+import cn.hutool.core.lang.Snowflake;
+import cn.hutool.core.util.IdUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+
+@Configuration
+public class SnowFlakeConfig {
+    @Autowired
+    DiscoveryClient discoveryClient;
+
+    @Value("${spring.application.name}")
+    private String applicationName;
+
+
+    @Bean
+    public Snowflake snowflake(){
+
+        List<ServiceInstance> instances = discoveryClient.getInstances(applicationName);
+
+        return IdUtil.getSnowflake(instances.size());
+    }
+
+}

+ 46 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/SwagerConfig.java

@@ -0,0 +1,46 @@
+package com.zhongshu.reward.server.core.config;
+
+import com.github.microservice.components.swagger.config.SwaggerConfiguration;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+@Import(SwaggerConfiguration.class)
+public class SwagerConfig {
+
+    @Value("${spring.application.name}")
+    private String applicationName;
+    @Bean
+    public Docket defaultApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .host("https://api.dev.zonelife.cn/")
+                .apiInfo(apiInfo())
+                .groupName(applicationName)
+                .select()
+                // 添加@Api注解才显示
+                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+    /**
+     * swagger-api接口描述信息
+     */
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title(applicationName)
+                .version("1.0.0")
+                .build();
+    }
+}

+ 15 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/VipConfig.java

@@ -0,0 +1,15 @@
+package com.zhongshu.reward.server.core.config;
+
+import com.github.microservice.auth.config.AuthClientConfiguration;
+import com.zhongshu.vip.client.config.VipCenterClientConfiguration;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * @author wjf
+ * @date 2024/8/8
+ */
+@Configuration
+@Import(VipCenterClientConfiguration.class)
+public class VipConfig {
+}

+ 65 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/WeChatConfig.java

@@ -0,0 +1,65 @@
+package com.zhongshu.reward.server.core.config;
+
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+//@Configuration
+@ConfigurationProperties(prefix = "wechat")
+public class WeChatConfig {
+
+    /**
+     * 商户号
+     */
+    private String merchantId;
+
+    /**
+     * 商户API私钥
+     */
+    private String privateKey;
+
+    /**
+     * 商户证书序列号
+     */
+    private String merchantSerialNumber;
+
+    /**
+     * 商户APIV3密钥
+     */
+    private String apiV3Key;
+
+    /**
+     * 资金类型 (归类)
+     */
+    private String transferSceneId;
+
+    /**
+     * 商户id
+     */
+    private String appid;
+
+//    @Bean
+//    public TransferBatchService index() {
+//        // 初始化商户配置
+//        Config config =
+//                new RSAAutoCertificateConfig.Builder()
+//                        .merchantId(merchantId)
+//                        // 使用 com.wechat.pay.java.core.util
+//                        // 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
+//                        .privateKey(privateKey)
+//                        .merchantSerialNumber(merchantSerialNumber)
+//                        .apiV3Key(apiV3Key)
+//                        .build();
+//
+////        com.wechat.pay.java.core.util.PemUtil
+//
+//        // 初始化服务
+//        return new TransferBatchService.Builder().config(config).build();
+//
+//
+//    }
+
+}

+ 15 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/feign/ZswlCloudBdbConfig.java

@@ -0,0 +1,15 @@
+package com.zhongshu.reward.server.core.config.feign;
+
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author wjf
+ * @date 2024/8/7
+ */
+@EnableFeignClients("com.zswl.cloud.bdb.client.service")
+@ComponentScan("com.zswl.cloud.bdb.client")
+@Configuration
+public class ZswlCloudBdbConfig {
+}

+ 11 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/config/feign/ZswlCloudShopConfig.java

@@ -0,0 +1,11 @@
+package com.zhongshu.reward.server.core.config.feign;
+
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@EnableFeignClients("com.zswl.cloud.shop.client.service")
+@ComponentScan("com.zswl.cloud.shop.client")
+@Configuration
+public class ZswlCloudShopConfig {
+}

+ 54 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/controller/wallet/WalletController.java

@@ -0,0 +1,54 @@
+package com.zhongshu.reward.server.core.controller.wallet;
+
+import com.github.microservice.auth.security.annotations.ResourceAuth;
+import com.github.microservice.auth.security.type.AuthType;
+import com.zhongshu.reward.client.model.param.QueryTransferParam;
+import com.zhongshu.reward.client.model.param.WalletTransferParam;
+import com.zhongshu.reward.server.core.service.WalletService;
+import com.zhongshu.reward.server.core.service.WxTransferService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Slf4j
+@RestController
+@RequestMapping("/wallet")
+@Tag(name = "钱包")
+public class WalletController {
+
+    @Autowired
+    WalletService walletService;
+
+    @Autowired
+    WxTransferService wxTransferService;
+
+    @Operation(summary = "获取(开通)当前用户钱包信息", description = "获取(开通)当前用户钱包信息")
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @GetMapping ("getWallet")
+    public Object getWalletByUser(@RequestParam(name = "userId") String userId){
+        return walletService.getWallet(userId);
+    }
+
+    @Operation(summary = "发起提现", description = "发起提现")
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @PostMapping (value = "transfer", consumes = MediaType.APPLICATION_JSON_VALUE)
+    public Object transfer(@RequestBody WalletTransferParam param){
+        return wxTransferService.transfer(param);
+    }
+
+
+    @Operation(summary = "查询提现列表", description = "查询提现列表")
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @PostMapping (value = "queryTransfer", consumes = MediaType.APPLICATION_JSON_VALUE)
+    public Object queryTransfer(@RequestBody QueryTransferParam param){
+        return wxTransferService.queryTransfer(param.getWalletId(), param.getYear(), param.getMonth());
+    }
+
+}

+ 36 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/Impl/WalletDaoImpl.java

@@ -0,0 +1,36 @@
+package com.zhongshu.reward.server.core.dao.Impl;
+
+import com.github.microservice.components.data.mongo.mongo.helper.DBHelper;
+import com.zhongshu.reward.server.core.dao.extend.WalletDaoExtend;
+import com.zhongshu.reward.server.core.domain.Wallet;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+
+import java.math.BigDecimal;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public class WalletDaoImpl implements WalletDaoExtend {
+
+    @Autowired
+    DBHelper dbHelper;
+
+    @Autowired
+    MongoTemplate mongoTemplate;
+
+    @Override
+    public boolean resetTodayAmount() {
+        Query query = Query.query(Criteria.where("todayTransferAmount").ne(BigDecimal.ZERO));
+        Update update = new Update();
+        update.set("todayTransferAmount", BigDecimal.ZERO);
+        this.dbHelper.updateTime(update);
+        return this.mongoTemplate.updateMulti(
+                query, update, Wallet.class
+        ).getModifiedCount() > 0;
+    }
+}

+ 106 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/Impl/WxTransferBatchDaoImpl.java

@@ -0,0 +1,106 @@
+package com.zhongshu.reward.server.core.dao.Impl;
+
+import com.github.microservice.components.data.mongo.mongo.helper.DBHelper;
+import com.zhongshu.reward.client.model.TotalStatisticsModel;
+import com.zhongshu.reward.client.type.TransferStatus;
+import com.zhongshu.reward.server.core.dao.extend.WxTransferBatchDaoExtend;
+import com.zhongshu.reward.server.core.domain.WxTransferBatch;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.aggregation.Aggregation;
+import org.springframework.data.mongodb.core.aggregation.AggregationResults;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public class WxTransferBatchDaoImpl implements WxTransferBatchDaoExtend {
+
+    @Autowired
+    MongoTemplate mongoTemplate;
+
+    @Autowired
+    DBHelper dbHelper;
+
+
+    @Override
+    public List<WxTransferBatch> list(String walletId, Long startTime, Long endTime) {
+        Criteria criteria = new Criteria();
+
+        if (ObjectUtils.isNotEmpty(walletId)){
+            criteria.and("wallet._id").is(walletId);
+        }
+
+        if (null != startTime){
+            criteria.and("createTime").gte(startTime);
+        }
+
+        if (null != endTime){
+            criteria.and("createTime").lte(endTime);
+        }
+
+        Query query = Query.query(criteria);
+        query.with(Sort.by(Sort.Order.desc("createTime")));
+
+        return mongoTemplate.find(query, WxTransferBatch.class);
+    }
+
+    @Override
+    public boolean updateStatus(String id, String batchStatus, String detailStatus, TransferStatus transferStatus) {
+        Query query = Query.query(Criteria.where("_id").is(id));
+        Update update = new Update();
+        update.set("batchStatus", batchStatus);
+        update.set("detailStatus", detailStatus);
+        update.set("transferStatus", transferStatus);
+        this.dbHelper.updateTime(update);
+        return this.mongoTemplate.updateFirst(
+                query, update, WxTransferBatch.class
+        ).getModifiedCount() > 0;
+    }
+
+    public Long countByTime(String walletId, Long startTime, Long endTime) {
+        Criteria criteria = new Criteria();
+        criteria.and("wallet._id").is(walletId);
+        criteria.and("createTime").gte(startTime);
+        criteria.and("createTime").lte(endTime);
+        criteria.and("transferStatus").in(List.of(TransferStatus.PROCESSING, TransferStatus.SUCCESS));
+
+        Query query = Query.query(criteria);
+        query.with(Sort.by(Sort.Order.desc("createTime")));
+
+        return mongoTemplate.count(query, WxTransferBatch.class);
+    }
+
+    public Integer sumDayTotal(String walletId, Long startTime, Long endTime){
+
+        Criteria criteria = new Criteria();
+        criteria.and("wallet._id").is(walletId);
+        criteria.and("createTime").gte(startTime);
+        criteria.and("createTime").lte(endTime);
+        criteria.and("transferStatus").in(List.of(TransferStatus.PROCESSING, TransferStatus.SUCCESS));
+
+        Aggregation aggregation = Aggregation.newAggregation(
+                Aggregation.match(criteria),
+//                Aggregation.project("_id","amountTotal"),
+                Aggregation.group("wallet._id").sum("total").as("totalAmount")
+//                Aggregation.group("tradeType").last("tradeType").as("_id")
+        );
+
+
+        AggregationResults<TotalStatisticsModel> groupList = mongoTemplate.aggregate(aggregation, WxTransferBatch.class, TotalStatisticsModel.class);
+
+        if (groupList.getMappedResults().size()==0){
+            return 0;
+        }
+        return groupList.getMappedResults().get(0).getTotalAmount();
+    }
+
+}

+ 14 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/InviteReceiptsRoleDao.java

@@ -0,0 +1,14 @@
+package com.zhongshu.reward.server.core.dao;
+
+import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.reward.server.core.domain.InviteReceiptsRole;
+
+/**
+ * @author wjf
+ * @date 2024/8/7
+ */
+public interface InviteReceiptsRoleDao extends MongoDao<InviteReceiptsRole> {
+
+    boolean existsBySetMealIdAndDisable(String setMealId, boolean disable);
+
+}

+ 12 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/TransferRulerDao.java

@@ -0,0 +1,12 @@
+package com.zhongshu.reward.server.core.dao;
+
+import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.reward.server.core.domain.TransferRuler;
+
+/**
+ * @author wjf
+ * @date 2024/8/7
+ */
+public interface TransferRulerDao extends MongoDao<TransferRuler> {
+
+}

+ 17 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/WalletDao.java

@@ -0,0 +1,17 @@
+package com.zhongshu.reward.server.core.dao;
+
+
+import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.reward.server.core.dao.extend.WalletDaoExtend;
+import com.zhongshu.reward.server.core.domain.Wallet;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public interface WalletDao extends MongoDao<Wallet>, WalletDaoExtend {
+
+    Wallet findByUserId(String userId);
+
+    Wallet findTop1ById(String id);
+}

+ 17 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/WalletReceiptsDao.java

@@ -0,0 +1,17 @@
+package com.zhongshu.reward.server.core.dao;
+
+import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.reward.server.core.domain.WalletReceipts;
+
+import java.util.List;
+
+/**
+ * @author wjf
+ * @date 2024/8/6
+ */
+public interface WalletReceiptsDao extends MongoDao<WalletReceipts> {
+
+    List<WalletReceipts> findByWallet_IdOrderByCreateTimeDesc(String walletId);
+
+    WalletReceipts findTopByOutTradeNo(String outTradeNo);
+}

+ 20 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/WxTransferBatchDao.java

@@ -0,0 +1,20 @@
+package com.zhongshu.reward.server.core.dao;
+
+
+import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.reward.client.type.TransferStatus;
+import com.zhongshu.reward.server.core.dao.extend.WxTransferBatchDaoExtend;
+import com.zhongshu.reward.server.core.domain.WxTransferBatch;
+
+import java.util.List;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public interface WxTransferBatchDao extends MongoDao<WxTransferBatch>, WxTransferBatchDaoExtend {
+
+    WxTransferBatch findTop1ById(String id);
+
+    List<WxTransferBatch> findByTransferStatus(TransferStatus transferStatus);
+}

+ 10 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/extend/WalletDaoExtend.java

@@ -0,0 +1,10 @@
+package com.zhongshu.reward.server.core.dao.extend;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public interface WalletDaoExtend {
+
+    boolean resetTodayAmount();
+}

+ 22 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/dao/extend/WxTransferBatchDaoExtend.java

@@ -0,0 +1,22 @@
+package com.zhongshu.reward.server.core.dao.extend;
+
+
+import com.zhongshu.reward.client.type.TransferStatus;
+import com.zhongshu.reward.server.core.domain.WxTransferBatch;
+
+import java.util.List;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public interface WxTransferBatchDaoExtend {
+
+    List<WxTransferBatch> list(String walletId, Long startTime, Long endTime);
+
+    boolean updateStatus(String id, String batchStatus, String detailStatus, TransferStatus transferStatus);
+
+    Long countByTime(String walletId, Long startTime, Long endTime);
+
+    Integer sumDayTotal(String walletId, Long startTime, Long endTime);
+}

+ 43 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/InviteReceiptsRole.java

@@ -0,0 +1,43 @@
+package com.zhongshu.reward.server.core.domain;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import com.zhongshu.reward.client.type.ComputationType;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.math.BigDecimal;
+
+/**
+ * @author wjf
+ * @date 2024/8/7
+ */
+@Data
+@Builder
+@Document
+@AllArgsConstructor
+@NoArgsConstructor
+public class InviteReceiptsRole extends SuperEntity {
+
+    @ApiModelProperty("规则名称")
+    private String roleName;
+
+    @ApiModelProperty("套餐id")
+    private String setMealId;
+
+    @ApiModelProperty("计算规则:固定、百分比")
+    private ComputationType computation;
+
+    @ApiModelProperty("金额额度")
+    private BigDecimal baseTotal;
+
+    @ApiModelProperty("生效状态")
+    private boolean disable;
+
+    @ApiModelProperty("生效范围是否所有")
+    private boolean isALL = true;
+
+}

+ 86 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/TransferRuler.java

@@ -0,0 +1,86 @@
+package com.zhongshu.reward.server.core.domain;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import com.zhongshu.reward.client.type.TimeUnitType;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.math.BigDecimal;
+
+/**
+ * 提现规则设置
+ * @author wjf
+ * @date 2024/8/7
+ */
+@Data
+@Builder
+@Document
+@AllArgsConstructor
+@NoArgsConstructor
+public class TransferRuler extends SuperEntity {
+
+    /**
+     * 单笔最小提现金额
+     */
+    private BigDecimal minTotal = BigDecimal.ZERO;
+
+    /**
+     * 单笔最大提现金额
+     */
+    private BigDecimal maxTotal = BigDecimal.ZERO;
+
+    /**
+     * 单日最大转账金额
+     */
+    private BigDecimal dayMaxTotal = BigDecimal.ZERO;
+
+    /**
+     * 提现手续费
+     */
+    private BigDecimal commission = BigDecimal.ZERO;
+
+    /**
+     * 提现次数
+     */
+    private Integer size;
+
+    /**
+     * 时间单位
+     */
+    private TimeUnitType timeUnit;
+
+    /**
+     * 每月开始号数
+     */
+    private Integer startDay;
+
+    /**
+     * 每月结束号数
+     */
+    private Integer endDay;
+
+    /**
+     * 每日开始时
+     */
+    private Integer startHour;
+
+    /**
+     * 每日开始分
+     */
+    private Integer startMinute;
+
+    /**
+     * 每日结束时
+     */
+    private Integer endHour;
+
+    /**
+     * 每日结束时
+     */
+    private Integer endMinute;
+
+}

+ 59 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/Wallet.java

@@ -0,0 +1,59 @@
+package com.zhongshu.reward.server.core.domain;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import com.zhongshu.reward.client.type.DataState;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.index.Indexed;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.math.BigDecimal;
+
+/**
+ * 钱包
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Data
+@Builder
+@Document
+@AllArgsConstructor
+@NoArgsConstructor
+public class Wallet extends SuperEntity {
+
+    /**
+     * 用户id
+     */
+    @Indexed
+    private String userId;
+
+    /**
+     * 商铺id
+     */
+    @Indexed
+    private String shopId;
+
+
+    /**
+     * 账户余额(可提现金额)
+     */
+    private BigDecimal amount = BigDecimal.ZERO;
+
+    /**
+     * 未结算金额
+     */
+    private BigDecimal waitAmount = BigDecimal.ZERO;
+
+    /**
+     * 当日已提现金额
+     */
+    private BigDecimal todayTransferAmount = BigDecimal.ZERO;
+
+    /**
+     * 钱包状态
+     */
+    private DataState dataState;
+
+}

+ 62 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/WalletReceipts.java

@@ -0,0 +1,62 @@
+package com.zhongshu.reward.server.core.domain;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import com.zhongshu.reward.client.type.ReceiptsStatus;
+import com.zhongshu.reward.client.type.ReceiptsType;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.math.BigDecimal;
+
+/**
+ * 到账记录
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Data
+@Builder
+@Document
+@AllArgsConstructor
+@NoArgsConstructor
+public class WalletReceipts extends SuperEntity {
+
+    /**
+     * 钱包
+     */
+    @DBRef(lazy = true)
+    private Wallet wallet;
+
+    /**
+     * 预计到账时间
+     */
+    private Long estimatedTime;
+
+    /**
+     * 实际到账时间
+     */
+    private Long receiptsTime;
+
+    /**
+     * 到账类型
+     */
+    private ReceiptsType receiptsType;
+
+    /**
+     * 到账金额
+     */
+    private BigDecimal total = BigDecimal.ZERO;
+
+    /**
+     * 状态
+     */
+    private ReceiptsStatus status;
+
+    /**
+     * 外部订单号
+     */
+    private String outTradeNo;
+}

+ 109 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/WxTransferBatch.java

@@ -0,0 +1,109 @@
+package com.zhongshu.reward.server.core.domain;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import com.zhongshu.reward.client.type.TransferChannel;
+import com.zhongshu.reward.client.type.TransferStatus;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.index.Indexed;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.math.BigDecimal;
+
+/**
+ * 提现记录
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Data
+@Builder
+@Document
+@AllArgsConstructor
+@NoArgsConstructor
+public class WxTransferBatch extends SuperEntity {
+
+    /**
+     * 内部批次单号
+     */
+    @Indexed(unique = true)
+    private String batchNo;
+
+    /**
+     * (内部)提现明细单号
+     */
+    @Indexed
+    private String detailNo;
+
+    /**
+     * 提现钱包
+     */
+    @DBRef(lazy = true)
+    private Wallet wallet;
+
+    /**
+     * 提现金额
+     */
+    private BigDecimal total;
+
+    /**
+     * 提现渠道
+     */
+    @Indexed
+    private TransferChannel channel;
+
+    /**
+     * 提现前账户信息
+     */
+    private Wallet beforeWalletInfo;
+
+//    /**
+//     * 到账时间
+//     */
+//    private Long tradeTime;
+
+    /**
+     * 订单状态
+     */
+    @Indexed
+    private TransferStatus transferStatus;
+
+    /**
+     * 批次状态
+     */
+    @Indexed
+    private String batchStatus;
+
+    /**
+     * 明细状态
+     */
+    @Indexed
+    private String detailStatus;
+
+
+    private String closeReason;
+
+    /**
+     * wx批次单号
+     */
+    @Indexed
+    private String wxBatchId;
+
+    /**
+     * wx批次单号
+     */
+    @Indexed
+    private String wxDetailId;
+
+    /**
+     * openid
+     */
+    private String openid;
+
+    /**
+     * 异常原因
+     */
+    private String failReason;
+}

+ 42 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/domain/WxTransferScene.java

@@ -0,0 +1,42 @@
+package com.zhongshu.reward.server.core.domain;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.index.Indexed;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.math.BigDecimal;
+
+/**
+ * 微信转账场景
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Data
+@Builder
+@Document
+@AllArgsConstructor
+@NoArgsConstructor
+public class WxTransferScene extends SuperEntity {
+
+    /**
+     * 转账场景id
+     */
+    @Indexed
+    private String sceneId;
+
+    /**
+     * 单次转账额度
+     */
+    private BigDecimal onceTotal;
+
+    /**
+     * 单日转账额度
+     */
+    private BigDecimal dayTotal;
+
+
+}

+ 23 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/listener/VipEventListener.java

@@ -0,0 +1,23 @@
+package com.zhongshu.reward.server.core.listener;
+
+import com.github.microservice.auth.client.event.auth.EnterpriseApplicationEvent;
+import com.zhongshu.vip.client.event.VipUserEvent;
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.context.ApplicationListener;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author wjf
+ * @date 2024/8/7
+ */
+@Slf4j
+@Order(100)
+@Component
+public class VipEventListener implements ApplicationListener<VipUserEvent> {
+    @Override
+    public void onApplicationEvent(VipUserEvent event) {
+        log.info("收到用户会员订阅消息:{}", event.getStreamModel());
+    }
+}

+ 117 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/service/ChatTransferBatchService.java

@@ -0,0 +1,117 @@
+package com.zhongshu.reward.server.core.service;
+
+import cn.hutool.core.lang.Snowflake;
+import com.wechat.pay.java.core.Config;
+import com.wechat.pay.java.core.RSAAutoCertificateConfig;
+import com.wechat.pay.java.core.exception.HttpException;
+import com.wechat.pay.java.core.exception.MalformedMessageException;
+import com.wechat.pay.java.core.exception.ServiceException;
+import com.wechat.pay.java.service.transferbatch.TransferBatchService;
+import com.wechat.pay.java.service.transferbatch.model.*;
+import com.zhongshu.reward.client.model.wallet.TransferModel;
+import com.zhongshu.reward.client.model.wallet.TransferStatusModel;
+import com.zhongshu.reward.server.core.config.WeChatConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+
+@Service
+@Slf4j
+public class ChatTransferBatchService {
+
+    @Autowired
+    WeChatConfig weChatConfig;
+
+
+//    @Autowired
+//    TransferBatchService service;
+
+    public static TransferBatchService service;
+
+    @Autowired
+    Snowflake snowflake;
+
+
+
+    public  Config RSAAutoCertificateConfig(){
+        // 初始化商户配置
+        return new  RSAAutoCertificateConfig.Builder()
+                        .merchantId(weChatConfig.getMerchantId())
+                        // 使用 com.wechat.pay.java.core.util
+                        // 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
+                        .privateKey(weChatConfig.getPrivateKey())
+                        .merchantSerialNumber(weChatConfig.getMerchantSerialNumber())
+                        .apiV3Key(weChatConfig.getApiV3Key())
+                        .build();
+
+    }
+
+
+    /**
+     * 通过微信批次单号查询批次单
+     */
+    public  TransferBatchEntity getTransferBatchByNo(TransferStatusModel transferStatusModel) {
+        Config config = RSAAutoCertificateConfig();
+        // 初始化服务
+        service = new TransferBatchService.Builder().config(config).build();
+
+        GetTransferBatchByNoRequest request = new GetTransferBatchByNoRequest();
+        BeanUtils.copyProperties(transferStatusModel, request);
+        return service.getTransferBatchByNo(request);
+    }
+
+//    /**
+//     * 通过商家批次单号查询批次单
+//     */
+//    public  TransferBatchEntity getTransferBatchByOutNo() {
+//
+//        GetTransferBatchByOutNoRequest request = new GetTransferBatchByOutNoRequest();
+//        return service.getTransferBatchByOutNo(request);
+//    }
+
+    /**
+     * 发起商家转账
+     */
+    public InitiateBatchTransferResponse initiateBatchTransfer(TransferModel transferModel) {
+        Config config = RSAAutoCertificateConfig();
+        // 初始化服务
+        service = new TransferBatchService.Builder().config(config).build();
+        try {
+            InitiateBatchTransferRequest request = new InitiateBatchTransferRequest();
+            BeanUtils.copyProperties(transferModel,request);
+            request.setAppid(weChatConfig.getAppid());
+            request.setTransferSceneId(transferModel.getTransferSceneId());
+            return service.initiateBatchTransfer(request);
+        } catch (HttpException e) { // 发送HTTP请求失败
+            // 调用e.getHttpRequest()获取请求打印日志或上报监控,更多方法见HttpException定义
+            log.info("发送HTTP请求失败:{}", e.getHttpRequest());
+        } catch (ServiceException e) { // 服务返回状态小于200或大于等于300,例如500
+            // 调用e.getResponseBody()获取返回体打印日志或上报监控,更多方法见ServiceException定义
+            log.info("请求失败2:{}", e.getResponseBody());
+        } catch (MalformedMessageException e) { // 服务返回成功,返回体类型不合法,或者解析返回体失败
+            // 调用e.getMessage()获取信息打印日志或上报监控,更多方法见MalformedMessageException定义
+            log.info("请求失败3:{}", e.getMessage());
+        }
+        return null;
+    }
+
+//    /**
+//     * 通过微信明细单号查询明细单
+//     */
+//    public  TransferDetailEntity getTransferDetailByNo() {
+//
+//        GetTransferDetailByNoRequest request = new GetTransferDetailByNoRequest();
+//        return service.getTransferDetailByNo(request);
+//    }
+//
+//    /**
+//     * 通过商家明细单号查询明细单
+//     */
+//    public  TransferDetailEntity getTransferDetailByOutNo() {
+//
+//        GetTransferDetailByOutNoRequest request = new GetTransferDetailByOutNoRequest();
+//        return service.getTransferDetailByOutNo(request);
+//    }
+}

+ 8 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/service/Impl/WalletFeignServiceImpl.java

@@ -0,0 +1,8 @@
+package com.zhongshu.reward.server.core.service.Impl;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+public class WalletFeignServiceImpl {
+}

+ 65 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/service/InviteReceiptsRoleService.java

@@ -0,0 +1,65 @@
+package com.zhongshu.reward.server.core.service;
+
+import com.zhongshu.reward.client.model.InviteReceiptsRoleModel;
+import com.zhongshu.reward.client.ret.ResultContent;
+import com.zhongshu.reward.server.core.dao.InviteReceiptsRoleDao;
+import com.zhongshu.reward.server.core.domain.InviteReceiptsRole;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.awt.print.Pageable;
+
+/**
+ * @author wjf
+ * @date 2024/8/7
+ */
+@Service
+public class InviteReceiptsRoleService {
+
+    @Autowired
+    InviteReceiptsRoleDao inviteReceiptsRoleDao;
+
+    /**
+     * 添加推广规则
+     * @param inviteReceiptsRoleModel
+     * @return
+     */
+//    public Object add(InviteReceiptsRoleModel inviteReceiptsRoleModel){
+//        boolean existsBySetMeal= inviteReceiptsRoleDao.existsBySetMealIdAndDisable(inviteReceiptsRoleModel.getSetMealId(), false);
+//        if (existsBySetMeal){
+//            return ResultContent.buildFail("该套餐存在推广规则");
+//        }
+//        InviteReceiptsRole inviteReceiptsRole = new InviteReceiptsRole();
+//        BeanUtils.copyProperties(inviteReceiptsRoleModel, inviteReceiptsRole);
+//        return ResultContent.buildContent(toModel(inviteReceiptsRoleDao.save(inviteReceiptsRole)));
+//    }
+
+    public Object update(InviteReceiptsRoleModel inviteReceiptsRoleModel){
+        if (StringUtils.isEmpty(inviteReceiptsRoleModel.getId())) {//添加
+            boolean existsBySetMeal= inviteReceiptsRoleDao.existsBySetMealIdAndDisable(inviteReceiptsRoleModel.getSetMealId(), false);
+            if (existsBySetMeal){
+                return ResultContent.buildFail("该套餐存在推广规则");
+            }
+        }else if (!inviteReceiptsRoleDao.existsById(inviteReceiptsRoleModel.getId())){
+            return ResultContent.buildContent("找不到要修改的推广规则");
+        }
+
+        InviteReceiptsRole inviteReceiptsRole = new InviteReceiptsRole();
+        BeanUtils.copyProperties(inviteReceiptsRoleModel, inviteReceiptsRole);
+        return ResultContent.buildContent(toModel(inviteReceiptsRoleDao.save(inviteReceiptsRole)));
+    }
+
+
+
+
+    InviteReceiptsRoleModel toModel(InviteReceiptsRole inviteReceiptsRole){
+        InviteReceiptsRoleModel model = new InviteReceiptsRoleModel();
+        if (ObjectUtils.isNotEmpty(inviteReceiptsRole)){
+            BeanUtils.copyProperties(inviteReceiptsRole, model);
+        }
+        return model;
+    }
+}

+ 98 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/service/WalletReceiptsService.java

@@ -0,0 +1,98 @@
+package com.zhongshu.reward.server.core.service;
+
+import com.github.microservice.core.util.result.content.ResultContent;
+import com.github.microservice.core.util.result.content.ResultState;
+import com.zhongshu.reward.client.model.param.WalletReceiptsParam;
+import com.zhongshu.reward.client.model.wallet.WalletReceiptsModel;
+import com.zhongshu.reward.client.type.ReceiptsStatus;
+import com.zhongshu.reward.server.core.dao.WalletDao;
+import com.zhongshu.reward.server.core.dao.WalletReceiptsDao;
+import com.zhongshu.reward.server.core.domain.Wallet;
+import com.zhongshu.reward.server.core.domain.WalletReceipts;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @author wjf
+ * @date 2024/8/6
+ */
+@Service
+@Slf4j
+public class WalletReceiptsService {
+
+    @Autowired
+    WalletDao walletDao;
+
+    @Autowired
+    WalletService walletService;
+
+    @Autowired
+    WalletReceiptsDao walletReceiptsDao;
+
+    /**
+     * 邀请返利入账
+     * @param param
+     * @return
+     */
+    @Transactional
+    public Object receipts(WalletReceiptsParam param){
+
+        Wallet wallet = walletService.getWalletByUserId(param.getUserId());
+
+        WalletReceipts walletReceipts = new WalletReceipts();
+        BeanUtils.copyProperties(param, walletReceipts);
+        walletReceipts.setWallet(wallet);
+        if (walletReceipts.getReceiptsType()==null){
+            walletReceipts.setStatus(ReceiptsStatus.WAIT);
+        }
+        wallet.setWaitAmount(wallet.getWaitAmount().add(param.getTotal()));
+        walletDao.save(wallet);
+        return ResultContent.buildContent(toModel(walletReceiptsDao.save(walletReceipts)));
+    }
+
+    /**
+     * 取消返利入账
+     * @param
+     * @return
+     */
+    @Transactional
+    public Object cancelReceipts(String outTradeNo){
+
+        WalletReceipts walletReceipts = walletReceiptsDao.findTopByOutTradeNo(outTradeNo);
+        if (ObjectUtils.isEmpty(walletReceipts)){
+            return ResultContent.build(ResultState.Fail,"返利订单不存在或未入账");
+        }
+        if (!walletReceipts.getStatus().equals(ReceiptsStatus.WAIT)){
+            return ResultContent.build(ResultState.Fail,"订单不处于未结算状态");
+        }
+
+        walletReceipts.setStatus(ReceiptsStatus.CANCEL);
+        walletReceiptsDao.save(walletReceipts);
+        Wallet wallet = walletDao.findTop1ById(walletReceipts.getWallet().getId());
+        wallet.setWaitAmount(wallet.getWaitAmount().subtract(walletReceipts.getTotal()));
+        walletDao.save(wallet);
+        return ResultContent.build(ResultState.Success);
+    }
+
+    public Object listByWallet(String walletId){
+        List<WalletReceipts> list = walletReceiptsDao.findByWallet_IdOrderByCreateTimeDesc(walletId);
+        return ResultContent.buildContent(list.stream().map(this::toModel).collect(Collectors.toList()));
+    }
+
+    WalletReceiptsModel toModel(WalletReceipts walletReceipts){
+        WalletReceiptsModel model = new WalletReceiptsModel();
+        if (null != walletReceipts){
+            BeanUtils.copyProperties(walletReceipts, model, "wallet");
+            model.setWalletId(walletReceipts.getWallet().getId());
+        }
+        return model;
+    }
+}

+ 58 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/service/WalletService.java

@@ -0,0 +1,58 @@
+package com.zhongshu.reward.server.core.service;
+
+import com.github.microservice.auth.security.helper.AuthHelper;
+import com.github.microservice.core.util.result.content.ResultContent;
+import com.zhongshu.reward.client.model.wallet.WalletModel;
+import com.zhongshu.reward.client.type.DataState;
+import com.zhongshu.reward.server.core.dao.WalletDao;
+import com.zhongshu.reward.server.core.domain.Wallet;
+import org.apache.commons.lang3.ObjectUtils;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Service
+public class WalletService {
+
+    @Autowired
+    AuthHelper authHelper;
+
+    @Autowired
+    WalletDao walletDao;
+
+    /**
+     * 获取当前登录用户(开通)钱包
+     */
+    public ResultContent getWallet(String userId){
+        Wallet wallet = getWalletByUserId(userId);
+        return ResultContent.buildContent(toModel(wallet));
+    }
+
+    @NotNull
+    public Wallet getWalletByUserId(String userId) {
+        if (ObjectUtils.isEmpty(userId)){
+            userId = authHelper.getCurrentUser().getUserId();
+        }
+        Wallet wallet = walletDao.findByUserId(userId);
+        if (wallet==null){
+            wallet = new Wallet();
+            wallet.setUserId(userId);
+            wallet.setDataState(DataState.Enable);
+            wallet = walletDao.save(wallet);
+        }
+        return wallet;
+    }
+
+    private WalletModel toModel(Wallet wallet){
+        WalletModel walletModel = new WalletModel();
+        if (wallet!=null){
+            BeanUtils.copyProperties(wallet, walletModel);
+        }
+        return walletModel;
+    }
+}

+ 226 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/service/WxTransferService.java

@@ -0,0 +1,226 @@
+package com.zhongshu.reward.server.core.service;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.Snowflake;
+import com.github.microservice.auth.client.content.ResultContent;
+import com.github.microservice.auth.client.content.ResultState;
+import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse;
+import com.wechat.pay.java.service.transferbatch.model.TransferBatchEntity;
+import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
+import com.zhongshu.reward.client.model.param.WalletTransferParam;
+import com.zhongshu.reward.client.model.wallet.TransferModel;
+import com.zhongshu.reward.client.model.wallet.TransferStatusModel;
+import com.zhongshu.reward.client.model.wallet.WxTransferBatchModel;
+import com.zhongshu.reward.client.ret.CommentException;
+import com.zhongshu.reward.client.type.TimeUnitType;
+import com.zhongshu.reward.client.type.TransferChannel;
+import com.zhongshu.reward.client.type.TransferStatus;
+import com.zhongshu.reward.server.core.dao.TransferRulerDao;
+import com.zhongshu.reward.server.core.dao.WalletDao;
+import com.zhongshu.reward.server.core.dao.WxTransferBatchDao;
+import com.zhongshu.reward.server.core.domain.TransferRuler;
+import com.zhongshu.reward.server.core.domain.Wallet;
+import com.zhongshu.reward.server.core.domain.WxTransferBatch;
+import com.zhongshu.reward.server.core.util.DateUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.aggregation.DateOperators;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAdjusters;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Service
+@Slf4j
+public class WxTransferService {
+
+    @Autowired
+    WalletDao walletDao;
+
+    @Autowired
+    ChatTransferBatchService wechatService;
+
+    @Autowired
+    Snowflake snowflake;
+
+    @Autowired
+    WxTransferBatchDao wxTransferBatchDao;
+
+    @Autowired
+    TransferRulerDao transferRulerDao;
+
+
+    /**
+     * 发起提现
+     * @param param
+     * @return
+     */
+    @Transactional
+    public Object transfer(WalletTransferParam param){
+        Wallet wallet = walletDao.findTop1ById(param.getWalletId());
+        //校验提现规则
+        validTransfer(param.getTotal(), wallet);
+
+        String outBatchNo = snowflake.nextIdStr();
+        String outDetailNo = snowflake.nextIdStr();
+
+        TransferModel transferModel = new TransferModel();
+        transferModel.setBatchName("佣金/返利发放");
+        transferModel.setBatchRemark("佣金/返利发放");
+        transferModel.setTotalAmount(param.getTotal().longValue());
+        transferModel.setOutBatchNo(outBatchNo);
+
+        List<TransferDetailInput> detailList = new ArrayList<>();
+        TransferDetailInput detail = new TransferDetailInput();
+        detail.setTransferAmount(param.getTotal().longValue());
+        detail.setTransferRemark("佣金/返利发放");
+        detail.setOpenid(param.getOpenid());
+        detail.setOutDetailNo(outDetailNo);
+        detailList.add(detail);
+        transferModel.setTotalNum(detailList.size());
+        transferModel.setTransferDetailList(detailList);
+
+        InitiateBatchTransferResponse response = wechatService.initiateBatchTransfer(transferModel);
+        if (response==null){
+            return ResultContent.build(ResultState.Fail);
+        }
+
+        WxTransferBatch wxTransferBatch = new WxTransferBatch();
+        wxTransferBatch.setBatchNo(outBatchNo);
+        wxTransferBatch.setDetailNo(outDetailNo);
+        wxTransferBatch.setWallet(wallet);
+        wxTransferBatch.setTotal(param.getTotal());
+        wxTransferBatch.setChannel(TransferChannel.WeChat);
+        wxTransferBatch.setBeforeWalletInfo(wallet);
+        wxTransferBatch.setBatchStatus(response.getBatchStatus());
+        wxTransferBatch.setWxBatchId(response.getBatchId());
+        wxTransferBatch.setTransferStatus(TransferStatus.PROCESSING);
+
+        wxTransferBatchDao.save(wxTransferBatch);
+        wallet.setAmount(wallet.getAmount().subtract(param.getTotal()));
+        wallet.setTodayTransferAmount(wallet.getTodayTransferAmount().add(param.getTotal()));
+        walletDao.save(wallet);
+        return ResultContent.build(ResultState.Success);
+    }
+
+
+
+    public Object queryTransfer(String walletId, Integer year, Integer month){
+        Long monthStartTime = DateUtils.getMonthStartTime(year, month);
+        Long monthEndTime = DateUtils.getMonthEndTime(year, month);
+        List<WxTransferBatch> list = wxTransferBatchDao.list(walletId, monthStartTime, monthEndTime);
+        return ResultContent.buildContent(list.stream().map(this::toModel).collect(Collectors.toList()));
+    }
+
+    @Transactional
+    public Object updateTransferStatus(String transferId){
+        WxTransferBatch wxTransferBatch = wxTransferBatchDao.findTop1ById(transferId);
+        if (ObjectUtils.isEmpty(wxTransferBatch)){
+            return ResultContent.build(ResultState.Fail, "提现订单不存在");
+        }
+
+        TransferStatus transferStatus = wxTransferBatch.getTransferStatus();
+        if (!transferStatus.equals(TransferStatus.PROCESSING)){
+            return ResultContent.build(ResultState.Success);
+        }
+
+        TransferStatusModel transferStatusModel = new TransferStatusModel();
+        transferStatusModel.setBatchId(wxTransferBatch.getWxBatchId());
+        transferStatusModel.setNeedQueryDetail(true);
+        transferStatusModel.setDetailStatus("ALL");
+        TransferBatchEntity transferBatchByNo = wechatService.getTransferBatchByNo(transferStatusModel);
+
+        String batchStatus = transferBatchByNo.getTransferBatch().getBatchStatus();
+        String detailStatus = transferBatchByNo.getTransferDetailList().get(0).getDetailStatus();
+
+        if(batchStatus.equals("FINISHED") && detailStatus.equals("SUCCESS")){
+            transferStatus = TransferStatus.SUCCESS;
+        }else if(batchStatus.equals("CLOSED")){
+            transferStatus = TransferStatus.CLOSE;
+            Wallet wallet = walletDao.findTop1ById(wxTransferBatch.getWallet().getId());
+            wallet.setAmount(wallet.getAmount().add(wxTransferBatch.getTotal()));
+            wallet.setTodayTransferAmount(wallet.getTodayTransferAmount().subtract(wxTransferBatch.getTotal()));
+            walletDao.save(wallet);
+        }else if (detailStatus.equals("FAIL")){
+            transferStatus = TransferStatus.FAIL;
+            Wallet wallet = walletDao.findTop1ById(wxTransferBatch.getWallet().getId());
+            wallet.setAmount(wallet.getAmount().add(wxTransferBatch.getTotal()));
+            wallet.setTodayTransferAmount(wallet.getTodayTransferAmount().subtract(wxTransferBatch.getTotal()));
+            walletDao.save(wallet);
+        }
+        boolean update = wxTransferBatchDao.updateStatus(transferId, batchStatus, detailStatus, transferStatus);
+        log.info("更新微信转账批次状态:结果:{}, id:{}, batchStatus:{}, detailStatus: {}, transferStatus: {}",update, transferId, batchStatus, detailStatus, transferStatus);
+        return ResultContent.build(update);
+    }
+
+    WxTransferBatchModel toModel(WxTransferBatch wxTransferBatch){
+        WxTransferBatchModel model = new WxTransferBatchModel();
+        if (null != wxTransferBatch){
+            BeanUtil.copyProperties(wxTransferBatch, model, "beforeWalletInfo", "wallet");
+            model.setWalletId(wxTransferBatch.getWallet().getId());
+        }
+        return model;
+    }
+
+    void validTransfer(BigDecimal total, Wallet wallet){
+        long currentTime = System.currentTimeMillis();
+        Integer size = 0;
+        List<TransferRuler> list = transferRulerDao.findAll();
+        if (list.isEmpty()){
+            throw new CommentException(com.zhongshu.reward.client.ret.ResultState.Exception, "管理员未设置提现规则");
+        }
+        TransferRuler transferRuler = list.get(0);
+        //提现时间
+        if (transferRuler.getTimeUnit().equals(TimeUnitType.MONTH)){//每月
+            Long dayOfMonthStartTime = DateUtils.getDayOfMonthStartTime(transferRuler.getStartDay());
+            Long dayOfMonthEndTime = DateUtils.getDayOfMonthEndTime(transferRuler.getEndDay());
+            if (currentTime < dayOfMonthStartTime || currentTime > dayOfMonthEndTime){
+                throw new CommentException(com.zhongshu.reward.client.ret.ResultState.Exception, "当前不处于提现时间段");
+            }
+            size = wxTransferBatchDao.countByTime(wallet.getId(), dayOfMonthStartTime, dayOfMonthEndTime).intValue();
+        }else if (transferRuler.getTimeUnit().equals(TimeUnitType.DAY)){
+            Long hourMinuteStartTime = DateUtils.getHourMinuteStartTime(transferRuler.getStartHour(), transferRuler.getStartMinute());
+            Long hourMinuteEndTime = DateUtils.getHourMinuteEndTime(transferRuler.getEndHour(), transferRuler.getEndMinute());
+            if (currentTime < hourMinuteStartTime || currentTime > hourMinuteEndTime){
+                throw new CommentException(com.zhongshu.reward.client.ret.ResultState.Exception, "当前不处于提现时间段");
+            }
+            size = wxTransferBatchDao.countByTime(wallet.getId(), hourMinuteStartTime, hourMinuteEndTime).intValue();
+        }
+        //单笔金额
+        if (total.compareTo(transferRuler.getMinTotal()) < 0){
+            throw new CommentException(com.zhongshu.reward.client.ret.ResultState.Exception, "单笔提现金额低于最小值");
+        }else if (total.compareTo(transferRuler.getMaxTotal()) > 0){
+            throw new CommentException(com.zhongshu.reward.client.ret.ResultState.Exception, "单笔提现金额超出最大值");
+        }
+
+        //判断提现额度是否超出每日上限
+        Integer sumDayTotal = wxTransferBatchDao.sumDayTotal(wallet.getId(), DateUtils.getCurrentDayStartTime().getTime(), DateUtils.getCurrentDayEndTime().getTime());
+        if (total.add(BigDecimal.valueOf(sumDayTotal)).compareTo(transferRuler.getDayMaxTotal()) > 0){
+            throw new CommentException(com.zhongshu.reward.client.ret.ResultState.Exception, "超出每日提现金额上限");
+//            return ResultContent.build(ResultState.Fail, "超出每日提现金额上限");
+        }
+        //判断可提现金额是否足够
+        if (total.compareTo(wallet.getAmount()) < 0){
+            throw new CommentException(com.zhongshu.reward.client.ret.ResultState.Exception, "可提现余额不足");
+//            return ResultContent.build(ResultState.Fail, "可提现余额不足");
+        }
+        //提现次数
+        if (transferRuler.getSize() >= size){
+            throw new CommentException(com.zhongshu.reward.client.ret.ResultState.Exception, "超过可提现次数");
+        }
+    }
+
+
+}

+ 56 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/timer/WalletTimer.java

@@ -0,0 +1,56 @@
+package com.zhongshu.reward.server.core.timer;
+
+
+import com.zhongshu.reward.client.type.TransferStatus;
+import com.zhongshu.reward.server.core.dao.WalletDao;
+import com.zhongshu.reward.server.core.dao.WxTransferBatchDao;
+import com.zhongshu.reward.server.core.domain.WxTransferBatch;
+import com.zhongshu.reward.server.core.service.WxTransferService;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author wjf
+ * @date 2024/8/5
+ */
+@Component
+@Log4j2
+public class WalletTimer {
+
+    @Autowired
+    WalletDao walletDao;
+
+    @Autowired
+    WxTransferBatchDao wxTransferBatchDao;
+
+    @Autowired
+    WxTransferService wxTransferService;
+
+    /**
+     * 重置每日提现额度
+     */
+    @Scheduled(cron = "0 0 0 * * ?")
+    public void resetTodayAmount(){
+        try {
+            walletDao.resetTodayAmount();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    @Scheduled(fixedRate = 5000)
+    public void updateTransferStatus(){
+        try {
+            List<WxTransferBatch> byTransferStatus = wxTransferBatchDao.findByTransferStatus(TransferStatus.PROCESSING);
+            for (WxTransferBatch wxTransferBatch : byTransferStatus){
+                wxTransferService.updateTransferStatus(wxTransferBatch.getId());
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+}

+ 156 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/util/DateUtils.java

@@ -0,0 +1,156 @@
+package com.zhongshu.reward.server.core.util;
+
+import cn.hutool.log.Log;
+import lombok.extern.slf4j.Slf4j;
+
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * @author wjf
+ * @date 2024/8/8
+ */
+@Slf4j
+public class DateUtils {
+
+
+    /**
+     * 获得本天的开始时间
+     *
+     * @return
+     */
+    public static Date getCurrentDayStartTime() {
+        ZoneId zoneId = ZoneId.systemDefault();
+        LocalDateTime date = LocalDateTime.now();
+        LocalDateTime startOfTheDay = LocalDateTime.of(date.toLocalDate(), LocalTime.MIN);
+        Date beginTime = Date.from(startOfTheDay.atZone(zoneId).toInstant());
+        return beginTime;
+    }
+
+    /**
+     * 获得本天的结束时间
+     *
+     * @return
+     */
+    public static Date getCurrentDayEndTime() {
+        ZoneId zoneId = ZoneId.systemDefault();
+        LocalDateTime date = LocalDateTime.now();
+        LocalDateTime startOfTheDay = LocalDateTime.of(date.toLocalDate(), LocalTime.MAX);
+        Date beginTime = Date.from(startOfTheDay.atZone(zoneId).toInstant());
+        return beginTime;
+    }
+
+    /**
+     * 本月指定日的开始时间
+     *
+     * @return
+     */
+    public static Long getDayOfMonthStartTime(Integer day) {
+        Calendar c = Calendar.getInstance();
+
+        c.set(Calendar.DATE, 1);
+        c.add(Calendar.DATE, day-1);
+
+        c.set(Calendar.HOUR_OF_DAY, 23);
+        c.set(Calendar.MINUTE, 59);
+        c.set(Calendar.SECOND, 59);
+
+        return c.getTimeInMillis();
+    }
+
+    /**
+     * 本月指定日的结束时间
+     *
+     * @return
+     */
+    public static Long getDayOfMonthEndTime(Integer day) {
+        Calendar c = Calendar.getInstance();
+
+        c.set(Calendar.DATE, 1);
+        c.add(Calendar.DATE, day-1);
+
+        c.set(Calendar.HOUR_OF_DAY, 0);
+        c.set(Calendar.MINUTE, 0);
+        c.set(Calendar.SECOND, 0);
+
+        return c.getTimeInMillis();
+    }
+
+    /**
+     * 指定年月开始时间
+     *
+     * @return
+     */
+    public static Long getMonthStartTime(Integer year, Integer month) {
+        Calendar c = Calendar.getInstance();
+
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, month - 1);
+        c.set(Calendar.DATE, 1);
+
+        c.set(Calendar.HOUR_OF_DAY, 0);
+        c.set(Calendar.MINUTE, 0);
+        c.set(Calendar.SECOND, 0);
+
+        return c.getTimeInMillis();
+
+    }
+
+    /**
+     * 指定年月结束时间
+     *
+     * @return
+     */
+    public static Long getMonthEndTime(Integer year, Integer month) {
+        Calendar c = Calendar.getInstance();
+
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, month - 1);
+        c.add(Calendar.MONTH, 1);
+        c.set(Calendar.DAY_OF_MONTH, 0);
+
+        c.set(Calendar.HOUR_OF_DAY, 23);
+        c.set(Calendar.MINUTE, 59);
+        c.set(Calendar.SECOND, 59);
+        return c.getTimeInMillis();
+    }
+
+    /**
+     * 当天指定时分开始时间 time: HH:mm
+     *
+     * @return
+     */
+    public static Long getHourMinuteStartTime(Integer hour, Integer minute) {
+        Calendar c = Calendar.getInstance();
+
+        c.set(Calendar.HOUR_OF_DAY, hour);
+        c.set(Calendar.MINUTE, minute);
+        c.set(Calendar.SECOND, 59);
+        return c.getTimeInMillis();
+    }
+
+    /**
+     * 当天指定时分结束时间 time: HH:mm
+     *
+     * @return
+     */
+    public static Long getHourMinuteEndTime(Integer hour, Integer minute) {
+        Calendar c = Calendar.getInstance();
+
+        c.set(Calendar.HOUR_OF_DAY, 21);
+        c.set(Calendar.MINUTE, hour);
+        c.set(Calendar.SECOND, minute);
+        return c.getTimeInMillis();
+    }
+
+    public static void main(String[] args) {
+        Calendar c = Calendar.getInstance();
+
+        c.set(Calendar.HOUR_OF_DAY, 21);
+        c.set(Calendar.MINUTE, 50);
+        c.set(Calendar.SECOND, 59);
+    }
+}

+ 41 - 0
RewardServer/src/main/resources/application-dev.yml

@@ -0,0 +1,41 @@
+spring:
+  data:
+    mongodb:
+      #uri: mongodb://paymentcenter:paymentcenter@192.168.110.241:30117,192.168.110.241:30118,192.168.110.241:30119/paymentcenter?replicaSet=MongoSetsShard1
+      uri: mongodb://rewardcenter:rewardcenter@192.168.110.241:30117,192.168.110.241:30118,192.168.110.241:30119/rewardcenter?replicaSet=MongoSetsShard1
+      auto-index-creation: true
+  redis:
+    host: 192.168.110.241
+    port: 6379
+    database: 6
+
+swagger:
+  packageName: "com.zhongshu.reward.core.controller"
+  title: ${project.artifactId}
+  description: ${project.description}
+  version: "1.0"
+  enable: true
+
+payment:
+  mer_no: 89852017372911Y
+  tid: PEYAH8X1
+  accesser_id: GZHYXHSH52011
+  key: udik876ehjde32dU61edsxsf
+  h5_page_url: https://selfapply-test.chinaums.com/self-sign-mobile/#/chooseRole
+  pc_page_url: https://selfapply-test.chinaums.com/self-sign-web/#/verify
+  interface_url: https://selfapply-test.chinaums.com/self-contract-nmrs/interface/autoReg
+#  interface_url: http://192.168.110.241:7300/mock/654babd538574f002773e5f8/dev/autoReg
+#  interface_url: https://yinshangpai.chinaums.com/self-contract-nmrs/interface/autoReg
+  pay_url: https://dhjt-uat.chinaums.com/queryService/UmsWebPayPlugins
+  pay_key: 11111111111111111111111111111111
+  withdrawals_url: https://dhjt.chinaums.com/entryService/unified-withdrawals-api
+  # 提现秘钥
+  withdrawals_key: 11111111111111111111111111111111
+  notifyUrl: https://api.dev.zonelife.cn/springbatchservice/pay/sync
+#  pay_url: https://dhjt-api.chinaums.com/queryService/UmsWebPayPlugins
+
+
+
+#knife4j:
+#debug: true
+#  production: false

+ 64 - 0
RewardServer/src/main/resources/application.yml

@@ -0,0 +1,64 @@
+#Web?????
+server:
+  port: 9403
+
+#??????
+spring:
+  cloud:
+    consul:
+      discovery:
+        prefer-ip-address: true # ip????
+        hostname: localhost    # ??????
+        port: ${server.port}
+        health-check-path: /actuator/health  # ??????
+        health-check-interval: 10s   # ??10s??
+        register: true  # ????
+        service-name: ${spring.application.name} # ????
+        instance-id: ${spring.application.name}:${server.port}
+      host: ${ApplicationCenter.url}
+      port: ${ApplicationCenter.port}
+    #kafka
+    stream:
+      kafka:
+        binder:
+          brokers: ${Kafka.brokers}
+          replication-factor: 1
+      function:
+        definition: userLogStreamConsumer;vipUserStreamConsumer
+      bindings:
+        userLogStreamConsumer-in-0:
+          destination: UserLogStream
+          group: ${project.artifactId}
+        vipUserStreamConsumer-in-0:
+          destination: VipUserStream
+          group: ${project.artifactId}
+    bus:
+      enabled: true
+  #??zipkin???????
+  zipkin:
+    base-url: ${Zipkin.baseUrl}
+    enabled: true
+    sender:
+      type: web
+  sleuth:
+    sampler:
+      probability: ${Zipkin.sampler.probability}
+
+
+
+
+wechat:
+  merchantId: 111
+  privateKey: 1212
+  merchantSerialNumber: 111
+  apiV3Key: 1111
+  appid: 1111
+  transferSceneId: 1111
+
+
+
+#????????
+logging:
+  file:
+    name: logs/${project.artifactId}.log
+#debug: true

+ 23 - 0
RewardServer/src/main/resources/bootstrap.yml

@@ -0,0 +1,23 @@
+###需拷贝到每一个模块下
+
+spring:
+  mvc:
+    pathmatch:
+      matching-strategy: ant_path_matcher
+  main: #允许循环引用
+    allow-circular-references: true
+  # 应用名
+  application:
+    name: ${project.artifactId}
+  # 当前读取配置文件的类型
+  profiles:
+    active: ${spring.profiles.active}
+  #配置中心
+  cloud:
+    config:
+      uri: ${ConfigCenter.url}
+      name: ${project.artifactId},ConfigCenter
+  autoconfigure:
+    exclude:
+      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
+      - org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration

+ 402 - 0
RewardServer/src/test/java/com/zhongshu/payment/server/ServerApplicationTests.java

@@ -0,0 +1,402 @@
+package com.zhongshu.payment.server;
+
+import cn.hutool.core.lang.Snowflake;
+import cn.hutool.json.JSONUtil;
+import com.github.microservice.auth.client.content.ResultContent;
+import com.zhongshu.payment.client.model.order.AdminSeachOrderModel;
+import com.zhongshu.payment.client.model.order.v2.*;
+import com.zhongshu.payment.client.model.payment.CreateRequestModel;
+import com.zhongshu.payment.client.model.payment.CreateResponseModel;
+import com.zhongshu.payment.client.model.payment.SubOrdersConfirmResponseModel;
+import com.zhongshu.payment.client.model.payment.withdrawals.*;
+import com.zhongshu.payment.client.model.payment.zswl.ApplyWithdrawalsModel;
+import com.zhongshu.payment.client.service.v2.OrderService2;
+import com.zhongshu.payment.client.type.Channel;
+import com.zhongshu.payment.client.type.JobFlowMap;
+import com.zhongshu.payment.client.type.OrderType;
+import com.zhongshu.payment.server.core.api.PaymentApi;
+import com.zhongshu.payment.server.core.api.PaymentApi2;
+import com.zhongshu.payment.server.core.api.WithdrawalsApi;
+import com.zhongshu.payment.server.core.config.PaymentConfig;
+import com.zhongshu.payment.server.core.dao.*;
+import com.zhongshu.payment.server.core.domain.Complex;
+import com.zhongshu.payment.server.core.domain.Goods;
+import com.zhongshu.payment.server.core.domain.PaymentBind;
+import com.zhongshu.payment.server.core.domain.PaymentInfo;
+import com.zhongshu.payment.server.core.service.v2.PaymentServerImpl2;
+import com.zhongshu.payment.server.core.timer.ComplexTimer;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.util.Assert;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+@SpringBootTest
+public class ServerApplicationTests {
+
+    private static final Logger log = LoggerFactory.getLogger(ServerApplicationTests.class);
+    @Autowired
+    Snowflake snowflake;
+
+    @Autowired
+    PaymentApi paymentApi;
+
+    @Autowired
+    WithdrawalsApi withdrawalsApi;
+
+    @Autowired
+    PaymentConfig paymentConfig;
+
+
+    @Autowired
+    PaymentServerImpl2 paymentService2;
+
+    @Autowired
+    OrderService2 orderService2;
+
+    @Autowired
+    PaymentBindDao paymentBindDao;
+
+    @Autowired
+    ApiLogDao apiLogDao;
+
+    @Autowired
+    GoodsDao goodsDao;
+
+    @Autowired
+    ComplexDao complexDao;
+
+    @Autowired
+    PaymentDao paymentDao;
+
+    @Autowired
+    Order2Dao order2Dao;
+
+    @Autowired
+    TransferDetailDao transferDetailDao;
+    @Autowired
+    private TransferDao transferDao;
+
+    @Autowired
+    ComplexTimer complexTimer;
+
+
+
+    @Test
+    public void payOrder() {
+
+        orderService2.findChannelGoods(JobFlowMap.Hotel,"");
+    }
+
+    @Test
+    public void query() {
+
+        AdminSeachOrderModel adminSeachOrderModel = new AdminSeachOrderModel();
+        adminSeachOrderModel.setPlatInter(true);
+        adminSeachOrderModel.setOrderType(OrderType.REFUNDED);
+        orderService2.adminSearch(adminSeachOrderModel);
+
+    }
+
+    @Test
+    public void create() {
+        Complex byAccesserUserId = complexDao.findByAccesser_user_id("65aa17f980f6d56f44643a1f");
+        Assert.isTrue(byAccesserUserId.isFinish(), "签约未完成");
+        String merNo = byAccesserUserId.getMer_no();
+//        String mappNo = byAccesserUserId.getMapp_info_list().get(0).getMapp_no();
+
+        GetMoneyDetailRequest getDetailRequest = new GetMoneyDetailRequest();
+        getDetailRequest.setTransMid(merNo);
+//        getDetailRequest.setMappId(mappNo);
+        GetMoneyDetailResponse moneyDetail = withdrawalsApi.getMoneyDetail(getDetailRequest);
+
+//        String quotaUse = moneyDetail.getData().get(0).getQuotaUse();
+//        CountDetail countDetail = new CountDetail();
+//        countDetail.setQuotaUse(quotaUse);
+    }
+
+
+    @Test
+    public void refund() {
+
+//        PaymentBind bind = paymentBindDao.findByEpId("Platform");
+//        PaymentInfo paymentInfo = bind.getPaymentInfo();
+//////
+//////
+//        RefundRequestModel requestModel = new RefundRequestModel();
+//        requestModel.setPlatformAmount(0L);
+//        requestModel.setRefundDesc("测试退款,未分账退款");
+//        requestModel.setRefundOrderId("42171772810695244943360");
+//        requestModel.setRefundAmount(10L);
+//        requestModel.setBillDate("2024-03-27");
+//        requestModel.setTid("PEYAH8X1");
+//        requestModel.setMerOrderId("89852017372911Y");
+//        CreateRequestModel.SubOrders subOrders = new CreateRequestModel.SubOrders();
+//        subOrders.setMid("89852015995900D");
+//        subOrders.setTotalAmount(10L);
+//
+//
+//        requestModel.setSubOrders(List.of(subOrders));
+//
+//
+//        PaymentApi2 paymentApi2 = new PaymentApi2(paymentInfo, apiLogDao);
+//        RefundResponseModel refund = paymentApi2.refund(requestModel);
+//        System.out.println(refund);
+
+        RefundParam2Model refundParam2Model = new RefundParam2Model();
+        refundParam2Model.setRefundAmount(BigDecimal.valueOf(10));
+        refundParam2Model.setBuyShopAmount(BigDecimal.valueOf(10));
+        refundParam2Model.setPlatformAmount(BigDecimal.valueOf(0));
+        refundParam2Model.setUseShopAmount(BigDecimal.valueOf(0));
+
+//        Goods goods = goodsDao.findById("6603823d85012d0d233372b2").get();
+//        paymentService2.refund(refundParam2Model, goods);
+
+        paymentService2.close("1788021041601630208", "660a534e32e63427d1a09c2a");
+
+    }
+
+    @Test
+    public void close() {
+
+
+        PaymentBind bind = paymentBindDao.findByChannel(Channel.ZhongShu);
+        PaymentInfo paymentInfo = bind.getPaymentInfo();
+        CreateRequestModel createRequestModel = new CreateRequestModel("wx.unifiedOrder");
+        createRequestModel.setExpireTime("2024-03-30 12:12:12");
+
+        createRequestModel.setMerOrderId("4217" + "22222222222222");
+        createRequestModel.setBusiOrderId("1111111111111111");
+        createRequestModel.setMid("89852017372911Y");
+        createRequestModel.setTid("PEYAH8X1");
+        createRequestModel.setTotalAmount(10L);
+        createRequestModel.setSubOpenId("oZJ7S4uer9LHDvLrIWmDQRuFtk98");
+        createRequestModel.setEmployeeNo("gonghao");
+//        createRequestModel.setNotifyUrl(paymentInfo.getNotifyUrl());
+//        createRequestModel.setReturnUrl("回调链接");
+        // 是否分账
+        createRequestModel.setDivisionFlag(false);
+        // 异步分账
+
+
+        PaymentApi2 paymentApi2 = new PaymentApi2(paymentInfo, apiLogDao);
+        CreateResponseModel responseBaseModel = paymentApi2.creatOrder(createRequestModel);
+        System.out.println(responseBaseModel);
+    }
+
+    @Test
+    public void ttt() {
+
+        AdminSeachOrderModel adminSeachOrderModel = new AdminSeachOrderModel();
+        adminSeachOrderModel.setNoOrGName("1772440085801148416");
+        adminSeachOrderModel.setShopId("");
+
+        ResultContent<Page<OrderResult2Model>> pageResultContent = orderService2.adminSearch(adminSeachOrderModel);
+
+        System.out.println(pageResultContent.getContent());
+
+    }
+
+    @Test
+    public void ttt2() {
+
+        AdminSeachOrderModel adminSeachOrderModel = new AdminSeachOrderModel();
+        adminSeachOrderModel.setOrderType(OrderType.WAIT_USE);
+        ResultContent<Page<OrderResult2Model>> pageResultContent = orderService2.adminSearch(adminSeachOrderModel);
+        System.out.println(pageResultContent);
+//        ResultContent<SubOrdersConfirmResponseModel> subOrdersConfirmResponseModelResultContent = paymentService2.subOrdersConfirm("66042b98aefddc65323e187e", "6580f9b9cae1326607eaa24a");
+//        subOrdersConfirmResponseModelResultContent.getContent();
+        List<Goods> distinctByGoodsIdAndUserId = goodsDao.findByGoodsIdAndUserId("1772928077253447680", "65fe583d74d67a7dbd842b45");
+        System.out.println(distinctByGoodsIdAndUserId.size());
+
+
+    }
+
+
+    @Test
+    public void videoWithdrawals() {
+
+
+    }
+
+
+    @Test
+    public void batchQueryRequest() {
+        BatchQueryRequest batchQueryRequest = new BatchQueryRequest();
+        batchQueryRequest.setBatchNo("17453442885887262722");
+        batchQueryRequest.setTxnDate("20240417");
+        batchQueryRequest.setTransMid("89852017372912P");
+
+        BatchQueryResponse withdrawals = withdrawalsApi.batchQuery(batchQueryRequest);
+        log.info("响应:{}", JSONUtil.toJsonStr(withdrawals));
+
+    }
+
+
+    @Test
+    public void tt112t() {
+
+        ApplyWithdrawalsModel applyWithdrawalsModel = new ApplyWithdrawalsModel();
+        applyWithdrawalsModel.setPlatform(false);
+        applyWithdrawalsModel.setChannel(Channel.ZhongShu);
+        applyWithdrawalsModel.setShopId("6605627832e63427d1a08714");
+
+        paymentService2.applicationWithdrawals(applyWithdrawalsModel);
+
+        ApplyWithdrawalsModel applyWithdrawalsModel1 = new ApplyWithdrawalsModel();
+        applyWithdrawalsModel1.setPlatform(true);
+        applyWithdrawalsModel1.setChannel(Channel.ZhongShu);
+        applyWithdrawalsModel1.setShopId(Channel.ZhongShu.name());
+
+        paymentService2.applicationWithdrawals(applyWithdrawalsModel);
+
+//        for (TransferDetail transferDetail : transferDetailDao.findByShopMid("89852017372912Y")) {
+//
+//            List<Transfer> byOrderNo = transferDao.findByOrderNo(transferDetail.getOrderNo());
+//            byOrderNo.forEach(it->it.setChannel(Channel.GuiDa));
+//            transferDao.saveAll(byOrderNo);
+//        }
+
+
+    }
+
+
+    @Test
+    public void testw() {
+
+
+        WithdrawalsRequest withdrawalsRequest = new WithdrawalsRequest();
+//        withdrawalsRequest.setTotalAmt("8");
+//        withdrawalsRequest.setTotalQty("1");
+        withdrawalsRequest.setTransMid("89852017372911Y");
+        withdrawalsRequest.setBatchNo(snowflake.nextIdStr());
+        WithdrawalsRequest.Deatil deatil = new WithdrawalsRequest.Deatil();
+        deatil.setTxnNo(snowflake.nextIdStr());
+        deatil.setMerOrderId("42171773171497466568704");
+        deatil.setClearDate("20240328");
+        deatil.setMerNo("89852015995900D");
+        deatil.setMerName("宠物店");
+//        deatil.setTxnAmt("8");
+        withdrawalsRequest.setDetail(List.of(deatil));
+
+
+        WithdrawalsResponse withdrawals = withdrawalsApi.withdrawals(withdrawalsRequest);
+        System.out.println(withdrawals);
+
+
+    }
+
+
+    @Test
+    public void ttttt() {
+
+        ResultContent<SubOrdersConfirmResponseModel> subOrdersConfirmResponseModelResultContent = paymentService2.subOrdersConfirm("6605b6f666f86738e91987e9", "65fe7c9174d67a7dbd842b74");
+        System.out.println(subOrdersConfirmResponseModelResultContent);
+
+    }
+
+    @Test
+    public void transferDetailDao() {
+
+        WithdrawRequestModel withdrawRequestModel = new WithdrawRequestModel();
+        withdrawRequestModel.setShopId("6605627832e63427d1a08714");
+        withdrawRequestModel.setSize(10);
+        withdrawRequestModel.setPage(0);
+
+        transferDetailDao.shopTransferDetail(withdrawRequestModel);
+        ApplyWithdrawalsModel applyWithdrawalsModel = new ApplyWithdrawalsModel();
+        applyWithdrawalsModel.setPlatform(false);
+        applyWithdrawalsModel.setChannel(Channel.ZhongShu);
+        applyWithdrawalsModel.setShopId("661e1fad30fed626f8b583f8");
+        transferDetailDao.detailAccount(applyWithdrawalsModel);
+//        transferDetailDao.acount("6605627832e63427d1a08714");
+//        transferDetailDao.withdrawOrder(withdrawRequestModel);
+    }
+
+    @Test
+    public void tee() {
+//        AdminSeachOrderModel adminSeachOrderModel = new AdminSeachOrderModel();
+//        adminSeachOrderModel.setOrderType(OrderType.APPLY_REFUND);
+//        order2Dao.findAdminOrder(adminSeachOrderModel, PageRequest.of(0, 10));
+
+//        ResultContent resultContent = paymentService2.applicationWithdrawals("PLATFORM");
+        transferDetailDao.acountDetail("6603b43c32e63427d1a07ab6");
+    }
+
+    @Test
+    public void transfer() {
+
+        ResultContent<GoodsResultModel> goodsResultModelResultContent = orderService2.goodsDetail2("1777974122433875968", "1777974122842091520");
+        System.out.println(goodsResultModelResultContent.getContent());
+
+    }
+
+    @Autowired
+    MongoTemplate mongoTemplate;
+
+    @Test
+    public void time() {
+//        goods.goodsState": "WAIT_USE", "transfer": false, "pay": true
+//
+//        Aggregation aggregation = newAggregation(
+//                Aggregation.lookup("goods", "orderNo", "orderNo", "goods"),
+//                Aggregation.match(Criteria.where("goods.validDay").ne(null).and("goods.goodsState").is("WAIT_USE").and("pay").is(true)),
+//                Aggregation.project()
+//                        .and("createTime").as("createTime")
+//                        .and("goodsId").as("goodsId")
+//                        .and("orderNo").as("orderNo")
+//                        .and("transfer").as("transfer")
+//                        .and("platform").as("platform")
+//                        .and("buyShop").as("buyShop")
+//                        .and("useShop").as("useShop")
+//                        .and("shopId").as("goods.shopId")
+//                        .andExpression("{$add: {{ $arrayElemAt: {'$goods.createTime', 0} },{ $multiply: {{ $arrayElemAt: {'$goods.validDay', 0} }, 24 * 60 * 60 * 1000} }}}").as("time"),
+//                Aggregation.match(Criteria.where("time").lte(new Date().getTime()))
+//        );
+//
+//        mongoTemplate.aggregate(aggregation, "transfer", Document.class).getMappedResults();
+
+        for (TransferModel transferModel : transferDao.validDayTimeOute()) {
+            System.out.println(transferModel);
+        }
+
+    }
+
+
+    @Test
+    public void guiDaPayment() {
+
+
+        CreateRequestModel createRequestModel = new CreateRequestModel("wx.miniPreOrder");
+        createRequestModel.setAsynDivisionFlag(true);
+        createRequestModel.setSubOpenId("1784754317116801025");
+        createRequestModel.setDivisionFlag(true);
+        createRequestModel.setMerOrderId("42171784754317116801025");
+        createRequestModel.setMid("89852017372912Y");
+        createRequestModel.setOrderDesc("文创商品");
+        createRequestModel.setPlatformAmount(0L);
+        createRequestModel.setSubOpenId("ovIOO4spgsdv4vNtrs0j3_VDkKLY");
+        CreateRequestModel.SubOrders subOrders = new CreateRequestModel.SubOrders();
+        subOrders.setMid("89852015995900D");
+        subOrders.setTotalAmount(10L);
+        createRequestModel.setSubOrders(List.of(subOrders));
+        createRequestModel.setTid("NT4RL61Q");
+        createRequestModel.setTotalAmount(10L);
+        createRequestModel.setUserId("65fe583d74d67a7dbd842b45");
+
+
+        paymentApi.creatOrder(createRequestModel);
+
+
+    }
+
+
+}

+ 113 - 0
RewardServer/target/classes/META-INF/spring-configuration-metadata.json

@@ -0,0 +1,113 @@
+{
+  "groups": [
+    {
+      "name": "payment",
+      "type": "com.zhongshu.payment.server.core.config.PaymentConfig",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "wechat",
+      "type": "com.zhongshu.reward.server.core.config.WeChatConfig",
+      "sourceType": "com.zhongshu.reward.server.core.config.WeChatConfig"
+    }
+  ],
+  "properties": [
+    {
+      "name": "payment.accesser-id",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.h5-page-url",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.interface-url",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.key",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.mer-no",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.notify-url",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.pay-key",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.pay-url",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.pc-page-url",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.tid",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.withdrawals-key",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "payment.withdrawals-url",
+      "type": "java.lang.String",
+      "sourceType": "com.zhongshu.payment.server.core.config.PaymentConfig"
+    },
+    {
+      "name": "wechat.api-v3-key",
+      "type": "java.lang.String",
+      "description": "商户APIV3密钥",
+      "sourceType": "com.zhongshu.reward.server.core.config.WeChatConfig"
+    },
+    {
+      "name": "wechat.appid",
+      "type": "java.lang.String",
+      "description": "商户id",
+      "sourceType": "com.zhongshu.reward.server.core.config.WeChatConfig"
+    },
+    {
+      "name": "wechat.merchant-id",
+      "type": "java.lang.String",
+      "description": "商户号",
+      "sourceType": "com.zhongshu.reward.server.core.config.WeChatConfig"
+    },
+    {
+      "name": "wechat.merchant-serial-number",
+      "type": "java.lang.String",
+      "description": "商户证书序列号",
+      "sourceType": "com.zhongshu.reward.server.core.config.WeChatConfig"
+    },
+    {
+      "name": "wechat.private-key",
+      "type": "java.lang.String",
+      "description": "商户API私钥",
+      "sourceType": "com.zhongshu.reward.server.core.config.WeChatConfig"
+    },
+    {
+      "name": "wechat.transfer-scene-id",
+      "type": "java.lang.String",
+      "description": "资金类型 (归类)",
+      "sourceType": "com.zhongshu.reward.server.core.config.WeChatConfig"
+    }
+  ],
+  "hints": []
+}

+ 41 - 0
RewardServer/target/classes/application-dev.yml

@@ -0,0 +1,41 @@
+spring:
+  data:
+    mongodb:
+      #uri: mongodb://paymentcenter:paymentcenter@192.168.110.241:30117,192.168.110.241:30118,192.168.110.241:30119/paymentcenter?replicaSet=MongoSetsShard1
+      uri: mongodb://rewardcenter:rewardcenter@192.168.110.241:30117,192.168.110.241:30118,192.168.110.241:30119/rewardcenter?replicaSet=MongoSetsShard1
+      auto-index-creation: true
+  redis:
+    host: 192.168.110.241
+    port: 6379
+    database: 6
+
+swagger:
+  packageName: "com.zhongshu.payment.core.controller"
+  title: RewardServer
+  description: 返利中心
+  version: "1.0"
+  enable: true
+
+payment:
+  mer_no: 89852017372911Y
+  tid: PEYAH8X1
+  accesser_id: GZHYXHSH52011
+  key: udik876ehjde32dU61edsxsf
+  h5_page_url: https://selfapply-test.chinaums.com/self-sign-mobile/#/chooseRole
+  pc_page_url: https://selfapply-test.chinaums.com/self-sign-web/#/verify
+  interface_url: https://selfapply-test.chinaums.com/self-contract-nmrs/interface/autoReg
+#  interface_url: http://192.168.110.241:7300/mock/654babd538574f002773e5f8/dev/autoReg
+#  interface_url: https://yinshangpai.chinaums.com/self-contract-nmrs/interface/autoReg
+  pay_url: https://dhjt-uat.chinaums.com/queryService/UmsWebPayPlugins
+  pay_key: 11111111111111111111111111111111
+  withdrawals_url: https://dhjt.chinaums.com/entryService/unified-withdrawals-api
+  # 提现秘钥
+  withdrawals_key: 11111111111111111111111111111111
+  notifyUrl: https://api.dev.zonelife.cn/springbatchservice/pay/sync
+#  pay_url: https://dhjt-api.chinaums.com/queryService/UmsWebPayPlugins
+
+
+
+#knife4j:
+#debug: true
+#  production: false

+ 64 - 0
RewardServer/target/classes/application.yml

@@ -0,0 +1,64 @@
+#Web?????
+server:
+  port: 9403
+
+#??????
+spring:
+  cloud:
+    consul:
+      discovery:
+        prefer-ip-address: true # ip????
+        hostname: localhost    # ??????
+        port: ${server.port}
+        health-check-path: /actuator/health  # ??????
+        health-check-interval: 10s   # ??10s??
+        register: true  # ????
+        service-name: ${spring.application.name} # ????
+        instance-id: ${spring.application.name}:${server.port}
+      host: 192.168.110.241:8500,192.168.110.241:8501,192.168.110.241:8502
+      port: 8500
+    #kafka
+    stream:
+      kafka:
+        binder:
+          brokers: 192.168.110.241:9092,192.168.110.241:9093,192.168.110.241:9094
+          replication-factor: 1
+      function:
+        definition: userLogStreamConsumer;vipUserStreamConsumer
+      bindings:
+        userLogStreamConsumer-in-0:
+          destination: UserLogStream
+          group: RewardServer
+        vipUserStreamConsumer-in-0:
+          destination: VipUserStream
+          group: RewardServer
+    bus:
+      enabled: true
+  #??zipkin???????
+  zipkin:
+    base-url: http://192.168.110.241:9411
+    enabled: true
+    sender:
+      type: web
+  sleuth:
+    sampler:
+      probability: 0.01
+
+
+
+
+wechat:
+  merchantId: 111
+  privateKey: 1212
+  merchantSerialNumber: 111
+  apiV3Key: 1111
+  appid: 1111
+  transferSceneId: 1111
+
+
+
+#????????
+logging:
+  file:
+    name: logs/RewardServer.log
+#debug: true

+ 23 - 0
RewardServer/target/classes/bootstrap.yml

@@ -0,0 +1,23 @@
+###需拷贝到每一个模块下
+
+spring:
+  mvc:
+    pathmatch:
+      matching-strategy: ant_path_matcher
+  main: #允许循环引用
+    allow-circular-references: true
+  # 应用名
+  application:
+    name: RewardServer
+  # 当前读取配置文件的类型
+  profiles:
+    active: dev
+  #配置中心
+  cloud:
+    config:
+      uri: http://192.168.110.241:8000
+      name: RewardServer,ConfigCenter
+  autoconfigure:
+    exclude:
+      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
+      - org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration

BIN
RewardServer/target/classes/com/zhongshu/payment/server/core/config/MVCConfig.class


BIN
RewardServer/target/classes/com/zhongshu/payment/server/core/config/PaymentConfig.class


BIN
RewardServer/target/classes/com/zhongshu/payment/server/core/config/RedisConfig.class


BIN
RewardServer/target/classes/com/zhongshu/reward/server/RewardServerApplication.class


BIN
RewardServer/target/classes/com/zhongshu/reward/server/core/config/AuthConfig.class


BIN
RewardServer/target/classes/com/zhongshu/reward/server/core/config/ClientConfig.class


BIN
RewardServer/target/classes/com/zhongshu/reward/server/core/config/MongoConfig.class


BIN
RewardServer/target/classes/com/zhongshu/reward/server/core/config/PushConfig.class


BIN
RewardServer/target/classes/com/zhongshu/reward/server/core/config/SchedulingConfig.class


BIN
RewardServer/target/classes/com/zhongshu/reward/server/core/config/SnowFlakeConfig.class


BIN
RewardServer/target/classes/com/zhongshu/reward/server/core/config/SwagerConfig.class


BIN
RewardServer/target/classes/com/zhongshu/reward/server/core/config/WeChatConfig.class


BIN
RewardServer/target/classes/com/zhongshu/reward/server/core/config/feign/ZswlCloudShopConfig.class


+ 21 - 0
pom.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>com.zhongshu</groupId>
+	<artifactId>RewardCenter</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>RewardCenter</name>
+	<packaging>pom</packaging>
+	<description>RewardCenter</description>
+
+	<modules>
+		<module>RewardClient</module>
+		<module>RewardServer</module>
+
+	</modules>
+
+
+
+</project>