Browse Source

添加免费资产每个月底续费的数据同步定时任务

wangPH 2 years ago
parent
commit
fa6c393e96
27 changed files with 947 additions and 0 deletions
  1. 38 0
      background-paddle/pom.xml
  2. 15 0
      background-paddle/src/main/java/com/kdan/compdf/PaddleApplication.java
  3. 108 0
      background-paddle/src/main/java/com/kdan/compdf/client/PaddleClient.java
  4. 23 0
      background-paddle/src/main/java/com/kdan/compdf/controller/TestWebhookController.java
  5. 120 0
      background-paddle/src/main/java/com/kdan/compdf/dto/Currencies.java
  6. 64 0
      background-paddle/src/main/java/com/kdan/compdf/dto/PaySuccessInfoDTO.java
  7. 27 0
      background-paddle/src/main/java/com/kdan/compdf/dto/SubscriptionPlansDTO.java
  8. 31 0
      background-paddle/src/main/java/com/kdan/compdf/dto/TestWebhookDTO.java
  9. 68 0
      background-paddle/src/main/java/com/kdan/compdf/exception/PaddleException.java
  10. 19 0
      background-paddle/src/main/java/com/kdan/compdf/properties/PaddleProperties.java
  11. 15 0
      background-paddle/src/main/java/com/kdan/compdf/resultmap/PaddleResultMap.java
  12. 19 0
      background-paddle/src/main/java/com/kdan/compdf/webhook/SubscriptionWebhook.java
  13. 9 0
      background-paddle/src/main/resources/application.yml
  14. 29 0
      background-paddle/src/test/java/com/kdan/compdf/TestPaddle.java
  15. 2 0
      background-user/src/main/java/cn/kdan/compdf/config/RedisConstantServer.java
  16. 16 0
      background-user/src/main/java/cn/kdan/compdf/controller/v1/BackgroundUserBalanceController.java
  17. 39 0
      background-user/src/main/java/cn/kdan/compdf/controller/v1/BackgroundUserRemainController.java
  18. 22 0
      background-user/src/main/java/cn/kdan/compdf/dto/AddFreePlanDTO.java
  19. 46 0
      background-user/src/main/java/cn/kdan/compdf/dto/Asset.java
  20. 35 0
      background-user/src/main/java/cn/kdan/compdf/dto/TenantAssetBalanceDTO.java
  21. 40 0
      background-user/src/main/java/cn/kdan/compdf/entity/BackgroundUserRemain.java
  22. 11 0
      background-user/src/main/java/cn/kdan/compdf/mapper/BackgroundUserRemainMapper.java
  23. 6 0
      background-user/src/main/java/cn/kdan/compdf/service/BackgroundUserBalanceService.java
  24. 37 0
      background-user/src/main/java/cn/kdan/compdf/service/BackgroundUserRemainService.java
  25. 33 0
      background-user/src/main/java/cn/kdan/compdf/service/impl/BackgroundUserBalanceServiceImpl.java
  26. 56 0
      background-user/src/main/java/cn/kdan/compdf/service/impl/BackgroundUserRemainServiceImpl.java
  27. 19 0
      background-user/src/main/resources/mapper/BackgroundUserRemainMapper.xml

+ 38 - 0
background-paddle/pom.xml

@@ -0,0 +1,38 @@
+<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>background</artifactId>
+        <groupId>cn.kdan.compdf</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>background-paddle</artifactId>
+    <description>paddle-自动续订demo</description>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>cn.kdan.compdf</groupId>
+            <artifactId>background-common</artifactId>
+            <version>0.0.1</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.alibaba.cloud</groupId>
+                    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.alibaba.cloud</groupId>
+                    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+
+</project>

+ 15 - 0
background-paddle/src/main/java/com/kdan/compdf/PaddleApplication.java

@@ -0,0 +1,15 @@
+package com.kdan.compdf;
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class PaddleApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(PaddleApplication.class, args);
+    }
+
+
+}

+ 108 - 0
background-paddle/src/main/java/com/kdan/compdf/client/PaddleClient.java

@@ -0,0 +1,108 @@
+package com.kdan.compdf.client;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import cn.kdan.compdf.exception.CommonException;
+import com.alibaba.fastjson.JSON;
+import com.kdan.compdf.dto.SubscriptionPlansDTO;
+import com.kdan.compdf.resultmap.PaddleResultMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.IOException;
+import java.time.Duration;
+import java.util.*;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/8
+ * <p>
+ * Paddle 客服端
+ */
+@Slf4j
+public class PaddleClient {
+    /**
+     * 请求地址
+     */
+    private final String address;
+    /**
+     * vendor_id
+     */
+    private final String vendorId;
+    /**
+     * vendor_auth_code
+     */
+    private final String vendorAuthCode;
+    private final RestTemplate restTemplate;
+
+    public PaddleClient(String address, String vendorId, String vendorAuthCode) {
+        if (!address.endsWith("/")) {
+            address += "/";
+        }
+        this.address = address;
+        this.restTemplate = new RestTemplateBuilder()
+                .build();
+        this.vendorId = vendorId;
+        this.vendorAuthCode = vendorAuthCode;
+    }
+
+
+    /**
+     * 查询出订阅计划列表
+     *
+     * @param planId 订阅计划id,为空则查询所有订阅计划
+     * @return 订阅计划列表
+     */
+    public List<SubscriptionPlansDTO> getSubscriptionPlans(Integer planId) {
+        String url = address + "subscription/plans";
+        HttpHeaders headers = getHeaders();
+        MultiValueMap<String, String> paramMap = getParamMap();
+        if (planId != null) {
+            paramMap.add("plan", planId.toString());
+        }
+        ResponseEntity<Map> exchange = restTemplate.exchange(
+                url,
+                HttpMethod.POST,
+                new HttpEntity<>(paramMap, headers),
+                Map.class);
+        Map<String, Object> result = exchange.getBody();
+        resultIsTrue(result);
+
+        List<SubscriptionPlansDTO> data = JSONUtil.parseArray(exchange.getBody().get("response")).toList(SubscriptionPlansDTO.class);
+        return Objects.requireNonNull(data);
+
+    }
+
+
+    private HttpHeaders getHeaders() {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        return headers;
+    }
+
+    private MultiValueMap<String, String> getParamMap() {
+        MultiValueMap<String, String> param = new LinkedMultiValueMap<String, String>();
+        param.add("vendor_id", "159972");
+        param.add("vendor_auth_code", "7ce557336b096a1bb5719fcb92e8122236f0522b1cde4e8b1d");
+        return param;
+    }
+
+    /**
+     * 判断返回对象是否为true
+     *
+     * @param result 返回值
+     */
+    private void resultIsTrue(Map<String, Object> result) {
+        if (Boolean.FALSE.equals(result.get("success"))){
+            throw new CommonException("");
+        }
+    }
+
+}

+ 23 - 0
background-paddle/src/main/java/com/kdan/compdf/controller/TestWebhookController.java

@@ -0,0 +1,23 @@
+package com.kdan.compdf.controller;
+
+import cn.kdan.compdf.base.R;
+import com.kdan.compdf.dto.TestWebhookDTO;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/7
+ */
+@RestController
+@RequestMapping("/v1")
+public class TestWebhookController {
+
+
+    @PostMapping("/test/webhook")
+    public R t(@RequestBody TestWebhookDTO webhookDTO){
+        System.out.println(webhookDTO);
+        return R.ok();
+    }
+
+
+
+}

+ 120 - 0
background-paddle/src/main/java/com/kdan/compdf/dto/Currencies.java

@@ -0,0 +1,120 @@
+package com.kdan.compdf.dto;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.math.BigDecimal;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/8
+ */
+@Data
+@ToString
+public class Currencies {
+    /**
+     * 美元
+     */
+    private BigDecimal USD;
+    /**
+     * 欧元
+     */
+    private BigDecimal EUR;
+    /**
+     * 英镑
+     */
+    private BigDecimal GBP;
+    /**
+     * 阿根廷比索
+     */
+    private BigDecimal ARS;
+    /**
+     * 澳元
+     */
+    private BigDecimal AUD;
+    /**
+     * 加元
+     */
+    private BigDecimal CAD;
+    /**
+     * 瑞士法郎
+     */
+    private BigDecimal CHF;
+    /**
+     * 捷克克朗
+     */
+    private BigDecimal CZK;
+    /**
+     * 丹麦克朗
+     */
+    private BigDecimal DKK;
+    /**
+     * 港元
+     */
+    private BigDecimal HKD;
+    /**
+     * 匈牙利福林
+     */
+    private BigDecimal HUF;
+    /**
+     * 印度卢比
+     */
+    private BigDecimal INR;
+    /**
+     * 以色列谢克尔
+     */
+    private BigDecimal ILS;
+    /**
+     * 日圓
+     */
+    private BigDecimal JPY;
+    /**
+     * 韩元
+     */
+    private BigDecimal KRW;
+    /**
+     * 墨西哥比索
+     */
+    private BigDecimal MXN;
+    /**
+     * 挪威克朗
+     */
+    private BigDecimal NOK;
+    /**
+     * 新西兰元
+     */
+    private BigDecimal NZD;
+    /**
+     * 波兰兹罗提
+     */
+    private BigDecimal PLN;
+    /**
+     * 俄罗斯卢布
+     */
+    private BigDecimal RUB;
+    /**
+     * 瑞典克朗
+     */
+    private BigDecimal SEK;
+    /**
+     * 新加坡元
+     */
+    private BigDecimal SGD;
+    /**
+     * 泰銖
+     */
+    private BigDecimal THB;
+    /**
+     * 土耳其里拉
+     */
+    private BigDecimal TRY;
+    /**
+     * 新台币
+     */
+    private BigDecimal TWD;
+    /**
+     * 乌克兰格里夫纳
+     */
+    private BigDecimal UAH;
+
+
+}

+ 64 - 0
background-paddle/src/main/java/com/kdan/compdf/dto/PaySuccessInfoDTO.java

@@ -0,0 +1,64 @@
+package com.kdan.compdf.dto;
+
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/9
+ */
+@Data
+@ToString
+public class PaySuccessInfoDTO {
+
+    private String alert_id;
+
+    private String alert_name;
+
+    private String balance_currency;
+
+    private String balance_earnings;
+    private String balance_fee;
+    private String balance_gross;
+    private String balance_tax;
+    private String checkout_id;
+    private String country;
+    private String coupon;
+    private String currency;
+    private String custom_data;
+    private String customer_name;
+    private String earnings;
+    private String email;
+    private String event_time;
+    private String fee;
+    private String initial_payment;
+    private String instalments;
+    private String marketing_consent;
+    private String next_bill_date;
+    private String next_payment_amount;
+    private String order_id;
+
+
+    private String p_signature;
+    private String passthrough;
+    private String payment_method;
+    private String payment_tax;
+    private String plan_name;
+    private String quantity;
+    private String receipt_url;
+    private String sale_gross;
+    private String status;
+    private String subscription_id;
+
+    private String subscription_payment_id;
+    private String subscription_plan_id;
+    private String unit_price;
+    private String user_id;
+
+
+
+
+
+
+
+
+}

+ 27 - 0
background-paddle/src/main/java/com/kdan/compdf/dto/SubscriptionPlansDTO.java

@@ -0,0 +1,27 @@
+package com.kdan.compdf.dto;
+
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/8
+ */
+@Data
+@ToString
+public class SubscriptionPlansDTO {
+
+    private Integer id;
+
+    private String name;
+
+    private String billingType;
+
+    private Integer billingPeriod;
+
+    private Currencies initialPrice;
+
+    private Currencies recurring_price;
+
+    private Integer trialDays;
+
+}

+ 31 - 0
background-paddle/src/main/java/com/kdan/compdf/dto/TestWebhookDTO.java

@@ -0,0 +1,31 @@
+package com.kdan.compdf.dto;
+
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/7
+ */
+@Data
+@ToString
+public class TestWebhookDTO {
+
+    private String p_product_id;
+    private String p_price;
+    private String p_country;
+    private String p_currency;
+    private String p_sale_gross;
+    private String p_tax_amount;
+    private String p_paddle_fee;
+    private String p_coupon_savings;
+    private String p_earnings;
+    private String p_order_id;
+    private String p_coupon;
+    private String p_used_price_override;
+    private String p_custom_data;
+    private String passthrough;
+    private String p_quantity;
+    private String quantity;
+    private String event_time;
+
+}

+ 68 - 0
background-paddle/src/main/java/com/kdan/compdf/exception/PaddleException.java

@@ -0,0 +1,68 @@
+//package com.kdan.compdf.exception;
+//
+//import lombok.Getter;
+//
+///**
+// * @author ComPDFKit-WPH 2022/11/8
+// */
+//@Getter
+//public enum PaddleException {
+//    UNABLE_TO_FIND_REQUESTED_LICENSE("100","Unable to find requested license"),
+//    BAD_METHOD_CALL("101","Bad method call"),
+//    BAD_API_KEY("102","Bad api key"),
+//    TIMESTAMP_IS_TOO_OLD_OR_NOT_VALID("103","Timestamp is too old or not valid"),
+//    LICENSE_CODE_HAS_ALREADY_BEEN_UTILIZED("104","License code has already been utilized"),
+//    LICENSE_CODE_IS_NOT_ACTIVE("105","License code is not active"),
+//    UNABLE_TO_FIND_REQUESTED_ACTIVATION("106","Unable to find requested activation"),
+//    YOU_DONT_HAVE_PERMISSION_TO_ACCESS_THIS_RESOURCE("107","You don’t have permission to access this resource"),
+//    UNABLE_TO_FIND_REQUESTED_PRODUCT("108","Unable to find requested product"),
+//    PROVIDED_CURRENCY_IS_NOT_VALID("109","Provided currency is not valid"),
+//    UNABLE_TO_FIND_REQUESTED_PURCHASE("110","Unable to find requested purchase"),
+//    ("111","Invalid authentication token"),
+//    ("112","Invalid verification token"),
+//    ("113","Invalid padding on decrypted string"),
+//    ("114","Invalid or duplicated affiliate"),
+//    ("115","Invalid or missing affiliate commision"),
+//    ("116","One or more required arguments are missing"),
+//    ("117","Provided expiration time is incorrect"),
+//    ("118","Price is too low"),
+//    ("119","Unable to find requested subscription"),
+//    ("120","Request failed due to internal error"),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//    ("",""),
+//
+//
+//
+//    ;
+//    String code;
+//
+//    String message;
+//
+//    PaddleException(String code,String message){
+//        this.code = code;
+//        this.message = message;
+//    }
+//
+//}

+ 19 - 0
background-paddle/src/main/java/com/kdan/compdf/properties/PaddleProperties.java

@@ -0,0 +1,19 @@
+package com.kdan.compdf.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/8
+ */
+@Data
+@ConfigurationProperties(prefix = "com.paddle.config")
+public class PaddleProperties {
+
+    private String address;
+
+    private String vendorId;
+
+    private String vendorAuthCode;
+
+}

+ 15 - 0
background-paddle/src/main/java/com/kdan/compdf/resultmap/PaddleResultMap.java

@@ -0,0 +1,15 @@
+package com.kdan.compdf.resultmap;
+
+import lombok.Data;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/8
+ */
+@Data
+public class PaddleResultMap<T> {
+
+    private boolean success;
+
+    private T response;
+
+}

+ 19 - 0
background-paddle/src/main/java/com/kdan/compdf/webhook/SubscriptionWebhook.java

@@ -0,0 +1,19 @@
+package com.kdan.compdf.webhook;
+
+import com.kdan.compdf.dto.PaySuccessInfoDTO;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/9
+ */
+@RestController
+@RequestMapping("/saas")
+public class SubscriptionWebhook {
+
+    @PostMapping("/paySuccess")
+    public void paySuccess(PaySuccessInfoDTO subscription_payment_succeeded){
+        System.out.println("成功接收");
+        System.out.println(subscription_payment_succeeded.toString());
+    }
+
+}

+ 9 - 0
background-paddle/src/main/resources/application.yml

@@ -0,0 +1,9 @@
+server:
+  port: ${SERVER_PORT:8050}
+
+spring:
+  application:
+    name: background-paddle
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8

+ 29 - 0
background-paddle/src/test/java/com/kdan/compdf/TestPaddle.java

@@ -0,0 +1,29 @@
+package com.kdan.compdf;
+
+import com.kdan.compdf.client.PaddleClient;
+import com.kdan.compdf.dto.SubscriptionPlansDTO;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.time.Duration;
+import java.util.List;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/8
+ */
+@SpringBootTest
+public class TestPaddle {
+
+    @Test
+    public void testPlanList(){
+        PaddleClient paddleClient = new PaddleClient("https://vendors.paddle.com/api/2.0", "159972", "7ce557336b096a1bb5719fcb92e8122236f0522b1cde4e8b1d");
+        List<SubscriptionPlansDTO> subscriptionPlans = paddleClient.getSubscriptionPlans(null);
+        System.out.println(subscriptionPlans);
+
+
+    }
+
+
+
+
+}

+ 2 - 0
background-user/src/main/java/cn/kdan/compdf/config/RedisConstantServer.java

@@ -4,6 +4,8 @@ package cn.kdan.compdf.config;
  * @author ComPDFKit-WPH 2022/10/10
  */
 public class RedisConstantServer {
+    public static final String USER_REMAIN_TENANT = "user:remain:tenant";
+
     private RedisConstantServer(){}
 
     public static final String DASHBOARD = "dashboard:";

+ 16 - 0
background-user/src/main/java/cn/kdan/compdf/controller/v1/BackgroundUserBalanceController.java

@@ -1,6 +1,7 @@
 package cn.kdan.compdf.controller.v1;
 
 import cn.kdan.compdf.base.R;
+import cn.kdan.compdf.dto.AddFreePlanDTO;
 import cn.kdan.compdf.dto.PlanStatisticsDTO;
 import cn.kdan.compdf.exception.CommonException;
 import cn.kdan.compdf.service.BackgroundUserBalanceService;
@@ -62,4 +63,19 @@ public class BackgroundUserBalanceController {
         return R.ok();
     }
 
+    /**
+     * FreePlan 免费资产月底跟新记录数据同步
+     */
+    @PostMapping("/freePlanSync")
+    public R<Void> freePlanSync(@RequestBody AddFreePlanDTO freePlanDTO, HttpServletRequest request) {
+        if (!DASHBOARD_SYNC_AUTOGRAPH.equals(request.getHeader("autograph"))) {
+            throw new CommonException("错误");
+        }
+        backgroundUserBalanceService.freePlanSync(freePlanDTO);
+        return R.ok();
+    }
+
+
+
+
 }

+ 39 - 0
background-user/src/main/java/cn/kdan/compdf/controller/v1/BackgroundUserRemainController.java

@@ -0,0 +1,39 @@
+package cn.kdan.compdf.controller.v1;
+
+import cn.kdan.compdf.base.R;
+import cn.kdan.compdf.dto.TenantAssetBalanceDTO;
+import cn.kdan.compdf.exception.CommonException;
+import cn.kdan.compdf.service.BackgroundUserRemainService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * @author ComPDFKit-WPH 2022/12/2
+ */
+@RestController
+@RequestMapping("/v1/remain")
+@RequiredArgsConstructor
+public class BackgroundUserRemainController {
+
+    private final BackgroundUserRemainService remainService;
+    @Value("${background.dashboard.autograph}")
+    private String DASHBOARD_SYNC_AUTOGRAPH;
+
+    @PostMapping("/assetsync")
+    public R<Void>assetsync(@RequestBody List<TenantAssetBalanceDTO> tenantBalance, HttpServletRequest request){
+        if (!DASHBOARD_SYNC_AUTOGRAPH.equals(request.getHeader("autograph"))) {
+            throw new CommonException("错误");
+        }
+        remainService.userRemainSync(tenantBalance);
+        return R.ok();
+    }
+
+
+}

+ 22 - 0
background-user/src/main/java/cn/kdan/compdf/dto/AddFreePlanDTO.java

@@ -0,0 +1,22 @@
+package cn.kdan.compdf.dto;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/29
+ */
+@Data
+@ToString
+@Builder
+public class AddFreePlanDTO implements Serializable {
+
+    private Integer freeAsset;
+
+    private List<Asset> assets;
+
+}

+ 46 - 0
background-user/src/main/java/cn/kdan/compdf/dto/Asset.java

@@ -0,0 +1,46 @@
+package cn.kdan.compdf.dto;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * @author ComPDFKit-WangPH 2022-08-25
+ */
+@Data
+public class Asset{
+
+    /**
+     * 资产余额
+     */
+    private Integer asset;
+    /**
+     * 资产过期时间
+     */
+    private Date assetOverTime;
+    /**
+     * 资产类型
+     */
+    private Integer assetTypeId;
+    /**
+     * 
+     */
+    private Long id;
+    /**
+     * 0 未启用,1启用
+     */
+    private Integer status;
+    /**
+     * 租户id
+     */
+    private Long tenantId;
+    /**
+     * 预扣费资产
+     */
+    private Integer withholdingAsset;
+
+}

+ 35 - 0
background-user/src/main/java/cn/kdan/compdf/dto/TenantAssetBalanceDTO.java

@@ -0,0 +1,35 @@
+package cn.kdan.compdf.dto;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+
+/**
+ * @author ComPDFKit-WPH 2022/11/15
+ */
+@Data
+@ToString
+public class TenantAssetBalanceDTO implements Serializable {
+    /**
+     * 企业用户id
+     */
+    private Long tenantId;
+    /**
+     * 资产类型id
+     */
+    private Integer assetTypeId;
+    /**
+     * 资产类型名称
+     */
+    private String assetTypeName;
+    /**
+     * 资金余额
+     */
+    private Integer asset;
+    /**
+     * 预扣费资产
+     */
+    private Integer withholdingAsset;
+
+}

+ 40 - 0
background-user/src/main/java/cn/kdan/compdf/entity/BackgroundUserRemain.java

@@ -0,0 +1,40 @@
+package cn.kdan.compdf.entity;
+
+import cn.kdan.compdf.base.BaseEntity;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author ComPDFKit-WPH 2022-11-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("background_user_remain")
+public class BackgroundUserRemain extends BaseEntity {
+
+    /**
+     * 主键id
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    /**
+     * 租户id
+     */
+    private Long tenantId;
+    /**
+     * 套餐余额总数
+     */
+    private Integer totalFiles;
+    /**
+     * 已使用数量
+     */
+    private Integer usedFiles;
+    /**
+     * 关联用户主键id
+     */
+    private Long userId;
+
+}

+ 11 - 0
background-user/src/main/java/cn/kdan/compdf/mapper/BackgroundUserRemainMapper.java

@@ -0,0 +1,11 @@
+package cn.kdan.compdf.mapper;
+
+import cn.kdan.compdf.entity.BackgroundUserRemain;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @author ComPDFKit-WPH 2022-11-10
+ */
+public interface BackgroundUserRemainMapper extends BaseMapper<BackgroundUserRemain> {
+
+}

+ 6 - 0
background-user/src/main/java/cn/kdan/compdf/service/BackgroundUserBalanceService.java

@@ -1,5 +1,6 @@
 package cn.kdan.compdf.service;
 
+import cn.kdan.compdf.dto.AddFreePlanDTO;
 import cn.kdan.compdf.dto.PlanStatisticsDTO;
 import cn.kdan.compdf.entity.BackgroundUserBalance;
 import cn.kdan.compdf.vo.BackgroundUserBalanceVO;
@@ -41,4 +42,9 @@ public interface BackgroundUserBalanceService extends IService<BackgroundUserBal
      * plan 消费记录数据同步 一天一次
      */
     void planSync(List<PlanStatisticsDTO> list);
+
+    /**
+     * FreePlan 免费资产月底跟新记录数据同步
+     */
+    void freePlanSync(AddFreePlanDTO freePlanDTO);
 }

+ 37 - 0
background-user/src/main/java/cn/kdan/compdf/service/BackgroundUserRemainService.java

@@ -0,0 +1,37 @@
+package cn.kdan.compdf.service;
+
+import cn.kdan.compdf.dto.TenantAssetBalanceDTO;
+import cn.kdan.compdf.entity.BackgroundUserRemain;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.util.List;
+
+/**
+ * @author ComPDFKit-WPH 2022-11-10
+ */
+public interface BackgroundUserRemainService extends IService<BackgroundUserRemain> {
+
+    /**
+     * 列表查询
+     *
+     * @param query 查询参数
+     * @return 列表数据
+     */
+    IPage<BackgroundUserRemain> page(BackgroundUserRemain query);
+
+    /**
+     * 通过tenantId 获得BackgroundUserRemain
+     *
+     * @param tenantId tenantId
+     * @return 获得BackgroundUserRemain
+     */
+    BackgroundUserRemain getUserRemain(Long tenantId);
+
+    /**
+     * tenantBalance 同步
+     *
+     * @param tenantBalance tenantBalance
+     */
+    void userRemainSync(List<TenantAssetBalanceDTO> tenantBalance);
+}

+ 33 - 0
background-user/src/main/java/cn/kdan/compdf/service/impl/BackgroundUserBalanceServiceImpl.java

@@ -2,6 +2,8 @@ package cn.kdan.compdf.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollectionUtil;
+import cn.kdan.compdf.dto.AddFreePlanDTO;
+import cn.kdan.compdf.dto.Asset;
 import cn.kdan.compdf.dto.PlanStatisticsDTO;
 import cn.kdan.compdf.entity.BackgroundUserBalance;
 import cn.kdan.compdf.mapper.BackgroundUserBalanceMapper;
@@ -147,4 +149,35 @@ public class BackgroundUserBalanceServiceImpl extends ServiceImpl<BackgroundUser
         }
     }
 
+    @Override
+    public void freePlanSync(AddFreePlanDTO freePlanDTO) {
+        Integer freeAsset = freePlanDTO.getFreeAsset();
+        List<Asset> assets = freePlanDTO.getAssets();
+        for (Asset asset : assets) {
+            // 最新的plan剩余额度
+            Integer newestPlanRemainingFiles = this.baseMapper.selectNewestPlanRemainingFiles(asset.getTenantId());
+            BackgroundUserBalance userBalance = new BackgroundUserBalance();
+            userBalance.setTenantId(asset.getTenantId());
+            userBalance.setUserId(userService.getUserId(asset.getTenantId()));
+            userBalance.setDate(new Date());
+            userBalance.setDescriptionType(3);
+            userBalance.setDescription("Free过期资产");
+            userBalance.setRemainingFiles(newestPlanRemainingFiles - asset.getAsset());
+            userBalance.setBalanceChange(asset.getAsset());
+            userBalance.setChangeType(3);
+
+            this.save(userBalance);
+
+            newestPlanRemainingFiles = this.baseMapper.selectNewestPlanRemainingFiles(asset.getTenantId());
+            userBalance.setDate(new Date());
+            userBalance.setDescriptionType(3);
+            userBalance.setDescription("Free增加资产");
+            userBalance.setRemainingFiles(newestPlanRemainingFiles + freeAsset);
+            userBalance.setBalanceChange(freeAsset);
+            userBalance.setChangeType(1);
+            this.save(userBalance);
+        }
+    }
+
+
 }

+ 56 - 0
background-user/src/main/java/cn/kdan/compdf/service/impl/BackgroundUserRemainServiceImpl.java

@@ -0,0 +1,56 @@
+package cn.kdan.compdf.service.impl;
+
+import cn.kdan.compdf.config.RedisConstantServer;
+import cn.kdan.compdf.dto.TenantAssetBalanceDTO;
+import cn.kdan.compdf.entity.BackgroundUserRemain;
+import cn.kdan.compdf.mapper.BackgroundUserRemainMapper;
+import cn.kdan.compdf.service.BackgroundUserRemainService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author ComPDFKit-WPH 2022-11-10
+ */
+@Service
+public class BackgroundUserRemainServiceImpl extends ServiceImpl<BackgroundUserRemainMapper, BackgroundUserRemain> implements BackgroundUserRemainService {
+
+    @Override
+    public IPage<BackgroundUserRemain> page(BackgroundUserRemain query) {
+        return this.page(new Page<>(query.getPage(), query.getSize()), Wrappers.query(query));
+    }
+
+    @Cacheable(value = RedisConstantServer.USER_REMAIN_TENANT, key = "#tenantId", unless = "#result == null")
+    @Override
+    public BackgroundUserRemain getUserRemain(Long tenantId) {
+        return this.baseMapper.selectOne(new LambdaQueryWrapper<BackgroundUserRemain>()
+                .eq(BackgroundUserRemain::getTenantId, tenantId));
+    }
+
+    @Override
+    public void userRemainSync(List<TenantAssetBalanceDTO> tenantBalance) {
+        Map<Long, List<TenantAssetBalanceDTO>> collect = tenantBalance.stream()
+                .collect(Collectors.groupingBy(TenantAssetBalanceDTO::getTenantId));
+        for (Long tenantId : collect.keySet()) {
+            BackgroundUserRemain userRemain = this.getUserRemain(tenantId);
+            Integer totalFiles = userRemain.getTotalFiles();
+            int fileBalance = 0;
+            for (TenantAssetBalanceDTO tenantAssetBalanceDTO : collect.get(tenantId)) {
+                fileBalance += tenantAssetBalanceDTO.getAsset();
+            }
+            userRemain.setUsedFiles(totalFiles - fileBalance);
+            this.baseMapper.update(userRemain, new LambdaQueryWrapper<BackgroundUserRemain>()
+                    .eq(BackgroundUserRemain::getTenantId, tenantId));
+        }
+    }
+
+
+}

+ 19 - 0
background-user/src/main/resources/mapper/BackgroundUserRemainMapper.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.kdan.compdf.mapper.BackgroundUserRemainMapper">
+
+    <!-- 可根据自己的需求,是否要使用 -->
+    <resultMap id="BackgroundUserRemainResultMap" type="cn.kdan.compdf.entity.BackgroundUserRemain">
+        <result property="createBy" column="create_by" />
+        <result property="createDate" column="create_date" />
+        <result property="id" column="id" />
+        <result property="tenantId" column="tenant_id" />
+        <result property="totalFiles" column="total_files" />
+        <result property="updateBy" column="update_by" />
+        <result property="updateDate" column="update_date" />
+        <result property="usedFiles" column="used_files" />
+        <result property="userId" column="user_id" />
+    </resultMap>
+
+</mapper>