Browse Source

Merge branch 'develop/v1.0' into master-test

# Conflicts:
#	pdf-office-account/src/main/resources/bootstrap.properties
#	pdf-office-email/src/main/resources/bootstrap.properties
#	pdf-office-gateway/src/main/resources/bootstrap.properties
#	pdf-office-payment/src/main/resources/bootstrap.properties
#	pdf-office-pdf-website/src/main/resources/bootstrap.properties
#	pdf-office-product/src/main/resources/bootstrap.properties
#	pdf-office-sso/src/main/resources/bootstrap.properties
tangxiangan 4 months ago
parent
commit
ff6ec5afcb
100 changed files with 5508 additions and 348 deletions
  1. 2 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/constant/UserConstant.java
  2. 44 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/controller/AIController.java
  3. 4 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/controller/LoginDeviceController.java
  4. 12 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/controller/UserController.java
  5. 15 1
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/controller/UserSubscriptionInfoController.java
  6. 30 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/enums/SourceProduct.java
  7. 33 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/mapper/AiRecordMapper.java
  8. 20 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/mapper/ext/ExtUserSubscriptionInfoMapper.java
  9. 238 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/AiRecord.java
  10. 966 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/AiRecordExample.java
  11. 18 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/LoginDevice.java
  12. 75 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/LoginDeviceExample.java
  13. 109 1
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/User.java
  14. 450 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/UserExample.java
  15. 20 2
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/UserSubscriptionInfo.java
  16. 61 1
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/UserSubscriptionInfoExample.java
  17. 9 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/AIService.java
  18. 2 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/LoginDeviceService.java
  19. 4 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/UserService.java
  20. 6 2
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/UserSubscriptionInfoService.java
  21. 32 0
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/impl/AIServiceImpl.java
  22. 12 4
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/impl/LoginDeviceServiceImpl.java
  23. 73 13
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/impl/UserServiceImpl.java
  24. 20 9
      pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/impl/UserSubscriptionInfoServiceImpl.java
  25. 16 9
      pdf-office-account/src/main/resources/generatorConfig.xml
  26. 320 0
      pdf-office-account/src/main/resources/sqlmap/AiRecordMapper.xml
  27. 25 8
      pdf-office-account/src/main/resources/sqlmap/LoginDeviceMapper.xml
  28. 100 5
      pdf-office-account/src/main/resources/sqlmap/UserMapper.xml
  29. 28 11
      pdf-office-account/src/main/resources/sqlmap/UserSubscriptionInfoMapper.xml
  30. 67 0
      pdf-office-account/src/main/resources/sqlmap/ext/ExtUserSubscriptionInfoMapper.xml
  31. 3 0
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/dto/UpdateUserForOrderDTO.java
  32. 40 0
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/AIApi.java
  33. 2 3
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/LoginDeviceApi.java
  34. 13 0
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/UserApi.java
  35. 12 0
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/UserSubscriptionInfoApi.java
  36. 19 0
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/hystrix/AIHystrix.java
  37. 5 0
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/hystrix/LoginDeviceApiHystrix.java
  38. 10 0
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/hystrix/UserHystrix.java
  39. 8 0
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/hystrix/UserSubscriptionInfoHystrix.java
  40. 238 0
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/vo/AiRecord.java
  41. 66 36
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/vo/LoginDevice.java
  42. 26 126
      pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/vo/UserSubscriptionInfo.java
  43. 50 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/appstore/AppTransaction.java
  44. 45 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/appstore/Environment.java
  45. 231 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/appstore/HistoryResponse.java
  46. 1 2
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/constant/SubscriptionConstant.java
  47. 43 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/AppStoreBuyCompleteDTO.java
  48. 3 1
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/AppStoreOrderSucceedDTO.java
  49. 18 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/CreateOrderManualDTO.java
  50. 12 1
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/CreateSubscriptionDTO.java
  51. 9 5
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/EquityVerificationDTO.java
  52. 21 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/GooglePayDTO.java
  53. 1 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/enums/PaymentMethodEnum.java
  54. 66 10
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/feign/OrderApi.java
  55. 10 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/feign/SubscriptionApi.java
  56. 67 2
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/feign/hystrix/OrderHystrix.java
  57. 9 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/feign/hystrix/SubscriptionHystrix.java
  58. 53 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/vo/OrderGiftLogVO.java
  59. 34 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/vo/OrdersVO.java
  60. 2 0
      pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/vo/SubscriptionsVO.java
  61. 1 0
      pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/enums/PlatformEnum.java
  62. 24 0
      pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/feign/PrizeApi.java
  63. 45 0
      pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/feign/ProductApi.java
  64. 22 0
      pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/feign/hystrix/PrizeHystrix.java
  65. 48 0
      pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/feign/hystrix/ProductHystrix.java
  66. 84 0
      pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/vo/ListingProductVO.java
  67. 65 0
      pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/vo/PrizeVO.java
  68. 20 2
      pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/vo/ProductVO.java
  69. 15 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/config/RabbitMqConfig.java
  70. 4 2
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/constant/CommonConstant.java
  71. 3 1
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/constant/RabbitMqConstant.java
  72. 58 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/dto/CreateUserOrderDTO.java
  73. 32 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/dto/ResetPasswordDTO.java
  74. 6 3
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/dto/UserRegisterDTO.java
  75. 36 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/AIActionEnum.java
  76. 23 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/EmailCodeTypeEnum.java
  77. 29 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/ExceptionEnum.java
  78. 34 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/OrderGiftLogVaildFlagEnum.java
  79. 34 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/OrderGiftVaildFlagEnum.java
  80. 38 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/PDFReaderProPlatformEnum.java
  81. 34 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/PrizeTypeEnum.java
  82. 46 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/product/BlcakFivePriceEnum.java
  83. 49 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/product/ProductEducationPriceEnum.java
  84. 9 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/pojo/ResultMap.java
  85. 10 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/utils/CommonUtils.java
  86. 71 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/vo/MemberInfoVO.java
  87. 72 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/vo/SimpleUserSubscriptionInfoVO.java
  88. 16 2
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/vo/UserInfoVO.java
  89. 25 2
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/vo/UserSubscriptionInfoVO.java
  90. 7 0
      pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/vo/UserVO.java
  91. 21 21
      pdf-office-email/src/main/java/cn/kdan/cloud/pdf/office/email/rabbit/listener/SendEmailListener.java
  92. 3 3
      pdf-office-generate/src/main/resources/application.yml
  93. 63 12
      pdf-office-payment/pom.xml
  94. 3 1
      pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/PDFOfficePaymentApplication.java
  95. 121 21
      pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/client/AppStoreClient.java
  96. 203 0
      pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/client/GooglePayClient.java
  97. 173 26
      pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/controller/OrderController.java
  98. 16 0
      pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/controller/SubscriptionController.java
  99. 17 0
      pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/entity/Order.java
  100. 0 0
      pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/entity/OrderGift.java

+ 2 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/constant/UserConstant.java

@@ -9,4 +9,6 @@ public class UserConstant {
     public static final String USER_QUERY_SUCCESS = "用户查询成功";
 
     public static final Long USER_LOGOFF_DELAY_TIME = 3 * 24 * 60 * 60 * 1000L;
+
+    public static final Long MEMBER_LOGOFF_DELAY_TIME = 7 * 24 * 60 * 60 * 1000L;
 }

+ 44 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/controller/AIController.java

@@ -0,0 +1,44 @@
+package cn.kdan.cloud.pdf.office.account.controller;
+
+import cn.kdan.cloud.pdf.office.account.constant.UserConstant;
+import cn.kdan.cloud.pdf.office.account.model.AiRecord;
+import cn.kdan.cloud.pdf.office.account.model.User;
+import cn.kdan.cloud.pdf.office.account.service.AIService;
+import cn.kdan.cloud.pdf.office.account.service.UserService;
+import cn.kdan.cloud.pdf.office.api.account.dto.LogOffUserDTO;
+import cn.kdan.cloud.pdf.office.api.account.dto.UpdateUserForOrderDTO;
+import cn.kdan.cloud.pdf.office.api.account.vo.UserDetailVO;
+import cn.kdan.cloud.pdf.office.api.account.vo.UserPageVO;
+import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.dto.UserRegisterDTO;
+import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
+import cn.kdan.cloud.pdf.office.common.vo.UserInfoVO;
+import cn.kdan.cloud.pdf.office.common.vo.UserVO;
+import com.github.pagehelper.PageInfo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+import java.util.List;
+
+@RestController
+@RequestMapping("ai")
+public class AIController {
+
+    @Autowired
+    private AIService aiService;
+
+
+
+    @PostMapping("/getByFileKey")
+    public ResultMap<AiRecord> getByFileKey(@RequestParam String fileKey) {
+        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS, aiService.getByFileKey(fileKey));
+    }
+
+    @PostMapping("/insert")
+    public ResultMap<Boolean> insert(@RequestBody AiRecord aiRecord) {
+        aiService.insert(aiRecord);
+        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS, Boolean.TRUE);
+    }
+}

+ 4 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/controller/LoginDeviceController.java

@@ -60,4 +60,8 @@ public class LoginDeviceController {
         loginDeviceService.delete(deviceSign,userId,appId,isDelete);
         return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS,Boolean.TRUE);
     }
+    @GetMapping("getById")
+    public ResultMap<LoginDevice> getById(@RequestParam("deviceId") String deviceId) {
+        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS, loginDeviceService.getById(deviceId));
+    }
 }

+ 12 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/controller/UserController.java

@@ -63,6 +63,11 @@ public class UserController {
         return new ResultMap<>(CommonConstant.SUCCESS, UserConstant.USER_QUERY_SUCCESS, userService.getInfoById(id));
     }
 
+    @GetMapping("getMemberInfoById")
+    public ResultMap<UserInfoVO> getMemberInfoById(@RequestParam String id) {
+        return new ResultMap<>(CommonConstant.SUCCESS, UserConstant.USER_QUERY_SUCCESS, userService.getMemberInfoById(id));
+    }
+
 
     /**
      * 注册
@@ -178,4 +183,11 @@ public class UserController {
         return ResultMap.success(userService.getByEmail(email));
     }
 
+    /**
+     * 判断用户邀请了多少人getInviteNum
+     */
+    @GetMapping("/getInviteNum")
+    public ResultMap<Integer> getInviteNum(@RequestParam("userId") String userId){
+        return ResultMap.success(userService.getInviteNum(userId));
+    }
 }

+ 15 - 1
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/controller/UserSubscriptionInfoController.java

@@ -6,9 +6,12 @@ import cn.kdan.cloud.pdf.office.account.service.UserSubscriptionInfoService;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
 import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
 
+import cn.kdan.cloud.pdf.office.common.vo.UserSubscriptionInfoVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 
 /**
  * @author tangxiangan
@@ -38,7 +41,18 @@ public class UserSubscriptionInfoController {
      */
     @GetMapping("/getByUserIdAndPlatform")
     public ResultMap<UserSubscriptionInfo> getByUserIdAndPlatform(@RequestParam String userId,@RequestParam Integer platform) {
-        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS,userSubscriptionInfoService.getByUserIdAndPlatform(userId,platform));
+        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS,userSubscriptionInfoService.getByUserIdAndPlatform(userId,platform, null));
+    }
+
+    /**
+     * 获取用户关于某一个产品的所有会员
+     * @param userId 用户id
+     * @param appId 产品id pro为1
+     * @return List<UserSubscriptionInfo>
+     */
+    @GetMapping("/getByUserIdAndAppId")
+    public ResultMap<List<UserSubscriptionInfoVO>> getByUserIdAndAppId(@RequestParam String userId, @RequestParam String appId) {
+        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS,userSubscriptionInfoService.getByUserIdAndAppId(userId,appId));
     }
 
     @PostMapping("/update")

+ 30 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/enums/SourceProduct.java

@@ -0,0 +1,30 @@
+package cn.kdan.cloud.pdf.office.account.enums;
+
+public enum SourceProduct {
+    PDF_READER_PRO_MAC("1", "mac"),
+    PDF_READER_PRO_WINDOWS("2", "windows"),
+    PDF_READER_PRO_ANDROID("3", "android"),
+    PDF_READER_PRO_IOS("4", "ios"),
+    PDF_READER_PRO_WEB("5", "官网");
+
+    private final String id;
+    private final String name;
+
+    SourceProduct(String id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public static String getIdByName(String name) {
+        for (SourceProduct product : values()) {
+            if (product.name.toLowerCase().contains(name.toLowerCase())) {
+                return product.getId();
+            }
+        }
+        return null; // 或者抛出异常
+    }
+}

+ 33 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/mapper/AiRecordMapper.java

@@ -0,0 +1,33 @@
+package cn.kdan.cloud.pdf.office.account.mapper;
+
+import cn.kdan.cloud.pdf.office.account.model.AiRecord;
+import cn.kdan.cloud.pdf.office.account.model.AiRecordExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.session.RowBounds;
+
+public interface AiRecordMapper {
+    long countByExample(AiRecordExample example);
+
+    int deleteByExample(AiRecordExample example);
+
+    int deleteByPrimaryKey(String id);
+
+    int insert(AiRecord record);
+
+    int insertSelective(AiRecord record);
+
+    List<AiRecord> selectByExampleWithRowbounds(AiRecordExample example, RowBounds rowBounds);
+
+    List<AiRecord> selectByExample(AiRecordExample example);
+
+    AiRecord selectByPrimaryKey(String id);
+
+    int updateByExampleSelective(@Param("record") AiRecord record, @Param("example") AiRecordExample example);
+
+    int updateByExample(@Param("record") AiRecord record, @Param("example") AiRecordExample example);
+
+    int updateByPrimaryKeySelective(AiRecord record);
+
+    int updateByPrimaryKey(AiRecord record);
+}

+ 20 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/mapper/ext/ExtUserSubscriptionInfoMapper.java

@@ -0,0 +1,20 @@
+package cn.kdan.cloud.pdf.office.account.mapper.ext;
+
+import cn.kdan.cloud.pdf.office.account.mapper.UserSubscriptionInfoMapper;
+import cn.kdan.cloud.pdf.office.common.vo.UserSubscriptionInfoVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface ExtUserSubscriptionInfoMapper extends UserSubscriptionInfoMapper {
+
+    /**
+     * 获取用户对于某个app的订阅情况,带设备限制数和相关平台
+     *
+     * @param userId 用户id
+     * @param appId  appid
+     * @return List
+     */
+    List<UserSubscriptionInfoVO> getInfo(@Param("userId") String userId, @Param("appId") String appId);
+
+}

+ 238 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/AiRecord.java

@@ -0,0 +1,238 @@
+package cn.kdan.cloud.pdf.office.account.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class AiRecord implements Serializable {
+    private String id;
+
+    private String userId;
+
+    private String function;
+
+    private String result;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+
+    private String content;
+
+    private String fileKey;
+
+    private Integer charCount;
+
+    private String fileId;
+
+    private Integer credit;
+
+    private static final long serialVersionUID = 1L;
+
+    public String getId() {
+        return id;
+    }
+
+    public AiRecord withId(String id) {
+        this.setId(id);
+        return this;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public AiRecord withUserId(String userId) {
+        this.setUserId(userId);
+        return this;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getFunction() {
+        return function;
+    }
+
+    public AiRecord withFunction(String function) {
+        this.setFunction(function);
+        return this;
+    }
+
+    public void setFunction(String function) {
+        this.function = function;
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    public AiRecord withResult(String result) {
+        this.setResult(result);
+        return this;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public AiRecord withCreatedAt(Date createdAt) {
+        this.setCreatedAt(createdAt);
+        return this;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public AiRecord withUpdatedAt(Date updatedAt) {
+        this.setUpdatedAt(updatedAt);
+        return this;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public AiRecord withContent(String content) {
+        this.setContent(content);
+        return this;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getFileKey() {
+        return fileKey;
+    }
+
+    public AiRecord withFileKey(String fileKey) {
+        this.setFileKey(fileKey);
+        return this;
+    }
+
+    public void setFileKey(String fileKey) {
+        this.fileKey = fileKey;
+    }
+
+    public Integer getCharCount() {
+        return charCount;
+    }
+
+    public AiRecord withCharCount(Integer charCount) {
+        this.setCharCount(charCount);
+        return this;
+    }
+
+    public void setCharCount(Integer charCount) {
+        this.charCount = charCount;
+    }
+
+    public String getFileId() {
+        return fileId;
+    }
+
+    public AiRecord withFileId(String fileId) {
+        this.setFileId(fileId);
+        return this;
+    }
+
+    public void setFileId(String fileId) {
+        this.fileId = fileId;
+    }
+
+    public Integer getCredit() {
+        return credit;
+    }
+
+    public AiRecord withCredit(Integer credit) {
+        this.setCredit(credit);
+        return this;
+    }
+
+    public void setCredit(Integer credit) {
+        this.credit = credit;
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        AiRecord other = (AiRecord) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+            && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
+            && (this.getFunction() == null ? other.getFunction() == null : this.getFunction().equals(other.getFunction()))
+            && (this.getResult() == null ? other.getResult() == null : this.getResult().equals(other.getResult()))
+            && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
+            && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))
+            && (this.getContent() == null ? other.getContent() == null : this.getContent().equals(other.getContent()))
+            && (this.getFileKey() == null ? other.getFileKey() == null : this.getFileKey().equals(other.getFileKey()))
+            && (this.getCharCount() == null ? other.getCharCount() == null : this.getCharCount().equals(other.getCharCount()))
+            && (this.getFileId() == null ? other.getFileId() == null : this.getFileId().equals(other.getFileId()))
+            && (this.getCredit() == null ? other.getCredit() == null : this.getCredit().equals(other.getCredit()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
+        result = prime * result + ((getFunction() == null) ? 0 : getFunction().hashCode());
+        result = prime * result + ((getResult() == null) ? 0 : getResult().hashCode());
+        result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
+        result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
+        result = prime * result + ((getContent() == null) ? 0 : getContent().hashCode());
+        result = prime * result + ((getFileKey() == null) ? 0 : getFileKey().hashCode());
+        result = prime * result + ((getCharCount() == null) ? 0 : getCharCount().hashCode());
+        result = prime * result + ((getFileId() == null) ? 0 : getFileId().hashCode());
+        result = prime * result + ((getCredit() == null) ? 0 : getCredit().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", userId=").append(userId);
+        sb.append(", function=").append(function);
+        sb.append(", result=").append(result);
+        sb.append(", createdAt=").append(createdAt);
+        sb.append(", updatedAt=").append(updatedAt);
+        sb.append(", content=").append(content);
+        sb.append(", fileKey=").append(fileKey);
+        sb.append(", charCount=").append(charCount);
+        sb.append(", fileId=").append(fileId);
+        sb.append(", credit=").append(credit);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 966 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/AiRecordExample.java

@@ -0,0 +1,966 @@
+package cn.kdan.cloud.pdf.office.account.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class AiRecordExample {
+    protected String orderByClause;
+
+    protected boolean distinct;
+
+    protected List<Criteria> oredCriteria;
+
+    public AiRecordExample() {
+        oredCriteria = new ArrayList<Criteria>();
+    }
+
+    public void setOrderByClause(String orderByClause) {
+        this.orderByClause = orderByClause;
+    }
+
+    public String getOrderByClause() {
+        return orderByClause;
+    }
+
+    public void setDistinct(boolean distinct) {
+        this.distinct = distinct;
+    }
+
+    public boolean isDistinct() {
+        return distinct;
+    }
+
+    public List<Criteria> getOredCriteria() {
+        return oredCriteria;
+    }
+
+    public void or(Criteria criteria) {
+        oredCriteria.add(criteria);
+    }
+
+    public Criteria or() {
+        Criteria criteria = createCriteriaInternal();
+        oredCriteria.add(criteria);
+        return criteria;
+    }
+
+    public Criteria createCriteria() {
+        Criteria criteria = createCriteriaInternal();
+        if (oredCriteria.size() == 0) {
+            oredCriteria.add(criteria);
+        }
+        return criteria;
+    }
+
+    protected Criteria createCriteriaInternal() {
+        Criteria criteria = new Criteria();
+        return criteria;
+    }
+
+    public void clear() {
+        oredCriteria.clear();
+        orderByClause = null;
+        distinct = false;
+    }
+
+    protected abstract static class GeneratedCriteria {
+        protected List<Criterion> criteria;
+
+        protected GeneratedCriteria() {
+            super();
+            criteria = new ArrayList<Criterion>();
+        }
+
+        public boolean isValid() {
+            return criteria.size() > 0;
+        }
+
+        public List<Criterion> getAllCriteria() {
+            return criteria;
+        }
+
+        public List<Criterion> getCriteria() {
+            return criteria;
+        }
+
+        protected void addCriterion(String condition) {
+            if (condition == null) {
+                throw new RuntimeException("Value for condition cannot be null");
+            }
+            criteria.add(new Criterion(condition));
+        }
+
+        protected void addCriterion(String condition, Object value, String property) {
+            if (value == null) {
+                throw new RuntimeException("Value for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value));
+        }
+
+        protected void addCriterion(String condition, Object value1, Object value2, String property) {
+            if (value1 == null || value2 == null) {
+                throw new RuntimeException("Between values for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value1, value2));
+        }
+
+        public Criteria andIdIsNull() {
+            addCriterion("id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIsNotNull() {
+            addCriterion("id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdEqualTo(String value) {
+            addCriterion("id =", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotEqualTo(String value) {
+            addCriterion("id <>", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThan(String value) {
+            addCriterion("id >", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThanOrEqualTo(String value) {
+            addCriterion("id >=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThan(String value) {
+            addCriterion("id <", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThanOrEqualTo(String value) {
+            addCriterion("id <=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLike(String value) {
+            addCriterion("id like", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotLike(String value) {
+            addCriterion("id not like", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIn(List<String> values) {
+            addCriterion("id in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotIn(List<String> values) {
+            addCriterion("id not in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdBetween(String value1, String value2) {
+            addCriterion("id between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotBetween(String value1, String value2) {
+            addCriterion("id not between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdIsNull() {
+            addCriterion("user_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdIsNotNull() {
+            addCriterion("user_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdEqualTo(String value) {
+            addCriterion("user_id =", value, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdNotEqualTo(String value) {
+            addCriterion("user_id <>", value, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdGreaterThan(String value) {
+            addCriterion("user_id >", value, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdGreaterThanOrEqualTo(String value) {
+            addCriterion("user_id >=", value, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdLessThan(String value) {
+            addCriterion("user_id <", value, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdLessThanOrEqualTo(String value) {
+            addCriterion("user_id <=", value, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdLike(String value) {
+            addCriterion("user_id like", value, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdNotLike(String value) {
+            addCriterion("user_id not like", value, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdIn(List<String> values) {
+            addCriterion("user_id in", values, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdNotIn(List<String> values) {
+            addCriterion("user_id not in", values, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdBetween(String value1, String value2) {
+            addCriterion("user_id between", value1, value2, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdNotBetween(String value1, String value2) {
+            addCriterion("user_id not between", value1, value2, "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionIsNull() {
+            addCriterion("`function` is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionIsNotNull() {
+            addCriterion("`function` is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionEqualTo(String value) {
+            addCriterion("`function` =", value, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionNotEqualTo(String value) {
+            addCriterion("`function` <>", value, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionGreaterThan(String value) {
+            addCriterion("`function` >", value, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionGreaterThanOrEqualTo(String value) {
+            addCriterion("`function` >=", value, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionLessThan(String value) {
+            addCriterion("`function` <", value, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionLessThanOrEqualTo(String value) {
+            addCriterion("`function` <=", value, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionLike(String value) {
+            addCriterion("`function` like", value, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionNotLike(String value) {
+            addCriterion("`function` not like", value, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionIn(List<String> values) {
+            addCriterion("`function` in", values, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionNotIn(List<String> values) {
+            addCriterion("`function` not in", values, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionBetween(String value1, String value2) {
+            addCriterion("`function` between", value1, value2, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionNotBetween(String value1, String value2) {
+            addCriterion("`function` not between", value1, value2, "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultIsNull() {
+            addCriterion("`result` is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultIsNotNull() {
+            addCriterion("`result` is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultEqualTo(String value) {
+            addCriterion("`result` =", value, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultNotEqualTo(String value) {
+            addCriterion("`result` <>", value, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultGreaterThan(String value) {
+            addCriterion("`result` >", value, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultGreaterThanOrEqualTo(String value) {
+            addCriterion("`result` >=", value, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultLessThan(String value) {
+            addCriterion("`result` <", value, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultLessThanOrEqualTo(String value) {
+            addCriterion("`result` <=", value, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultLike(String value) {
+            addCriterion("`result` like", value, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultNotLike(String value) {
+            addCriterion("`result` not like", value, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultIn(List<String> values) {
+            addCriterion("`result` in", values, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultNotIn(List<String> values) {
+            addCriterion("`result` not in", values, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultBetween(String value1, String value2) {
+            addCriterion("`result` between", value1, value2, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultNotBetween(String value1, String value2) {
+            addCriterion("`result` not between", value1, value2, "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtIsNull() {
+            addCriterion("created_at is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtIsNotNull() {
+            addCriterion("created_at is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtEqualTo(Date value) {
+            addCriterion("created_at =", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtNotEqualTo(Date value) {
+            addCriterion("created_at <>", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtGreaterThan(Date value) {
+            addCriterion("created_at >", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtGreaterThanOrEqualTo(Date value) {
+            addCriterion("created_at >=", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtLessThan(Date value) {
+            addCriterion("created_at <", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtLessThanOrEqualTo(Date value) {
+            addCriterion("created_at <=", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtIn(List<Date> values) {
+            addCriterion("created_at in", values, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtNotIn(List<Date> values) {
+            addCriterion("created_at not in", values, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtBetween(Date value1, Date value2) {
+            addCriterion("created_at between", value1, value2, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtNotBetween(Date value1, Date value2) {
+            addCriterion("created_at not between", value1, value2, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtIsNull() {
+            addCriterion("updated_at is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtIsNotNull() {
+            addCriterion("updated_at is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtEqualTo(Date value) {
+            addCriterion("updated_at =", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtNotEqualTo(Date value) {
+            addCriterion("updated_at <>", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtGreaterThan(Date value) {
+            addCriterion("updated_at >", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtGreaterThanOrEqualTo(Date value) {
+            addCriterion("updated_at >=", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtLessThan(Date value) {
+            addCriterion("updated_at <", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtLessThanOrEqualTo(Date value) {
+            addCriterion("updated_at <=", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtIn(List<Date> values) {
+            addCriterion("updated_at in", values, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtNotIn(List<Date> values) {
+            addCriterion("updated_at not in", values, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtBetween(Date value1, Date value2) {
+            addCriterion("updated_at between", value1, value2, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtNotBetween(Date value1, Date value2) {
+            addCriterion("updated_at not between", value1, value2, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentIsNull() {
+            addCriterion("content is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentIsNotNull() {
+            addCriterion("content is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentEqualTo(String value) {
+            addCriterion("content =", value, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentNotEqualTo(String value) {
+            addCriterion("content <>", value, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentGreaterThan(String value) {
+            addCriterion("content >", value, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentGreaterThanOrEqualTo(String value) {
+            addCriterion("content >=", value, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLessThan(String value) {
+            addCriterion("content <", value, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLessThanOrEqualTo(String value) {
+            addCriterion("content <=", value, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLike(String value) {
+            addCriterion("content like", value, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentNotLike(String value) {
+            addCriterion("content not like", value, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentIn(List<String> values) {
+            addCriterion("content in", values, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentNotIn(List<String> values) {
+            addCriterion("content not in", values, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentBetween(String value1, String value2) {
+            addCriterion("content between", value1, value2, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentNotBetween(String value1, String value2) {
+            addCriterion("content not between", value1, value2, "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyIsNull() {
+            addCriterion("file_key is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyIsNotNull() {
+            addCriterion("file_key is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyEqualTo(String value) {
+            addCriterion("file_key =", value, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyNotEqualTo(String value) {
+            addCriterion("file_key <>", value, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyGreaterThan(String value) {
+            addCriterion("file_key >", value, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyGreaterThanOrEqualTo(String value) {
+            addCriterion("file_key >=", value, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyLessThan(String value) {
+            addCriterion("file_key <", value, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyLessThanOrEqualTo(String value) {
+            addCriterion("file_key <=", value, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyLike(String value) {
+            addCriterion("file_key like", value, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyNotLike(String value) {
+            addCriterion("file_key not like", value, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyIn(List<String> values) {
+            addCriterion("file_key in", values, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyNotIn(List<String> values) {
+            addCriterion("file_key not in", values, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyBetween(String value1, String value2) {
+            addCriterion("file_key between", value1, value2, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyNotBetween(String value1, String value2) {
+            addCriterion("file_key not between", value1, value2, "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountIsNull() {
+            addCriterion("char_count is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountIsNotNull() {
+            addCriterion("char_count is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountEqualTo(Integer value) {
+            addCriterion("char_count =", value, "charCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountNotEqualTo(Integer value) {
+            addCriterion("char_count <>", value, "charCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountGreaterThan(Integer value) {
+            addCriterion("char_count >", value, "charCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountGreaterThanOrEqualTo(Integer value) {
+            addCriterion("char_count >=", value, "charCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountLessThan(Integer value) {
+            addCriterion("char_count <", value, "charCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountLessThanOrEqualTo(Integer value) {
+            addCriterion("char_count <=", value, "charCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountIn(List<Integer> values) {
+            addCriterion("char_count in", values, "charCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountNotIn(List<Integer> values) {
+            addCriterion("char_count not in", values, "charCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountBetween(Integer value1, Integer value2) {
+            addCriterion("char_count between", value1, value2, "charCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCharCountNotBetween(Integer value1, Integer value2) {
+            addCriterion("char_count not between", value1, value2, "charCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdIsNull() {
+            addCriterion("file_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdIsNotNull() {
+            addCriterion("file_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdEqualTo(String value) {
+            addCriterion("file_id =", value, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdNotEqualTo(String value) {
+            addCriterion("file_id <>", value, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdGreaterThan(String value) {
+            addCriterion("file_id >", value, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdGreaterThanOrEqualTo(String value) {
+            addCriterion("file_id >=", value, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdLessThan(String value) {
+            addCriterion("file_id <", value, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdLessThanOrEqualTo(String value) {
+            addCriterion("file_id <=", value, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdLike(String value) {
+            addCriterion("file_id like", value, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdNotLike(String value) {
+            addCriterion("file_id not like", value, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdIn(List<String> values) {
+            addCriterion("file_id in", values, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdNotIn(List<String> values) {
+            addCriterion("file_id not in", values, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdBetween(String value1, String value2) {
+            addCriterion("file_id between", value1, value2, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdNotBetween(String value1, String value2) {
+            addCriterion("file_id not between", value1, value2, "fileId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditIsNull() {
+            addCriterion("credit is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditIsNotNull() {
+            addCriterion("credit is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditEqualTo(Integer value) {
+            addCriterion("credit =", value, "credit");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditNotEqualTo(Integer value) {
+            addCriterion("credit <>", value, "credit");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditGreaterThan(Integer value) {
+            addCriterion("credit >", value, "credit");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditGreaterThanOrEqualTo(Integer value) {
+            addCriterion("credit >=", value, "credit");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditLessThan(Integer value) {
+            addCriterion("credit <", value, "credit");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditLessThanOrEqualTo(Integer value) {
+            addCriterion("credit <=", value, "credit");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditIn(List<Integer> values) {
+            addCriterion("credit in", values, "credit");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditNotIn(List<Integer> values) {
+            addCriterion("credit not in", values, "credit");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditBetween(Integer value1, Integer value2) {
+            addCriterion("credit between", value1, value2, "credit");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreditNotBetween(Integer value1, Integer value2) {
+            addCriterion("credit not between", value1, value2, "credit");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLikeInsensitive(String value) {
+            addCriterion("upper(id) like", value.toUpperCase(), "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserIdLikeInsensitive(String value) {
+            addCriterion("upper(user_id) like", value.toUpperCase(), "userId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFunctionLikeInsensitive(String value) {
+            addCriterion("upper(`function`) like", value.toUpperCase(), "function");
+            return (Criteria) this;
+        }
+
+        public Criteria andResultLikeInsensitive(String value) {
+            addCriterion("upper(`result`) like", value.toUpperCase(), "result");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLikeInsensitive(String value) {
+            addCriterion("upper(content) like", value.toUpperCase(), "content");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileKeyLikeInsensitive(String value) {
+            addCriterion("upper(file_key) like", value.toUpperCase(), "fileKey");
+            return (Criteria) this;
+        }
+
+        public Criteria andFileIdLikeInsensitive(String value) {
+            addCriterion("upper(file_id) like", value.toUpperCase(), "fileId");
+            return (Criteria) this;
+        }
+    }
+
+    public static class Criteria extends GeneratedCriteria {
+
+        protected Criteria() {
+            super();
+        }
+    }
+
+    public static class Criterion {
+        private String condition;
+
+        private Object value;
+
+        private Object secondValue;
+
+        private boolean noValue;
+
+        private boolean singleValue;
+
+        private boolean betweenValue;
+
+        private boolean listValue;
+
+        private String typeHandler;
+
+        public String getCondition() {
+            return condition;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object getSecondValue() {
+            return secondValue;
+        }
+
+        public boolean isNoValue() {
+            return noValue;
+        }
+
+        public boolean isSingleValue() {
+            return singleValue;
+        }
+
+        public boolean isBetweenValue() {
+            return betweenValue;
+        }
+
+        public boolean isListValue() {
+            return listValue;
+        }
+
+        public String getTypeHandler() {
+            return typeHandler;
+        }
+
+        protected Criterion(String condition) {
+            super();
+            this.condition = condition;
+            this.typeHandler = null;
+            this.noValue = true;
+        }
+
+        protected Criterion(String condition, Object value, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.typeHandler = typeHandler;
+            if (value instanceof List<?>) {
+                this.listValue = true;
+            } else {
+                this.singleValue = true;
+            }
+        }
+
+        protected Criterion(String condition, Object value) {
+            this(condition, value, null);
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.secondValue = secondValue;
+            this.typeHandler = typeHandler;
+            this.betweenValue = true;
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue) {
+            this(condition, value, secondValue, null);
+        }
+    }
+}

+ 18 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/LoginDevice.java

@@ -18,6 +18,8 @@ public class LoginDevice implements Serializable {
 
     private String os;
 
+    private String deviceName;
+
     private String language;
 
     private String timeZone;
@@ -125,6 +127,19 @@ public class LoginDevice implements Serializable {
         this.os = os;
     }
 
+    public String getDeviceName() {
+        return deviceName;
+    }
+
+    public LoginDevice withDeviceName(String deviceName) {
+        this.setDeviceName(deviceName);
+        return this;
+    }
+
+    public void setDeviceName(String deviceName) {
+        this.deviceName = deviceName;
+    }
+
     public String getLanguage() {
         return language;
     }
@@ -235,6 +250,7 @@ public class LoginDevice implements Serializable {
             && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
             && (this.getModel() == null ? other.getModel() == null : this.getModel().equals(other.getModel()))
             && (this.getOs() == null ? other.getOs() == null : this.getOs().equals(other.getOs()))
+            && (this.getDeviceName() == null ? other.getDeviceName() == null : this.getDeviceName().equals(other.getDeviceName()))
             && (this.getLanguage() == null ? other.getLanguage() == null : this.getLanguage().equals(other.getLanguage()))
             && (this.getTimeZone() == null ? other.getTimeZone() == null : this.getTimeZone().equals(other.getTimeZone()))
             && (this.getAppVersion() == null ? other.getAppVersion() == null : this.getAppVersion().equals(other.getAppVersion()))
@@ -255,6 +271,7 @@ public class LoginDevice implements Serializable {
         result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
         result = prime * result + ((getModel() == null) ? 0 : getModel().hashCode());
         result = prime * result + ((getOs() == null) ? 0 : getOs().hashCode());
+        result = prime * result + ((getDeviceName() == null) ? 0 : getDeviceName().hashCode());
         result = prime * result + ((getLanguage() == null) ? 0 : getLanguage().hashCode());
         result = prime * result + ((getTimeZone() == null) ? 0 : getTimeZone().hashCode());
         result = prime * result + ((getAppVersion() == null) ? 0 : getAppVersion().hashCode());
@@ -278,6 +295,7 @@ public class LoginDevice implements Serializable {
         sb.append(", userId=").append(userId);
         sb.append(", model=").append(model);
         sb.append(", os=").append(os);
+        sb.append(", deviceName=").append(deviceName);
         sb.append(", language=").append(language);
         sb.append(", timeZone=").append(timeZone);
         sb.append(", appVersion=").append(appVersion);

+ 75 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/LoginDeviceExample.java

@@ -595,6 +595,76 @@ public class LoginDeviceExample {
             return (Criteria) this;
         }
 
+        public Criteria andDeviceNameIsNull() {
+            addCriterion("device_name is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameIsNotNull() {
+            addCriterion("device_name is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameEqualTo(String value) {
+            addCriterion("device_name =", value, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameNotEqualTo(String value) {
+            addCriterion("device_name <>", value, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameGreaterThan(String value) {
+            addCriterion("device_name >", value, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameGreaterThanOrEqualTo(String value) {
+            addCriterion("device_name >=", value, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameLessThan(String value) {
+            addCriterion("device_name <", value, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameLessThanOrEqualTo(String value) {
+            addCriterion("device_name <=", value, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameLike(String value) {
+            addCriterion("device_name like", value, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameNotLike(String value) {
+            addCriterion("device_name not like", value, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameIn(List<String> values) {
+            addCriterion("device_name in", values, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameNotIn(List<String> values) {
+            addCriterion("device_name not in", values, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameBetween(String value1, String value2) {
+            addCriterion("device_name between", value1, value2, "deviceName");
+            return (Criteria) this;
+        }
+
+        public Criteria andDeviceNameNotBetween(String value1, String value2) {
+            addCriterion("device_name not between", value1, value2, "deviceName");
+            return (Criteria) this;
+        }
+
         public Criteria andLanguageIsNull() {
             addCriterion("`language` is null");
             return (Criteria) this;
@@ -1090,6 +1160,11 @@ public class LoginDeviceExample {
             return (Criteria) this;
         }
 
+        public Criteria andDeviceNameLikeInsensitive(String value) {
+            addCriterion("upper(device_name) like", value.toUpperCase(), "deviceName");
+            return (Criteria) this;
+        }
+
         public Criteria andLanguageLikeInsensitive(String value) {
             addCriterion("upper(`language`) like", value.toUpperCase(), "language");
             return (Criteria) this;

+ 109 - 1
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/User.java

@@ -52,8 +52,20 @@ public class User implements Serializable {
 
     private String remark;
 
+    private String canAccessAi;
+
     private String validFlag;
 
+    private String sourceProductId;
+
+    private String inviteUserId;
+
+    private String firstName;
+
+    private String lastName;
+
+    private String address;
+
     private static final long serialVersionUID = 1L;
 
     public String getId() {
@@ -368,6 +380,19 @@ public class User implements Serializable {
         this.remark = remark;
     }
 
+    public String getCanAccessAi() {
+        return canAccessAi;
+    }
+
+    public User withCanAccessAi(String canAccessAi) {
+        this.setCanAccessAi(canAccessAi);
+        return this;
+    }
+
+    public void setCanAccessAi(String canAccessAi) {
+        this.canAccessAi = canAccessAi;
+    }
+
     public String getValidFlag() {
         return validFlag;
     }
@@ -381,6 +406,71 @@ public class User implements Serializable {
         this.validFlag = validFlag;
     }
 
+    public String getSourceProductId() {
+        return sourceProductId;
+    }
+
+    public User withSourceProductId(String sourceProductId) {
+        this.setSourceProductId(sourceProductId);
+        return this;
+    }
+
+    public void setSourceProductId(String sourceProductId) {
+        this.sourceProductId = sourceProductId;
+    }
+
+    public String getInviteUserId() {
+        return inviteUserId;
+    }
+
+    public User withInviteUserId(String inviteUserId) {
+        this.setInviteUserId(inviteUserId);
+        return this;
+    }
+
+    public void setInviteUserId(String inviteUserId) {
+        this.inviteUserId = inviteUserId;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public User withFirstName(String firstName) {
+        this.setFirstName(firstName);
+        return this;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public User withLastName(String lastName) {
+        this.setLastName(lastName);
+        return this;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public User withAddress(String address) {
+        this.setAddress(address);
+        return this;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
     @Override
     public boolean equals(Object that) {
         if (this == that) {
@@ -417,7 +507,13 @@ public class User implements Serializable {
             && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
             && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))
             && (this.getRemark() == null ? other.getRemark() == null : this.getRemark().equals(other.getRemark()))
-            && (this.getValidFlag() == null ? other.getValidFlag() == null : this.getValidFlag().equals(other.getValidFlag()));
+            && (this.getCanAccessAi() == null ? other.getCanAccessAi() == null : this.getCanAccessAi().equals(other.getCanAccessAi()))
+            && (this.getValidFlag() == null ? other.getValidFlag() == null : this.getValidFlag().equals(other.getValidFlag()))
+            && (this.getSourceProductId() == null ? other.getSourceProductId() == null : this.getSourceProductId().equals(other.getSourceProductId()))
+            && (this.getInviteUserId() == null ? other.getInviteUserId() == null : this.getInviteUserId().equals(other.getInviteUserId()))
+            && (this.getFirstName() == null ? other.getFirstName() == null : this.getFirstName().equals(other.getFirstName()))
+            && (this.getLastName() == null ? other.getLastName() == null : this.getLastName().equals(other.getLastName()))
+            && (this.getAddress() == null ? other.getAddress() == null : this.getAddress().equals(other.getAddress()));
     }
 
     @Override
@@ -448,7 +544,13 @@ public class User implements Serializable {
         result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
         result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
         result = prime * result + ((getRemark() == null) ? 0 : getRemark().hashCode());
+        result = prime * result + ((getCanAccessAi() == null) ? 0 : getCanAccessAi().hashCode());
         result = prime * result + ((getValidFlag() == null) ? 0 : getValidFlag().hashCode());
+        result = prime * result + ((getSourceProductId() == null) ? 0 : getSourceProductId().hashCode());
+        result = prime * result + ((getInviteUserId() == null) ? 0 : getInviteUserId().hashCode());
+        result = prime * result + ((getFirstName() == null) ? 0 : getFirstName().hashCode());
+        result = prime * result + ((getLastName() == null) ? 0 : getLastName().hashCode());
+        result = prime * result + ((getAddress() == null) ? 0 : getAddress().hashCode());
         return result;
     }
 
@@ -482,7 +584,13 @@ public class User implements Serializable {
         sb.append(", createdAt=").append(createdAt);
         sb.append(", updatedAt=").append(updatedAt);
         sb.append(", remark=").append(remark);
+        sb.append(", canAccessAi=").append(canAccessAi);
         sb.append(", validFlag=").append(validFlag);
+        sb.append(", sourceProductId=").append(sourceProductId);
+        sb.append(", inviteUserId=").append(inviteUserId);
+        sb.append(", firstName=").append(firstName);
+        sb.append(", lastName=").append(lastName);
+        sb.append(", address=").append(address);
         sb.append(", serialVersionUID=").append(serialVersionUID);
         sb.append("]");
         return sb.toString();

+ 450 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/UserExample.java

@@ -1675,6 +1675,76 @@ public class UserExample {
             return (Criteria) this;
         }
 
+        public Criteria andCanAccessAiIsNull() {
+            addCriterion("can_access_ai is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiIsNotNull() {
+            addCriterion("can_access_ai is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiEqualTo(String value) {
+            addCriterion("can_access_ai =", value, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiNotEqualTo(String value) {
+            addCriterion("can_access_ai <>", value, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiGreaterThan(String value) {
+            addCriterion("can_access_ai >", value, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiGreaterThanOrEqualTo(String value) {
+            addCriterion("can_access_ai >=", value, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiLessThan(String value) {
+            addCriterion("can_access_ai <", value, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiLessThanOrEqualTo(String value) {
+            addCriterion("can_access_ai <=", value, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiLike(String value) {
+            addCriterion("can_access_ai like", value, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiNotLike(String value) {
+            addCriterion("can_access_ai not like", value, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiIn(List<String> values) {
+            addCriterion("can_access_ai in", values, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiNotIn(List<String> values) {
+            addCriterion("can_access_ai not in", values, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiBetween(String value1, String value2) {
+            addCriterion("can_access_ai between", value1, value2, "canAccessAi");
+            return (Criteria) this;
+        }
+
+        public Criteria andCanAccessAiNotBetween(String value1, String value2) {
+            addCriterion("can_access_ai not between", value1, value2, "canAccessAi");
+            return (Criteria) this;
+        }
+
         public Criteria andValidFlagIsNull() {
             addCriterion("valid_flag is null");
             return (Criteria) this;
@@ -1745,6 +1815,356 @@ public class UserExample {
             return (Criteria) this;
         }
 
+        public Criteria andSourceProductIdIsNull() {
+            addCriterion("source_product_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdIsNotNull() {
+            addCriterion("source_product_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdEqualTo(String value) {
+            addCriterion("source_product_id =", value, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdNotEqualTo(String value) {
+            addCriterion("source_product_id <>", value, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdGreaterThan(String value) {
+            addCriterion("source_product_id >", value, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdGreaterThanOrEqualTo(String value) {
+            addCriterion("source_product_id >=", value, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdLessThan(String value) {
+            addCriterion("source_product_id <", value, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdLessThanOrEqualTo(String value) {
+            addCriterion("source_product_id <=", value, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdLike(String value) {
+            addCriterion("source_product_id like", value, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdNotLike(String value) {
+            addCriterion("source_product_id not like", value, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdIn(List<String> values) {
+            addCriterion("source_product_id in", values, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdNotIn(List<String> values) {
+            addCriterion("source_product_id not in", values, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdBetween(String value1, String value2) {
+            addCriterion("source_product_id between", value1, value2, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceProductIdNotBetween(String value1, String value2) {
+            addCriterion("source_product_id not between", value1, value2, "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdIsNull() {
+            addCriterion("invite_user_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdIsNotNull() {
+            addCriterion("invite_user_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdEqualTo(String value) {
+            addCriterion("invite_user_id =", value, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdNotEqualTo(String value) {
+            addCriterion("invite_user_id <>", value, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdGreaterThan(String value) {
+            addCriterion("invite_user_id >", value, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdGreaterThanOrEqualTo(String value) {
+            addCriterion("invite_user_id >=", value, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdLessThan(String value) {
+            addCriterion("invite_user_id <", value, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdLessThanOrEqualTo(String value) {
+            addCriterion("invite_user_id <=", value, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdLike(String value) {
+            addCriterion("invite_user_id like", value, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdNotLike(String value) {
+            addCriterion("invite_user_id not like", value, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdIn(List<String> values) {
+            addCriterion("invite_user_id in", values, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdNotIn(List<String> values) {
+            addCriterion("invite_user_id not in", values, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdBetween(String value1, String value2) {
+            addCriterion("invite_user_id between", value1, value2, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdNotBetween(String value1, String value2) {
+            addCriterion("invite_user_id not between", value1, value2, "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameIsNull() {
+            addCriterion("first_name is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameIsNotNull() {
+            addCriterion("first_name is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameEqualTo(String value) {
+            addCriterion("first_name =", value, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameNotEqualTo(String value) {
+            addCriterion("first_name <>", value, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameGreaterThan(String value) {
+            addCriterion("first_name >", value, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameGreaterThanOrEqualTo(String value) {
+            addCriterion("first_name >=", value, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameLessThan(String value) {
+            addCriterion("first_name <", value, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameLessThanOrEqualTo(String value) {
+            addCriterion("first_name <=", value, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameLike(String value) {
+            addCriterion("first_name like", value, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameNotLike(String value) {
+            addCriterion("first_name not like", value, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameIn(List<String> values) {
+            addCriterion("first_name in", values, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameNotIn(List<String> values) {
+            addCriterion("first_name not in", values, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameBetween(String value1, String value2) {
+            addCriterion("first_name between", value1, value2, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameNotBetween(String value1, String value2) {
+            addCriterion("first_name not between", value1, value2, "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameIsNull() {
+            addCriterion("last_name is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameIsNotNull() {
+            addCriterion("last_name is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameEqualTo(String value) {
+            addCriterion("last_name =", value, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameNotEqualTo(String value) {
+            addCriterion("last_name <>", value, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameGreaterThan(String value) {
+            addCriterion("last_name >", value, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameGreaterThanOrEqualTo(String value) {
+            addCriterion("last_name >=", value, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameLessThan(String value) {
+            addCriterion("last_name <", value, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameLessThanOrEqualTo(String value) {
+            addCriterion("last_name <=", value, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameLike(String value) {
+            addCriterion("last_name like", value, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameNotLike(String value) {
+            addCriterion("last_name not like", value, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameIn(List<String> values) {
+            addCriterion("last_name in", values, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameNotIn(List<String> values) {
+            addCriterion("last_name not in", values, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameBetween(String value1, String value2) {
+            addCriterion("last_name between", value1, value2, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameNotBetween(String value1, String value2) {
+            addCriterion("last_name not between", value1, value2, "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressIsNull() {
+            addCriterion("address is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressIsNotNull() {
+            addCriterion("address is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressEqualTo(String value) {
+            addCriterion("address =", value, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressNotEqualTo(String value) {
+            addCriterion("address <>", value, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressGreaterThan(String value) {
+            addCriterion("address >", value, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressGreaterThanOrEqualTo(String value) {
+            addCriterion("address >=", value, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressLessThan(String value) {
+            addCriterion("address <", value, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressLessThanOrEqualTo(String value) {
+            addCriterion("address <=", value, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressLike(String value) {
+            addCriterion("address like", value, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressNotLike(String value) {
+            addCriterion("address not like", value, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressIn(List<String> values) {
+            addCriterion("address in", values, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressNotIn(List<String> values) {
+            addCriterion("address not in", values, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressBetween(String value1, String value2) {
+            addCriterion("address between", value1, value2, "address");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressNotBetween(String value1, String value2) {
+            addCriterion("address not between", value1, value2, "address");
+            return (Criteria) this;
+        }
+
         public Criteria andIdLikeInsensitive(String value) {
             addCriterion("upper(id) like", value.toUpperCase(), "id");
             return (Criteria) this;
@@ -1810,10 +2230,40 @@ public class UserExample {
             return (Criteria) this;
         }
 
+        public Criteria andCanAccessAiLikeInsensitive(String value) {
+            addCriterion("upper(can_access_ai) like", value.toUpperCase(), "canAccessAi");
+            return (Criteria) this;
+        }
+
         public Criteria andValidFlagLikeInsensitive(String value) {
             addCriterion("upper(valid_flag) like", value.toUpperCase(), "validFlag");
             return (Criteria) this;
         }
+
+        public Criteria andSourceProductIdLikeInsensitive(String value) {
+            addCriterion("upper(source_product_id) like", value.toUpperCase(), "sourceProductId");
+            return (Criteria) this;
+        }
+
+        public Criteria andInviteUserIdLikeInsensitive(String value) {
+            addCriterion("upper(invite_user_id) like", value.toUpperCase(), "inviteUserId");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstNameLikeInsensitive(String value) {
+            addCriterion("upper(first_name) like", value.toUpperCase(), "firstName");
+            return (Criteria) this;
+        }
+
+        public Criteria andLastNameLikeInsensitive(String value) {
+            addCriterion("upper(last_name) like", value.toUpperCase(), "lastName");
+            return (Criteria) this;
+        }
+
+        public Criteria andAddressLikeInsensitive(String value) {
+            addCriterion("upper(address) like", value.toUpperCase(), "address");
+            return (Criteria) this;
+        }
     }
 
     public static class Criteria extends GeneratedCriteria {

+ 20 - 2
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/UserSubscriptionInfo.java

@@ -20,6 +20,8 @@ public class UserSubscriptionInfo implements Serializable {
 
     private String productId;
 
+    private Integer point;
+
     private static final long serialVersionUID = 1L;
 
     public String getId() {
@@ -126,6 +128,19 @@ public class UserSubscriptionInfo implements Serializable {
         this.productId = productId;
     }
 
+    public Integer getPoint() {
+        return point;
+    }
+
+    public UserSubscriptionInfo withPoint(Integer point) {
+        this.setPoint(point);
+        return this;
+    }
+
+    public void setPoint(Integer point) {
+        this.point = point;
+    }
+
     @Override
     public boolean equals(Object that) {
         if (this == that) {
@@ -145,7 +160,8 @@ public class UserSubscriptionInfo implements Serializable {
             && (this.getEndDate() == null ? other.getEndDate() == null : this.getEndDate().equals(other.getEndDate()))
             && (this.getPayType() == null ? other.getPayType() == null : this.getPayType().equals(other.getPayType()))
             && (this.getAppId() == null ? other.getAppId() == null : this.getAppId().equals(other.getAppId()))
-            && (this.getProductId() == null ? other.getProductId() == null : this.getProductId().equals(other.getProductId()));
+            && (this.getProductId() == null ? other.getProductId() == null : this.getProductId().equals(other.getProductId()))
+            && (this.getPoint() == null ? other.getPoint() == null : this.getPoint().equals(other.getPoint()));
     }
 
     @Override
@@ -160,6 +176,7 @@ public class UserSubscriptionInfo implements Serializable {
         result = prime * result + ((getPayType() == null) ? 0 : getPayType().hashCode());
         result = prime * result + ((getAppId() == null) ? 0 : getAppId().hashCode());
         result = prime * result + ((getProductId() == null) ? 0 : getProductId().hashCode());
+        result = prime * result + ((getPoint() == null) ? 0 : getPoint().hashCode());
         return result;
     }
 
@@ -177,8 +194,9 @@ public class UserSubscriptionInfo implements Serializable {
         sb.append(", payType=").append(payType);
         sb.append(", appId=").append(appId);
         sb.append(", productId=").append(productId);
+        sb.append(", point=").append(point);
         sb.append(", serialVersionUID=").append(serialVersionUID);
         sb.append("]");
         return sb.toString();
     }
-}
+}

+ 61 - 1
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/UserSubscriptionInfoExample.java

@@ -625,6 +625,66 @@ public class UserSubscriptionInfoExample {
             return (Criteria) this;
         }
 
+        public Criteria andPointIsNull() {
+            addCriterion("point is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointIsNotNull() {
+            addCriterion("point is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointEqualTo(Integer value) {
+            addCriterion("point =", value, "point");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointNotEqualTo(Integer value) {
+            addCriterion("point <>", value, "point");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointGreaterThan(Integer value) {
+            addCriterion("point >", value, "point");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointGreaterThanOrEqualTo(Integer value) {
+            addCriterion("point >=", value, "point");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointLessThan(Integer value) {
+            addCriterion("point <", value, "point");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointLessThanOrEqualTo(Integer value) {
+            addCriterion("point <=", value, "point");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointIn(List<Integer> values) {
+            addCriterion("point in", values, "point");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointNotIn(List<Integer> values) {
+            addCriterion("point not in", values, "point");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointBetween(Integer value1, Integer value2) {
+            addCriterion("point between", value1, value2, "point");
+            return (Criteria) this;
+        }
+
+        public Criteria andPointNotBetween(Integer value1, Integer value2) {
+            addCriterion("point not between", value1, value2, "point");
+            return (Criteria) this;
+        }
+
         public Criteria andIdLikeInsensitive(String value) {
             addCriterion("upper(id) like", value.toUpperCase(), "id");
             return (Criteria) this;
@@ -738,4 +798,4 @@ public class UserSubscriptionInfoExample {
             this(condition, value, secondValue, null);
         }
     }
-}
+}

+ 9 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/AIService.java

@@ -0,0 +1,9 @@
+package cn.kdan.cloud.pdf.office.account.service;
+
+import cn.kdan.cloud.pdf.office.account.model.AiRecord;
+
+public interface AIService {
+    void insert(AiRecord aiRecord);
+
+    AiRecord getByFileKey(String fileKey);
+}

+ 2 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/LoginDeviceService.java

@@ -44,4 +44,6 @@ public interface LoginDeviceService {
      * @return LoginDevice
      */
     LoginDevice getByDeviceSignAndAppId(String deviceSign, String userId, String appId);
+
+    LoginDevice getById(String deviceId);
 }

+ 4 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/UserService.java

@@ -124,6 +124,10 @@ public interface UserService {
      */
     UserInfoVO getInfoById(String id);
 
+    UserInfoVO getMemberInfoById(String id);
+
+    Integer getInviteNum(String userId);
+
     void handleLogOff(User user, String remark);
 
 

+ 6 - 2
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/UserSubscriptionInfoService.java

@@ -1,6 +1,7 @@
 package cn.kdan.cloud.pdf.office.account.service;
 
 import cn.kdan.cloud.pdf.office.account.model.UserSubscriptionInfo;
+import cn.kdan.cloud.pdf.office.common.vo.UserSubscriptionInfoVO;
 
 import java.util.List;
 
@@ -23,11 +24,12 @@ public interface UserSubscriptionInfoService {
     /**
      * 获取用户在某一个平台的会员情况
      *
-     * @param userId 用户id
+     * @param userId   用户id
      * @param platform 平台
+     * @param appId
      * @return UserSubscriptionInfo
      */
-    UserSubscriptionInfo getByUserIdAndPlatform(String userId, Integer platform);
+    UserSubscriptionInfo getByUserIdAndPlatform(String userId, Integer platform, String appId);
 
     /**
      * 插入用户会员信息
@@ -44,4 +46,6 @@ public interface UserSubscriptionInfoService {
     void update(UserSubscriptionInfo userSubscriptionInfo);
 
     UserSubscriptionInfo getByUserIdAndProductId(String userId, String productId);
+
+    List<UserSubscriptionInfoVO> getByUserIdAndAppId(String userId, String appId);
 }

+ 32 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/impl/AIServiceImpl.java

@@ -0,0 +1,32 @@
+package cn.kdan.cloud.pdf.office.account.service.impl;
+
+import cn.kdan.cloud.pdf.office.account.mapper.AiRecordMapper;
+import cn.kdan.cloud.pdf.office.account.model.AiRecord;
+import cn.kdan.cloud.pdf.office.account.model.AiRecordExample;
+import cn.kdan.cloud.pdf.office.account.service.AIService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+@Service
+@Transactional
+@Slf4j
+public class AIServiceImpl implements AIService {
+
+    @Resource
+    private AiRecordMapper AiRecordMapper;
+
+    @Override
+    public void insert(AiRecord aiRecord) {
+        AiRecordMapper.insert(aiRecord);
+    }
+    @Override
+    public AiRecord getByFileKey(String fileKey) {
+        AiRecordExample example = new AiRecordExample();
+        example.createCriteria().andFileKeyEqualTo(fileKey);
+        return AiRecordMapper.selectByExample(example).get(0);
+    }
+
+}

+ 12 - 4
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/impl/LoginDeviceServiceImpl.java

@@ -44,16 +44,19 @@ public class LoginDeviceServiceImpl implements LoginDeviceService {
         example.createCriteria().andUniqueSnEqualTo(deviceSign).andUserIdEqualTo(userId).andAppIdEqualTo(appId);
         if(isDelete){
             loginDeviceMapper.deleteByExample(example);
+        }else{
+            LoginDevice device = new LoginDevice();
+            device.setValidFlag(ValidStatusEnum.INVALID.value());
+            loginDeviceMapper.updateByExampleSelective(device,example);
         }
-        LoginDevice device = new LoginDevice();
-        device.setValidFlag(ValidStatusEnum.INVALID.value());
-        loginDeviceMapper.updateByExampleSelective(device,example);
     }
 
     @Override
     public LoginDevice getByDeviceSignAndAppId(String deviceSign, String userId, String appId) {
         LoginDeviceExample example = new LoginDeviceExample();
-        LoginDeviceExample.Criteria criteria = example.createCriteria().andUniqueSnEqualTo(deviceSign).andAppIdEqualTo(appId);
+        LoginDeviceExample.Criteria criteria = example.createCriteria().andUniqueSnEqualTo(deviceSign)
+                .andAppIdEqualTo(appId);
+        example.setOrderByClause("created_at DESC");
         if(!StringUtils.isEmpty(userId)){
             criteria.andUserIdEqualTo(userId);
         }
@@ -64,4 +67,9 @@ public class LoginDeviceServiceImpl implements LoginDeviceService {
         return list.get(0);
     }
 
+    @Override
+    public LoginDevice getById(String deviceId) {
+        return loginDeviceMapper.selectByPrimaryKey(deviceId);
+    }
+
 }

+ 73 - 13
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/impl/UserServiceImpl.java

@@ -1,6 +1,7 @@
 package cn.kdan.cloud.pdf.office.account.service.impl;
 
 import cn.kdan.cloud.pdf.office.account.constant.UserConstant;
+import cn.kdan.cloud.pdf.office.account.enums.SourceProduct;
 import cn.kdan.cloud.pdf.office.account.mapper.ext.ExtUserMapper;
 import cn.kdan.cloud.pdf.office.account.model.User;
 import cn.kdan.cloud.pdf.office.account.model.UserExample;
@@ -142,15 +143,24 @@ public class UserServiceImpl implements UserService {
         //通过用户可以查到对应的app
         user.setUpdatedAt(new Date());
         //账号类型 付费账号1 免费账号0 AccountTypeEnum
-        user.setAccountType(AccountTypeEnum.PAID_ACCOUNT.value());
+        if(!ObjectUtils.isEmpty(updateUserForOrderDTO.getAccountType())){
+            user.setAccountType(updateUserForOrderDTO.getAccountType().value());
+        }else {
+            user.setAccountType(AccountTypeEnum.PAID_ACCOUNT.value());
+        }
         //通过用户id和平台类型查询会员信息表,如果有会员信息则更新,如果没有会员信息就插入
-        UserSubscriptionInfo userSubscriptionInfo = userSubscriptionInfoService.getByUserIdAndPlatform(user.getId(), updateUserForOrderDTO.getPlatform());
+        //platform是从product中来的app_id = 1时: 0免费,1永久版,2订阅,3AI
+        String appId = StringUtils.isEmpty(updateUserForOrderDTO.getAppId()) ? "16":updateUserForOrderDTO.getAppId();
+        UserSubscriptionInfo userSubscriptionInfo = userSubscriptionInfoService.getByUserIdAndPlatform(user.getId(), updateUserForOrderDTO.getPlatform(), appId);
         if(ObjectUtils.isEmpty(userSubscriptionInfo)){
             UserSubscriptionInfo newInfo = new UserSubscriptionInfo().withId(CommonUtils.generateId())
                     .withUserId(user.getId()).withStatus(updateUserForOrderDTO.getUserStatus())
                     .withPayType(updateUserForOrderDTO.getPayTpe()).withEndDate(updateUserForOrderDTO.getEndDate())
                     .withProductId(updateUserForOrderDTO.getProductId()).withAppId(updateUserForOrderDTO.getAppId())
                     .withPlatform(updateUserForOrderDTO.getPlatform());
+            if(StringUtils.isNotEmpty(appId)&&appId.equals(CommonConstant.PDF_READER_PRO_APP_ID)&&updateUserForOrderDTO.getPlatform().equals(3)){
+                newInfo.setPoint(updateUserForOrderDTO.getPoint());
+            }
             userSubscriptionInfoService.insert(newInfo);
         }else{
           //更新
@@ -159,6 +169,12 @@ public class UserServiceImpl implements UserService {
             if(!ObjectUtils.isEmpty(updateUserForOrderDTO.getEndDate())){
                 userSubscriptionInfo.setEndDate(updateUserForOrderDTO.getEndDate());
             }
+            if(!ObjectUtils.isEmpty(updateUserForOrderDTO.getProductId())){
+                userSubscriptionInfo.setProductId(updateUserForOrderDTO.getProductId());
+            }
+            if(StringUtils.isNotEmpty(appId)&&appId.equals(CommonConstant.PDF_READER_PRO_APP_ID)&&updateUserForOrderDTO.getPlatform().equals(3)){
+                userSubscriptionInfo.setPoint(userSubscriptionInfo.getPoint() + updateUserForOrderDTO.getPoint());
+            }
             userSubscriptionInfoService.update(userSubscriptionInfo);
         }
         extUserMapper.updateByPrimaryKey(user);
@@ -170,20 +186,34 @@ public class UserServiceImpl implements UserService {
         //参数校验
         validRegisterParam(userRegisterDTO);
         Integer accountSource = ObjectUtils.isEmpty(userRegisterDTO.getAccountSource()) ? AccountSourceEnum.REGISTER.value() : userRegisterDTO.getAccountSource();
-        initUser(userRegisterDTO.getAppId(),userRegisterDTO.getUsername(),userRegisterDTO.getPassword(), accountSource,userRegisterDTO.getModel());
+        initUser(userRegisterDTO.getAppId(),userRegisterDTO.getUsername(),userRegisterDTO.getPassword(),
+                accountSource,userRegisterDTO.getModel(),userRegisterDTO.getInviteUserId(),userRegisterDTO.getAccountTypeEnum());
     }
 
-    private User initUser(String appId, String email, String pwd, Integer accountSource, String model) {
+    private User initUser(String appId, String email, String pwd, Integer accountSource, String model, String inviteUserId, AccountTypeEnum accountTypeEnum) {
         User user = new User();
-        user.setId(CommonUtils.generateId());
+        String id = CommonUtils.generateRandomUserId();
+        if(!ObjectUtils.isEmpty(getById(id))){
+            id = CommonUtils.generateRandomUserId();
+        }
+        if(!StringUtils.isEmpty(inviteUserId)){
+            user.setInviteUserId(inviteUserId);
+        }
+        user.setId(CommonUtils.generateRandomUserId());
         user.setAppId(appId);
         user.setEmail(email);
         user.setCreatedAt(new Date());
-        user.setAccountType(AccountTypeEnum.FREE_ACCOUNT.value());
+        if(!ObjectUtils.isEmpty(accountTypeEnum)){
+            user.setAccountType(accountTypeEnum.value());
+        }else{
+            user.setAccountType(AccountTypeEnum.FREE_ACCOUNT.value());
+        }
         user.setPlatformType(PlatformTypeEnum.WEBSITE.value());
         user.setAccountSource(accountSource);
-        //用户来源平台
-        user.setModelSource(model);
+        if(StringUtils.isNotEmpty(model)){
+            user.setModelSource(model);
+            user.setSourceProductId(SourceProduct.getIdByName(model));
+        }
         user.setValidFlag(PDFOfficeUserStatusEnum.VALID.value().toString());
         if(StringUtils.isNotEmpty(pwd)){
             user.setDigestPassword(new RSAUtils().encrypt(pwd));
@@ -207,13 +237,23 @@ public class UserServiceImpl implements UserService {
     public void logOffForUser(String code, String userId, String appId) {
         User user = getUser(userId);
         //检查验证码是否正确
-        checkEmailCodeValid(EmailCodeTypeEnum.USER_LOG_OFF, user.getEmail(), code,user.getAppId());
+        if(StringUtils.isEmpty(appId)){
+            appId = user.getAppId();
+        }
+        EmailCodeTypeEnum codeTypeEnum = EmailCodeTypeEnum.USER_LOG_OFF;
+        if(appId.equals("1")){
+            codeTypeEnum = EmailCodeTypeEnum.MEMBER_LOG_OFF;
+        }
+        checkEmailCodeValid(codeTypeEnum, user.getEmail(), code,appId);
         //检查用户订阅(试用期可以注销,订阅期不能注销)
         List<UserSubscriptionInfo> list = userSubscriptionInfoService.listByUserId(userId);
         if(!CollectionUtils.isEmpty(list)){
             list.forEach(item->{
                 //如果订阅中,则提示不能注销
-                if(item.getStatus().equals(PDFOfficeUserSubscriptionStatusEnum.SUBSCRIPTION_IN_PROGRESS.value()) ){
+                if(item.getStatus().equals(PDFOfficeUserSubscriptionStatusEnum.SUBSCRIPTION_IN_PROGRESS.value())&&item.getAppId().equals("16")){
+                    throw new BackendRuntimeException(ExceptionEnum.EXCEPTION_MSG_USER_SUBSCRIPTION_IN_PROGRESS);
+                }
+                if(item.getPayType().equals(PayTypeEnum.AUTO.value())&&item.getAppId().equals("1")){
                     throw new BackendRuntimeException(ExceptionEnum.EXCEPTION_MSG_USER_SUBSCRIPTION_IN_PROGRESS);
                 }
             });
@@ -224,7 +264,8 @@ public class UserServiceImpl implements UserService {
                 RabbitMqConstant.USER_LOGOFF_ROUTING_KEY,
                 userId,
                 (msg -> {
-                    msg.getMessageProperties().setHeader("x-delay", UserConstant.USER_LOGOFF_DELAY_TIME + "");
+                    Long time = "1".equals(user.getAppId())?UserConstant.MEMBER_LOGOFF_DELAY_TIME:UserConstant.USER_LOGOFF_DELAY_TIME;
+                    msg.getMessageProperties().setHeader("x-delay", time + "");
                     return msg;
                 }));
         //注销中
@@ -237,6 +278,9 @@ public class UserServiceImpl implements UserService {
     public UserInfoVO getInfoById(String id) {
         UserInfoVO infoVO = new UserInfoVO();
         User user = getUser(id);
+        if(ObjectUtils.isEmpty(user)){
+            return null;
+        }
         BeanUtils.copyProperties(user,infoVO);
         List<UserSubscriptionInfo> list = userSubscriptionInfoService.listByUserId(id);
         List<UserSubscriptionInfoVO> voList = new ArrayList<>();
@@ -258,6 +302,22 @@ public class UserServiceImpl implements UserService {
         return infoVO;
     }
 
+    @Override
+    public UserInfoVO getMemberInfoById(String id) {
+        UserInfoVO infoVO = new UserInfoVO();
+        User user = getUser(id);
+        BeanUtils.copyProperties(user,infoVO);
+        List<UserSubscriptionInfoVO> voList = userSubscriptionInfoService.getByUserIdAndAppId(id,"1");
+        infoVO.setSubscriptionInfoList(voList);
+        return infoVO;
+    }
+    @Override
+    public Integer getInviteNum(String userId){
+        UserExample example = new UserExample();
+        example.createCriteria().andInviteUserIdEqualTo(userId);
+        return (int)extUserMapper.countByExample(example);
+    }
+
     /**
      * 注销公共方法
      *
@@ -315,10 +375,10 @@ public class UserServiceImpl implements UserService {
 
     private void checkEmailCodeValid(EmailCodeTypeEnum type, String account, String code, String appId) {
         //获取用户存在redis中的登录邮箱验证码
-        String captchaCode = redisUtils.hget(CommonConstant.EMAIL_VERIFY_CODE_KEY + type.value()  + CommonConstant.STRIKE_THROUGH + appId , account);
+        String captchaCode = redisUtils.hget(CommonConstant.EMAIL_VERIFY_CODE_KEY + type.value()  + CommonConstant.STRING_SIGN_COLON + appId , account);
         if(StringUtils.isNotEmpty(code) && code.equals(captchaCode)){
             //验证通过删除
-            redisUtils.hdel(CommonConstant.EMAIL_VERIFY_CODE_KEY + type.value() + CommonConstant.STRIKE_THROUGH + appId  , account);
+            redisUtils.hdel(CommonConstant.EMAIL_VERIFY_CODE_KEY + type.value() + CommonConstant.STRING_SIGN_COLON + appId  , account);
         }else{
             throw new BackendRuntimeException(ExceptionEnum.EMAIL_VERIFY_CODE_KEY_ERROR);
         }

+ 20 - 9
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/impl/UserSubscriptionInfoServiceImpl.java

@@ -1,10 +1,12 @@
 package cn.kdan.cloud.pdf.office.account.service.impl;
 
-import cn.kdan.cloud.pdf.office.account.mapper.UserSubscriptionInfoMapper;
+import cn.kdan.cloud.pdf.office.account.mapper.ext.ExtUserSubscriptionInfoMapper;
 import cn.kdan.cloud.pdf.office.account.model.UserSubscriptionInfo;
 import cn.kdan.cloud.pdf.office.account.model.UserSubscriptionInfoExample;
 import cn.kdan.cloud.pdf.office.account.service.UserSubscriptionInfoService;
+import cn.kdan.cloud.pdf.office.common.vo.UserSubscriptionInfoVO;
 import com.alibaba.nacos.common.utils.CollectionUtils;
+import com.alibaba.nacos.common.utils.StringUtils;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -17,39 +19,48 @@ import java.util.List;
 public class UserSubscriptionInfoServiceImpl implements UserSubscriptionInfoService {
 
     @Resource
-    private UserSubscriptionInfoMapper userSubscriptionInfoMapper;
+    private ExtUserSubscriptionInfoMapper extUserSubscriptionInfoMapper;
 
 
     @Override
     public List<UserSubscriptionInfo> listByUserId(String userId) {
         UserSubscriptionInfoExample example = new UserSubscriptionInfoExample();
         example.createCriteria().andUserIdEqualTo(userId);
-        return userSubscriptionInfoMapper.selectByExample(example);
+        return extUserSubscriptionInfoMapper.selectByExample(example);
     }
 
     @Override
-    public UserSubscriptionInfo getByUserIdAndPlatform(String userId, Integer platform) {
+    public UserSubscriptionInfo getByUserIdAndPlatform(String userId, Integer platform, String appId) {
         UserSubscriptionInfoExample example = new UserSubscriptionInfoExample();
-        example.createCriteria().andUserIdEqualTo(userId).andPlatformEqualTo(platform);
-        List<UserSubscriptionInfo> list = userSubscriptionInfoMapper.selectByExample(example);
+        UserSubscriptionInfoExample.Criteria criteria =  example.createCriteria().andUserIdEqualTo(userId).andPlatformEqualTo(platform);
+        if(StringUtils.isNotEmpty(appId)){
+            criteria.andAppIdEqualTo(appId);
+        }
+        List<UserSubscriptionInfo> list = extUserSubscriptionInfoMapper.selectByExample(example);
         return CollectionUtils.isNotEmpty(list) ? list.get(0): null;
     }
 
     @Override
     public void insert(UserSubscriptionInfo userSubscriptionInfo) {
-        userSubscriptionInfoMapper.insert(userSubscriptionInfo);
+        extUserSubscriptionInfoMapper.insert(userSubscriptionInfo);
     }
 
     @Override
     public void update(UserSubscriptionInfo userSubscriptionInfo) {
-        userSubscriptionInfoMapper.updateByPrimaryKeySelective(userSubscriptionInfo);
+        extUserSubscriptionInfoMapper.updateByPrimaryKeySelective(userSubscriptionInfo);
     }
 
     @Override
     public UserSubscriptionInfo getByUserIdAndProductId(String userId, String productId) {
         UserSubscriptionInfoExample example = new UserSubscriptionInfoExample();
         example.createCriteria().andUserIdEqualTo(userId).andProductIdEqualTo(productId);
-        List<UserSubscriptionInfo> list = userSubscriptionInfoMapper.selectByExample(example);
+        List<UserSubscriptionInfo> list = extUserSubscriptionInfoMapper.selectByExample(example);
         return CollectionUtils.isNotEmpty(list) ? list.get(0): null;
     }
+
+    @Override
+    public List<UserSubscriptionInfoVO> getByUserIdAndAppId(String userId, String appId) {
+        return extUserSubscriptionInfoMapper.getInfo(userId,appId);
+    }
+
 }

+ 16 - 9
pdf-office-account/src/main/resources/generatorConfig.xml

@@ -21,9 +21,8 @@
 		</commentGenerator>
 
 		<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
-						connectionURL="jdbc:mysql://124.223.7.184:33056/pdf_office_dev"
-						userId="root" password="root123"
-
+						connectionURL="jdbc:mysql://101.132.103.13:33056/pdf_office_dev?useSSL=false"
+						userId="deployer" password="deployer@123!"
 		>
 			<property name="nullCatalogMeansCurrent" value="true"/>
 		</jdbcConnection>
@@ -40,11 +39,18 @@
 			<property name="enableSubPackages" value="true" />
 		</javaClientGenerator>
 <!--		<table tableName="oauth_client_details"/>-->
-<!--		<table tableName="user">-->
-<!--			<columnOverride column="platform_type"  javaType="java.lang.Integer"/>-->
-<!--			<columnOverride column="account_type"  javaType="java.lang.Integer"/>-->
-<!--			<columnOverride column="account_source" javaType="java.lang.Integer"/>-->
-<!--			<columnOverride column="remark" javaType="java.lang.String" jdbcType="VARCHAR"/>-->
+		<table tableName="user">
+			<columnOverride column="platform_type"  javaType="java.lang.Integer"/>
+			<columnOverride column="account_type"  javaType="java.lang.Integer"/>
+			<columnOverride column="account_source" javaType="java.lang.Integer"/>
+			<columnOverride column="remark" javaType="java.lang.String" jdbcType="VARCHAR"/>
+		</table>
+<!--		<table tableName="ai_record">-->
+
+<!--			<columnOverride column="credit" javaType="java.lang.Integer" />-->
+<!--			<columnOverride column="char_count" javaType="java.lang.Integer" />-->
+<!--			<columnOverride column="content" javaType="java.lang.String" jdbcType="VARCHAR"/>-->
+<!--			<columnOverride column="result" javaType="java.lang.String" jdbcType="VARCHAR"/>-->
 <!--		</table>-->
 <!--		<table tableName="user_subscription_info">-->
 <!--			<columnOverride column="platform" javaType="java.lang.Integer"/>-->
@@ -54,7 +60,8 @@
 
 <!--		<table tableName="vpp_company">-->
 <!--		</table>-->
-		<table tableName="login_device"/>
+<!--		<table tableName="login_device"/>-->
+<!--		<table tableName="user"/>-->
 <!--		<table tableName="device_log"/>-->
 	</context>
 </generatorConfiguration>

+ 320 - 0
pdf-office-account/src/main/resources/sqlmap/AiRecordMapper.xml

@@ -0,0 +1,320 @@
+<?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.cloud.pdf.office.account.mapper.AiRecordMapper">
+  <resultMap id="BaseResultMap" type="cn.kdan.cloud.pdf.office.account.model.AiRecord">
+    <id column="id" jdbcType="CHAR" property="id" />
+    <result column="user_id" jdbcType="VARCHAR" property="userId" />
+    <result column="function" jdbcType="VARCHAR" property="function" />
+    <result column="result" jdbcType="VARCHAR" property="result" />
+    <result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
+    <result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
+    <result column="content" jdbcType="VARCHAR" property="content" />
+    <result column="file_key" jdbcType="VARCHAR" property="fileKey" />
+    <result column="char_count" jdbcType="BIGINT" property="charCount" />
+    <result column="file_id" jdbcType="VARCHAR" property="fileId" />
+    <result column="credit" jdbcType="SMALLINT" property="credit" />
+  </resultMap>
+  <sql id="Example_Where_Clause">
+    <where>
+      <foreach collection="oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Update_By_Example_Where_Clause">
+    <where>
+      <foreach collection="example.oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Base_Column_List">
+    id, user_id, `function`, `result`, created_at, updated_at, content, file_key, char_count,
+    file_id, credit
+  </sql>
+  <select id="selectByExample" parameterType="cn.kdan.cloud.pdf.office.account.model.AiRecordExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from ai_record
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+  <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
+    select
+    <include refid="Base_Column_List" />
+    from ai_record
+    where id = #{id,jdbcType=CHAR}
+  </select>
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
+    delete from ai_record
+    where id = #{id,jdbcType=CHAR}
+  </delete>
+  <delete id="deleteByExample" parameterType="cn.kdan.cloud.pdf.office.account.model.AiRecordExample">
+    delete from ai_record
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </delete>
+  <insert id="insert" parameterType="cn.kdan.cloud.pdf.office.account.model.AiRecord">
+    insert into ai_record (id, user_id, `function`,
+      `result`, created_at, updated_at,
+      content, file_key, char_count,
+      file_id, credit)
+    values (#{id,jdbcType=CHAR}, #{userId,jdbcType=VARCHAR}, #{function,jdbcType=VARCHAR},
+      #{result,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP}, #{updatedAt,jdbcType=TIMESTAMP},
+      #{content,jdbcType=VARCHAR}, #{fileKey,jdbcType=VARCHAR}, #{charCount,jdbcType=BIGINT},
+      #{fileId,jdbcType=VARCHAR}, #{credit,jdbcType=SMALLINT})
+  </insert>
+  <insert id="insertSelective" parameterType="cn.kdan.cloud.pdf.office.account.model.AiRecord">
+    insert into ai_record
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        id,
+      </if>
+      <if test="userId != null">
+        user_id,
+      </if>
+      <if test="function != null">
+        `function`,
+      </if>
+      <if test="result != null">
+        `result`,
+      </if>
+      <if test="createdAt != null">
+        created_at,
+      </if>
+      <if test="updatedAt != null">
+        updated_at,
+      </if>
+      <if test="content != null">
+        content,
+      </if>
+      <if test="fileKey != null">
+        file_key,
+      </if>
+      <if test="charCount != null">
+        char_count,
+      </if>
+      <if test="fileId != null">
+        file_id,
+      </if>
+      <if test="credit != null">
+        credit,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        #{id,jdbcType=CHAR},
+      </if>
+      <if test="userId != null">
+        #{userId,jdbcType=VARCHAR},
+      </if>
+      <if test="function != null">
+        #{function,jdbcType=VARCHAR},
+      </if>
+      <if test="result != null">
+        #{result,jdbcType=VARCHAR},
+      </if>
+      <if test="createdAt != null">
+        #{createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updatedAt != null">
+        #{updatedAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="content != null">
+        #{content,jdbcType=VARCHAR},
+      </if>
+      <if test="fileKey != null">
+        #{fileKey,jdbcType=VARCHAR},
+      </if>
+      <if test="charCount != null">
+        #{charCount,jdbcType=BIGINT},
+      </if>
+      <if test="fileId != null">
+        #{fileId,jdbcType=VARCHAR},
+      </if>
+      <if test="credit != null">
+        #{credit,jdbcType=SMALLINT},
+      </if>
+    </trim>
+  </insert>
+  <select id="countByExample" parameterType="cn.kdan.cloud.pdf.office.account.model.AiRecordExample" resultType="java.lang.Long">
+    select count(*) from ai_record
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </select>
+  <update id="updateByExampleSelective" parameterType="map">
+    update ai_record
+    <set>
+      <if test="record.id != null">
+        id = #{record.id,jdbcType=CHAR},
+      </if>
+      <if test="record.userId != null">
+        user_id = #{record.userId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.function != null">
+        `function` = #{record.function,jdbcType=VARCHAR},
+      </if>
+      <if test="record.result != null">
+        `result` = #{record.result,jdbcType=VARCHAR},
+      </if>
+      <if test="record.createdAt != null">
+        created_at = #{record.createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="record.updatedAt != null">
+        updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="record.content != null">
+        content = #{record.content,jdbcType=VARCHAR},
+      </if>
+      <if test="record.fileKey != null">
+        file_key = #{record.fileKey,jdbcType=VARCHAR},
+      </if>
+      <if test="record.charCount != null">
+        char_count = #{record.charCount,jdbcType=BIGINT},
+      </if>
+      <if test="record.fileId != null">
+        file_id = #{record.fileId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.credit != null">
+        credit = #{record.credit,jdbcType=SMALLINT},
+      </if>
+    </set>
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExample" parameterType="map">
+    update ai_record
+    set id = #{record.id,jdbcType=CHAR},
+      user_id = #{record.userId,jdbcType=VARCHAR},
+      `function` = #{record.function,jdbcType=VARCHAR},
+      `result` = #{record.result,jdbcType=VARCHAR},
+      created_at = #{record.createdAt,jdbcType=TIMESTAMP},
+      updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
+      content = #{record.content,jdbcType=VARCHAR},
+      file_key = #{record.fileKey,jdbcType=VARCHAR},
+      char_count = #{record.charCount,jdbcType=BIGINT},
+      file_id = #{record.fileId,jdbcType=VARCHAR},
+      credit = #{record.credit,jdbcType=SMALLINT}
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByPrimaryKeySelective" parameterType="cn.kdan.cloud.pdf.office.account.model.AiRecord">
+    update ai_record
+    <set>
+      <if test="userId != null">
+        user_id = #{userId,jdbcType=VARCHAR},
+      </if>
+      <if test="function != null">
+        `function` = #{function,jdbcType=VARCHAR},
+      </if>
+      <if test="result != null">
+        `result` = #{result,jdbcType=VARCHAR},
+      </if>
+      <if test="createdAt != null">
+        created_at = #{createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updatedAt != null">
+        updated_at = #{updatedAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="content != null">
+        content = #{content,jdbcType=VARCHAR},
+      </if>
+      <if test="fileKey != null">
+        file_key = #{fileKey,jdbcType=VARCHAR},
+      </if>
+      <if test="charCount != null">
+        char_count = #{charCount,jdbcType=BIGINT},
+      </if>
+      <if test="fileId != null">
+        file_id = #{fileId,jdbcType=VARCHAR},
+      </if>
+      <if test="credit != null">
+        credit = #{credit,jdbcType=SMALLINT},
+      </if>
+    </set>
+    where id = #{id,jdbcType=CHAR}
+  </update>
+  <update id="updateByPrimaryKey" parameterType="cn.kdan.cloud.pdf.office.account.model.AiRecord">
+    update ai_record
+    set user_id = #{userId,jdbcType=VARCHAR},
+      `function` = #{function,jdbcType=VARCHAR},
+      `result` = #{result,jdbcType=VARCHAR},
+      created_at = #{createdAt,jdbcType=TIMESTAMP},
+      updated_at = #{updatedAt,jdbcType=TIMESTAMP},
+      content = #{content,jdbcType=VARCHAR},
+      file_key = #{fileKey,jdbcType=VARCHAR},
+      char_count = #{charCount,jdbcType=BIGINT},
+      file_id = #{fileId,jdbcType=VARCHAR},
+      credit = #{credit,jdbcType=SMALLINT}
+    where id = #{id,jdbcType=CHAR}
+  </update>
+  <select id="selectByExampleWithRowbounds" parameterType="cn.kdan.cloud.pdf.office.account.model.AiRecordExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from ai_record
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+</mapper>

+ 25 - 8
pdf-office-account/src/main/resources/sqlmap/LoginDeviceMapper.xml

@@ -9,6 +9,7 @@
     <result column="user_id" jdbcType="VARCHAR" property="userId" />
     <result column="model" jdbcType="VARCHAR" property="model" />
     <result column="os" jdbcType="VARCHAR" property="os" />
+    <result column="device_name" jdbcType="VARCHAR" property="deviceName" />
     <result column="language" jdbcType="VARCHAR" property="language" />
     <result column="time_zone" jdbcType="VARCHAR" property="timeZone" />
     <result column="app_version" jdbcType="VARCHAR" property="appVersion" />
@@ -76,8 +77,8 @@
     </where>
   </sql>
   <sql id="Base_Column_List">
-    id, product_id, unique_sn, app_id, user_id, model, os, `language`, time_zone, app_version, 
-    platform, updated_at, created_at, valid_flag
+    id, product_id, unique_sn, app_id, user_id, model, os, device_name, `language`, time_zone, 
+    app_version, platform, updated_at, created_at, valid_flag
   </sql>
   <select id="selectByExample" parameterType="cn.kdan.cloud.pdf.office.account.model.LoginDeviceExample" resultMap="BaseResultMap">
     select
@@ -112,14 +113,16 @@
   <insert id="insert" parameterType="cn.kdan.cloud.pdf.office.account.model.LoginDevice">
     insert into login_device (id, product_id, unique_sn, 
       app_id, user_id, model, 
-      os, `language`, time_zone, 
-      app_version, platform, updated_at, 
-      created_at, valid_flag)
+      os, device_name, `language`, 
+      time_zone, app_version, platform, 
+      updated_at, created_at, valid_flag
+      )
     values (#{id,jdbcType=VARCHAR}, #{productId,jdbcType=VARCHAR}, #{uniqueSn,jdbcType=VARCHAR}, 
       #{appId,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR}, #{model,jdbcType=VARCHAR}, 
-      #{os,jdbcType=VARCHAR}, #{language,jdbcType=VARCHAR}, #{timeZone,jdbcType=VARCHAR}, 
-      #{appVersion,jdbcType=VARCHAR}, #{platform,jdbcType=SMALLINT}, #{updatedAt,jdbcType=TIMESTAMP}, 
-      #{createdAt,jdbcType=TIMESTAMP}, #{validFlag,jdbcType=VARCHAR})
+      #{os,jdbcType=VARCHAR}, #{deviceName,jdbcType=VARCHAR}, #{language,jdbcType=VARCHAR}, 
+      #{timeZone,jdbcType=VARCHAR}, #{appVersion,jdbcType=VARCHAR}, #{platform,jdbcType=SMALLINT}, 
+      #{updatedAt,jdbcType=TIMESTAMP}, #{createdAt,jdbcType=TIMESTAMP}, #{validFlag,jdbcType=VARCHAR}
+      )
   </insert>
   <insert id="insertSelective" parameterType="cn.kdan.cloud.pdf.office.account.model.LoginDevice">
     insert into login_device
@@ -145,6 +148,9 @@
       <if test="os != null">
         os,
       </if>
+      <if test="deviceName != null">
+        device_name,
+      </if>
       <if test="language != null">
         `language`,
       </if>
@@ -189,6 +195,9 @@
       <if test="os != null">
         #{os,jdbcType=VARCHAR},
       </if>
+      <if test="deviceName != null">
+        #{deviceName,jdbcType=VARCHAR},
+      </if>
       <if test="language != null">
         #{language,jdbcType=VARCHAR},
       </if>
@@ -242,6 +251,9 @@
       <if test="record.os != null">
         os = #{record.os,jdbcType=VARCHAR},
       </if>
+      <if test="record.deviceName != null">
+        device_name = #{record.deviceName,jdbcType=VARCHAR},
+      </if>
       <if test="record.language != null">
         `language` = #{record.language,jdbcType=VARCHAR},
       </if>
@@ -277,6 +289,7 @@
       user_id = #{record.userId,jdbcType=VARCHAR},
       model = #{record.model,jdbcType=VARCHAR},
       os = #{record.os,jdbcType=VARCHAR},
+      device_name = #{record.deviceName,jdbcType=VARCHAR},
       `language` = #{record.language,jdbcType=VARCHAR},
       time_zone = #{record.timeZone,jdbcType=VARCHAR},
       app_version = #{record.appVersion,jdbcType=VARCHAR},
@@ -309,6 +322,9 @@
       <if test="os != null">
         os = #{os,jdbcType=VARCHAR},
       </if>
+      <if test="deviceName != null">
+        device_name = #{deviceName,jdbcType=VARCHAR},
+      </if>
       <if test="language != null">
         `language` = #{language,jdbcType=VARCHAR},
       </if>
@@ -341,6 +357,7 @@
       user_id = #{userId,jdbcType=VARCHAR},
       model = #{model,jdbcType=VARCHAR},
       os = #{os,jdbcType=VARCHAR},
+      device_name = #{deviceName,jdbcType=VARCHAR},
       `language` = #{language,jdbcType=VARCHAR},
       time_zone = #{timeZone,jdbcType=VARCHAR},
       app_version = #{appVersion,jdbcType=VARCHAR},

+ 100 - 5
pdf-office-account/src/main/resources/sqlmap/UserMapper.xml

@@ -26,7 +26,13 @@
     <result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
     <result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
     <result column="remark" jdbcType="VARCHAR" property="remark" />
+    <result column="can_access_ai" jdbcType="VARCHAR" property="canAccessAi" />
     <result column="valid_flag" jdbcType="VARCHAR" property="validFlag" />
+    <result column="source_product_id" jdbcType="VARCHAR" property="sourceProductId" />
+    <result column="invite_user_id" jdbcType="VARCHAR" property="inviteUserId" />
+    <result column="first_name" jdbcType="VARCHAR" property="firstName" />
+    <result column="last_name" jdbcType="VARCHAR" property="lastName" />
+    <result column="address" jdbcType="VARCHAR" property="address" />
   </resultMap>
   <sql id="Example_Where_Clause">
     <where>
@@ -90,7 +96,8 @@
     id, company_id, app_id, model_source, email, full_name, subscriber_type, subscribed, 
     digest_password, phone, industry, last_popularize_at, last_presented_coupon_at, mailable, 
     reset_token, `role`, job, area, platform_type, account_type, account_source, created_at, 
-    updated_at, remark, valid_flag
+    updated_at, remark, can_access_ai, valid_flag, source_product_id, invite_user_id, 
+    first_name, last_name, address
   </sql>
   <select id="selectByExample" parameterType="cn.kdan.cloud.pdf.office.account.model.UserExample" resultMap="BaseResultMap">
     select
@@ -130,7 +137,9 @@
       last_presented_coupon_at, mailable, reset_token, 
       `role`, job, area, platform_type, 
       account_type, account_source, created_at, 
-      updated_at, remark, valid_flag
+      updated_at, remark, can_access_ai, 
+      valid_flag, source_product_id, invite_user_id, 
+      first_name, last_name, address
       )
     values (#{id,jdbcType=VARCHAR}, #{companyId,jdbcType=VARCHAR}, #{appId,jdbcType=VARCHAR}, 
       #{modelSource,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{fullName,jdbcType=VARCHAR}, 
@@ -139,7 +148,9 @@
       #{lastPresentedCouponAt,jdbcType=TIMESTAMP}, #{mailable,jdbcType=INTEGER}, #{resetToken,jdbcType=INTEGER}, 
       #{role,jdbcType=VARCHAR}, #{job,jdbcType=VARCHAR}, #{area,jdbcType=VARCHAR}, #{platformType,jdbcType=TINYINT}, 
       #{accountType,jdbcType=TINYINT}, #{accountSource,jdbcType=TINYINT}, #{createdAt,jdbcType=TIMESTAMP}, 
-      #{updatedAt,jdbcType=TIMESTAMP}, #{remark,jdbcType=VARCHAR}, #{validFlag,jdbcType=VARCHAR}
+      #{updatedAt,jdbcType=TIMESTAMP}, #{remark,jdbcType=VARCHAR}, #{canAccessAi,jdbcType=VARCHAR}, 
+      #{validFlag,jdbcType=VARCHAR}, #{sourceProductId,jdbcType=VARCHAR}, #{inviteUserId,jdbcType=VARCHAR}, 
+      #{firstName,jdbcType=VARCHAR}, #{lastName,jdbcType=VARCHAR}, #{address,jdbcType=VARCHAR}
       )
   </insert>
   <insert id="insertSelective" parameterType="cn.kdan.cloud.pdf.office.account.model.User">
@@ -217,9 +228,27 @@
       <if test="remark != null">
         remark,
       </if>
+      <if test="canAccessAi != null">
+        can_access_ai,
+      </if>
       <if test="validFlag != null">
         valid_flag,
       </if>
+      <if test="sourceProductId != null">
+        source_product_id,
+      </if>
+      <if test="inviteUserId != null">
+        invite_user_id,
+      </if>
+      <if test="firstName != null">
+        first_name,
+      </if>
+      <if test="lastName != null">
+        last_name,
+      </if>
+      <if test="address != null">
+        address,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -294,9 +323,27 @@
       <if test="remark != null">
         #{remark,jdbcType=VARCHAR},
       </if>
+      <if test="canAccessAi != null">
+        #{canAccessAi,jdbcType=VARCHAR},
+      </if>
       <if test="validFlag != null">
         #{validFlag,jdbcType=VARCHAR},
       </if>
+      <if test="sourceProductId != null">
+        #{sourceProductId,jdbcType=VARCHAR},
+      </if>
+      <if test="inviteUserId != null">
+        #{inviteUserId,jdbcType=VARCHAR},
+      </if>
+      <if test="firstName != null">
+        #{firstName,jdbcType=VARCHAR},
+      </if>
+      <if test="lastName != null">
+        #{lastName,jdbcType=VARCHAR},
+      </if>
+      <if test="address != null">
+        #{address,jdbcType=VARCHAR},
+      </if>
     </trim>
   </insert>
   <select id="countByExample" parameterType="cn.kdan.cloud.pdf.office.account.model.UserExample" resultType="java.lang.Long">
@@ -380,9 +427,27 @@
       <if test="record.remark != null">
         remark = #{record.remark,jdbcType=VARCHAR},
       </if>
+      <if test="record.canAccessAi != null">
+        can_access_ai = #{record.canAccessAi,jdbcType=VARCHAR},
+      </if>
       <if test="record.validFlag != null">
         valid_flag = #{record.validFlag,jdbcType=VARCHAR},
       </if>
+      <if test="record.sourceProductId != null">
+        source_product_id = #{record.sourceProductId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.inviteUserId != null">
+        invite_user_id = #{record.inviteUserId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.firstName != null">
+        first_name = #{record.firstName,jdbcType=VARCHAR},
+      </if>
+      <if test="record.lastName != null">
+        last_name = #{record.lastName,jdbcType=VARCHAR},
+      </if>
+      <if test="record.address != null">
+        address = #{record.address,jdbcType=VARCHAR},
+      </if>
     </set>
     <if test="_parameter != null">
       <include refid="Update_By_Example_Where_Clause" />
@@ -414,7 +479,13 @@
       created_at = #{record.createdAt,jdbcType=TIMESTAMP},
       updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
       remark = #{record.remark,jdbcType=VARCHAR},
-      valid_flag = #{record.validFlag,jdbcType=VARCHAR}
+      can_access_ai = #{record.canAccessAi,jdbcType=VARCHAR},
+      valid_flag = #{record.validFlag,jdbcType=VARCHAR},
+      source_product_id = #{record.sourceProductId,jdbcType=VARCHAR},
+      invite_user_id = #{record.inviteUserId,jdbcType=VARCHAR},
+      first_name = #{record.firstName,jdbcType=VARCHAR},
+      last_name = #{record.lastName,jdbcType=VARCHAR},
+      address = #{record.address,jdbcType=VARCHAR}
     <if test="_parameter != null">
       <include refid="Update_By_Example_Where_Clause" />
     </if>
@@ -491,9 +562,27 @@
       <if test="remark != null">
         remark = #{remark,jdbcType=VARCHAR},
       </if>
+      <if test="canAccessAi != null">
+        can_access_ai = #{canAccessAi,jdbcType=VARCHAR},
+      </if>
       <if test="validFlag != null">
         valid_flag = #{validFlag,jdbcType=VARCHAR},
       </if>
+      <if test="sourceProductId != null">
+        source_product_id = #{sourceProductId,jdbcType=VARCHAR},
+      </if>
+      <if test="inviteUserId != null">
+        invite_user_id = #{inviteUserId,jdbcType=VARCHAR},
+      </if>
+      <if test="firstName != null">
+        first_name = #{firstName,jdbcType=VARCHAR},
+      </if>
+      <if test="lastName != null">
+        last_name = #{lastName,jdbcType=VARCHAR},
+      </if>
+      <if test="address != null">
+        address = #{address,jdbcType=VARCHAR},
+      </if>
     </set>
     where id = #{id,jdbcType=VARCHAR}
   </update>
@@ -522,7 +611,13 @@
       created_at = #{createdAt,jdbcType=TIMESTAMP},
       updated_at = #{updatedAt,jdbcType=TIMESTAMP},
       remark = #{remark,jdbcType=VARCHAR},
-      valid_flag = #{validFlag,jdbcType=VARCHAR}
+      can_access_ai = #{canAccessAi,jdbcType=VARCHAR},
+      valid_flag = #{validFlag,jdbcType=VARCHAR},
+      source_product_id = #{sourceProductId,jdbcType=VARCHAR},
+      invite_user_id = #{inviteUserId,jdbcType=VARCHAR},
+      first_name = #{firstName,jdbcType=VARCHAR},
+      last_name = #{lastName,jdbcType=VARCHAR},
+      address = #{address,jdbcType=VARCHAR}
     where id = #{id,jdbcType=VARCHAR}
   </update>
   <select id="selectByExampleWithRowbounds" parameterType="cn.kdan.cloud.pdf.office.account.model.UserExample" resultMap="BaseResultMap">

+ 28 - 11
pdf-office-account/src/main/resources/sqlmap/UserSubscriptionInfoMapper.xml

@@ -10,6 +10,7 @@
     <result column="pay_type" jdbcType="TINYINT" property="payType" />
     <result column="app_id" jdbcType="VARCHAR" property="appId" />
     <result column="product_id" jdbcType="VARCHAR" property="productId" />
+    <result column="point" jdbcType="INTEGER" property="point" />
   </resultMap>
   <sql id="Example_Where_Clause">
     <where>
@@ -70,7 +71,7 @@
     </where>
   </sql>
   <sql id="Base_Column_List">
-    id, user_id, platform, `status`, end_date, pay_type, app_id, product_id
+    id, user_id, platform, `status`, end_date, pay_type, app_id, product_id, point
   </sql>
   <select id="selectByExample" parameterType="cn.kdan.cloud.pdf.office.account.model.UserSubscriptionInfoExample" resultMap="BaseResultMap">
     select
@@ -87,7 +88,7 @@
     </if>
   </select>
   <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
-    select 
+    select
     <include refid="Base_Column_List" />
     from user_subscription_info
     where id = #{id,jdbcType=VARCHAR}
@@ -103,12 +104,14 @@
     </if>
   </delete>
   <insert id="insert" parameterType="cn.kdan.cloud.pdf.office.account.model.UserSubscriptionInfo">
-    insert into user_subscription_info (id, user_id, platform, 
-      `status`, end_date, pay_type, 
-      app_id, product_id)
-    values (#{id,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR}, #{platform,jdbcType=TINYINT}, 
-      #{status,jdbcType=TINYINT}, #{endDate,jdbcType=TIMESTAMP}, #{payType,jdbcType=TINYINT}, 
-      #{appId,jdbcType=VARCHAR}, #{productId,jdbcType=VARCHAR})
+    insert into user_subscription_info (id, user_id, platform,
+      `status`, end_date, pay_type,
+      app_id, product_id, point
+      )
+    values (#{id,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR}, #{platform,jdbcType=TINYINT},
+      #{status,jdbcType=TINYINT}, #{endDate,jdbcType=TIMESTAMP}, #{payType,jdbcType=TINYINT},
+      #{appId,jdbcType=VARCHAR}, #{productId,jdbcType=VARCHAR}, #{point,jdbcType=INTEGER}
+      )
   </insert>
   <insert id="insertSelective" parameterType="cn.kdan.cloud.pdf.office.account.model.UserSubscriptionInfo">
     insert into user_subscription_info
@@ -137,6 +140,9 @@
       <if test="productId != null">
         product_id,
       </if>
+      <if test="point != null">
+        point,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -163,6 +169,9 @@
       <if test="productId != null">
         #{productId,jdbcType=VARCHAR},
       </if>
+      <if test="point != null">
+        #{point,jdbcType=INTEGER},
+      </if>
     </trim>
   </insert>
   <select id="countByExample" parameterType="cn.kdan.cloud.pdf.office.account.model.UserSubscriptionInfoExample" resultType="java.lang.Long">
@@ -198,6 +207,9 @@
       <if test="record.productId != null">
         product_id = #{record.productId,jdbcType=VARCHAR},
       </if>
+      <if test="record.point != null">
+        point = #{record.point,jdbcType=INTEGER},
+      </if>
     </set>
     <if test="_parameter != null">
       <include refid="Update_By_Example_Where_Clause" />
@@ -212,7 +224,8 @@
       end_date = #{record.endDate,jdbcType=TIMESTAMP},
       pay_type = #{record.payType,jdbcType=TINYINT},
       app_id = #{record.appId,jdbcType=VARCHAR},
-      product_id = #{record.productId,jdbcType=VARCHAR}
+      product_id = #{record.productId,jdbcType=VARCHAR},
+      point = #{record.point,jdbcType=INTEGER}
     <if test="_parameter != null">
       <include refid="Update_By_Example_Where_Clause" />
     </if>
@@ -241,6 +254,9 @@
       <if test="productId != null">
         product_id = #{productId,jdbcType=VARCHAR},
       </if>
+      <if test="point != null">
+        point = #{point,jdbcType=INTEGER},
+      </if>
     </set>
     where id = #{id,jdbcType=VARCHAR}
   </update>
@@ -252,7 +268,8 @@
       end_date = #{endDate,jdbcType=TIMESTAMP},
       pay_type = #{payType,jdbcType=TINYINT},
       app_id = #{appId,jdbcType=VARCHAR},
-      product_id = #{productId,jdbcType=VARCHAR}
+      product_id = #{productId,jdbcType=VARCHAR},
+      point = #{point,jdbcType=INTEGER}
     where id = #{id,jdbcType=VARCHAR}
   </update>
   <select id="selectByExampleWithRowbounds" parameterType="cn.kdan.cloud.pdf.office.account.model.UserSubscriptionInfoExample" resultMap="BaseResultMap">
@@ -269,4 +286,4 @@
       order by ${orderByClause}
     </if>
   </select>
-</mapper>
+</mapper>

+ 67 - 0
pdf-office-account/src/main/resources/sqlmap/ext/ExtUserSubscriptionInfoMapper.xml

@@ -0,0 +1,67 @@
+<?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.cloud.pdf.office.account.mapper.ext.ExtUserSubscriptionInfoMapper">
+  <resultMap id="BaseResultMap" type="cn.kdan.cloud.pdf.office.common.vo.UserSubscriptionInfoVO">
+    <id column="id" jdbcType="VARCHAR" property="id" />
+    <result column="user_id" jdbcType="VARCHAR" property="userId" />
+    <result column="platform" jdbcType="TINYINT" property="platform" />
+    <result column="status" jdbcType="TINYINT" property="status" />
+    <result column="end_date" jdbcType="TIMESTAMP" property="endDate" />
+    <result column="pay_type" jdbcType="TINYINT" property="payType" />
+    <result column="app_id" jdbcType="VARCHAR" property="appId" />
+    <result column="product_id" jdbcType="VARCHAR" property="productId" />
+    <result column="point" jdbcType="INTEGER" property="point" />
+    <result column="product_name" jdbcType="VARCHAR" property="productName" />
+    <result column="max_device_num" jdbcType="INTEGER" property="maxDeviceNum" />
+    <result column="levels" jdbcType="VARCHAR" property="levels" />
+    <result column="platforms" jdbcType="VARCHAR" property="platforms" />
+    <result column="simplified_chinese_name" jdbcType="VARCHAR" property="simplifiedChineseName" />
+    <result column="traditional_chinese_name" jdbcType="VARCHAR" property="traditionalChineseName" />
+    <result column="payment_model" jdbcType="VARCHAR" property="paymentModel" />
+    <result column="is_ai" jdbcType="VARCHAR" property="isAi" />
+    <result column="code" jdbcType="VARCHAR" property="code" />
+  </resultMap>
+  <select id="getInfo" resultMap="BaseResultMap">
+    SELECT
+      usi.id,
+      usi.user_id,
+      usi.platform,
+      usi.status,
+      usi.end_date,
+      usi.pay_type,
+      usi.app_id,
+      usi.product_id,
+      usi.point,
+      p.product_name,
+      p.code,
+      p.max_device_num,
+      p.payment_model,
+      p.is_ai,
+      p.cycle,
+      p.simplified_chinese_name,
+      p.traditional_chinese_name,
+      GROUP_CONCAT(Distinct r.level) AS levels,
+      GROUP_CONCAT(Distinct p2.name) AS platforms
+    FROM
+      user_subscription_info usi
+        LEFT JOIN
+      product p ON p.id = usi.product_id
+        LEFT JOIN
+      r_product_right rpr ON p.id = rpr.product_id
+        LEFT JOIN
+      `right` r ON rpr.right_id = r.id
+        LEFT JOIN
+      r_product_platform rpp ON p.id = rpp.product_id
+        LEFT JOIN
+      platform p2 ON rpp.platform_id = p2.id
+    WHERE
+      usi.user_id =  #{userId}
+      AND usi.app_id =  #{appId}
+    GROUP BY
+      usi.id, usi.user_id, usi.platform, usi.status, usi.end_date,
+      usi.pay_type, usi.app_id, usi.product_id, usi.point,
+      p.product_name, p.max_device_num,p.is_ai,p.code,p.cycle;
+  </select>
+
+
+</mapper>

+ 3 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/dto/UpdateUserForOrderDTO.java

@@ -1,5 +1,6 @@
 package cn.kdan.cloud.pdf.office.api.account.dto;
 
+import cn.kdan.cloud.pdf.office.common.enums.account.AccountTypeEnum;
 import lombok.Data;
 
 import java.util.Date;
@@ -34,4 +35,6 @@ public class UpdateUserForOrderDTO {
 
     private String appId;
 
+    private Integer point;
+    private AccountTypeEnum accountType;
 }

+ 40 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/AIApi.java

@@ -0,0 +1,40 @@
+package cn.kdan.cloud.pdf.office.api.account.feign;
+
+import cn.kdan.cloud.pdf.office.api.account.dto.LogOffUserDTO;
+import cn.kdan.cloud.pdf.office.api.account.dto.UpdateUserForOrderDTO;
+import cn.kdan.cloud.pdf.office.api.account.feign.hystrix.AIHystrix;
+import cn.kdan.cloud.pdf.office.api.account.feign.hystrix.UserHystrix;
+import cn.kdan.cloud.pdf.office.api.account.vo.AiRecord;
+import cn.kdan.cloud.pdf.office.api.account.vo.UserDetailVO;
+import cn.kdan.cloud.pdf.office.api.account.vo.UserPageVO;
+import cn.kdan.cloud.pdf.office.common.config.FeignConfig;
+import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.dto.UserRegisterDTO;
+import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
+import cn.kdan.cloud.pdf.office.common.vo.UserInfoVO;
+import cn.kdan.cloud.pdf.office.common.vo.UserVO;
+import com.github.pagehelper.PageInfo;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.Date;
+import java.util.List;
+
+
+@Component
+@FeignClient(value = CommonConstant.ACCOUNT_PROVIDER_NAME + "/ai" , configuration = FeignConfig.class,fallback = AIHystrix.class)
+public interface AIApi {
+
+
+    @PostMapping(value = "insert")
+    ResultMap<Boolean> insert(@RequestBody AiRecord aiRecord);
+
+    @PostMapping(value = "getByFileKey")
+    ResultMap<AiRecord> getByFileKey(@RequestParam("fileKey") String fileKey);
+
+
+}

+ 2 - 3
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/LoginDeviceApi.java

@@ -36,7 +36,6 @@ public interface LoginDeviceApi {
     @PostMapping("delete")
     ResultMap<Boolean> delete(@RequestParam("deviceSign") String deviceSign, @RequestParam("userId") String userId,@RequestParam("appId") String appId,@RequestParam("isDelete") Boolean isDelete) ;
 
-
     /**
      * 获取用户的设备登录情况
      *
@@ -47,6 +46,8 @@ public interface LoginDeviceApi {
     @GetMapping("getByUserId")
     ResultMap<List<LoginDevice>> getByUserId(@RequestParam("userId") String userId,@RequestParam(value = "appId",required = false) String appId);
 
+    @GetMapping("getById")
+    ResultMap<LoginDevice> getById(@RequestParam("deviceId") String deviceId);
 
     /**
      * 获取登录设备记录
@@ -58,6 +59,4 @@ public interface LoginDeviceApi {
      */
     @GetMapping("getByDeviceSignAndAppId")
     ResultMap<LoginDevice> getByDeviceSignAndAppId(@RequestParam("deviceSign") String deviceSign, @RequestParam(value = "userId",required = false) String userId, @RequestParam("appId") String appId) ;
-
-
 }

+ 13 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/UserApi.java

@@ -42,6 +42,16 @@ public interface UserApi {
     @GetMapping("getInfoById")
     ResultMap<UserInfoVO> getInfoById(@RequestParam("id") String id);
 
+
+    /**
+     * 用户信息包括用户的会员信息(新会员系统)
+     *
+     * @param id id
+     * @return UserInfoVO
+     */
+    @GetMapping("getMemberInfoById")
+    ResultMap<UserInfoVO> getMemberInfoById(@RequestParam("id") String id);
+
     @PostMapping(value = "register")
     ResultMap<Boolean> register(@RequestBody UserRegisterDTO userRegisterDTO);
 
@@ -112,4 +122,7 @@ public interface UserApi {
      */
     @GetMapping("/getByEmail")
     ResultMap<UserVO> getByEmail(@RequestParam("email") String email);
+
+    @GetMapping("/getInviteNum")
+    ResultMap<Integer> getInviteNum(@RequestParam("userId") String userId);
 }

+ 12 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/UserSubscriptionInfoApi.java

@@ -8,6 +8,7 @@ import cn.kdan.cloud.pdf.office.common.config.FeignConfig;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
 import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
 
+import cn.kdan.cloud.pdf.office.common.vo.UserSubscriptionInfoVO;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.stereotype.Component;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -15,6 +16,8 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import java.util.List;
+
 
 /**
  * @author tangxiangan
@@ -56,4 +59,13 @@ public interface UserSubscriptionInfoApi {
      */
     @GetMapping("/getByUserIdAndProductId")
     ResultMap<UserSubscriptionInfo> getByUserIdAndProductId(@RequestParam("userId") String userId,@RequestParam("productId") String productId);
+
+    /**
+     * 获取用户在某个产品的所有会员
+     * @param userId 用户id
+     * @param appId 产品id
+     * @return List
+     */
+    @GetMapping("/getByUserIdAndAppId")
+    ResultMap<List<UserSubscriptionInfoVO>> getByUserIdAndAppId(@RequestParam("userId") String userId, @RequestParam("appId") String appId);
 }

+ 19 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/hystrix/AIHystrix.java

@@ -0,0 +1,19 @@
+package cn.kdan.cloud.pdf.office.api.account.feign.hystrix;
+
+import cn.kdan.cloud.pdf.office.api.account.feign.AIApi;
+import cn.kdan.cloud.pdf.office.api.account.feign.LoginDeviceApi;
+import cn.kdan.cloud.pdf.office.api.account.vo.AiRecord;
+import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
+
+public class AIHystrix implements AIApi {
+    @Override
+    public ResultMap<Boolean> insert(AiRecord aiRecord) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<AiRecord> getByFileKey(String fileKey) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+}

+ 5 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/hystrix/LoginDeviceApiHystrix.java

@@ -31,6 +31,11 @@ public class LoginDeviceApiHystrix implements LoginDeviceApi {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
 
+    @Override
+    public ResultMap<LoginDevice> getById(String deviceId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
     @Override
     public ResultMap<LoginDevice> getByDeviceSignAndAppId(String deviceSign, String userId, String appId) {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);

+ 10 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/hystrix/UserHystrix.java

@@ -34,6 +34,11 @@ public class UserHystrix implements UserApi {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
 
+    @Override
+    public ResultMap<UserInfoVO> getMemberInfoById(String id) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
     @Override
     public ResultMap<Boolean> register(UserRegisterDTO userRegisterDTO) {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
@@ -74,4 +79,9 @@ public class UserHystrix implements UserApi {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
 
+    @Override
+    public ResultMap<Integer> getInviteNum(String userId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
 }

+ 8 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/hystrix/UserSubscriptionInfoHystrix.java

@@ -7,8 +7,11 @@ import cn.kdan.cloud.pdf.office.api.account.feign.UserSubscriptionInfoApi;
 import cn.kdan.cloud.pdf.office.api.account.vo.UserSubscriptionInfo;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
 import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
+import cn.kdan.cloud.pdf.office.common.vo.UserSubscriptionInfoVO;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 @Service
 public class UserSubscriptionInfoHystrix implements UserSubscriptionInfoApi {
 
@@ -31,4 +34,9 @@ public class UserSubscriptionInfoHystrix implements UserSubscriptionInfoApi {
     public ResultMap<UserSubscriptionInfo> getByUserIdAndProductId(String userId, String productId) {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
+
+    @Override
+    public ResultMap<List<UserSubscriptionInfoVO>> getByUserIdAndAppId(String userId, String appId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
 }

+ 238 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/vo/AiRecord.java

@@ -0,0 +1,238 @@
+package cn.kdan.cloud.pdf.office.api.account.vo;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class AiRecord implements Serializable {
+    private String id;
+
+    private String userId;
+
+    private String function;
+
+    private String result;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+
+    private String content;
+
+    private String fileKey;
+
+    private Integer charCount;
+
+    private String fileId;
+
+    private Integer credit;
+
+    private static final long serialVersionUID = 1L;
+
+    public String getId() {
+        return id;
+    }
+
+    public AiRecord withId(String id) {
+        this.setId(id);
+        return this;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public AiRecord withUserId(String userId) {
+        this.setUserId(userId);
+        return this;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getFunction() {
+        return function;
+    }
+
+    public AiRecord withFunction(String function) {
+        this.setFunction(function);
+        return this;
+    }
+
+    public void setFunction(String function) {
+        this.function = function;
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    public AiRecord withResult(String result) {
+        this.setResult(result);
+        return this;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public AiRecord withCreatedAt(Date createdAt) {
+        this.setCreatedAt(createdAt);
+        return this;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public AiRecord withUpdatedAt(Date updatedAt) {
+        this.setUpdatedAt(updatedAt);
+        return this;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public AiRecord withContent(String content) {
+        this.setContent(content);
+        return this;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getFileKey() {
+        return fileKey;
+    }
+
+    public AiRecord withFileKey(String fileKey) {
+        this.setFileKey(fileKey);
+        return this;
+    }
+
+    public void setFileKey(String fileKey) {
+        this.fileKey = fileKey;
+    }
+
+    public Integer getCharCount() {
+        return charCount;
+    }
+
+    public AiRecord withCharCount(Integer charCount) {
+        this.setCharCount(charCount);
+        return this;
+    }
+
+    public void setCharCount(Integer charCount) {
+        this.charCount = charCount;
+    }
+
+    public String getFileId() {
+        return fileId;
+    }
+
+    public AiRecord withFileId(String fileId) {
+        this.setFileId(fileId);
+        return this;
+    }
+
+    public void setFileId(String fileId) {
+        this.fileId = fileId;
+    }
+
+    public Integer getCredit() {
+        return credit;
+    }
+
+    public AiRecord withCredit(Integer credit) {
+        this.setCredit(credit);
+        return this;
+    }
+
+    public void setCredit(Integer credit) {
+        this.credit = credit;
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        AiRecord other = (AiRecord) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+            && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
+            && (this.getFunction() == null ? other.getFunction() == null : this.getFunction().equals(other.getFunction()))
+            && (this.getResult() == null ? other.getResult() == null : this.getResult().equals(other.getResult()))
+            && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
+            && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))
+            && (this.getContent() == null ? other.getContent() == null : this.getContent().equals(other.getContent()))
+            && (this.getFileKey() == null ? other.getFileKey() == null : this.getFileKey().equals(other.getFileKey()))
+            && (this.getCharCount() == null ? other.getCharCount() == null : this.getCharCount().equals(other.getCharCount()))
+            && (this.getFileId() == null ? other.getFileId() == null : this.getFileId().equals(other.getFileId()))
+            && (this.getCredit() == null ? other.getCredit() == null : this.getCredit().equals(other.getCredit()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
+        result = prime * result + ((getFunction() == null) ? 0 : getFunction().hashCode());
+        result = prime * result + ((getResult() == null) ? 0 : getResult().hashCode());
+        result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
+        result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
+        result = prime * result + ((getContent() == null) ? 0 : getContent().hashCode());
+        result = prime * result + ((getFileKey() == null) ? 0 : getFileKey().hashCode());
+        result = prime * result + ((getCharCount() == null) ? 0 : getCharCount().hashCode());
+        result = prime * result + ((getFileId() == null) ? 0 : getFileId().hashCode());
+        result = prime * result + ((getCredit() == null) ? 0 : getCredit().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", userId=").append(userId);
+        sb.append(", function=").append(function);
+        sb.append(", result=").append(result);
+        sb.append(", createdAt=").append(createdAt);
+        sb.append(", updatedAt=").append(updatedAt);
+        sb.append(", content=").append(content);
+        sb.append(", fileKey=").append(fileKey);
+        sb.append(", charCount=").append(charCount);
+        sb.append(", fileId=").append(fileId);
+        sb.append(", credit=").append(credit);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 66 - 36
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/vo/LoginDevice.java

@@ -4,12 +4,21 @@ import java.io.Serializable;
 import java.util.Date;
 
 public class LoginDevice implements Serializable {
+    /**
+     * 设备id
+     */
     private String id;
-
+    /**
+     * 产品id
+     */
     private String productId;
-
+    /**
+     * 设备唯一标识
+     */
     private String uniqueSn;
-
+    /**
+     * appId
+     */
     private String appId;
 
     private String userId;
@@ -17,6 +26,10 @@ public class LoginDevice implements Serializable {
     private String model;
 
     private String os;
+    /**
+     * 设备名称
+     */
+    private String deviceName;
 
     private String language;
 
@@ -125,6 +138,19 @@ public class LoginDevice implements Serializable {
         this.os = os;
     }
 
+    public String getDeviceName() {
+        return deviceName;
+    }
+
+    public LoginDevice withDeviceName(String deviceName) {
+        this.setDeviceName(deviceName);
+        return this;
+    }
+
+    public void setDeviceName(String deviceName) {
+        this.deviceName = deviceName;
+    }
+
     public String getLanguage() {
         return language;
     }
@@ -229,19 +255,20 @@ public class LoginDevice implements Serializable {
         }
         LoginDevice other = (LoginDevice) that;
         return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
-            && (this.getProductId() == null ? other.getProductId() == null : this.getProductId().equals(other.getProductId()))
-            && (this.getUniqueSn() == null ? other.getUniqueSn() == null : this.getUniqueSn().equals(other.getUniqueSn()))
-            && (this.getAppId() == null ? other.getAppId() == null : this.getAppId().equals(other.getAppId()))
-            && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
-            && (this.getModel() == null ? other.getModel() == null : this.getModel().equals(other.getModel()))
-            && (this.getOs() == null ? other.getOs() == null : this.getOs().equals(other.getOs()))
-            && (this.getLanguage() == null ? other.getLanguage() == null : this.getLanguage().equals(other.getLanguage()))
-            && (this.getTimeZone() == null ? other.getTimeZone() == null : this.getTimeZone().equals(other.getTimeZone()))
-            && (this.getAppVersion() == null ? other.getAppVersion() == null : this.getAppVersion().equals(other.getAppVersion()))
-            && (this.getPlatform() == null ? other.getPlatform() == null : this.getPlatform().equals(other.getPlatform()))
-            && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))
-            && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
-            && (this.getValidFlag() == null ? other.getValidFlag() == null : this.getValidFlag().equals(other.getValidFlag()));
+                && (this.getProductId() == null ? other.getProductId() == null : this.getProductId().equals(other.getProductId()))
+                && (this.getUniqueSn() == null ? other.getUniqueSn() == null : this.getUniqueSn().equals(other.getUniqueSn()))
+                && (this.getAppId() == null ? other.getAppId() == null : this.getAppId().equals(other.getAppId()))
+                && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
+                && (this.getModel() == null ? other.getModel() == null : this.getModel().equals(other.getModel()))
+                && (this.getOs() == null ? other.getOs() == null : this.getOs().equals(other.getOs()))
+                && (this.getDeviceName() == null ? other.getDeviceName() == null : this.getDeviceName().equals(other.getDeviceName()))
+                && (this.getLanguage() == null ? other.getLanguage() == null : this.getLanguage().equals(other.getLanguage()))
+                && (this.getTimeZone() == null ? other.getTimeZone() == null : this.getTimeZone().equals(other.getTimeZone()))
+                && (this.getAppVersion() == null ? other.getAppVersion() == null : this.getAppVersion().equals(other.getAppVersion()))
+                && (this.getPlatform() == null ? other.getPlatform() == null : this.getPlatform().equals(other.getPlatform()))
+                && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))
+                && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
+                && (this.getValidFlag() == null ? other.getValidFlag() == null : this.getValidFlag().equals(other.getValidFlag()));
     }
 
     @Override
@@ -255,6 +282,7 @@ public class LoginDevice implements Serializable {
         result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
         result = prime * result + ((getModel() == null) ? 0 : getModel().hashCode());
         result = prime * result + ((getOs() == null) ? 0 : getOs().hashCode());
+        result = prime * result + ((getDeviceName() == null) ? 0 : getDeviceName().hashCode());
         result = prime * result + ((getLanguage() == null) ? 0 : getLanguage().hashCode());
         result = prime * result + ((getTimeZone() == null) ? 0 : getTimeZone().hashCode());
         result = prime * result + ((getAppVersion() == null) ? 0 : getAppVersion().hashCode());
@@ -267,25 +295,27 @@ public class LoginDevice implements Serializable {
 
     @Override
     public String toString() {
-        String sb = getClass().getSimpleName() +
-                " [" +
-                "Hash = " + hashCode() +
-                ", id=" + id +
-                ", productId=" + productId +
-                ", uniqueSn=" + uniqueSn +
-                ", appId=" + appId +
-                ", userId=" + userId +
-                ", model=" + model +
-                ", os=" + os +
-                ", language=" + language +
-                ", timeZone=" + timeZone +
-                ", appVersion=" + appVersion +
-                ", platform=" + platform +
-                ", updatedAt=" + updatedAt +
-                ", createdAt=" + createdAt +
-                ", validFlag=" + validFlag +
-                ", serialVersionUID=" + serialVersionUID +
-                "]";
-        return sb;
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", productId=").append(productId);
+        sb.append(", uniqueSn=").append(uniqueSn);
+        sb.append(", appId=").append(appId);
+        sb.append(", userId=").append(userId);
+        sb.append(", model=").append(model);
+        sb.append(", os=").append(os);
+        sb.append(", deviceName=").append(deviceName);
+        sb.append(", language=").append(language);
+        sb.append(", timeZone=").append(timeZone);
+        sb.append(", appVersion=").append(appVersion);
+        sb.append(", platform=").append(platform);
+        sb.append(", updatedAt=").append(updatedAt);
+        sb.append(", createdAt=").append(createdAt);
+        sb.append(", validFlag=").append(validFlag);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
     }
 }

+ 26 - 126
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/vo/UserSubscriptionInfo.java

@@ -1,8 +1,13 @@
 package cn.kdan.cloud.pdf.office.api.account.vo;
 
+import lombok.Builder;
+import lombok.Data;
+
 import java.io.Serializable;
 import java.util.Date;
 
+
+@Data
 public class UserSubscriptionInfo implements Serializable {
     private String id;
 
@@ -20,164 +25,59 @@ public class UserSubscriptionInfo implements Serializable {
 
     private String productId;
 
-    private static final long serialVersionUID = 1L;
-
-    public String getId() {
-        return id;
-    }
+    private Integer point;
 
+    // withId 方法
     public UserSubscriptionInfo withId(String id) {
-        this.setId(id);
-        return this;
-    }
-
-    public void setId(String id) {
         this.id = id;
-    }
-
-    public String getUserId() {
-        return userId;
-    }
-
-    public UserSubscriptionInfo withUserId(String userId) {
-        this.setUserId(userId);
         return this;
     }
 
-    public void setUserId(String userId) {
+    // withUserId 方法
+    public UserSubscriptionInfo withUserId(String userId) {
         this.userId = userId;
-    }
-
-    public Integer getPlatform() {
-        return platform;
-    }
-
-    public UserSubscriptionInfo withPlatform(Integer platform) {
-        this.setPlatform(platform);
         return this;
     }
 
-    public void setPlatform(Integer platform) {
+    // withPlatform 方法
+    public UserSubscriptionInfo withPlatform(Integer platform) {
         this.platform = platform;
-    }
-
-    public Integer getStatus() {
-        return status;
-    }
-
-    public UserSubscriptionInfo withStatus(Integer status) {
-        this.setStatus(status);
         return this;
     }
 
-    public void setStatus(Integer status) {
+    // withStatus 方法
+    public UserSubscriptionInfo withStatus(Integer status) {
         this.status = status;
-    }
-
-    public Date getEndDate() {
-        return endDate;
-    }
-
-    public UserSubscriptionInfo withEndDate(Date endDate) {
-        this.setEndDate(endDate);
         return this;
     }
 
-    public void setEndDate(Date endDate) {
+    // withEndDate 方法
+    public UserSubscriptionInfo withEndDate(Date endDate) {
         this.endDate = endDate;
-    }
-
-    public Integer getPayType() {
-        return payType;
-    }
-
-    public UserSubscriptionInfo withPayType(Integer payType) {
-        this.setPayType(payType);
         return this;
     }
 
-    public void setPayType(Integer payType) {
+    // withPayType 方法
+    public UserSubscriptionInfo withPayType(Integer payType) {
         this.payType = payType;
-    }
-
-    public String getAppId() {
-        return appId;
-    }
-
-    public UserSubscriptionInfo withAppId(String appId) {
-        this.setAppId(appId);
         return this;
     }
 
-    public void setAppId(String appId) {
+    // withAppId 方法
+    public UserSubscriptionInfo withAppId(String appId) {
         this.appId = appId;
-    }
-
-    public String getProductId() {
-        return productId;
-    }
-
-    public UserSubscriptionInfo withProductId(String productId) {
-        this.setProductId(productId);
         return this;
     }
 
-    public void setProductId(String productId) {
+    // withProductId 方法
+    public UserSubscriptionInfo withProductId(String productId) {
         this.productId = productId;
+        return this;
     }
 
-    @Override
-    public boolean equals(Object that) {
-        if (this == that) {
-            return true;
-        }
-        if (that == null) {
-            return false;
-        }
-        if (getClass() != that.getClass()) {
-            return false;
-        }
-        UserSubscriptionInfo other = (UserSubscriptionInfo) that;
-        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
-            && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
-            && (this.getPlatform() == null ? other.getPlatform() == null : this.getPlatform().equals(other.getPlatform()))
-            && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus()))
-            && (this.getEndDate() == null ? other.getEndDate() == null : this.getEndDate().equals(other.getEndDate()))
-            && (this.getPayType() == null ? other.getPayType() == null : this.getPayType().equals(other.getPayType()))
-            && (this.getAppId() == null ? other.getAppId() == null : this.getAppId().equals(other.getAppId()))
-            && (this.getProductId() == null ? other.getProductId() == null : this.getProductId().equals(other.getProductId()));
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
-        result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
-        result = prime * result + ((getPlatform() == null) ? 0 : getPlatform().hashCode());
-        result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode());
-        result = prime * result + ((getEndDate() == null) ? 0 : getEndDate().hashCode());
-        result = prime * result + ((getPayType() == null) ? 0 : getPayType().hashCode());
-        result = prime * result + ((getAppId() == null) ? 0 : getAppId().hashCode());
-        result = prime * result + ((getProductId() == null) ? 0 : getProductId().hashCode());
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        String sb = getClass().getSimpleName() +
-                " [" +
-                "Hash = " + hashCode() +
-                ", id=" + id +
-                ", userId=" + userId +
-                ", platform=" + platform +
-                ", status=" + status +
-                ", endDate=" + endDate +
-                ", payType=" + payType +
-                ", appId=" + appId +
-                ", productId=" + productId +
-                ", serialVersionUID=" + serialVersionUID +
-                "]";
-        return sb;
+    // withPoint 方法
+    public UserSubscriptionInfo withPoint(Integer point) {
+        this.point = point;
+        return this;
     }
 }

+ 50 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/appstore/AppTransaction.java

@@ -0,0 +1,50 @@
+package cn.kdan.cloud.pdf.office.api.payment.appstore;
+
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import lombok.Data;
+import lombok.ToString;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+
+@Data
+@ToString
+public class AppTransaction  {
+    private String appAccountToken; // UUID for transaction association
+    private String bundleId; // Bundle identifier of the app
+    private String currency; // ISO 4217 currency code
+    private String environment; // Server environment (sandbox or production)
+    @JsonFormat(shape = JsonFormat.Shape.NUMBER)
+    private Date expiresDate; // Subscription expires or renews (UNIX time in ms)
+    private String inAppOwnershipType; // Ownership type description
+    private boolean isUpgraded; // Indicates if upgraded to another subscription
+    private String offerDiscountType; // Payment mode for subscription offer
+    private String offerIdentifier; // Offer code or promotional identifier
+    private String offerType; // Promotional offer type
+    @JsonFormat(shape = JsonFormat.Shape.NUMBER)
+    private Date originalPurchaseDate; // Original transaction purchase date (UNIX time in ms)
+    private String originalTransactionId; // Original purchase transaction ID
+    private int price; // Price multiplied by 1000
+    private String productId; // Unique identifier of the product
+    @JsonFormat(shape = JsonFormat.Shape.NUMBER)
+    private Date purchaseDate; // Purchase charge date (UNIX time in ms)
+    private int quantity; // Number of consumable products purchased
+    @JsonFormat(shape = JsonFormat.Shape.NUMBER)
+    private Date revocationDate; // Refund or revoke date (UNIX time in ms)
+    private String revocationReason; // Reason for refund or revocation
+    @JsonFormat(shape = JsonFormat.Shape.NUMBER)
+    private Date signedDate; // Signed JSON Web Signature date (UNIX time in ms)
+    private String storefront; // Country/region code for App Store
+    private String storefrontId; // Unique App Store storefront identifier
+    private String subscriptionGroupIdentifier; // Identifier of subscription group
+    private String transactionId; // Unique transaction identifier
+    private String transactionReason; // Reason for purchase transaction
+    private String type; // Type of the in-app purchase
+    private String webOrderLineItemId; // Unique identifier for subscription purchase events
+}
+

+ 45 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/appstore/Environment.java

@@ -0,0 +1,45 @@
+// Copyright (c) 2023 Apple Inc. Licensed under MIT License.
+
+package cn.kdan.cloud.pdf.office.api.payment.appstore;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+/**
+ * The server environment, either sandbox or production.
+ *
+ * @see <a href="https://developer.apple.com/documentation/appstoreserverapi/environment">environment</a>
+ */
+public enum Environment {
+
+    SANDBOX("Sandbox"),
+    PRODUCTION("Production"),
+    XCODE("Xcode"),
+    // Used for unit testing
+    LOCAL_TESTING("LocalTesting");
+
+    private final String value;
+
+    Environment(String value) {
+        this.value = value;
+    }
+
+    public static Environment fromValue(String value) {
+        for (Environment b : Environment.values()) {
+            if (b.value.equals(value)) {
+                return b;
+            }
+        }
+        return null;
+    }
+
+    @JsonValue
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return String.valueOf(value);
+    }
+}
+

+ 231 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/appstore/HistoryResponse.java

@@ -0,0 +1,231 @@
+// Copyright (c) 2023 Apple Inc. Licensed under MIT License.
+
+package cn.kdan.cloud.pdf.office.api.payment.appstore;
+
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A response that contains the customer’s transaction history for an app.
+ *
+ * @see <a href="https://developer.apple.com/documentation/appstoreserverapi/historyresponse">HistoryResponse</a>
+ */
+public class HistoryResponse {
+    private static final String SERIALIZED_NAME_REVISION = "revision";
+    private static final String SERIALIZED_NAME_HAS_MORE = "hasMore";
+    private static final String SERIALIZED_NAME_BUNDLE_ID = "bundleId";
+    private static final String SERIALIZED_NAME_APP_APPLE_ID = "appAppleId";
+    private static final String SERIALIZED_NAME_ENVIRONMENT = "environment";
+    private static final String SERIALIZED_NAME_SIGNED_TRANSACTIONS = "signedTransactions";
+    @JsonProperty(SERIALIZED_NAME_REVISION)
+    private String revision;
+    @JsonProperty(SERIALIZED_NAME_HAS_MORE)
+    private Boolean hasMore;
+    @JsonProperty(SERIALIZED_NAME_BUNDLE_ID)
+    private String bundleId;
+    @JsonProperty(SERIALIZED_NAME_APP_APPLE_ID)
+    private Long appAppleId;
+    @JsonProperty(SERIALIZED_NAME_ENVIRONMENT)
+    private String environment;
+    @JsonProperty(SERIALIZED_NAME_SIGNED_TRANSACTIONS)
+    private List<String> signedTransactions = null;
+    @JsonAnySetter
+    private Map<String, Object> unknownFields;
+
+
+    public HistoryResponse() {
+    }
+
+    public HistoryResponse revision(String revision) {
+        this.revision = revision;
+        return this;
+    }
+
+    /**
+     * A token you use in a query to request the next set of transactions for the customer.
+     *
+     * @return revision
+     * @see <a href="https://developer.apple.com/documentation/appstoreserverapi/revision">revision</a>
+     **/
+    public String getRevision() {
+        return revision;
+    }
+
+    public void setRevision(String revision) {
+        this.revision = revision;
+    }
+
+    public HistoryResponse hasMore(Boolean hasMore) {
+        this.hasMore = hasMore;
+        return this;
+    }
+
+    /**
+     * A Boolean value indicating whether the App Store has more transaction data.
+     *
+     * @return hasMore
+     * @see <a href="https://developer.apple.com/documentation/appstoreserverapi/hasmore">hasMore</a>
+     **/
+    public Boolean getHasMore() {
+        return hasMore;
+    }
+
+    public void setHasMore(Boolean hasMore) {
+        this.hasMore = hasMore;
+    }
+
+    public HistoryResponse bundleId(String bundleId) {
+        this.bundleId = bundleId;
+        return this;
+    }
+
+    /**
+     * The bundle identifier of an app.
+     *
+     * @return bundleId
+     * @see <a href="https://developer.apple.com/documentation/appstoreserverapi/bundleid">bundleId</a>
+     **/
+    public String getBundleId() {
+        return bundleId;
+    }
+
+    public void setBundleId(String bundleId) {
+        this.bundleId = bundleId;
+    }
+
+    public HistoryResponse appAppleId(Long appAppleId) {
+        this.appAppleId = appAppleId;
+        return this;
+    }
+
+    /**
+     * The unique identifier of an app in the App Store.
+     *
+     * @return appAppleId
+     * @see <a href="https://developer.apple.com/documentation/appstoreservernotifications/appappleid">appAppleId</a>
+     **/
+    public Long getAppAppleId() {
+        return appAppleId;
+    }
+
+    public void setAppAppleId(Long appAppleId) {
+        this.appAppleId = appAppleId;
+    }
+
+    public HistoryResponse environment(Environment environment) {
+        this.environment = environment != null ? environment.getValue() : null;
+        return this;
+    }
+
+    /**
+     * The server environment in which you’re making the request, whether sandbox or production.
+     *
+     * @return environment
+     * @see <a href="https://developer.apple.com/documentation/appstoreserverapi/environment">environment</a>
+     **/
+    public Environment getEnvironment() {
+        return environment != null ? Environment.fromValue(environment) : null;
+    }
+
+    /**
+     * @see #getEnvironment()
+     */
+    public String getRawEnvironment() {
+        return environment;
+    }
+
+    public void setEnvironment(Environment environment) {
+        this.environment = environment != null ? environment.getValue() : null;
+    }
+
+    public void setRawEnvironment(String rawEnvironment) {
+        this.environment = rawEnvironment;
+    }
+
+    public HistoryResponse signedTransactions(List<String> signedTransactions) {
+        this.signedTransactions = signedTransactions;
+        return this;
+    }
+
+    public HistoryResponse addSignedTransactionsItem(String signedTransactionsItem) {
+        if (this.signedTransactions == null) {
+            this.signedTransactions = new ArrayList<>();
+        }
+        this.signedTransactions.add(signedTransactionsItem);
+        return this;
+    }
+
+    /**
+     * An array of in-app purchase transactions for the customer, signed by Apple, in JSON Web Signature format.
+     *
+     * @return signedTransactions
+     * @see <a href="https://developer.apple.com/documentation/appstoreserverapi/jwstransaction">JWSTransaction</a>
+     **/
+    public List<String> getSignedTransactions() {
+        return signedTransactions;
+    }
+
+    public void setSignedTransactions(List<String> signedTransactions) {
+        this.signedTransactions = signedTransactions;
+    }
+
+    public HistoryResponse unknownFields(Map<String, Object> unknownFields) {
+        this.unknownFields = unknownFields;
+        return this;
+    }
+
+    /**
+     Fields that are not recognized for this object
+
+     @return A map of JSON keys to objects
+     */
+    public Map<String, Object> getUnknownFields() {
+        return unknownFields;
+    }
+
+    public void setUnknownFields(Map<String, Object> unknownFields) {
+        this.unknownFields = unknownFields;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        HistoryResponse historyResponse = (HistoryResponse) o;
+        return Objects.equals(this.revision, historyResponse.revision) &&
+                Objects.equals(this.hasMore, historyResponse.hasMore) &&
+                Objects.equals(this.bundleId, historyResponse.bundleId) &&
+                Objects.equals(this.appAppleId, historyResponse.appAppleId) &&
+                Objects.equals(this.environment, historyResponse.environment) &&
+                Objects.equals(this.signedTransactions, historyResponse.signedTransactions) &&
+                Objects.equals(this.unknownFields, historyResponse.unknownFields);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(revision, hasMore, bundleId, appAppleId, environment, signedTransactions, unknownFields);
+    }
+
+    @Override
+    public String toString() {
+        return "HistoryResponse{" +
+                "revision='" + revision + '\'' +
+                ", hasMore=" + hasMore +
+                ", bundleId='" + bundleId + '\'' +
+                ", appAppleId=" + appAppleId +
+                ", environment='" + environment + '\'' +
+                ", signedTransactions=" + signedTransactions +
+                ", unknownFields=" + unknownFields +
+                '}';
+    }
+}
+

+ 1 - 2
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/constant/SubscriptionConstant.java

@@ -12,7 +12,6 @@ public interface SubscriptionConstant {
     int actived = 3;
     int expired = 4;
     int refunded = 5;
-//    // 试用
-//    int trial = 6;
+    int trial = 6;
 
 }

+ 43 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/AppStoreBuyCompleteDTO.java

@@ -0,0 +1,43 @@
+package cn.kdan.cloud.pdf.office.api.payment.dto;
+
+import cn.kdan.cloud.pdf.office.api.payment.enums.PaymentMethodEnum;
+import lombok.*;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author ComPDFKit-WPH 2023/1/29
+ * <p>
+ * 创建订单DTO
+ */
+@Data
+public class AppStoreBuyCompleteDTO {
+    /**
+     * app ID
+     */
+//    @NotNull(message = "appId 不能为空")
+    private String appId;
+    /**
+     * 产品ID
+     */
+    @NotNull(message = "产品id 不能为空")
+    private String productId;
+    /**
+     * 支付方式
+     */
+    @NotNull(message = "paymentMethod 不能为空")
+    private PaymentMethodEnum paymentMethod;
+    /**
+     * userId
+     */
+    private String userId;
+
+    private String applePayProductId;
+
+    /**
+     * 票据
+     */
+    @NotNull(message = "receipt 不能为空")
+    private String receipt;
+
+}

+ 3 - 1
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/AppStoreOrderSucceedDTO.java

@@ -14,10 +14,12 @@ public class AppStoreOrderSucceedDTO {
 
     private String applePayProductId;
 
+    private String transactionId;
+
     /**
      * 收据
      */
-    private String receipt;
+//    private String receipt;
 
     private String uuid;
 

+ 18 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/CreateOrderManualDTO.java

@@ -45,4 +45,22 @@ public class CreateOrderManualDTO {
     private String email;
 
     private String invoiceNo;
+    /**
+     * 1自动续订 2单次扣费订单
+     */
+    private Integer paymentModel;
+    /**
+     * 是否开启自动续订0 关闭 1 开启
+     */
+
+    private Integer subscriptionType;
+    /**
+     * payNumber默认为1
+     */
+    private Integer payNumber;
+
+    private String result;
+
+    private String currency;
+    private BigDecimal reducedPrice;
 }

+ 12 - 1
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/CreateSubscriptionDTO.java

@@ -5,6 +5,7 @@ import lombok.ToString;
 
 import javax.validation.constraints.NotNull;
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
 /**
@@ -56,6 +57,16 @@ public class CreateSubscriptionDTO implements Serializable {
 
     private String email;
 
-
+    //2官网购买 3后台赠送 4appstore
     private Integer buyerType;
+
+    private Integer isLock;
+    /**
+     * 1自动续订 2单次扣费订单
+     */
+    private Integer paymentModel;
+
+    private BigDecimal price;
+
+    private Integer payTime;
 }

+ 9 - 5
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/EquityVerificationDTO.java

@@ -3,6 +3,8 @@ package cn.kdan.cloud.pdf.office.api.payment.dto;
 import lombok.Data;
 import lombok.ToString;
 
+import javax.validation.constraints.NotNull;
+
 /**
  * @author ComPDFKit-WPH 2023/7/13
  */
@@ -10,12 +12,14 @@ import lombok.ToString;
 @ToString
 public class EquityVerificationDTO {
 
-    /**
-     * 票据
-     */
-    private String receipt;
-
+    @NotNull(message = "userId 不能为空")
     private String userId;
 
     private String applePayProductId;
+
+    private String transactionId;
+
+    private String productCode;
+
+    private String appBundleId;
 }

+ 21 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/dto/GooglePayDTO.java

@@ -0,0 +1,21 @@
+package cn.kdan.cloud.pdf.office.api.payment.dto;
+
+import lombok.Data;
+import lombok.ToString;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author ComPDFKit-WPH 2023/7/13
+ */
+@Data
+@ToString
+public class GooglePayDTO {
+
+    String packageName;
+    String productCode;
+    String purchaseToken;
+
+    String userId;
+
+}

+ 1 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/enums/PaymentMethodEnum.java

@@ -16,6 +16,7 @@ public enum PaymentMethodEnum {
     PADDLE(3),
     NO_NEED_TO_PAY(4),
     APPLE_PAY(5),
+    GOOGLE_PAY(6),
     ;
 
     @Getter

+ 66 - 10
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/feign/OrderApi.java

@@ -3,11 +3,14 @@ package cn.kdan.cloud.pdf.office.api.payment.feign;
 import cn.kdan.cloud.pdf.office.api.payment.dto.*;
 import cn.kdan.cloud.pdf.office.api.payment.feign.hystrix.OrderHystrix;
 import cn.kdan.cloud.pdf.office.api.payment.vo.CreateOrderResultVO;
+import cn.kdan.cloud.pdf.office.api.payment.vo.OrderGiftLogVO;
 import cn.kdan.cloud.pdf.office.api.payment.vo.OrderUpdateVO;
 import cn.kdan.cloud.pdf.office.api.payment.vo.OrdersVO;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.dto.CreateUserOrderDTO;
 import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
 import cn.kdan.cloud.pdf.office.common.vo.UserInfoVO;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.stereotype.Component;
 import org.springframework.validation.annotation.Validated;
@@ -18,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 
 import javax.validation.constraints.NotNull;
 import java.util.List;
+import java.util.Map;
 
 
 @Component
@@ -33,6 +37,12 @@ public interface OrderApi {
     @PostMapping("/createOrder")
     ResultMap<CreateOrderResultVO> createOrder(@Validated @RequestBody CreateOrderDTO createOrderDTO);
 
+    @PostMapping("/createUserOrder")
+    ResultMap<Map<String, String>> createUserOrder(@Validated @RequestBody CreateUserOrderDTO createOrderDTO);
+
+    @PostMapping("/createUserSubscription")
+    ResultMap<Map<String, String>> createUserSubscription(@Validated @RequestBody CreateUserOrderDTO createUserOrderDTO);
+
     /**
      * 订单创建(applePay专用)
      *
@@ -42,16 +52,6 @@ public interface OrderApi {
     @PostMapping("/appStoreCreateOrder")
     ResultMap<CreateOrderResultVO> appStoreCreateOrder(@Validated @RequestBody CreateOrderDTO createOrderDTO);
 
-    /**
-     * 订单支付成功(applePay专用)
-     * 回传appal pay id &签名证书
-     *
-     * @param appStoreOrderSucceed appStoreOrderSucceed
-     * @return Void
-     */
-    @PostMapping("/appStoreOrderSucceed")
-    ResultMap<UserInfoVO> appStoreOrderSucceed(@Validated @RequestBody AppStoreOrderSucceedDTO appStoreOrderSucceed);
-
 
     /**
      * appStore 权益校验
@@ -62,6 +62,17 @@ public interface OrderApi {
     @PostMapping("/appStoreEquityVerification")
     ResultMap<UserInfoVO> appStoreEquityVerification(@RequestBody EquityVerificationDTO equityVerificationDTO);
 
+    /**
+     * 谷歌权益校验
+     * @param
+     * @return
+     */
+    @PostMapping("/googleEquityVerification")
+    ResultMap<UserInfoVO> googleEquityVerification(@RequestBody GooglePayDTO googlePayDTO);
+
+    @PostMapping("/updateStatusPayment")
+    ResultMap<Boolean> updateStatusPayment(@RequestParam("userId") String userId, @RequestParam("productId") String productId);
+
     /**
      * 手动创建虚拟订单
      *
@@ -81,6 +92,16 @@ public interface OrderApi {
     ResultMap<OrdersVO> getOrderById(@Validated @NotNull(message = "orderId不能为空")
                                      @RequestParam("orderId") String orderId);
 
+    @GetMapping("/getStateByOrderId")
+    ResultMap<Map<String, String>> getStateByOrderId(@Validated @NotNull(message = "订单id不能为空") @RequestParam("orderId") String orderId);
+
+    @GetMapping("/getOrderListByStatus")
+    ResultMap<List<OrdersVO>> getOrderListByStatus(@Validated @NotNull(message = "订单状态不能为空") @RequestParam("orderStatus") Integer orderStatus,
+                                                   @Validated @NotNull(message = "userId不能为空") @RequestParam("userId") String userId);
+
+    @PostMapping("/closeOrder")
+    ResultMap<Boolean> closeOrder(@Validated @NotNull(message = "订单id不能为空") @RequestParam("orderId") String orderId);
+
     /**
      * 通过id获取订单信息
      *
@@ -120,4 +141,39 @@ public interface OrderApi {
     @PostMapping("/cancelSubscription")
     ResultMap<Void> cancelSubscription(@Validated @RequestBody CancelSubscriptionDTO cancelSubscription);
 
+    /**
+     * 通过用户id获取订单信息
+     *
+     * @param userId 用户id
+     * @return Orders
+     */
+    @GetMapping("/getOrderByUserId")
+    ResultMap<List<OrdersVO>> getOrderByUserId(@Validated @NotNull(message = "userId不能为空")
+                                                @RequestParam("userId") String userId);
+
+    /**
+     * 更新赠送订阅表,并且记录赠送日志
+     * @param userId 赠送人id
+     * @param email 被赠送人邮箱
+     * @param name 被赠送人名字
+     * @return
+     */
+    @PostMapping("/giveAway")
+    ResultMap<OrderGiftLogVO> giveAway(@RequestParam("userId") String userId, @RequestParam("email") String email, @RequestParam("name") String name);
+
+    @GetMapping("/getGiftNum")
+    ResultMap<Long> getGiftNum(@RequestParam("userId") String userId);
+
+    @GetMapping("/getOrderGiftLogById")
+    ResultMap<OrderGiftLogVO> getOrderGiftLogById(@RequestParam("orderGiftLogId")String orderGiftLogId);
+
+    @PostMapping("/acceptUser")
+    ResultMap<Boolean> acceptUser(@RequestParam("orderGiftLogId") String orderGiftLogId, @RequestParam("receiveUserId") String receiveUserId);
+
+    @GetMapping("/pageOrderGiftLog")
+    ResultMap<Page<OrderGiftLogVO>> pageOrderGiftLog(@RequestParam("userId")String userId,
+                                                     @RequestParam(name = "email",required = false)String email,
+                                                     @RequestParam(name = "name",required = false)String name,
+                                                     @RequestParam(name = "page",defaultValue = "1",required = false)Integer page,
+                                                     @RequestParam(name ="pageSize",defaultValue = "10",required = false)Integer pageSize);
 }

+ 10 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/feign/SubscriptionApi.java

@@ -101,4 +101,14 @@ public interface SubscriptionApi {
     @GetMapping("/getNextPayTime")
     ResultMap<LocalDateTime> getNextPayTime(@RequestParam("userId") String userId,
                                             @RequestParam("productId") String productId);
+
+    /**
+     * 判断是否可以送试用
+     * @param userId 用户id
+     * @return Boolean
+     */
+    @GetMapping("/judgeTrail")
+    ResultMap<Boolean> judgeTrail(@RequestParam("userId") String userId);
+    @GetMapping("/judgeAiDiscount")
+    ResultMap<Boolean> judgeAiDiscount(@RequestParam("userId") String userId);
 }

+ 67 - 2
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/feign/hystrix/OrderHystrix.java

@@ -4,16 +4,21 @@ package cn.kdan.cloud.pdf.office.api.payment.feign.hystrix;
 import cn.kdan.cloud.pdf.office.api.payment.dto.*;
 import cn.kdan.cloud.pdf.office.api.payment.feign.OrderApi;
 import cn.kdan.cloud.pdf.office.api.payment.vo.CreateOrderResultVO;
+import cn.kdan.cloud.pdf.office.api.payment.vo.OrderGiftLogVO;
 import cn.kdan.cloud.pdf.office.api.payment.vo.OrderUpdateVO;
 import cn.kdan.cloud.pdf.office.api.payment.vo.OrdersVO;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.dto.CreateUserOrderDTO;
 import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
 import cn.kdan.cloud.pdf.office.common.vo.UserInfoVO;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.springframework.stereotype.Service;
 import org.springframework.web.bind.annotation.RequestBody;
 
 import javax.validation.constraints.NotNull;
 import java.util.List;
+import java.util.Map;
 
 @Service
 public class OrderHystrix implements OrderApi {
@@ -24,12 +29,17 @@ public class OrderHystrix implements OrderApi {
     }
 
     @Override
-    public ResultMap<CreateOrderResultVO> appStoreCreateOrder(CreateOrderDTO createOrderDTO) {
+    public ResultMap<Map<String, String>> createUserOrder(CreateUserOrderDTO createOrderDTO) {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
 
     @Override
-    public ResultMap<UserInfoVO> appStoreOrderSucceed(AppStoreOrderSucceedDTO appStoreOrderSucceed) {
+    public ResultMap<Map<String, String>> createUserSubscription(CreateUserOrderDTO createUserOrderDTO) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<CreateOrderResultVO> appStoreCreateOrder(CreateOrderDTO createOrderDTO) {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
 
@@ -38,6 +48,16 @@ public class OrderHystrix implements OrderApi {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
 
+    @Override
+    public ResultMap<UserInfoVO> googleEquityVerification(GooglePayDTO googlePayDTO) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<Boolean> updateStatusPayment(String userId, String productId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
     @Override
     public ResultMap<OrderUpdateVO> createOrderManual(CreateOrderManualDTO createOrderManual) {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
@@ -48,6 +68,21 @@ public class OrderHystrix implements OrderApi {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
 
+    @Override
+    public ResultMap<Map<String, String>> getStateByOrderId(String orderId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<List<OrdersVO>> getOrderListByStatus(Integer orderStatus, String userId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<Boolean> closeOrder(String orderId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
     @Override
     public ResultMap<OrdersVO> getOrderWithUpdate(String orderId) {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
@@ -67,4 +102,34 @@ public class OrderHystrix implements OrderApi {
     public ResultMap<Void> cancelSubscription(CancelSubscriptionDTO cancelSubscription) {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
+
+    @Override
+    public ResultMap<List<OrdersVO>> getOrderByUserId(String userId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<OrderGiftLogVO> giveAway(String userId, String email, String name) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<Long> getGiftNum(String userId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<OrderGiftLogVO> getOrderGiftLogById(String orderGiftLogId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<Boolean> acceptUser(String orderGiftLogId, String receiveUserId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<Page<OrderGiftLogVO>> pageOrderGiftLog(String userId, String email, String name, Integer page, Integer pageSize) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
 }

+ 9 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/feign/hystrix/SubscriptionHystrix.java

@@ -60,6 +60,15 @@ public class SubscriptionHystrix implements SubscriptionApi {
     @Override
     public ResultMap<LocalDateTime> getNextPayTime(@RequestParam("userId")String userId, @RequestParam("productId")String productId) {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
 
+    @Override
+    public ResultMap<Boolean> judgeTrail(@RequestParam("userId")String userId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<Boolean> judgeAiDiscount(String userId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
 }

+ 53 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/vo/OrderGiftLogVO.java

@@ -0,0 +1,53 @@
+package cn.kdan.cloud.pdf.office.api.payment.vo;
+
+import cn.kdan.cloud.pdf.office.common.base.BaseEntity;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.*;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * @author ComPDFKit-WPH 2024-10-28
+ */
+@Data
+@ToString
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderGiftLogVO implements Serializable {
+
+    /**
+     *
+     */
+    private String id;
+    /**
+     *
+     */
+    private String orderGiftId;
+    private String email;
+    private String name;
+    /**
+     *
+     */
+    private String userId;
+    /**
+     * 0待接收1已接受2已失效
+     */
+    private String validFlag;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdAt;
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedAt;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date receiveAt;
+}

+ 34 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/vo/OrdersVO.java

@@ -60,6 +60,10 @@ public class OrdersVO implements Serializable {
      * 支付链接
      */
     private String pagePayUrl;
+    /**
+     * 支付链接
+     */
+    private String qrcode;
     /**
      * 发票编号 时间戳
      */
@@ -72,6 +76,18 @@ public class OrdersVO implements Serializable {
      * 产品/计划id
      */
     private String productId;
+    /**
+     * 产品名
+     */
+    private String productName;
+    /**
+     * 产品订阅周期:1、月(30天);2、季(90天);3、半年(183天);4、年(365天)
+     */
+    private Integer productCycle;
+    /**
+     * 产品是否AI 0否1是
+     */
+    private Integer productIsAi;
     /**
      * 折扣
      */
@@ -97,4 +113,22 @@ public class OrdersVO implements Serializable {
 
     private String email;
 
+    private Integer payNumber;
+
+    /**
+     * 优惠标记  0原价,1优惠券,2升级,3教育优惠,4批量购买,5黑五折扣;10教育商品升级,11黑五+优惠券
+     */
+    private Integer discountType;
+
+    /**
+     * 付费类型 0不是自动订阅 1自动订阅
+     */
+    private Integer subscriptionType;
+    /**
+     * 付费模式(1自动续订 2单次付费)
+     */
+    private Integer paymentModel;
+
+    private String simplifiedChineseName;
+    private String traditionalChineseName;
 }

+ 2 - 0
pdf-office-api/pdf-office-api-payment/src/main/java/cn/kdan/cloud/pdf/office/api/payment/vo/SubscriptionsVO.java

@@ -124,6 +124,8 @@ public class SubscriptionsVO implements Serializable {
 
     private String appId;
 
+    private Integer isLock;
+
     /**
      * 产品平台 1:mac,2:windows  PlatformEnum
      */

+ 1 - 0
pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/enums/PlatformEnum.java

@@ -8,6 +8,7 @@ import lombok.Getter;
  * 平台枚举
  */
 public enum PlatformEnum {
+    ALL(0),
     MAC(1),
     WINDOWS(2),
     ;

+ 24 - 0
pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/feign/PrizeApi.java

@@ -0,0 +1,24 @@
+package cn.kdan.cloud.pdf.office.api.product.feign;
+
+import cn.kdan.cloud.pdf.office.api.product.feign.hystrix.PrizeHystrix;
+import cn.kdan.cloud.pdf.office.api.product.vo.PrizeVO;
+import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+
+@Component
+@FeignClient(value = CommonConstant.PRODUCT_PROVIDER_NAME + "/prize", fallback = PrizeHystrix.class)
+public interface PrizeApi {
+
+    @PostMapping("/insert")
+     ResultMap<String> insert(@RequestBody PrizeVO prizeVO) ;
+
+    @PostMapping("/list")
+     ResultMap<List<PrizeVO>> list(@RequestBody PrizeVO prizeVO) ;
+ }

+ 45 - 0
pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/feign/ProductApi.java

@@ -1,6 +1,7 @@
 package cn.kdan.cloud.pdf.office.api.product.feign;
 
 import cn.kdan.cloud.pdf.office.api.product.feign.hystrix.ProductHystrix;
+import cn.kdan.cloud.pdf.office.api.product.vo.ListingProductVO;
 import cn.kdan.cloud.pdf.office.api.product.vo.ProductPriceVo;
 import cn.kdan.cloud.pdf.office.api.product.vo.ProductVO;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
@@ -10,10 +11,14 @@ import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.stereotype.Component;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import javax.validation.constraints.Min;
 import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 
 @Component
@@ -53,4 +58,44 @@ public interface ProductApi {
 
     @GetMapping("/getProductByThirdPayId")
     ResultMap<ProductVO> getProductByThirdPayId(@RequestParam("thirdPayId") String thirdPayId);
+
+    @GetMapping("/getListingProducts")
+    ResultMap<List<ListingProductVO>> getListingProducts(@Validated @NotNull(message = "是否教育优惠不能为空") @RequestParam("isEducation") Integer isEducation,
+                                                                @Validated @NotNull(message = "平台id不能为空") @RequestParam("platformId") String platformId);
+
+    @GetMapping("/getProductsByIds")
+    ResultMap<List<ListingProductVO>> getProductsByIds(@RequestParam(value = "productIds", required = false) List<String> productIds);
+
+    /**
+     * 验证用户邮箱教育优惠资格
+     * @param email 用户邮箱
+     * @return
+     */
+    @GetMapping("/checkEmail")
+    ResultMap<Integer> checkEmail(@RequestParam("email") String email);
+
+    @GetMapping("/getProductPriceForBuy")
+    ResultMap<ListingProductVO> getProductPriceForBuy(@Validated @NotNull(message = "产品id不能为空") @RequestParam("productId") String productId,
+                                                             @Validated @NotNull(message = "用户id不能为空") @RequestParam("userId") String userId,
+                                                             @Validated @NotNull(message = "是否教育优惠不能为空") @RequestParam("isEducation") Integer isEducation);
+
+    @GetMapping("/getBatchProductPrice")
+    ResultMap<BigDecimal> getBatchProductPrice(@Validated @NotNull(message = "产品id不能为空") @RequestParam("productId") String productId,
+                                                      @Validated @NotNull(message = "购买数量不能为空") @Min(2) @RequestParam("num") Integer num);
+
+    @GetMapping("/checkCoupon")
+    ResultMap<ListingProductVO> checkCoupon(@Validated @NotNull(message = "产品id不能为空") @RequestParam("productId") String productId,
+                                                   @NotNull(message = "用户id不能为空") @RequestParam("userId") String userId,
+                                                   @NotNull(message = "券码不能为空") @RequestParam("code") String code);
+
+    @GetMapping("/getProductByCode")
+    ResultMap<ProductVO> getProductByCode(@RequestParam("code") String code);
+
+    @PostMapping("/updateCouponState")
+    ResultMap<Boolean> updateCouponState(@Validated @NotNull(message = "券码不能为空") @RequestParam("code") String code,
+                                                @Validated @NotNull(message = "状态不能为空") @RequestParam("state") Integer state,
+                                         @Validated @NotNull(message = "订单id不能为空") @RequestParam("orderId") String orderId);
+
+    @PostMapping("/refundCouponByOrderId")
+    ResultMap<Boolean> refundCouponByOrderId(@Validated @NotNull(message = "订单id不能为空") @RequestParam("orderId") String orderId);
 }

+ 22 - 0
pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/feign/hystrix/PrizeHystrix.java

@@ -0,0 +1,22 @@
+package cn.kdan.cloud.pdf.office.api.product.feign.hystrix;
+
+import cn.kdan.cloud.pdf.office.api.product.feign.PrizeApi;
+import cn.kdan.cloud.pdf.office.api.product.vo.PrizeVO;
+import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class PrizeHystrix implements PrizeApi {
+    @Override
+    public ResultMap<String> insert(PrizeVO prizeVO) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<List<PrizeVO>> list(PrizeVO prizeVO) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+}

+ 48 - 0
pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/feign/hystrix/ProductHystrix.java

@@ -2,15 +2,18 @@ package cn.kdan.cloud.pdf.office.api.product.feign.hystrix;
 
 
 import cn.kdan.cloud.pdf.office.api.product.feign.ProductApi;
+import cn.kdan.cloud.pdf.office.api.product.vo.ListingProductVO;
 import cn.kdan.cloud.pdf.office.api.product.vo.ProductPriceVo;
 import cn.kdan.cloud.pdf.office.api.product.vo.ProductVO;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
 import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.RequestParam;
 
 import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
 import java.util.List;
 
 @Service
@@ -51,4 +54,49 @@ public class ProductHystrix implements ProductApi {
     public ResultMap<ProductVO> getProductByThirdPayId(String thirdPayId) {
         return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
     }
+
+    @Override
+    public ResultMap<List<ListingProductVO>> getListingProducts(Integer isEducation, String platformId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<List<ListingProductVO>> getProductsByIds(List<String> productIds) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<Integer> checkEmail(String email) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<ListingProductVO> getProductPriceForBuy(String productId, String userId, Integer isEducation) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<BigDecimal> getBatchProductPrice(String productId, Integer num) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<ListingProductVO> checkCoupon(String productId, String userId, String code) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<ProductVO> getProductByCode(String code) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<Boolean> updateCouponState(String code, Integer state, String orderId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<Boolean> refundCouponByOrderId(String orderId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
 }

+ 84 - 0
pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/vo/ListingProductVO.java

@@ -0,0 +1,84 @@
+package cn.kdan.cloud.pdf.office.api.product.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.math.BigDecimal;
+
+/**
+ * @author ComPDFKit-Bob 2024-10-15
+ */
+@Data
+@ToString
+public class ListingProductVO {
+
+    /**
+     * id
+     */
+    private String id;
+
+    /**
+     * id
+     */
+    private String code;
+    /**
+     * 产品/计划名称
+     */
+    private String productName;
+    /**
+     * 价格
+     */
+    private BigDecimal price;
+    /**
+     * 人民币价格
+     */
+    private BigDecimal cnyPrice;
+    /**
+     *
+     */
+    private Integer maxDeviceNum;
+    /**
+     * 优惠价格
+     */
+    private BigDecimal displayPrice;
+    /**
+     * 优惠人民币价格
+     */
+    private BigDecimal cnyDisplayPrice;
+    /**
+     * 买断升级订阅价格
+     */
+    private BigDecimal upgradePrice;
+    private BigDecimal cnyUpgradePrice;
+    /**
+     * 3高级2标准1免费
+     */
+    private String levels;
+    /**
+     * 产品支持平台
+     */
+    private String platforms;
+    /**
+     * 所属业务线id (1pdf产品线2compdfkit产品线)
+     */
+    private Integer productLineId;
+    /**
+     * 付费模式(1自动续订 2单次付费)
+     */
+    private Integer paymentModel;
+    /**
+     * 订阅周期:1、月(30天);2、季(90天);3、半年(183天);4、年(365天)
+     */
+    private Integer cycle;
+    /**
+     * 0否1是
+     */
+    private Integer isAi;
+    /**
+     * 产品优惠类型,0正常商品,1教育优惠,2黑五
+     */
+    private Integer discountType;
+
+    private String simplifiedChineseName;
+    private String traditionalChineseName;
+}

+ 65 - 0
pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/vo/PrizeVO.java

@@ -0,0 +1,65 @@
+package cn.kdan.cloud.pdf.office.api.product.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author ComPDFKit-WPH 2024-10-16
+ */
+@Data
+public class PrizeVO {
+
+    /**
+     *
+     */
+    private String id;
+    /**
+     * 用户
+     */
+    private String userId;
+    /**
+     * 1优惠券2兑换券
+     */
+    private Integer type;
+    /**
+     * 可用商品(优惠券)
+     */
+    private String productId;
+    /**
+     *
+     */
+    private String code;
+    private String productCode;
+    /**
+     * 有效开始日期
+     */
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date startDate;
+    /**
+     * 有效结束日期
+     */
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endDate;
+    /**
+     * 优惠美元金额
+     */
+    private BigDecimal usdPrice;
+    /**
+     * 优惠人民币金额
+     */
+    private BigDecimal cnyPrice;
+    /**
+     * 兑换券信息
+     */
+    private String voucher;
+
+    private String activityType;
+    /**
+     * 0不可用1可用2已使用
+     */
+    private Integer validFlag;
+
+}

+ 20 - 2
pdf-office-api/pdf-office-api-product/src/main/java/cn/kdan/cloud/pdf/office/api/product/vo/ProductVO.java

@@ -15,7 +15,7 @@ public class ProductVO {
     /**
      * id
      */
-    private Integer id;
+    private String id;
     /**
      * 产品/计划名称
      */
@@ -23,7 +23,7 @@ public class ProductVO {
     /**
      * app ID
      */
-    private Integer appId;
+    private String appId;
     /**
      *
      */
@@ -80,6 +80,7 @@ public class ProductVO {
 
     /**
      * 产品平台 1:windows,2:mac  PlatformEnum
+     * app_id = 1时: 0免费,1永久版,2订阅,3AI
      */
     private Integer platform;
     /**
@@ -94,4 +95,21 @@ public class ProductVO {
      * 1单次购买产品 2订阅计划产品
      */
     private Integer type;
+
+    /**
+     * 付费模式(1自动续订 2单次付费)
+     */
+    private Integer paymentModel;
+
+    /**
+     * 订阅周期:1、月(30天);2、季(90天);3、半年(183天);4、年(365天)
+     */
+    private Integer cycle;
+
+    private String points;
+
+    /**
+     * 产品优惠类型,0正常商品,1教育优惠,2黑五
+     */
+    private Integer discountType;
 }

+ 15 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/config/RabbitMqConfig.java

@@ -79,6 +79,12 @@ public class RabbitMqConfig {
         exchange.setDelayed(true);
         return exchange;
     }
+    @Bean
+    public TopicExchange orderGiftDelayExchange(){
+        TopicExchange exchange = new TopicExchange(RabbitMqConstant.ORDER_GIFT_DELAY_EXCHANGE, true, false);
+        exchange.setDelayed(true);
+        return exchange;
+    }
 
     // 订单关闭
     @Bean
@@ -90,6 +96,15 @@ public class RabbitMqConfig {
         return BindingBuilder.bind(paymentOrderDelayQueue()).to(paymentDelayExchange()).with(RabbitMqConstant.PAYMENT_ORDER_ROUTING_KEY);
     }
 
+    @Bean
+    public Queue orderGiftDelayQueue(){
+        return new Queue(RabbitMqConstant.ORDER_GIFT_DELAY_QUEUE, true, false, false);
+    }
+    @Bean
+    public Binding OrderGiftDelayBinding() {
+        return BindingBuilder.bind(orderGiftDelayQueue()).to(orderGiftDelayExchange()).with(RabbitMqConstant.ORDER_GIFT_DELAY_ROUTING_KEY);
+    }
+
     // AppStore验证票据重试处理相关
     @Bean
     public Queue appStoreVerifyRetryDelayQueue(){

+ 4 - 2
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/constant/CommonConstant.java

@@ -1,6 +1,7 @@
 package cn.kdan.cloud.pdf.office.common.constant;
 
 public interface CommonConstant {
+    String PDF_READER_PRO_APP_ID = "1";
 
     // 字符串分割符
     String STRING_SIGN_COMMA = ",";
@@ -107,7 +108,7 @@ public interface CommonConstant {
 
     String APP_PROVIDER_NAME = "pdf-office-app";
 
-    String EMAIL_VERIFY_CODE_KEY = "verifyCode_email";
+    String EMAIL_VERIFY_CODE_KEY = "verifyCode_email:";
 
     public static final String VERIFY_CODE_KEY = "pdf_office_verifyCode_";
 
@@ -120,6 +121,7 @@ public interface CommonConstant {
     /**
      * 邮箱正则验证
      */
-    String emailRegex = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$";
+    String emailRegex = "^([a-zA-Z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$";
 
+    Object TRAIL_PRODUCT_ID = "23";
 }

+ 3 - 1
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/constant/RabbitMqConstant.java

@@ -16,6 +16,7 @@ public interface RabbitMqConstant {
     /* payment发送交换机 */
     String PAYMENT_EXCHANGE = "pdf-office-payment-exchange";
     String PAYMENT_DELAY_EXCHANGE = "pdf-office-payment-delay-exchange";
+    String ORDER_GIFT_DELAY_EXCHANGE = "order-gift-delay-exchange";
     // 队列
     /* email发送队列 */
     String EMAIL_SEND_QUEUE = "pdf_office_email_send_queue";
@@ -34,7 +35,8 @@ public interface RabbitMqConstant {
     String PAYMENT_ORDER_ROUTING_KEY = "payment.order";
     String PAYMENT_ORDER_DELAY_QUEUE = "pdf_office_payment_order_delay_queue";
     String PAYMENT_ORDER_QUEUE = "pdf_office_payment_order_queue";
-
+    String ORDER_GIFT_DELAY_ROUTING_KEY = "order.gift.delay";
+    String ORDER_GIFT_DELAY_QUEUE = "order_gift_delay_queue";
     /* 订阅过期路由和队列 */
     String PAYMENT_SUBSCRIPTION_EXPIRED_ROUTING_KEY = "payment.subscription.expired";
     String PAYMENT_SUBSCRIPTION_EXPIRED_DELAY_QUEUE = "pdf_office_payment_subscription_expired_delay_queue";

+ 58 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/dto/CreateUserOrderDTO.java

@@ -0,0 +1,58 @@
+package cn.kdan.cloud.pdf.office.common.dto;
+
+import lombok.*;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.math.BigDecimal;
+
+/**
+ * @author ComPDFKit-Bob 2024/10/21
+ * <p>
+ * 创建订单DTO
+ */
+@Data
+@ToString
+@AllArgsConstructor
+@NoArgsConstructor
+public class CreateUserOrderDTO {
+
+    /**
+     * 产品ID
+     */
+    @NotNull(message = "产品id 不能为空")
+    private String productId;
+
+    /**
+     * 支付方式
+     * PAYPAL(0),ALIPAY(1),WXPAY(2),PADDLE(3),
+     */
+    @NotNull(message = "paymentMethod 不能为空")
+    @Size(min = 0, max = 3, message = "paymentMethod 值错误")
+    private Integer paymentMethod;
+
+    /**
+     * 价格
+     */
+    @NotNull(message = "价格 不能为空")
+    private BigDecimal price;
+
+    /**
+     * 优惠标记
+     * 0原价,1优惠券,2升级,3教育优惠,4批量购买,5黑五折扣;10教育商品升级,11黑五+优惠券
+     */
+    private Integer discountFlag;
+
+    /**
+     * 优惠卷
+     */
+    private String couponCode;
+
+    /**
+     * 批量购买数量
+     */
+    @NotNull(message = "购买数量 不能为空")
+    private Integer num;
+
+    private String userId;
+}

+ 32 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/dto/ResetPasswordDTO.java

@@ -0,0 +1,32 @@
+package cn.kdan.cloud.pdf.office.common.dto;
+
+import lombok.Data;
+
+/**
+ * @author tangxiangan
+ */
+@Data
+public class ResetPasswordDTO {
+
+    /**
+     * 用户名(邮箱)
+     */
+    private String email;
+
+    /**
+     * 邮箱验证码
+     */
+    private String verifyCode;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * appId 例如 pdf reader 1
+     */
+    private String appId;
+
+
+}

+ 6 - 3
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/dto/UserRegisterDTO.java

@@ -1,5 +1,6 @@
 package cn.kdan.cloud.pdf.office.common.dto;
 
+import cn.kdan.cloud.pdf.office.common.enums.account.AccountTypeEnum;
 import lombok.Data;
 
 /**
@@ -32,11 +33,13 @@ public class UserRegisterDTO {
      * platformType  平台类型 0官网 1后台
      */
     private String platformType;
-
     private String deviceSign;
-
     private String model;
 
-
     private Integer accountSource;
+
+    private String inviteUserId;
+
+    private AccountTypeEnum accountTypeEnum;
+
 }

+ 36 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/AIActionEnum.java

@@ -0,0 +1,36 @@
+package cn.kdan.cloud.pdf.office.common.enums;
+
+public enum AIActionEnum {
+    EXTRACT_SUMMARY("1", "提取摘要"),
+    CORRECTION("2", "纠错"),
+    REWRITE("3", "重写"),
+    FILE_TRANSLATION("4", "文件翻译"),
+    TEXT_TRANSLATION("5", "文本翻译"),
+    UPLOAD_TRANSLATION_FILE("6", "上传翻译文件");
+
+    private final String code;
+    private final String description;
+
+    AIActionEnum(String code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public static AIActionEnum fromCode(String code) {
+        for (AIActionEnum action : AIActionEnum.values()) {
+            if (action.code == code) {
+                return action;
+            }
+        }
+        throw new IllegalArgumentException("No action found for code: " + code);
+    }
+
+}

+ 23 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/EmailCodeTypeEnum.java

@@ -5,6 +5,10 @@ public enum EmailCodeTypeEnum {
      * 登录
      */
     LOGIN("login","邮箱验证码登录","邮箱验证码登录",""),
+    /**
+     * 会员系统登录
+     */
+    MEMBER_LOGIN("member_login","邮箱验证码登录","邮箱验证码登录",""),
     /**
      * 注册
      */
@@ -13,16 +17,35 @@ public enum EmailCodeTypeEnum {
      * 重置密码验证码
      */
     USER_RESET_PASSWORD("user_reset_password","重置密码验证码","重置密码验证码",""),
+    /**
+     * 会员系统重置密码验证码
+     */
+    MEMBER_RESET_PASSWORD("member_reset_password","重置密码验证码","重置密码验证码",""),
+    /**
+     * 会员系统修改邮箱验证码
+     */
+    MEMBER_UPDATE_EMAIL("member_update_email","修改邮箱验证码","修改邮箱验证码",""),
     /**
      * 用户注销
      */
     USER_LOG_OFF("user_log_off","注销验证码","注销验证码",""),
+    MEMBER_LOG_OFF("member_log_off","注销验证码","注销验证码",""),
 
     SUBSCRIPTION_SUCCESS("subscription_success","","",""),
 
     SUBSCRIPTION_SUCCESS_WITH_REGISTER("subscription_success_with_register","","",""),
 
     ORDER_SUCCESS("order_success","","",""),
+    ACCOUNT_WARMING("account_warming","","",""),
+    ACCOUNT_LOCKED("account_locked","","",""),
+    ACCOUNT_UNLOCKED("account_unlocked","","",""),
+    GIVE_AWAY("give_away","","",""),
+    //用户注册成功
+    MEMBER_REGISTER_SUCCESS("member_register_success","","",""),
+    MEMBER_UPDATE_PASSWORD_SUCCESS("member_update_password_success","","",""),
+    MEMBER_UPGRADE_SUCCESS("member_upgrade_success","","",""),
+    MEMBER_BUY_SUCCESS("member_buy_success","","",""),
+
 ;
     private final String value;
     private final String action;

+ 29 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/ExceptionEnum.java

@@ -70,6 +70,35 @@ public enum ExceptionEnum {
     EXCEPTION_MSG_THE_ORDER_STATUS_IS_ABNORMAL(341, "订单状态异常"),
 
     EXCEPTION_MSG_TRANSACTION_ID_REPEAT(342, "transactionId重复"),
+    EXCEPTION_TICKET_HAS_BEEN_BLOCKED(343, "The ticket has been blocked"),
+    EXCEPTION_TICKET_HAS_BEEN_CREATED(344, "当前票据已创建订单"),
+    EXCEPTION_USER_IS_NOT_EDUCATION_USER(345, "用户不是教育用户"),
+    EXCEPTION_USER_HAS_EDUCATION(346, "用户近一年有教育购买订单"),
+    EXCEPTION_USER_CANNOT_BUY_PREMIUM(347, "用户已有标准版订阅,无法购买高级版"),
+    EXCEPTION_USER_CANNOT_BUY_VIP(348, "用户已有高级版订阅,无法购买标准版"),
+    EXCEPTION_USER_CANNOT_UPGRADE_VIP(349, "买断用户无法升级为标准版"),
+    EXCEPTION_COUPON_NOT_EXISTS(350, "优惠券不存在"),
+    EXCEPTION_COUPON_TYPE_ERROR(351, "优惠券类型错误"),
+    EXCEPTION_COUPON_PRODUCT_ERROR(352, "优惠券关联产品错误"),
+    EXCEPTION_COUPON_INVALID(353, "优惠券已失效"),
+
+    EXCEPTION_PRODUCT_NOT_EXIST(354, "产品不存在"),
+    EXCEPTION_MSG_CONTACT_US(355, "请联系我们获取最新折扣"),
+    EXCEPTION_MSG_APP_STORE_TRANSACTION_ID_VALIDATION_FAILED(356,"验证苹果交易失败"),
+    EXCEPTION_MSG_GOOGLE_STORE_TRANSACTION_ID_VALIDATION_FAILED(357,"验证谷歌交易失败"),
+    EXCEPTION_PRICE_ERROR(358,"价格错误"),
+    EXCEPTION_MSG_ORDER_CREATE_FAILED(359,"订单创建失败"),
+
+
+    EXCEPTION_MSG_USER_NOT_EXIST(400,"用户不存在"),
+    USER_ALREADY_SUBSCRIBED_PLAN(360, "该用户已经是PDF Reader Pro订阅版会员,确定再赠送吗?"),
+    USER_ALREADY_SUBSCRIBED_PACKAGE(361, "该用户已经是PDF Reader Pro永久版会员,无需再赠送哦~"),
+    ORDER_GIFT_LOG_ALREADY_RECEIVE(362, "邮件已接收或者已失效"),
+    EXCEPTION_PRODUCT_NOT_SUPPORT_BATCH(363, "该产品不支持批量购买"),
+
+    EXCEPTION_USER_ALREADY_LOTTERY(364, "用户已经抽过奖啦!"),
+    EXCEPTION_PRODUCT_TYPE_ERROR(365, "产品类型错误"),
+    EXCEPTION_USER_ALREADY_SUBSCRIBED(366, "您已经是订阅会员,无需重复订阅"),
     ;
     private final Integer value;
     private final String msg;

+ 34 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/OrderGiftLogVaildFlagEnum.java

@@ -0,0 +1,34 @@
+package cn.kdan.cloud.pdf.office.common.enums;
+
+public enum OrderGiftLogVaildFlagEnum {
+    RECEIVE_GIFT("0", "待接收"),
+    RECEIVED("1", "已接收"),
+    RECEIVE_FAIL("2", "已失效"),
+;
+
+    private final String code;
+    private final String description;
+
+    OrderGiftLogVaildFlagEnum(String code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public static OrderGiftLogVaildFlagEnum fromCode(String code) {
+        for (OrderGiftLogVaildFlagEnum action : OrderGiftLogVaildFlagEnum.values()) {
+            if (action.code == code) {
+                return action;
+            }
+        }
+        throw new IllegalArgumentException("No action found for code: " + code);
+    }
+
+}

+ 34 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/OrderGiftVaildFlagEnum.java

@@ -0,0 +1,34 @@
+package cn.kdan.cloud.pdf.office.common.enums;
+
+public enum OrderGiftVaildFlagEnum {
+    GIFTED("0", "已赠送"),
+    GIFT_ABLE("1", "可赠送"),
+    GIFTING("2", "赠送中"),
+;
+
+    private final String code;
+    private final String description;
+
+    OrderGiftVaildFlagEnum(String code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public static OrderGiftVaildFlagEnum fromCode(String code) {
+        for (OrderGiftVaildFlagEnum action : OrderGiftVaildFlagEnum.values()) {
+            if (action.code == code) {
+                return action;
+            }
+        }
+        throw new IllegalArgumentException("No action found for code: " + code);
+    }
+
+}

+ 38 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/PDFReaderProPlatformEnum.java

@@ -0,0 +1,38 @@
+package cn.kdan.cloud.pdf.office.common.enums;
+
+import java.util.Objects;
+
+public enum PDFReaderProPlatformEnum {
+    // 0免费,1永久版,2订阅,3AI
+    FREE(0, "免费"),
+    PERMANENT(1, "永久版"),
+    SUBSCRIBE(2, "订阅"),
+    AI(3, "AI"),
+;
+
+    private final Integer code;
+    private final String description;
+
+    PDFReaderProPlatformEnum(Integer code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public static PDFReaderProPlatformEnum fromCode(Integer code) {
+        for (PDFReaderProPlatformEnum action : PDFReaderProPlatformEnum.values()) {
+            if (Objects.equals(action.code, code)) {
+                return action;
+            }
+        }
+        throw new IllegalArgumentException("No action found for code: " + code);
+    }
+
+}

+ 34 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/PrizeTypeEnum.java

@@ -0,0 +1,34 @@
+package cn.kdan.cloud.pdf.office.common.enums;
+
+import java.util.Objects;
+
+public enum PrizeTypeEnum {
+    COUPON(1,"优惠券"),
+    REDEEM_VOUCHER(2,"兑换券"),
+    AI_MEMBER(3,"AI会员");
+
+    private final Integer code;
+    private final String description;
+
+    PrizeTypeEnum(Integer code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public static PrizeTypeEnum fromCode(Integer code) {
+        for (PrizeTypeEnum action : PrizeTypeEnum.values()) {
+            if (Objects.equals(action.code, code)) {
+                return action;
+            }
+        }
+        throw new IllegalArgumentException("No action found for code: " + code);
+    }
+}

+ 46 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/product/BlcakFivePriceEnum.java

@@ -0,0 +1,46 @@
+package cn.kdan.cloud.pdf.office.common.enums.product;
+
+import java.math.BigDecimal;
+
+public enum BlcakFivePriceEnum {
+
+    SVIP("全平台高级版年订阅", new BigDecimal("99.99"), new BigDecimal("59.99")),
+    PERMANENT("MAC&Windows双平台高级版永久", new BigDecimal("119.99"), new BigDecimal("83.99")),
+
+    CNY_SVIP("全平台高级版年订阅", new BigDecimal("658"), new BigDecimal("388")),
+    CNY_PERMANENT("MAC&Windows双平台高级版永久", new BigDecimal("778"), new BigDecimal("539")),
+    ;
+
+    private final String product;
+    private final BigDecimal price;
+    // 教育版价格
+    private final BigDecimal displayPrice;
+
+    BlcakFivePriceEnum(String product, BigDecimal price, BigDecimal displayPrice) {
+        this.product = product;
+        this.price = price;
+        this.displayPrice = displayPrice;
+    }
+
+    public String getProduct() {
+        return product;
+    }
+
+    public BigDecimal getPrice() {
+        return price;
+    }
+
+    public BigDecimal getDisplayPrice() {
+        return displayPrice;
+    }
+
+    //    getbyprice
+    public static BlcakFivePriceEnum getByPrice(BigDecimal price) {
+        for (BlcakFivePriceEnum productEducationPriceEnum : BlcakFivePriceEnum.values()) {
+            if (productEducationPriceEnum.getPrice().compareTo(price) == 0) {
+                return productEducationPriceEnum;
+            }
+        }
+        return null;
+    }
+}

+ 49 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/product/ProductEducationPriceEnum.java

@@ -0,0 +1,49 @@
+package cn.kdan.cloud.pdf.office.common.enums.product;
+
+import java.math.BigDecimal;
+
+public enum ProductEducationPriceEnum {
+
+    VIP("全平台标准版年订阅", new BigDecimal("79.99"), new BigDecimal("39.99")),
+    SVIP("全平台高级版年订阅", new BigDecimal("99.99"), new BigDecimal("49.99")),
+    PERMANENT("MAC&Windows双平台高级版永久", new BigDecimal("119.99"), new BigDecimal("59.99")),
+
+    CNY_VIP("全平台标准版年订阅(教育版)", new BigDecimal("518"), new BigDecimal("259")),
+    CNY_SVIP("全平台高级版年订阅(教育版)", new BigDecimal("658"), new BigDecimal("329")),
+    CNY_PERMANENT("MAC&Windows双平台高级版永久(教育版)", new BigDecimal("778"), new BigDecimal("389")),
+    ;
+
+    private final String product;
+    private final BigDecimal price;
+    // 教育版价格
+    private final BigDecimal displayPrice;
+
+
+    ProductEducationPriceEnum(String product, BigDecimal price, BigDecimal displayPrice) {
+        this.product = product;
+        this.price = price;
+        this.displayPrice = displayPrice;
+    }
+
+    public String getProduct() {
+        return product;
+    }
+
+    public BigDecimal getPrice() {
+        return price;
+    }
+
+    public BigDecimal getDisplayPrice() {
+        return displayPrice;
+    }
+
+    //    getbyprice
+    public static ProductEducationPriceEnum getByPrice(BigDecimal price) {
+        for (ProductEducationPriceEnum productEducationPriceEnum : ProductEducationPriceEnum.values()) {
+            if (productEducationPriceEnum.getPrice().compareTo(price) == 0) {
+                return productEducationPriceEnum;
+            }
+        }
+        return null;
+    }
+}

+ 9 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/pojo/ResultMap.java

@@ -95,10 +95,19 @@ public class ResultMap<T> {
     public static <T> ResultMap<T> success(T result) {
         return success(CommonConstant.RESULT_SUCCESS, result);
     }
+
+    public static <T> ResultMap<T> fail(T result) {
+        return fail(CommonConstant.RESULT_ERROR, result);
+    }
+
     public static <T> ResultMap<T> success(String msg, T result) {
         return success(HttpStatus.SC_OK, msg, result);
     }
 
+    public static <T> ResultMap<T> fail(String msg, T result) {
+        return success(HttpStatus.SC_BAD_REQUEST, msg, result);
+    }
+
     public static <T> ResultMap<T> success(int code, String msg, T result) {
         return new ResultMap<>(code, msg, result);
     }

+ 10 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/utils/CommonUtils.java

@@ -95,6 +95,16 @@ public class CommonUtils {
 		String id = uuid.toString();
 //		id = id.replaceAll("-", "");
 		return id;
+	}    // 生成随机 8 位阿拉伯数字用户 ID
+	public static String generateRandomUserId() {
+		Random random = new Random();
+		StringBuilder userId = new StringBuilder();
+
+		for (int i = 0; i < 8; i++) {
+			userId.append(random.nextInt(10)); // 生成 0-9 之间的随机数
+		}
+
+		return userId.toString();
 	}
 
 	/**

+ 71 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/vo/MemberInfoVO.java

@@ -0,0 +1,71 @@
+package cn.kdan.cloud.pdf.office.common.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 个人信息类 主要返回前端使用
+ */
+@Data
+public class MemberInfoVO {
+
+    /**
+     * 用户id
+     */
+    private String id;
+    /**
+     * 用户邮箱
+     */
+    private String email;
+    /**
+     * 用户名称
+     */
+    private String fullName;
+
+    private SimpleUserSubscriptionInfoVO activeVIP;
+    private SimpleUserSubscriptionInfoVO activeAI;
+
+    private Integer aiPoint;
+    /**
+     *     注销(0),
+     *     正常(1),
+     *     停用(2),
+     *     注销中(5);
+     */
+    private String validFlag;
+
+    /**
+     * 是否设置了密码
+     */
+    private String isHavePwd;
+    /**
+     * 是否有ai优惠
+     */
+    private String isHaveAIDiscount;
+    /**
+     * 是否可以试用
+     */
+    private String canTrail;
+    /**
+     * 姓氏
+     */
+    private String firstName;
+    /**
+     * 名字
+     */
+    private String lastName;
+    /**
+     * 住址
+     */
+    private String address;
+    /**
+     * 国家
+     */
+    private String area;
+
+    private String avatarUrl;
+
+}

+ 72 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/vo/SimpleUserSubscriptionInfoVO.java

@@ -0,0 +1,72 @@
+package cn.kdan.cloud.pdf.office.common.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class SimpleUserSubscriptionInfoVO {
+    /**
+     * id
+     */
+    private String id;
+    /**
+     * 用户id
+     */
+    private String userId;
+
+    /**
+     *  状态 0注册1订阅中2订阅过期3试用中4试用过期
+     */
+    private Integer status;
+
+    /**
+     * 到期时间
+     */
+    @JsonFormat(shape =JsonFormat.Shape.STRING,pattern ="yyyy-MM-dd HH:mm:ss")
+    private Date endDate;
+
+    /**
+     * 0未开启自动续订 1自动续订
+     */
+    private Integer payType;
+    /**
+     * 产品名字
+     */
+    private String productName;
+    /**
+     * 会员等级 1是免费 2是标准 3是高级
+     */
+    private String levels;
+    /**
+     * 支持的平台
+     */
+    private String platforms;
+    /**
+     * 剩余ai点数(svip才有)
+     */
+    private Integer point;
+    /**
+     * 最大登录设备限制数
+     */
+    private Integer maxDeviceNum;
+    /**
+     * 支付方式 付费模式(1自动续订(vip svip) 2单次付费(永久会员))
+     */
+    private String paymentModel;
+    /**
+     * 是否是ai产品(0否1是)
+     */
+    private String isAi;
+
+    private String code;
+    /**
+     * 订阅周期:1、月(30天);2、季(90天);3、半年(183天);4、年(365天)
+     */
+    private Integer cycle;
+
+    private String simplifiedChineseName;
+    private String traditionalChineseName;
+
+}

+ 16 - 2
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/vo/UserInfoVO.java

@@ -12,14 +12,21 @@ import java.util.List;
 @Data
 public class UserInfoVO {
 
+    /**
+     * 用户id
+     */
     private String id;
 
     private String companyId;
 
     private String appId;
-
+    /**
+     * 用户邮箱
+     */
     private String email;
-
+    /**
+     * 用户名称
+     */
     private String fullName;
 
     private Integer subscriberType;
@@ -60,9 +67,16 @@ public class UserInfoVO {
 
     private String validFlag;
 
+    private String firstName;
+
+    private String lastName;
+
+    private String address;
+
     private List<UserSubscriptionInfoVO> subscriptionInfoList;
 
     private Date freeDate ;
 
     private Boolean isInFreeUseTime ;
+    private String canAccessAi;
 }

+ 25 - 2
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/vo/UserSubscriptionInfoVO.java

@@ -7,10 +7,17 @@ import java.util.Date;
 
 @Data
 public class UserSubscriptionInfoVO {
+    /**
+     * id
+     */
     private String id;
-
+    /**
+     * 用户id
+     */
     private String userId;
-
+    /**
+     *  app_id = 1时: 0免费,1永久版,2订阅,3AI
+     */
     private Integer platform;
 
     /**
@@ -35,4 +42,20 @@ public class UserSubscriptionInfoVO {
 
     private String productCode;
 
+    private String productName;
+    private String levels;
+    private String platforms;
+    private Integer point;
+    private Integer maxDeviceNum;
+
+    /**
+     * 付费模式(1自动续订 2单次付费)
+     */
+    private String paymentModel;
+    private String isAi;
+
+    private String code;
+    private Integer cycle;
+    private String simplifiedChineseName;
+    private String traditionalChineseName;
 }

+ 7 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/vo/UserVO.java

@@ -62,4 +62,11 @@ public class UserVO {
     private String validFlag;
 
     private String appId;
+
+    private String firstName;
+
+    private String lastName;
+
+    private String address;
+    private String canAccessAi;
 }

+ 21 - 21
pdf-office-email/src/main/java/cn/kdan/cloud/pdf/office/email/rabbit/listener/SendEmailListener.java

@@ -32,30 +32,30 @@ import java.util.Objects;
 /**
  * @author ComPDFKit-WPH 2023/1/11
  */
-@Component
-@Slf4j
-@RequiredArgsConstructor
-public class SendEmailListener {
+        @Component
+        @Slf4j
+        @RequiredArgsConstructor
+        public class SendEmailListener {
 
-    private final SendEmailHandlerService sendEmailService;
+            private final SendEmailHandlerService sendEmailService;
 
-    private final MailSenderConfig mailSenderConfig;
-    private final EmailLogService emailLogService;
-    private final EmailTemplateService emailTemplateService;
+            private final MailSenderConfig mailSenderConfig;
+            private final EmailLogService emailLogService;
+            private final EmailTemplateService emailTemplateService;
 
-    /**
-     * 发送邮件 监听
-     *
-     * @param message    message
-     * @param channel    channel
-     * @param emailSendBO sendObject
-     */
-    @RabbitListener(queues = RabbitMqConstant.EMAIL_SEND_QUEUE)
-    public void backgroundApiAddQueue(Message message, Channel channel, EmailSendBO emailSendBO) {
-        log.info("邮件发送监听内容:{}", emailSendBO);
-        EmailLog emailLog = new EmailLog();
-        String emailTemplateId = null;
-        File file = null;
+            /**
+             * 发送邮件 监听
+             *
+             * @param message    message
+             * @param channel    channel
+             * @param emailSendBO sendObject
+             */
+            @RabbitListener(queues = RabbitMqConstant.EMAIL_SEND_QUEUE)
+            public void backgroundApiAddQueue(Message message, Channel channel, EmailSendBO emailSendBO) {
+                log.info("邮件发送监听内容:{}", emailSendBO);
+                EmailLog emailLog = new EmailLog();
+                String emailTemplateId = null;
+                File file = null;
         try {
             if(StringUtils.isEmpty(emailSendBO.getToEmail())){
                 log.info("邮箱为空:{}", emailSendBO);

+ 3 - 3
pdf-office-generate/src/main/resources/application.yml

@@ -8,9 +8,9 @@ spring:
     static-locations: classpath:/views/
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://${DB_URL:124.223.7.184:33056/information_schema}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
-    username: ${DB_USERNAME:root}
-    password: ${DB_PASSWORD:root123}
+    url: jdbc:mysql://${DB_URL:101.132.103.13:33056/information_schema}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
+    username: ${DB_USERNAME:deployer}
+    password: ${DB_PASSWORD:deployer@123!}
     hikari:
       # 最小空闲连接,默认值10
       minimum-idle: 10

+ 63 - 12
pdf-office-payment/pom.xml

@@ -18,6 +18,50 @@
     </properties>
 
     <dependencies>
+        <dependency>
+            <groupId>com.google.auth</groupId>
+            <artifactId>google-auth-library-credentials</artifactId>
+            <version>1.21.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.http-client</groupId>
+            <artifactId>google-http-client</artifactId>
+            <version>1.43.3</version> <!-- 更新版本 -->
+        </dependency>
+        <dependency>
+            <groupId>com.google.api-client</groupId>
+            <artifactId>google-api-client</artifactId>
+            <version>1.31.1</version> <!-- 更新到至少 1.31.1 -->
+        </dependency>
+        <dependency>
+            <groupId>com.google.auth</groupId>
+            <artifactId>google-auth-library-oauth2-http</artifactId>
+            <version>1.19.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.apis</groupId>
+            <artifactId>google-api-services-androidpublisher</artifactId>
+            <version>v3-rev20231115-2.0.0</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-api</artifactId>
+            <version>0.11.2</version>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-impl</artifactId>
+            <version>0.11.2</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
+            <version>0.11.2</version>
+            <scope>runtime</scope>
+        </dependency>
         <dependency>
             <groupId>cn.kdan.pdf.office</groupId>
             <artifactId>pdf-office-common</artifactId>
@@ -109,19 +153,13 @@
             </exclusions>
         </dependency>
 
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.alibaba</groupId>
-            <artifactId>fastjson</artifactId>
-        </dependency>
-<!--        &lt;!&ndash;paddle webhook 验证&ndash;&gt;-->
 <!--        <dependency>-->
-<!--            <groupId>com.jamiussiam</groupId>-->
-<!--            <artifactId>paddle-verifier</artifactId>-->
-<!--            <version>2.1</version>-->
+<!--            <groupId>com.fasterxml.jackson.core</groupId>-->
+<!--            <artifactId>jackson-databind</artifactId>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>com.alibaba</groupId>-->
+<!--            <artifactId>fastjson</artifactId>-->
 <!--        </dependency>-->
         <dependency>
             <groupId>com.xk72</groupId>
@@ -170,6 +208,19 @@
 <!--            <artifactId>jackson-databind</artifactId>-->
 <!--            <version>2.13.4.2</version>-->
 <!--        </dependency>-->
+        <!--hutool工具包-->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.2</version>
+        </dependency>
+
+        <!-- 添加OkHttp依赖 -->
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>4.9.1</version> <!-- 请使用最新的稳定版本 -->
+        </dependency>
 
     </dependencies>
 

+ 3 - 1
pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/PDFOfficePaymentApplication.java

@@ -6,7 +6,9 @@ import cn.kdan.cloud.pdf.office.api.product.annotation.EnableProductApiClient;
 import cn.kdan.cloud.pdf.office.common.annotation.*;
 import cn.kdan.cloud.pdf.office.common.config.RedissonConfig;
 import cn.kdan.cloud.pdf.office.payment.properties.AppStoreProperties;
+import cn.kdan.cloud.pdf.office.payment.properties.GooglePayConfig;
 import cn.kdan.cloud.pdf.office.payment.properties.PaddleProperties;
+import cn.kdan.cloud.pdf.office.payment.properties.PayCenterConfigProperties;
 import cn.kdan.cloud.pdf.office.payment.properties.PaypalProperties;
 import cn.kdan.cloud.pdf.office.payment.verifier.Verifier;
 import lombok.RequiredArgsConstructor;
@@ -28,7 +30,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @SpringBootApplication
 @EnableDiscoveryClient
 @EnableHystrix
-@EnableConfigurationProperties({PaypalProperties.class, PaddleProperties.class, AppStoreProperties.class})
+@EnableConfigurationProperties({PaypalProperties.class, PaddleProperties.class, AppStoreProperties.class, GooglePayConfig.class, PayCenterConfigProperties.class})
 @EnableMybatisPlusConfig
 @MapperScan("cn.kdan.cloud.pdf.office.payment.mapper")
 @EnableMyRabbitMqHandler

File diff suppressed because it is too large
+ 121 - 21
pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/client/AppStoreClient.java


+ 203 - 0
pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/client/GooglePayClient.java

@@ -0,0 +1,203 @@
+package cn.kdan.cloud.pdf.office.payment.client;
+
+import cn.hutool.core.util.StrUtil;
+import cn.kdan.cloud.pdf.office.api.payment.appstore.AppStoreReceiptInfo;
+import cn.kdan.cloud.pdf.office.api.payment.appstore.AppTransaction;
+import cn.kdan.cloud.pdf.office.api.payment.appstore.HistoryResponse;
+import cn.kdan.cloud.pdf.office.api.payment.constant.AppStoreAPIConstant;
+import cn.kdan.cloud.pdf.office.api.payment.dto.AppStoreOrderSucceedDTO;
+import cn.kdan.cloud.pdf.office.api.payment.dto.GooglePayDTO;
+import cn.kdan.cloud.pdf.office.api.product.vo.ProductVO;
+import cn.kdan.cloud.pdf.office.common.constant.RabbitMqConstant;
+import cn.kdan.cloud.pdf.office.common.enums.ExceptionEnum;
+import cn.kdan.cloud.pdf.office.common.exception.BackendRuntimeException;
+import cn.kdan.cloud.pdf.office.common.utils.JsonUtils;
+import cn.kdan.cloud.pdf.office.common.utils.MyDateUtils;
+import cn.kdan.cloud.pdf.office.payment.enums.AppStoreReceiptVerifyStatusEnum;
+import cn.kdan.cloud.pdf.office.payment.enums.SubscriptionAckStateEnum;
+import cn.kdan.cloud.pdf.office.payment.interceptor.AppStoreClientHttpRequestInterceptor;
+import cn.kdan.cloud.pdf.office.payment.interceptor.GoogleClientHttpRequestInterceptor;
+import cn.kdan.cloud.pdf.office.payment.properties.AppStoreProperties;
+import cn.kdan.cloud.pdf.office.payment.properties.GooglePayConfig;
+import cn.kdan.cloud.pdf.office.payment.utils.BearerTokenAuthenticator;
+import cn.kdan.cloud.pdf.office.payment.utils.IOUtils;
+import cn.kdan.cloud.pdf.office.payment.webhook.google.SubscriptionPurchaseV3;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
+import com.google.api.client.json.gson.GsonFactory;
+
+import com.google.api.services.androidpublisher.AndroidPublisher;
+import com.google.api.services.androidpublisher.AndroidPublisherScopes;
+import com.google.api.services.androidpublisher.model.SubscriptionPurchaseV2;
+import com.google.auth.http.HttpCredentialsAdapter;
+import com.google.auth.oauth2.GoogleCredentials;
+import com.google.gson.JsonObject;
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.BeanUtils;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.*;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.DefaultResponseErrorHandler;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.LocalDateTime;
+import java.util.*;
+
+/**
+ * @author ComPDFKit-WPH 2023/6/28
+ */
+@Component
+@Slf4j
+public class GooglePayClient {
+
+    private final RestTemplate restTemplate = new RestTemplate();
+
+    private GooglePayConfig properties;
+
+
+    private AndroidPublisher androidPublisher;// 注入进来咔咔用
+
+    private final RabbitTemplate rabbitTemplate;
+
+
+    public GooglePayClient(GooglePayConfig properties, GoogleClientHttpRequestInterceptor googleClientHttpRequestInterceptor, RabbitTemplate rabbitTemplate) {
+        this.properties = properties;
+        this.rabbitTemplate = rabbitTemplate;
+        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
+        restTemplate.setRequestFactory(factory);
+        restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
+            @Override
+            public void handleError(@NotNull ClientHttpResponse clientHttpResponse) throws IOException {
+
+            }
+        });
+    }
+
+
+    private void getAndroidPublisher() {
+        try {
+            GoogleCredentials googleCredentials = GoogleCredentials.fromStream(new ClassPathResource("focus-pottery-439503-a3-e3bbeddf9ae0.json").getInputStream())
+                .createScoped(AndroidPublisherScopes.ANDROIDPUBLISHER);
+            this.androidPublisher = new AndroidPublisher.Builder(
+                GoogleNetHttpTransport.newTrustedTransport(),
+                GsonFactory.getDefaultInstance(),
+                new HttpCredentialsAdapter(googleCredentials)
+        ).setApplicationName("PDF Reader Pro").build();
+        } catch (Exception e) {
+            log.error("[Google] Get android publisher exception: {}", e.getMessage());
+            throw new BackendRuntimeException("[Google] Get android publisher exception: " + e.getMessage());
+        }
+    }
+
+    public SubscriptionPurchaseV3 getSubscription(String packageName, String purchaseToken) {
+        try {
+        String url = "https://backend.pdfreaderpro.com/system/google/getSubscriptionGoogleOrderV2" +
+                "?packageName=" + packageName + "&purchaseToken=" + purchaseToken;
+
+        // 设置请求头
+        HttpHeaders headers = new HttpHeaders();
+        // 创建 HttpEntity
+        HttpEntity<String> entity = new HttpEntity<>(headers);
+
+        // 发起请求
+        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
+        SubscriptionPurchaseV3 subscriptionsV2 = JSON.parseObject(response.getBody(),SubscriptionPurchaseV3.class);
+        return subscriptionsV2;
+        } catch (Exception e) {
+            log.error("谷歌订单校验异常,从会员系统获取订阅失败purchaseToken:{},package:{}",purchaseToken,packageName);
+            throw new BackendRuntimeException("[Google] Get google subscriptions v2 order info exception: " + e.getMessage());
+        }
+    }
+
+    public SubscriptionPurchaseV2 getSubscriptionGoogleOrderV2(String packageName, String purchaseToken){
+        getAndroidPublisher();
+        SubscriptionPurchaseV2 subscriptionsV2 = null;
+        try {
+            subscriptionsV2 = androidPublisher.purchases().subscriptionsv2().get(packageName, purchaseToken).execute();
+            log.info("SubscriptionsV2 order info: {}", JsonUtils.getJsonString(subscriptionsV2));
+        } catch (IOException e) {
+            log.error("谷歌订单校验异常,purchaseToken:{}",purchaseToken);
+            throw new BackendRuntimeException("[Google] Get google subscriptions v2 order info exception: " + e.getMessage());
+        }
+        return subscriptionsV2;
+    }
+
+    /**
+     * 校验订阅订单是否支付成功
+     *
+     * @param subscriptionsV2
+     * @return
+     */
+    public boolean checkSubscriptionSuccess(SubscriptionPurchaseV3 subscriptionsV2) {
+        String acknowledgementState = subscriptionsV2.getAcknowledgementState();
+        if (SubscriptionAckStateEnum.ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED.getCode().equals(acknowledgementState)) {
+            return true;
+        }
+        return false;
+    }
+    public static void main(String[] args) {
+//        testID();
+        RestTemplate restTemplate = new RestTemplate();
+        String url = "https://backend.pdfreaderpro.com/system/google/getSubscriptionGoogleOrderV2" +
+                "?packageName=" + "com.pdftechnologies.pdfreaderpro" + "&purchaseToken=" + "kkocpfbdghkkhpponlnmecao.AO-J1OxH2Cn0M_vUA_SDglNA92yA6jOxahaU-nC8ZljmOvEcQlIGrUtA5YvlDraJL8uFty95fMzl7us6VvvA2ow1TmewRaMBKbdANHudEuQBLMIRSC9Qykw";
+
+        // 设置请求头
+        HttpHeaders headers = new HttpHeaders();
+        // 创建 HttpEntity
+        HttpEntity<String> entity = new HttpEntity<>(headers);
+
+        // 发起请求
+        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
+        //判断有没有testPurchase 字段
+        SubscriptionPurchaseV3 subscriptionsV2 = JSON.parseObject(response.getBody(),SubscriptionPurchaseV3.class);
+//        // 创建目标对象
+        SubscriptionPurchaseV2 venueV2 = new SubscriptionPurchaseV2();
+//
+//        // 复制属性
+//        BeanUtils.copyProperties(subscriptionsV2, venueV2);
+//        System.out.println("123");
+//        String Period = "7.days,1.years";
+//        //7.days:0,1.years:20,1.years:40
+//        List<String> dateAndPriceList = Arrays.asList(Period.split(","));
+//        int times =  dateAndPriceList.size() > 1 ? 1 : dateAndPriceList.size()-1;
+//        String forPeriod = dateAndPriceList.get(times);;
+//        LocalDateTime dateTime = LocalDateTime.now();
+//        MyDateUtils.TimeAddition(dateTime, forPeriod);
+//        System.out.println(111);
+    }
+
+    private static void testID() {
+        String appName = "PDF Reader Pro";
+        String packageName = "com.pdftechnologies.pdfreaderpro";
+        String purchaseToken = "kkocpfbdghkkhpponlnmecao.AO-J1OxH2Cn0M_vUA_SDglNA92yA6jOxahaU-nC8ZljmOvEcQlIGrUtA5YvlDraJL8uFty95fMzl7us6VvvA2ow1TmewRaMBKbdANHudEuQBLMIRSC9Qykw" ;
+        InputStream content = new IOUtils().getGoogleKey();
+        try {
+            GoogleCredentials googleCredentials = GoogleCredentials.fromStream(content)
+                    .createScoped(AndroidPublisherScopes.ANDROIDPUBLISHER);
+           AndroidPublisher androidPublisher = new AndroidPublisher.Builder(
+                    GoogleNetHttpTransport.newTrustedTransport(),
+                    GsonFactory.getDefaultInstance(),
+                    new HttpCredentialsAdapter(googleCredentials)
+            ).setApplicationName(appName).build();
+            SubscriptionPurchaseV2 subscriptionsV2 = null;
+            try {
+                subscriptionsV2 = androidPublisher.purchases().subscriptionsv2().get(packageName, purchaseToken).execute();
+                log.info("SubscriptionsV2 order info: {}", JsonUtils.getJsonString(subscriptionsV2));
+            } catch (IOException e) {
+                log.error("谷歌订单校验异常");
+                throw new BackendRuntimeException("[Google] Get google subscriptions v2 order info exception: " + e.getMessage());
+            }
+        } catch (Exception e) {
+            log.error("[Google] Get android publisher exception: {}", e.getMessage());
+            throw new BackendRuntimeException("[Google] Get android publisher exception: " + e.getMessage());
+        }
+    }
+}

+ 173 - 26
pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/controller/OrderController.java

@@ -1,23 +1,39 @@
 package cn.kdan.cloud.pdf.office.payment.controller;
 
+import cn.kdan.cloud.pdf.office.api.payment.vo.OrderGiftLogVO;
+import cn.kdan.cloud.pdf.office.common.dto.CreateUserOrderDTO;
 import cn.kdan.cloud.pdf.office.common.vo.UserInfoVO;
 import cn.kdan.cloud.pdf.office.api.payment.dto.*;
-import cn.kdan.cloud.pdf.office.api.payment.enums.PaymentMethodEnum;
 import cn.kdan.cloud.pdf.office.api.payment.vo.CreateOrderResultVO;
 import cn.kdan.cloud.pdf.office.api.payment.vo.OrderUpdateVO;
 import cn.kdan.cloud.pdf.office.api.payment.vo.OrdersVO;
 import cn.kdan.cloud.pdf.office.api.product.feign.ProductApi;
 import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
-import cn.kdan.cloud.pdf.office.payment.service.AppStoreService;
-import cn.kdan.cloud.pdf.office.payment.service.OrderService;
-import cn.kdan.cloud.pdf.office.payment.service.SubscriptionsService;
-import cn.kdan.cloud.pdf.office.payment.service.WebhookService;
+import cn.kdan.cloud.pdf.office.payment.client.GooglePayClient;
+import cn.kdan.cloud.pdf.office.payment.entity.Order;
+import cn.kdan.cloud.pdf.office.payment.entity.OrderGift;
+import cn.kdan.cloud.pdf.office.payment.entity.OrderGiftLog;
+import cn.kdan.cloud.pdf.office.payment.service.*;
+import cn.kdan.cloud.pdf.office.payment.webhook.google.SubscriptionPurchaseV3;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.BeanUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
 
 import javax.validation.constraints.NotNull;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @author ComPDFKit-WPH 2023/2/6
@@ -38,6 +54,14 @@ public class OrderController {
     private final WebhookService webhookService;
 
     private final AppStoreService appStoreService;
+    private final GooglePayService googlePayService;
+
+    private final OrderGiftService orderGiftService;
+    private final OrderGiftLogService orderGiftLogService;
+
+    private final RestTemplate restTemplate = new RestTemplate();
+    private final RedissonClient redissonClient;
+    private final GooglePayClient googlePayClient;
 
     /**
      * 创建支付订单
@@ -50,39 +74,78 @@ public class OrderController {
         return ResultMap.success(ordersService.createOrder(createOrderDTO));
     }
 
-    /**
-     * 订单创建(applePay专用)
-     *
-     * @param createOrderDTO createOrderDTO
-     * @return CreateOrderResultVO
-     */
-    @PostMapping("/appStoreCreateOrder")
-    public ResultMap<CreateOrderResultVO> appStoreCreateOrder(@Validated @RequestBody CreateOrderDTO createOrderDTO){
-        return ResultMap.success(ordersService.appStoreCreateOrder(createOrderDTO));
+    @PostMapping("/createUserOrder")
+    public ResultMap<Map<String, String>> createUserOrder(@Validated @RequestBody CreateUserOrderDTO createUserOrderDTO) {
+        return ResultMap.success(ordersService.createUserOrder(createUserOrderDTO));
     }
 
-    /**
-     * 订单支付成功(applePay专用)
-     * 回传appal pay id &签名证书
-     *
-     * @param appStoreOrderSucceed appStoreOrderSucceed
-     * @return Void
-     */
-    @PostMapping("/appStoreOrderSucceed")
-    public ResultMap<UserInfoVO> appStoreOrderSucceed(@Validated @RequestBody AppStoreOrderSucceedDTO appStoreOrderSucceed){
-        return ResultMap.success(appStoreService.appStoreOrderSucceed(appStoreOrderSucceed));
+    @PostMapping("/createUserSubscription")
+    public ResultMap<Map<String, String>> createUserSubscription(@Validated @RequestBody CreateUserOrderDTO createUserOrderDTO) {
+        return ResultMap.success(ordersService.createUserSubscription(createUserOrderDTO));
     }
 
     /**
-     * appStore 权益校验
+     *  权益校验 (会员系统)
      *
-     * @param equityVerificationDTO equityVerificationDTO
+     * @param  equityVerificationDTO equityVerificationDTO
      * @return UserInfoVO
      */
     @PostMapping("/appStoreEquityVerification")
     public ResultMap<UserInfoVO> appStoreEquityVerification(@RequestBody EquityVerificationDTO equityVerificationDTO){
         return ResultMap.success(appStoreService.appStoreEquityVerification(equityVerificationDTO));
     }
+
+    /**
+     * 谷歌 权益校验 (会员系统)
+     *
+     * @param googlePayDTO googlePayDTO
+     * @return UserInfoVO
+     */
+    @PostMapping("/googleEquityVerification")
+    public ResultMap<UserInfoVO> googleEquityVerification(@RequestBody GooglePayDTO googlePayDTO){
+        return ResultMap.success(googlePayService.googleEquityVerification(googlePayDTO));
+    }
+
+    @PostMapping("/updateStatusPayment")
+    public ResultMap<Boolean> updateStatusPayment(@RequestParam String userId, @RequestParam String productId){
+        updatePayment(userId,productId);
+        return ResultMap.success(true);
+    }
+
+    public void updatePayment(String userId, String productId) {
+        /*
+         如果用户有进行中的订阅,查最近的完成订阅订单,
+         */
+        Order order = ordersService.getOrderByUserIdAndProductId(userId, productId);
+        //如果没有订单结束
+        if(ObjectUtils.isEmpty(order)||StringUtils.isEmpty(order.getResult())){
+            return;
+        }
+        if(order.getPayment()==6){
+            SubscriptionPurchaseV3 subscriptionGoogleOrderV2 = googlePayClient.getSubscription("com.pdftechnologies.pdfreaderpro",order.getResult());
+            if(subscriptionGoogleOrderV2.getSubscriptionState().equals("SUBSCRIPTION_STATE_CANCELED")||subscriptionGoogleOrderV2.getSubscriptionState().equals("SUBSCRIPTION_STATE_EXPIRED")){
+                googlePayService.subscriptionCancel(subscriptionGoogleOrderV2.getExternalAccountIdentifiers().getObfuscatedExternalAccountId());
+            }
+            if(subscriptionGoogleOrderV2.getSubscriptionState().equals("SUBSCRIPTION_STATE_ACTIVE")){
+                String lockKey = Integer.toString(2).concat(subscriptionGoogleOrderV2.getExternalAccountIdentifiers().getObfuscatedExternalAccountId()) + "-RedissonLock";
+                RLock rLock = redissonClient.getLock(lockKey);
+                try {
+                    // 上锁
+                    boolean resultLock = rLock.tryLock(30, 10, TimeUnit.SECONDS);
+                    if (resultLock) {
+                        googlePayService.subscriptionPaymentSucceeded(false, subscriptionGoogleOrderV2.getExternalAccountIdentifiers().getObfuscatedExternalAccountId(), subscriptionGoogleOrderV2.getLatestOrderId(), 2);
+                    }
+                } catch (InterruptedException e) {
+
+                } finally {
+                    if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
+                        rLock.unlock();
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * 手动创建虚拟订单
      *
@@ -106,6 +169,23 @@ public class OrderController {
         return ResultMap.success(ordersService.getOrderById(orderId));
     }
 
+    @GetMapping("/getStateByOrderId")
+    ResultMap<Map<String, String>> getStateByOrderId(@Validated @NotNull(message = "订单id不能为空") @RequestParam("orderId") String orderId) {
+        return ResultMap.success(ordersService.getStateByOrderId(orderId));
+    }
+
+    @GetMapping("/getOrderListByStatus")
+    ResultMap<List<OrdersVO>> getOrderListByStatus(@Validated @NotNull(message = "订单状态不能为空") @RequestParam("orderStatus") Integer orderStatus,
+                                                   @Validated @NotNull(message = "userId不能为空") @RequestParam("userId") String userId) {
+        return ResultMap.success(ordersService.getOrderListByStatus(orderStatus, userId));
+    }
+
+    @PostMapping("/closeOrder")
+    ResultMap<Boolean> closeOrder(@Validated @NotNull(message = "订单id不能为空") @RequestParam("orderId") String orderId) {
+        ordersService.closeOrder(orderId);
+        return ResultMap.success(true);
+    }
+
     /**
      * 查询订单详情(用于判断订阅是否已经支付完成)
      * @param orderId
@@ -156,4 +236,71 @@ public class OrderController {
         return ResultMap.success();
     }
 
+    /**
+     * 获取会员系统用户订单
+     * @param userId
+     * @return
+     */
+    @GetMapping("/getOrderByUserId")
+    ResultMap<List<OrdersVO>> getOrderByUserId(@Validated @NotNull(message = "userId不能为空")
+                                               @RequestParam("userId") String userId) {
+        return ResultMap.success(ordersService.getOrderByUserId(userId, "1"));
+    }
+
+    @PostMapping("/giveAway")
+    public ResultMap<OrderGiftLogVO> giveAway(@RequestParam("userId") String userId, @RequestParam("email") String email, @RequestParam("name") String name) {
+        OrderGift orderGift = orderGiftService.giveAway(userId);
+        OrderGiftLog orderGiftLog = orderGiftLogService.logGift(userId,email,name,orderGift.getId());
+        OrderGiftLogVO result = new OrderGiftLogVO();
+        BeanUtils.copyProperties(orderGiftLog,result);
+        return ResultMap.success(result);
+    }
+    /**
+     * 根据用户id查询list可赠送的数量
+     */
+    @GetMapping("/getGiftNum")
+    public ResultMap<Long> getGiftNum(@RequestParam("userId") String userId) {
+        return ResultMap.success(orderGiftService.getGiftNum(userId));
+    }
+
+    @GetMapping("/getOrderGiftLogById")
+    public ResultMap<OrderGiftLogVO> getOrderGiftLogById(@RequestParam("orderGiftLogId") String orderGiftLogId) {
+        OrderGiftLogVO result = new OrderGiftLogVO();
+        OrderGiftLog orderGiftLog = orderGiftLogService.getById(orderGiftLogId);
+        BeanUtils.copyProperties(orderGiftLog,result);
+        return ResultMap.success(result);
+    }
+
+    /**
+     * 接收
+     * @param orderGiftLogId  订单赠送记录id
+     * @param receiveUserId 接收者id
+     * @return
+     */
+    @PostMapping("/acceptUser")
+    public ResultMap<Boolean> acceptUser(@RequestParam("orderGiftLogId") String orderGiftLogId,@RequestParam("receiveUserId") String receiveUserId) {
+        return ResultMap.success(orderGiftLogService.acceptUser(orderGiftLogId,receiveUserId));
+    }
+    //分页查询orderGiftLog
+    @GetMapping("/pageOrderGiftLog")
+    public ResultMap<Page<OrderGiftLogVO>> pageOrderGiftLog(@RequestParam("userId")String userId,
+                                                             @RequestParam(name = "email",required = false)String email,
+                                                             @RequestParam(name = "name",required = false)String name,
+                                                             @RequestParam(name = "page",defaultValue = "1",required = false)Integer page,
+                                                             @RequestParam(name ="pageSize",defaultValue = "10",required = false)Integer pageSize) {
+        IPage<OrderGiftLog> pageGiftLog = orderGiftLogService.orderGiftLogPage(userId, email, name, page, pageSize);
+        List<OrderGiftLogVO> vos = new ArrayList<>();
+        pageGiftLog.getRecords().stream().forEach(orderGiftLog -> {
+            OrderGiftLogVO vo = new OrderGiftLogVO();
+            BeanUtils.copyProperties(orderGiftLog,vo);
+            //localdatetime转date
+            vo.setCreatedAt( Date.from(orderGiftLog.getCreatedAt().atZone(ZoneId.systemDefault()).toInstant()));
+            vo.setUpdatedAt(Date.from(orderGiftLog.getUpdatedAt().atZone(ZoneId.systemDefault()).toInstant()));
+            vos.add(vo);
+        });
+        Page<OrderGiftLogVO> resultPage = new Page<>(pageGiftLog.getPages(), pageGiftLog.getSize());
+        resultPage.setTotal(pageGiftLog.getTotal());
+        resultPage.setRecords(vos);
+        return ResultMap.success(resultPage);
+    }
 }

+ 16 - 0
pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/controller/SubscriptionController.java

@@ -114,4 +114,20 @@ public class SubscriptionController {
                                             @RequestParam("productId") String productId) {
         return ResultMap.success(subscriptionsService.getNextPayTime(userId,productId));
     }
+
+    /**
+     * 判断是否可以送试用
+     * @param userId 用户id
+     * @return Boolean
+     */
+    @GetMapping("/judgeTrail")
+    ResultMap<Boolean> judgeTrail(@RequestParam("userId") String userId) {
+        return ResultMap.success(subscriptionsService.judgeTrail(userId));
+    }
+    //判断用户是否有ai折扣
+    @GetMapping("/judgeAiDiscount")
+    ResultMap<Boolean> judgeAiDiscount(@RequestParam("userId") String userId) {
+        return ResultMap.success(subscriptionsService.judgeAiDiscount(userId));
+    }
+
 }

+ 17 - 0
pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/entity/Order.java

@@ -98,4 +98,21 @@ public class Order extends BaseEntity{
     private Date payDate;
 
     private String email;
+
+    private Integer payNumber;
+
+    /**
+     * 优惠标记  0原价,1优惠券,2升级,3教育优惠,4批量购买,5黑五折扣;10教育商品升级,11黑五+优惠券
+     */
+    private Integer discountType;
+
+    /**
+     * 付费类型 0不是自动订阅 1自动订阅
+     */
+    private Integer subscriptionType;
+    /**
+     * 付费模式(1自动续订 2单次付费)
+     */
+    private Integer paymentModel;
+    private String currency;
 }

+ 0 - 0
pdf-office-payment/src/main/java/cn/kdan/cloud/pdf/office/payment/entity/OrderGift.java


Some files were not shown because too many files changed in this diff