2 Achegas bfafb23a1c ... 4885f73997

Autor SHA1 Mensaxe Data
  wujiefeng 4885f73997 初始化 hai 11 meses
  wujiefeng cae31989ae 初始化 hai 11 meses
Modificáronse 91 ficheiros con 3680 adicións e 0 borrados
  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=BIN
      RewardClient/target/classes/com/zhongshu/reward/client/config/RewardClientConfiguration.class
  28. BIN=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=BIN
      RewardServer/target/classes/com/zhongshu/payment/server/core/config/MVCConfig.class
  79. BIN=BIN
      RewardServer/target/classes/com/zhongshu/payment/server/core/config/PaymentConfig.class
  80. BIN=BIN
      RewardServer/target/classes/com/zhongshu/payment/server/core/config/RedisConfig.class
  81. BIN=BIN
      RewardServer/target/classes/com/zhongshu/reward/server/RewardServerApplication.class
  82. BIN=BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/AuthConfig.class
  83. BIN=BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/ClientConfig.class
  84. BIN=BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/MongoConfig.class
  85. BIN=BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/PushConfig.class
  86. BIN=BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/SchedulingConfig.class
  87. BIN=BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/SnowFlakeConfig.class
  88. BIN=BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/SwagerConfig.class
  89. BIN=BIN
      RewardServer/target/classes/com/zhongshu/reward/server/core/config/WeChatConfig.class
  90. BIN=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=BIN
RewardClient/target/classes/com/zhongshu/reward/client/config/RewardClientConfiguration.class


BIN=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=BIN
RewardServer/target/classes/com/zhongshu/payment/server/core/config/MVCConfig.class


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


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


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


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


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


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


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


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


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


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


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


BIN=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>