Browse Source

调用图灵业务,改成业务方实现

nelson 4 months ago
parent
commit
bdffcd317a
42 changed files with 730 additions and 199 deletions
  1. 9 0
      sikey-hmd-business/pom.xml
  2. 28 0
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/DeviceActivationApi.java
  3. 2 7
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/QrCodeApi.java
  4. 5 1
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/TuLingApi.java
  5. 48 0
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/dto/activation/DeviceActivationDTO.java
  6. 5 1
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/tuling/ApiResponse.java
  7. 5 1
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/tuling/DataRequest.java
  8. 5 1
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/tuling/QueryUpgradeRequest.java
  9. 5 1
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/tuling/QueryUpgradeResponse.java
  10. 34 0
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/vo/activation/UpdateRemainingTimesExpireTimeReqVO.java
  11. 1 1
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/vo/plans/PlansRespVO.java
  12. 9 12
      sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/vo/qr/RemainingExpireTimeRespVO.java
  13. 6 0
      sikey-hmd-business/sikey-hmd-business-biz/pom.xml
  14. 39 0
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/api/DeviceActivationApiImpl.java
  15. 4 6
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/api/QrCodeApiImpl.java
  16. 5 1
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/api/TuLingApiImpl.java
  17. 4 4
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/config/HttpUtil.java
  18. 9 3
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/config/TuLingConfiguration.java
  19. 17 7
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/config/TuLingParamConfig.java
  20. 16 0
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/controller/app/activation/DeviceActivationController.java
  21. 0 0
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/controller/app/activation/vo/test.json
  22. 20 12
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/controller/app/index/PaymentIndexController.java
  23. 13 5
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/controller/app/qr/QRCodeController.java
  24. 18 0
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/convert/DeviceActivationConvert.java
  25. 2 2
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/convert/QrCodeConvert.java
  26. 51 0
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/dal/dataobject/DeviceActivationDO.java
  27. 3 3
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/dal/dataobject/DeviceQrcodeDO.java
  28. 2 2
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/dal/dataobject/PlansDO.java
  29. 34 0
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/dal/mysql/DeviceActivationMapper.java
  30. 13 5
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/enums/TulingLevelEnum.java
  31. 1 2
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/enums/ValidityEnum.java
  32. 13 17
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/AbstractPaymentService.java
  33. 24 0
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/activation/DeviceActivationService.java
  34. 114 0
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/activation/DeviceActivationServiceImpl.java
  35. 1 1
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/alipay/AlipayPaymentServiceImpl.java
  36. 4 11
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/qr/QRCodeService.java
  37. 14 23
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/qr/QRCodeServiceImpl.java
  38. 9 3
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/tuling/TuLingService.java
  39. 21 9
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/tuling/TuLingServiceImpl.java
  40. 57 17
      sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/util/DateToolUtil.java
  41. 30 21
      sikey-hmd-business/sikey-hmd-business-biz/src/main/resources/application.yml
  42. 30 20
      sikey-hmd-business/sikey-hmd-business-biz/src/main/resources/templates/index.html

+ 9 - 0
sikey-hmd-business/pom.xml

@@ -206,6 +206,13 @@
                 <version>${revision}</version>
             </dependency>
 
+            <!-- Redis 相关 -->
+            <dependency>
+                <groupId>cn.sikey.cloud</groupId>
+                <artifactId>sikey-spring-boot-starter-redis</artifactId>
+                <version>${revision}</version>
+            </dependency>
+
             <!-- 参数校验 -->
             <dependency>
                 <groupId>org.springframework.boot</groupId>
@@ -223,6 +230,8 @@
                 <version>${commons-codec.version}</version>
             </dependency>
 
+
+
             <!-- RPC 远程调用相关 -->
             <!--<dependency>
                 <groupId>org.springframework.cloud</groupId>

+ 28 - 0
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/DeviceActivationApi.java

@@ -0,0 +1,28 @@
+package cn.sikey.hmd.api.hmd;
+
+import cn.sikey.framework.common.pojo.CommonResult;
+import cn.sikey.hmd.api.hmd.dto.activation.DeviceActivationDTO;
+import cn.sikey.hmd.api.hmd.vo.activation.UpdateRemainingTimesExpireTimeReqVO;
+import cn.sikey.hmd.enums.ApiConstants;
+import org.springframework.cloud.openfeign.FeignClient;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @Author: nelson
+ * @Date: 2025/5/16
+ * @Description: 设备激活
+ */
+@FeignClient(name = ApiConstants.NAME)
+public interface DeviceActivationApi {
+    String PREFIX = ApiConstants.PREFIX;
+
+    @PostMapping(PREFIX + "/updateRemainingTimesExpireTime")
+    CommonResult<Void> updateRemainingTimesExpireTime(@RequestBody @Validated UpdateRemainingTimesExpireTimeReqVO updateRemainingTimesExpireTimeReqVO);
+
+    @GetMapping(PREFIX + "/queryDeviceActivation")
+    CommonResult<DeviceActivationDTO> queryDeviceActivation(@RequestParam String deviceId);
+}

+ 2 - 7
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/QrCodeApi.java

@@ -1,13 +1,8 @@
 package cn.sikey.hmd.api.hmd;
 
 
-import cn.sikey.framework.common.pojo.CommonResult;
-import cn.sikey.hmd.api.hmd.vo.qr.RemainingTimesExpireTimeRespVO;
 import cn.sikey.hmd.enums.ApiConstants;
 import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestParam;
 
 /**
  * @Author: qin
@@ -19,10 +14,10 @@ public interface QrCodeApi {
 
     String PREFIX = ApiConstants.PREFIX;
 
-    @PostMapping(PREFIX + "/updateRemainingTimesExpireTime")
+    /*@PostMapping(PREFIX + "/updateRemainingTimesExpireTime")
     CommonResult<Void> updateRemainingTimesExpireTime(@RequestParam String deviceId, @RequestParam String expireTime, @RequestParam int remainingTimes, @RequestParam int plansValidity);
 
     @GetMapping(PREFIX + "/queryDeviceQrcodeDOByDeviceId")
-    CommonResult<RemainingTimesExpireTimeRespVO> queryDeviceQrcodeDOByDeviceId(@RequestParam String deviceId);
+    CommonResult<RemainingTimesExpireTimeRespVO> queryDeviceQrcodeDOByDeviceId(@RequestParam String deviceId);*/
 
 }

+ 5 - 1
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/TuLingApi.java

@@ -1,3 +1,4 @@
+/*
 package cn.sikey.hmd.api.hmd;
 
 
@@ -8,11 +9,13 @@ import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 
+*/
 /**
  * @Author: qin
  * @Date: 2025/4/25
  * @Description: 图灵
- */
+ *//*
+
 @FeignClient(name = ApiConstants.NAME)
 public interface TuLingApi {
 
@@ -24,3 +27,4 @@ public interface TuLingApi {
     @GetMapping(PREFIX + "/getDeviceMenu")
     ApiResponse<QueryUpgradeResponse> getDeviceMenu(@RequestParam String deviceId, @RequestParam String apiKey, @RequestParam String secret);
 }
+*/

+ 48 - 0
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/dto/activation/DeviceActivationDTO.java

@@ -0,0 +1,48 @@
+package cn.sikey.hmd.api.hmd.dto.activation;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+/**
+ * 设备激活
+ *
+ * @author qin
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DeviceActivationDTO {
+
+    /**
+     * id
+     */
+    private Long id;
+    /**
+     * 类型
+     */
+    private String apiType;
+    /**
+     * 设备唯一标识
+     */
+    private String deviceId;
+    /**
+     * 激活时间
+     */
+    private LocalDateTime activationTime;
+    /**
+     * 普通用户到期时间
+     */
+    private LocalDateTime freeExpireTime;
+    /**
+     * 最终到期时间
+     */
+    private LocalDateTime finalExpireTime;
+    /**
+     * 套餐有效期(1:1年)
+     */
+    private Integer plansValidity;
+
+}

+ 5 - 1
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/tuling/ApiResponse.java

@@ -1,12 +1,15 @@
+/*
 package cn.sikey.hmd.api.hmd.tuling;
 
 import lombok.Data;
 
+*/
 /**
  * @Author: qin
  * @Date: 2025/4/21
  * @Description: 响应对象定义
- */
+ *//*
+
 @Data
 public class ApiResponse<T> {
     private Integer code;
@@ -15,3 +18,4 @@ public class ApiResponse<T> {
     private String requestId;
     private String dialog;
 }
+*/

+ 5 - 1
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/tuling/DataRequest.java

@@ -1,14 +1,18 @@
+/*
 package cn.sikey.hmd.api.hmd.tuling;
 
 import lombok.Data;
 
+*/
 /**
  * @Author: qin
  * @Date: 2025/4/21
  * @Description: 数据请求
- */
+ *//*
+
 @Data
 public class DataRequest {
     private String deviceId;
     private Integer level;
 }
+*/

+ 5 - 1
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/tuling/QueryUpgradeRequest.java

@@ -1,12 +1,15 @@
+/*
 package cn.sikey.hmd.api.hmd.tuling;
 
 import lombok.Data;
 
+*/
 /**
  * @Author: qin
  * @Date: 2025/4/21
  * @Description: 请求对象定义
- */
+ *//*
+
 @Data
 public class QueryUpgradeRequest {
     private String data;
@@ -14,3 +17,4 @@ public class QueryUpgradeRequest {
     private String timestamp;
 }
 
+*/

+ 5 - 1
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/tuling/QueryUpgradeResponse.java

@@ -1,12 +1,15 @@
+/*
 package cn.sikey.hmd.api.hmd.tuling;
 
 import lombok.Data;
 
+*/
 /**
  * @Author: qin
  * @Date: 2025/4/21
  * @Description: 升级返回
- */
+ *//*
+
 @Data
 public class QueryUpgradeResponse {
     private String deviceId;
@@ -20,3 +23,4 @@ public class QueryUpgradeResponse {
     private Integer periodOfValidityDay;
     private String expireTime;
 }
+*/

+ 34 - 0
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/vo/activation/UpdateRemainingTimesExpireTimeReqVO.java

@@ -0,0 +1,34 @@
+package cn.sikey.hmd.api.hmd.vo.activation;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+/**
+ * @Author: nelson
+ * @Date: 2025/5/16
+ * @Description: 设备激活
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class UpdateRemainingTimesExpireTimeReqVO {
+    /**
+     * 设备唯一标识
+     */
+    private String deviceId;
+    /**
+     * 普通用户到期时间
+     */
+    private LocalDateTime freeExpireTime;
+    /**
+     * 最终到期时间
+     */
+    private LocalDateTime finalExpireTime;
+    /**
+     * 当前时间
+     */
+    private LocalDateTime now;
+}

+ 1 - 1
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/vo/plans/PlansRespVO.java

@@ -26,7 +26,7 @@ public class PlansRespVO {
      */
     private Integer price;
     /**
-     * 有效期(1:1年2:终身
+     * 有效期(1:1年)
      */
     private Integer validity;
     /**

+ 9 - 12
sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/vo/qr/RemainingTimesExpireTimeRespVO.java → sikey-hmd-business/sikey-hmd-business-api/src/main/java/cn/sikey/hmd/api/hmd/vo/qr/RemainingExpireTimeRespVO.java

@@ -4,17 +4,15 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-import java.util.Date;
-
 /**
  * @Author: qin
  * @Date: 2025/3/31
- * @Description: 过期时间,天数
+ * @Description: 过期时间
  */
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class RemainingTimesExpireTimeRespVO {
+public class RemainingExpireTimeRespVO {
     /**
      * 设备唯一标识
      */
@@ -26,30 +24,29 @@ public class RemainingTimesExpireTimeRespVO {
     /**
      * apiKey
      */
-    private String apiKey;
+    //   private String apiKey;
     /**
      * apiSecret
      */
-    private String apiSecret;
+    //  private String apiSecret;
     /**
      * 二维码内容
      */
-    private String qrcodeContent;
+    //   private String qrcodeContent;
     /**
      * 每天剩余次数(非会员)
      */
-    private Integer remainingTimes;
+    //   private Integer remainingTimes;
     /**
      * 到期时间(会员)
      */
-    private Date expireTime;
+    // private Date expireTime;
     /**
-     * 剩余天数(会员)
+     * 剩余天数
      */
     private Integer remainingDays;
-
     /**
-     * 套餐有效期(1:1年2:终身
+     * 套餐有效期(1:1年)
      */
     private Integer plansValidity;
 }

+ 6 - 0
sikey-hmd-business/sikey-hmd-business-biz/pom.xml

@@ -171,6 +171,12 @@
             <artifactId>sikey-spring-boot-starter-mybatis</artifactId>
         </dependency>
 
+        <!-- Redis 相关 -->
+        <!--<dependency>
+            <groupId>cn.sikey.cloud</groupId>
+            <artifactId>sikey-spring-boot-starter-redis</artifactId>
+        </dependency>-->
+
         <!-- RPC 远程调用相关 -->
         <dependency>
             <groupId>org.springframework.cloud</groupId>

+ 39 - 0
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/api/DeviceActivationApiImpl.java

@@ -0,0 +1,39 @@
+package cn.sikey.hmd.api;
+
+import cn.sikey.framework.common.pojo.CommonResult;
+import cn.sikey.hmd.api.hmd.DeviceActivationApi;
+import cn.sikey.hmd.api.hmd.dto.activation.DeviceActivationDTO;
+import cn.sikey.hmd.api.hmd.vo.activation.UpdateRemainingTimesExpireTimeReqVO;
+import cn.sikey.hmd.enums.ValidityEnum;
+import cn.sikey.hmd.service.activation.DeviceActivationService;
+import jakarta.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 设备激活 API 接口实现类
+ *
+ * @author qin
+ */
+@RestController // 提供 RESTful API 接口,给 Feign 调用
+@Validated
+public class DeviceActivationApiImpl implements DeviceActivationApi {
+
+    @Resource
+    private DeviceActivationService deviceActivationService;
+
+    @Override
+    public CommonResult<Void> updateRemainingTimesExpireTime(@RequestBody @Validated UpdateRemainingTimesExpireTimeReqVO updateRemainingTimesExpireTimeReqVO) {
+        String deviceId = updateRemainingTimesExpireTimeReqVO.getDeviceId();
+        deviceActivationService.updateDeviceActivation(deviceId, updateRemainingTimesExpireTimeReqVO.getFreeExpireTime(),
+                updateRemainingTimesExpireTimeReqVO.getFinalExpireTime(),
+                updateRemainingTimesExpireTimeReqVO.getNow(), ValidityEnum.YEAR.getValue());
+        return CommonResult.success();
+    }
+
+    @Override
+    public CommonResult<DeviceActivationDTO> queryDeviceActivation(String deviceId) {
+        return CommonResult.success(deviceActivationService.queryDeviceActivation(deviceId));
+    }
+}

+ 4 - 6
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/api/QrCodeApiImpl.java

@@ -1,8 +1,6 @@
 package cn.sikey.hmd.api;
 
-import cn.sikey.framework.common.pojo.CommonResult;
 import cn.sikey.hmd.api.hmd.QrCodeApi;
-import cn.sikey.hmd.api.hmd.vo.qr.RemainingTimesExpireTimeRespVO;
 import cn.sikey.hmd.service.qr.QRCodeService;
 import jakarta.annotation.Resource;
 import org.springframework.validation.annotation.Validated;
@@ -20,13 +18,13 @@ public class QrCodeApiImpl implements QrCodeApi {
     @Resource
     private QRCodeService qrCodeService;
 
-    @Override
+    /*@Override
     public CommonResult<Void> updateRemainingTimesExpireTime(String deviceId, String expireTime, int remainingTimes, int plansValidity) {
         return qrCodeService.updateRemainingTimesExpireTime(deviceId, expireTime, remainingTimes, plansValidity);
-    }
+    }*/
 
-    @Override
+    /*@Override
     public CommonResult<RemainingTimesExpireTimeRespVO> queryDeviceQrcodeDOByDeviceId(String deviceId) {
         return CommonResult.success(qrCodeService.queryDeviceQrcodeDOByDeviceId(deviceId));
-    }
+    }*/
 }

+ 5 - 1
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/api/TuLingApiImpl.java

@@ -1,3 +1,4 @@
+/*
 package cn.sikey.hmd.api;
 
 import cn.sikey.framework.common.exception.ServiceException;
@@ -9,11 +10,13 @@ import jakarta.annotation.Resource;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.RestController;
 
+*/
 /**
  * 图灵 API 接口实现类
  *
  * @author qin
- */
+ *//*
+
 @RestController // 提供 RESTful API 接口,给 Feign 调用
 @Validated
 public class TuLingApiImpl implements TuLingApi {
@@ -31,3 +34,4 @@ public class TuLingApiImpl implements TuLingApi {
         return tulingService.getDeviceMenu(deviceId, apiKey, secret);
     }
 }
+*/

+ 4 - 4
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/config/HttpUtil.java

@@ -3,8 +3,8 @@ package cn.sikey.hmd.config;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import cn.sikey.framework.common.exception.ServiceException;
-import cn.sikey.hmd.api.hmd.tuling.ApiResponse;
-import cn.sikey.hmd.api.hmd.tuling.QueryUpgradeResponse;
+// import cn.sikey.hmd.api.hmd.tuling.ApiResponse;
+// import cn.sikey.hmd.api.hmd.tuling.QueryUpgradeResponse;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import okhttp3.*;
@@ -115,7 +115,7 @@ public class HttpUtil {
      * @param json
      * @return
      */
-    public ApiResponse<QueryUpgradeResponse> postRequest(String url, String json) {
+    /*public ApiResponse<QueryUpgradeResponse> postRequest(String url, String json) {
         RequestBody body = RequestBody.create(
                 json, MediaType.parse("application/json; charset=utf-8"));
 
@@ -156,6 +156,6 @@ public class HttpUtil {
         }
 
         return null;
-    }
+    }*/
 
 }

+ 9 - 3
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/config/TuLingConfiguration.java

@@ -1,3 +1,4 @@
+/*
 package cn.sikey.hmd.config;
 
 import cn.sikey.framework.common.exception.ServiceException;
@@ -10,22 +11,26 @@ import org.springframework.context.annotation.Configuration;
 import java.util.HashMap;
 import java.util.Map;
 
+*/
 /**
  * @Author: qin
  * @Date: 2025/3/31
  * @Description: 图灵配置
- */
+ *//*
+
 @Configuration
 @EnableConfigurationProperties({TuLingParamConfig.class})
 @Slf4j
 public class TuLingConfiguration {
 
-    /**
+    */
+/**
      * 初始化多个图灵配置
      *
      * @param tuLingParamConfig 图灵配置
      * @return
-     */
+     *//*
+
     @Bean
     public Map<String, TuLingParamConfig.TuLingConfig> tuLingConfig(TuLingParamConfig tuLingParamConfig) {
         Map<String, TuLingParamConfig.TuLingConfig> map = new HashMap<>();
@@ -41,3 +46,4 @@ public class TuLingConfiguration {
     }
 
 }
+*/

+ 17 - 7
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/config/TuLingParamConfig.java

@@ -1,3 +1,4 @@
+/*
 package cn.sikey.hmd.config;
 
 import lombok.Data;
@@ -5,11 +6,13 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
 
 import java.util.List;
 
+*/
 /**
  * @Author: qin
  * @Date: 2025/3/31
  * @Description: 图灵配置
- */
+ *//*
+
 @ConfigurationProperties(prefix = "tuling")
 @Data
 public class TuLingParamConfig {
@@ -18,17 +21,24 @@ public class TuLingParamConfig {
 
     @Data
     public static class TuLingConfig {
-        /**
+        */
+/**
          * apiType
-         */
+         *//*
+
         private String apiType;
-        /**
+        */
+/**
          * apiKey
-         */
+         *//*
+
         private String apiKey;
-        /**
+        */
+/**
          * apiSecret
-         */
+         *//*
+
         private String apiSecret;
     }
 }
+*/

+ 16 - 0
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/controller/app/activation/DeviceActivationController.java

@@ -0,0 +1,16 @@
+package cn.sikey.hmd.controller.app.activation;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author: qin
+ * @Date: 2025/3/31
+ * @Description: 设备激活
+ */
+@RestController
+@RequestMapping("/activation")
+@Slf4j
+public class DeviceActivationController {
+}

+ 0 - 0
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/controller/app/activation/vo/test.json


+ 20 - 12
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/controller/app/index/PaymentIndexController.java

@@ -3,11 +3,11 @@ package cn.sikey.hmd.controller.app.index;
 import cn.sikey.framework.common.exception.ServiceException;
 import cn.sikey.framework.common.pojo.CommonResult;
 import cn.sikey.hmd.api.hmd.vo.payments.PaymentsRespVO;
-import cn.sikey.hmd.api.hmd.vo.qr.RemainingTimesExpireTimeRespVO;
+import cn.sikey.hmd.api.hmd.vo.plans.PlansRespVO;
 import cn.sikey.hmd.entity.paymentindex.*;
 import cn.sikey.hmd.enums.ValidityEnum;
 import cn.sikey.hmd.service.payments.PaymentService;
-import cn.sikey.hmd.service.qr.QRCodeService;
+import cn.sikey.hmd.service.plans.PlansService;
 import cn.sikey.hmd.util.MapUtil;
 import cn.sikey.hmd.util.PriceUtil;
 import cn.sikey.order.api.order.OrderApi;
@@ -23,7 +23,6 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import java.math.BigDecimal;
-import java.time.Instant;
 import java.util.*;
 
 /**
@@ -46,23 +45,32 @@ public class PaymentIndexController {
     private PaymentService paymentService;
 
     @Resource
-    private QRCodeService qrCodeService;
+    private PlansService plansService;
 
     @GetMapping("/index")
     public String index(String imei, Model model) {
+        PlansRespVO plansRespVO = plansService.queryPlans(ValidityEnum.YEAR.getValue());
+        String price = "0.00";
+        if (Objects.nonNull(plansRespVO)) {
+            price = PriceUtil.convertFenToYuan(plansRespVO.getPrice());
+        }
         model.addAttribute("imei", imei);
         model.addAttribute("serviceInfo", new ServiceInfo("思奇智能AI助手", "现已接入Deep Seek大模型"));
-        model.addAttribute("pricingPlans", getAvailablePlans());
+        //  model.addAttribute("pricingPlans", getAvailablePlans());
+
+        model.addAttribute("yearPrice", price);
+        // 年套餐
+        model.addAttribute("validity", 1);
         model.addAttribute("featureList", getFeatureComparison());
         model.addAttribute("paymentMethods", Arrays.asList(new PaymentMethod("alipay", "支付宝", true), new PaymentMethod("wechat", "微信支付", false)));
-        // 校验套餐有效期(1:1年2:终身)
-        RemainingTimesExpireTimeRespVO remainingTimesExpireTimeRespVO = qrCodeService.queryDeviceQrcodeDOByDeviceId(imei);
 
-        boolean isExpire = Objects.nonNull(remainingTimesExpireTimeRespVO) && Objects.nonNull(remainingTimesExpireTimeRespVO.getPlansValidity()) && remainingTimesExpireTimeRespVO.getPlansValidity().intValue() == ValidityEnum.LIFE_LONG.getValue().intValue();
+        /*DeviceActivationDTO deviceActivationDTO = deviceActivationService.queryDeviceActivation(imei);
+
+        boolean isExpire = Objects.nonNull(deviceActivationDTO) && Objects.nonNull(deviceActivationDTO.getPlansValidity()) && deviceActivationDTO.getPlansValidity().intValue() == ValidityEnum.YEAR.getValue();
         if (isExpire) {
-            log.warn("[手机网站支付-支付宝]您已是终身会员,未过有效期,勿需再支付");
+            log.warn("[手机网站支付-支付宝]您已是会员,未过有效期,勿需再支付");
             return "lifelong";
-        }
+        }*/
 
         return "index";
     }
@@ -129,9 +137,9 @@ public class PaymentIndexController {
         // 使用 LinkedHashMap 保证顺序
         featureList.add(new Feature("专属特权", createOrderedMap("voiceArousal", "语音唤起", "intelligentService", "智能服务", "maximumNumberOfTimes", "次数上限"), false));
 
-        featureList.add(new Feature("普通", createOrderedMap("support", "支持", "tryOut", "试用", "day", "5次/天"), false));
+        featureList.add(new Feature("普通", createOrderedMap("support", "支持", "tryOut", "试用", "day", "100天"), false));
 
-        featureList.add(new Feature("包年", createOrderedMap("support", "支持", "advanced", "高级", "noLimit", "不限次"), false));
+        // featureList.add(new Feature("包年", createOrderedMap("support", "支持", "advanced", "高级", "noLimit", "不限次"), false));
 
         featureList.add(new Feature("VIP", createOrderedMap("support", "支持", "advanced", "高级", "noLimit", "不限次"), true));
 

+ 13 - 5
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/controller/app/qr/QRCodeController.java

@@ -2,7 +2,9 @@ package cn.sikey.hmd.controller.app.qr;
 
 import cn.sikey.framework.common.exception.ServiceException;
 import cn.sikey.framework.common.pojo.CommonResult;
-import cn.sikey.hmd.api.hmd.vo.qr.RemainingTimesExpireTimeRespVO;
+// import cn.sikey.framework.redis.core.enums.RateLimit;
+import cn.sikey.hmd.api.hmd.vo.qr.RemainingExpireTimeRespVO;
+import cn.sikey.hmd.service.activation.DeviceActivationService;
 import cn.sikey.hmd.service.qr.QRCodeService;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
@@ -10,7 +12,6 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpStatus;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 /**
@@ -26,6 +27,9 @@ public class QRCodeController {
     @Resource
     private QRCodeService qrCodeService;
 
+    @Resource
+    private DeviceActivationService deviceActivationService;
+
     /**
      * 生成二维码
      *
@@ -49,14 +53,18 @@ public class QRCodeController {
     }
 
     /**
-     * 查询每天剩余次数,到期时间
+     * 查询到期时间
      *
      * @param deviceId 设备唯一标识
+     * @param apiType  类型
      * @return
      */
     @GetMapping("/queryRemainingTimesExpireTime")
-    public CommonResult<RemainingTimesExpireTimeRespVO> queryRemainingTimesExpireTime(@RequestParam String deviceId) {
-        return qrCodeService.queryRemainingTimesExpireTime(deviceId);
+    public CommonResult<RemainingExpireTimeRespVO> queryRemainingTimesExpireTime(String deviceId, String apiType) {
+        if (StringUtils.isBlank(deviceId) || StringUtils.isBlank(apiType)) {
+            throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "请检查参数");
+        }
+        return deviceActivationService.queryExpireTime(deviceId, apiType);
     }
 
     /**

+ 18 - 0
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/convert/DeviceActivationConvert.java

@@ -0,0 +1,18 @@
+package cn.sikey.hmd.convert;
+
+import cn.sikey.hmd.api.hmd.dto.activation.DeviceActivationDTO;
+import cn.sikey.hmd.dal.dataobject.DeviceActivationDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @Author: nelson
+ * @Date: 2025/5/16
+ * @Description: 设备激活
+ */
+@Mapper
+public interface DeviceActivationConvert {
+    DeviceActivationConvert INSTANCE = Mappers.getMapper(DeviceActivationConvert.class);
+
+    DeviceActivationDTO convertDeviceActivationDTO(DeviceActivationDO deviceActivationDO);
+}

+ 2 - 2
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/convert/QrCodeConvert.java

@@ -1,6 +1,6 @@
 package cn.sikey.hmd.convert;
 
-import cn.sikey.hmd.api.hmd.vo.qr.RemainingTimesExpireTimeRespVO;
+import cn.sikey.hmd.api.hmd.vo.qr.RemainingExpireTimeRespVO;
 import cn.sikey.hmd.controller.app.qr.vo.DeviceQrcodeReqVO;
 
 import cn.sikey.hmd.dal.dataobject.DeviceQrcodeDO;
@@ -14,5 +14,5 @@ public interface QrCodeConvert {
 
     DeviceQrcodeReqVO convertDeviceQrcodeReqVO(DeviceQrcodeDO deviceQrcodeDO);
 
-    RemainingTimesExpireTimeRespVO convertRemainingTimesExpireTimeVO(DeviceQrcodeDO deviceQrcodeDO);
+    RemainingExpireTimeRespVO convertRemainingTimesExpireTimeVO(DeviceQrcodeDO deviceQrcodeDO);
 }

+ 51 - 0
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/dal/dataobject/DeviceActivationDO.java

@@ -0,0 +1,51 @@
+package cn.sikey.hmd.dal.dataobject;
+
+import cn.sikey.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+
+/**
+ * 设备激活
+ *
+ * @author qin
+ */
+@TableName("sw_device_activation")
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class DeviceActivationDO extends BaseDO {
+
+    /**
+     * id
+     */
+    @TableId
+    private Long id;
+    /**
+     * 类型
+     */
+    private String apiType;
+    /**
+     * 设备唯一标识
+     */
+    private String deviceId;
+    /**
+     * 激活时间
+     */
+    private LocalDateTime activationTime;
+    /**
+     * 普通用户到期时间
+     */
+    private LocalDateTime freeExpireTime;
+    /**
+     * 最终到期时间
+     */
+    private LocalDateTime finalExpireTime;
+    /**
+     * 套餐有效期(1:1年)
+     */
+    private Integer plansValidity;
+
+}

+ 3 - 3
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/dal/dataobject/DeviceQrcodeDO.java

@@ -38,14 +38,14 @@ public class DeviceQrcodeDO extends BaseDO {
     /**
      * 每天剩余次数(非会员)
      */
-    private Integer remainingTimes;
+  //  private Integer remainingTimes;
     /**
      * 到期时间(会员)
      */
-    private Date expireTime;
+  //  private Date expireTime;
 
     /**
      * 套餐有效期(1:1年2:终身)
      */
-    private Integer plansValidity;
+ //   private Integer plansValidity;
 }

+ 2 - 2
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/dal/dataobject/PlansDO.java

@@ -22,7 +22,7 @@ public class PlansDO extends BaseDO {
     @TableId
     private Long id;
     /**
-     * 套餐名称(1:包年2:终身
+     * 套餐名称(1:包年)
      */
     private String planName;
     /**
@@ -30,7 +30,7 @@ public class PlansDO extends BaseDO {
      */
     private Integer price;
     /**
-     * 有效期(1:1年2:终身
+     * 有效期(1:1年)
      */
     private Integer validity;
     /**

+ 34 - 0
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/dal/mysql/DeviceActivationMapper.java

@@ -0,0 +1,34 @@
+package cn.sikey.hmd.dal.mysql;
+
+import cn.sikey.hmd.dal.dataobject.DeviceActivationDO;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
+
+/**
+ * 设备激活
+ *
+ * @author qin
+ */
+@Mapper
+public interface DeviceActivationMapper extends BaseMapper<DeviceActivationDO> {
+
+    default DeviceActivationDO queryDeviceActivation(String deviceId) {
+        QueryWrapper<DeviceActivationDO> wrapper = new QueryWrapper<>();
+        wrapper.eq("device_id", deviceId);
+        return selectOne(wrapper);
+    }
+
+    default int updateDeviceActivation(String deviceId, LocalDateTime finalExpireTime,int plansValidity) {
+        UpdateWrapper<DeviceActivationDO> wrapper = new UpdateWrapper<>();
+        wrapper.eq("device_id", deviceId);
+        wrapper.set("final_expire_time", finalExpireTime);
+        wrapper.set("plans_validity", plansValidity);
+        return update(wrapper);
+    }
+}
+
+

+ 13 - 5
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/enums/TulingLevelEnum.java

@@ -1,3 +1,4 @@
+/*
 package cn.sikey.hmd.enums;
 
 import cn.hutool.core.util.ArrayUtil;
@@ -7,13 +8,15 @@ import lombok.Getter;
 
 import java.util.Arrays;
 
+*/
 /**
  * 图灵等级状态
  * 固定值1,2,3 分别对应的是下面这三个套餐
  * (1) 基础包:每天调用次数 ≤ 5次
  * (2)年包: 每天调用次数 > 5次(无限制次数) 启用日期起,365天内有效
  * (3)终身包:每天调用次数 > 5次(无限制次数) 启用日期起,8年使用周期
- */
+ *//*
+
 @AllArgsConstructor
 @Getter
 public enum TulingLevelEnum implements IntArrayValuable {
@@ -22,14 +25,18 @@ public enum TulingLevelEnum implements IntArrayValuable {
 
     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TulingLevelEnum::getValue).toArray();
 
-    /**
+    */
+/**
      * value
-     */
+     *//*
+
     private final Integer value;
 
-    /**
+    */
+/**
      * name
-     */
+     *//*
+
     private final String name;
 
     public static TulingLevelEnum valueOf(Integer value) {
@@ -41,3 +48,4 @@ public enum TulingLevelEnum implements IntArrayValuable {
         return ARRAYS;
     }
 }
+*/

+ 1 - 2
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/enums/ValidityEnum.java

@@ -14,8 +14,7 @@ import java.util.Arrays;
 @Getter
 public enum ValidityEnum implements IntArrayValuable {
 
-    YEAR(1, "年"),
-    LIFE_LONG(2, "终身");
+    YEAR(1, "年");
 
     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ValidityEnum::getValue).toArray();
 

+ 13 - 17
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/AbstractPaymentService.java

@@ -3,13 +3,11 @@ package cn.sikey.hmd.service;
 import cn.hutool.core.util.StrUtil;
 import cn.sikey.framework.common.exception.ServiceException;
 import cn.sikey.framework.common.pojo.CommonResult;
+import cn.sikey.hmd.api.hmd.dto.activation.DeviceActivationDTO;
 import cn.sikey.hmd.api.hmd.vo.payments.PaymentsReqVO;
-import cn.sikey.hmd.api.hmd.vo.qr.RemainingTimesExpireTimeRespVO;
-import cn.sikey.hmd.enums.PayChannelEnum;
 import cn.sikey.hmd.enums.PayStatusEnum;
-import cn.sikey.hmd.enums.ValidityEnum;
+import cn.sikey.hmd.service.activation.DeviceActivationService;
 import cn.sikey.hmd.service.payments.PaymentService;
-import cn.sikey.hmd.service.qr.QRCodeService;
 import cn.sikey.order.api.order.OrderApi;
 import cn.sikey.order.api.order.dto.GenerateOrderReqDTO;
 import cn.sikey.order.api.order.vo.GenerateOrderReqVO;
@@ -17,9 +15,7 @@ import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.http.HttpStatus;
 
-import java.time.Instant;
 import java.time.LocalDateTime;
-import java.util.Date;
 import java.util.Objects;
 
 /**
@@ -30,10 +26,10 @@ import java.util.Objects;
 @Slf4j
 public abstract class AbstractPaymentService {
 
-    private static final Integer VIP_LIFE_LONG = 9999;
+    // private static final Integer VIP_LIFE_LONG = 9999;
 
     @Resource
-    private QRCodeService qrCodeService;
+    private DeviceActivationService deviceActivationService;
 
     @Resource
     private OrderApi orderApi;
@@ -55,18 +51,18 @@ public abstract class AbstractPaymentService {
             throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "请配置商户配置");
         }
 
-        // 校验套餐有效期(1:1年2:终身)
-        RemainingTimesExpireTimeRespVO remainingTimesExpireTimeRespVO = qrCodeService.queryDeviceQrcodeDOByDeviceId(deviceId);
-        if (Objects.isNull(remainingTimesExpireTimeRespVO)) {
-            log.warn("[手机网站支付-{}]不存在设备二维码信息", payType);
-            throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "不存在设备二维码信息");
+        // 校验设备激活
+        DeviceActivationDTO deviceActivationDTO = deviceActivationService.queryDeviceActivation(deviceId);
+        if (Objects.isNull(deviceActivationDTO)) {
+            log.warn("[手机网站支付-{}]设备还未激活", payType);
+            throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "设备还未激活");
         }
 
-        boolean isExpire = Objects.nonNull(remainingTimesExpireTimeRespVO.getPlansValidity()) && remainingTimesExpireTimeRespVO.getPlansValidity().intValue() == ValidityEnum.LIFE_LONG.getValue().intValue();
+        /*boolean isExpire = Objects.nonNull(remainingTimesExpireTimeRespVO.getPlansValidity()) && remainingTimesExpireTimeRespVO.getPlansValidity().intValue() == ValidityEnum.YEAR.getValue().intValue();
         if (isExpire) {
-            log.warn("[手机网站支付-{}]您已是终身会员,勿需再支付", payType);
-            throw new ServiceException(VIP_LIFE_LONG, "您已是终身会员,勿需再支付");
-        }
+            log.warn("[手机网站支付-{}]您已是会员,勿需再支付", payType);
+            throw new ServiceException(VIP_LIFE_LONG, "您已是会员,勿需再支付");
+        }*/
     }
 
     /**

+ 24 - 0
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/activation/DeviceActivationService.java

@@ -0,0 +1,24 @@
+package cn.sikey.hmd.service.activation;
+
+import cn.sikey.framework.common.pojo.CommonResult;
+import cn.sikey.hmd.api.hmd.dto.activation.DeviceActivationDTO;
+import cn.sikey.hmd.api.hmd.vo.qr.RemainingExpireTimeRespVO;
+
+import java.time.LocalDateTime;
+
+/**
+ * @Author: qin
+ * @Date: 2025/3/31
+ * @Description: 设备激活
+ */
+public interface DeviceActivationService {
+
+    // 首次激活设备,免费天数
+    int REMAINING_FREE_DAYS = 100;
+
+    void updateDeviceActivation(String deviceId, LocalDateTime freeExpireTime, LocalDateTime finalExpireTime, LocalDateTime now, int plansValidity);
+
+    CommonResult<RemainingExpireTimeRespVO> queryExpireTime(String deviceId, String apiType);
+
+    DeviceActivationDTO queryDeviceActivation(String deviceId);
+}

+ 114 - 0
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/activation/DeviceActivationServiceImpl.java

@@ -0,0 +1,114 @@
+package cn.sikey.hmd.service.activation;
+
+import cn.sikey.framework.common.pojo.CommonResult;
+import cn.sikey.hmd.api.hmd.dto.activation.DeviceActivationDTO;
+import cn.sikey.hmd.api.hmd.vo.qr.RemainingExpireTimeRespVO;
+import cn.sikey.hmd.convert.DeviceActivationConvert;
+import cn.sikey.hmd.dal.dataobject.DeviceActivationDO;
+import cn.sikey.hmd.dal.mysql.DeviceActivationMapper;
+import cn.sikey.hmd.util.DateToolUtil;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.Objects;
+
+/**
+ * @Author: qin
+ * @Date: 2025/3/31
+ * @Description: 设备激活
+ */
+@Service
+@Slf4j
+public class DeviceActivationServiceImpl implements DeviceActivationService {
+
+    @Resource
+    private DeviceActivationMapper deviceActivationMapper;
+
+    /**
+     * 更新设备激活
+     *
+     * @param deviceId        设备编码
+     * @param freeExpireTime  普通用户到期时间
+     * @param finalExpireTime 最终到期时间
+     * @param now             现在时间
+     * @param plansValidity   套餐
+     * @return
+     */
+    @Override
+    public void updateDeviceActivation(String deviceId, LocalDateTime freeExpireTime,
+                                       LocalDateTime finalExpireTime,
+                                       LocalDateTime now, int plansValidity) {
+        // 最终时间
+        LocalDateTime fExpireTime = DateToolUtil.calculateFinalExpireTime(freeExpireTime, finalExpireTime, now);
+        log.info("[更新设备激活]设备编码:{},普通用户到期时间:{},原最终到期时间:{}", deviceId, freeExpireTime, finalExpireTime);
+        deviceActivationMapper.updateDeviceActivation(deviceId, fExpireTime, plansValidity);
+        log.info("[更新设备激活]更新数据库成功,设备编码:{},普通用户到期时间:{},最终到期时间:{}", deviceId, freeExpireTime, fExpireTime);
+    }
+
+    /**
+     * 查询到期时间
+     *
+     * @param deviceId 设备唯一标识
+     * @param apiType  类型
+     * @return
+     */
+    @Override
+    public CommonResult<RemainingExpireTimeRespVO> queryExpireTime(String deviceId, String apiType) {
+        DeviceActivationDO deviceActivationDO = deviceActivationMapper.queryDeviceActivation(deviceId);
+
+        RemainingExpireTimeRespVO remainingTimesExpireTimeVO = new RemainingExpireTimeRespVO();
+        int remainingDays;
+        if (Objects.isNull(deviceActivationDO)) {
+            // 激活设备 TODO 多次需限流,幂等
+            saveDeviceActivation(deviceId, apiType);
+            remainingDays = REMAINING_FREE_DAYS;
+        } else {
+            // 已激活设备
+            DeviceActivationDTO deviceActivationDTO = DeviceActivationConvert.INSTANCE.convertDeviceActivationDTO(deviceActivationDO);
+
+            LocalDateTime finalExpireTime = deviceActivationDTO.getFinalExpireTime();
+            remainingDays = DateToolUtil.calculateRemainingDays(finalExpireTime);
+            int plansValidity = deviceActivationDTO.getPlansValidity();
+            remainingTimesExpireTimeVO.setPlansValidity(plansValidity);
+        }
+
+        remainingTimesExpireTimeVO.setRemainingDays(remainingDays);
+
+
+        log.info("[查询到期时间]返回结果:{}", remainingTimesExpireTimeVO);
+        return CommonResult.success(remainingTimesExpireTimeVO);
+    }
+
+    @Override
+    public DeviceActivationDTO queryDeviceActivation(String deviceId) {
+        DeviceActivationDO deviceActivationDO = deviceActivationMapper.queryDeviceActivation(deviceId);
+        return DeviceActivationConvert.INSTANCE.convertDeviceActivationDTO(deviceActivationDO);
+    }
+
+    /**
+     * 保存设备激活
+     *
+     * @param deviceId 设备编码
+     * @param apiType  乐行
+     */
+    private void saveDeviceActivation(String deviceId, String apiType) {
+        LocalDateTime now = LocalDateTime.now();
+        DeviceActivationDO deviceActivationDO = new DeviceActivationDO();
+        deviceActivationDO.setDeviceId(deviceId);
+        deviceActivationDO.setApiType(apiType);
+        // 激活时间
+        deviceActivationDO.setActivationTime(now);
+        // 普通用户到期时间
+        deviceActivationDO.setFreeExpireTime(DateToolUtil.calculateFutureDate(REMAINING_FREE_DAYS, now));
+        // 最终到期时间
+        deviceActivationDO.setFinalExpireTime(DateToolUtil.calculateFutureDate(REMAINING_FREE_DAYS, now));
+        deviceActivationDO.setCreator(deviceId);
+        deviceActivationDO.setCreateTime(now);
+        deviceActivationDO.setUpdater(deviceId);
+        deviceActivationDO.setUpdateTime(now);
+        deviceActivationMapper.insert(deviceActivationDO);
+    }
+
+}

+ 1 - 1
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/alipay/AlipayPaymentServiceImpl.java

@@ -73,7 +73,7 @@ public class AlipayPaymentServiceImpl extends AbstractPaymentService implements
                         // 保存支付记录
                         savePayments(checkPayReqVO.getOrderId(), checkPayReqVO.getPlansId(), deviceId, checkPayReqVO.getAmount(), PayChannelEnum.ALI_PAY.getValue(), merchantProjectApplication);
                     } catch (Exception e) {
-                        log.error("[手机网站支付-支付宝,回调]编程时事务异常:{0}", e);
+                        log.error("[手机网站支付-支付宝]编程时事务异常:{0}", e);
                         status.setRollbackOnly(); // 标记回滚
                         throw e; // 抛出异常,确保事务回滚
                     }

+ 4 - 11
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/qr/QRCodeService.java

@@ -2,8 +2,6 @@ package cn.sikey.hmd.service.qr;
 
 import cn.sikey.framework.common.pojo.CommonResult;
 
-import cn.sikey.hmd.api.hmd.vo.qr.RemainingTimesExpireTimeRespVO;
-
 /**
  * @Author: qin
  * @Date: 2025/3/31
@@ -13,13 +11,8 @@ public interface QRCodeService {
 
     CommonResult<String> generateQRCode(String deviceId, String apiType);
 
-    CommonResult<RemainingTimesExpireTimeRespVO> queryRemainingTimesExpireTime(String deviceId);
-
-//    CommonResult<Void> updateRemainingTimes(UpdateRemainingTimesReqVO updateRemainingTimesReqVO);
-
-    CommonResult<Void> updateRemainingTimesExpireTime(String deviceId, String expireTime,int remainingTimes, int plansValidity);
-
-//    void updateDeviceQrcode(UpdateDeviceQrcodeReqVO updateDeviceQrcodeReqVO);
-
-    RemainingTimesExpireTimeRespVO queryDeviceQrcodeDOByDeviceId(String deviceId);
+    /*CommonResult<Void> updateRemainingTimesExpireTime(String deviceId, String expireTime, int remainingTimes, int plansValidity);
+    CommonResult<Void> updateRemainingTimes(UpdateRemainingTimesReqVO updateRemainingTimesReqVO);
+    void updateDeviceQrcode(UpdateDeviceQrcodeReqVO updateDeviceQrcodeReqVO);
+    RemainingTimesExpireTimeRespVO queryDeviceQrcodeDOByDeviceId(String deviceId);*/
 }

+ 14 - 23
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/qr/QRCodeServiceImpl.java

@@ -1,20 +1,14 @@
 package cn.sikey.hmd.service.qr;
 
 import cn.sikey.framework.common.pojo.CommonResult;
-import cn.sikey.hmd.api.hmd.vo.qr.RemainingTimesExpireTimeRespVO;
-import cn.sikey.hmd.config.TuLingParamConfig;
-import cn.sikey.hmd.convert.QrCodeConvert;
 import cn.sikey.hmd.dal.dataobject.DeviceQrcodeDO;
 import cn.sikey.hmd.dal.mysql.DeviceQrcodeMapper;
-import cn.sikey.hmd.service.tuling.TuLingService;
-import cn.sikey.hmd.util.DateToolUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -32,11 +26,8 @@ public class QRCodeServiceImpl implements QRCodeService {
     @Value("${qrcode.url}")
     private String url;
 
-    @Resource
-    private Map<String, TuLingParamConfig.TuLingConfig> tuLingConfigs;
-
-    @Resource
-    private TuLingService tulingService;
+    /*@Resource
+    private Map<String, TuLingParamConfig.TuLingConfig> tuLingConfigs;*/
 
     /**
      * 二维码
@@ -68,37 +59,37 @@ public class QRCodeServiceImpl implements QRCodeService {
     }
 
     /**
-     * 查询每天剩余次数,到期时间
+     * 查询剩余次数,到期时间
      *
      * @param deviceId 设备唯一标识
+     * @param apiType  类型
      * @return
      */
     // @Transactional(rollbackFor = Exception.class)
-    @Override
-    public CommonResult<RemainingTimesExpireTimeRespVO> queryRemainingTimesExpireTime(String deviceId) {
-        //  deviceQrcodeMapper.resetIfNeeded(deviceId);
+    /*@Override
+    public CommonResult<RemainingExpireTimeRespVO> queryRemainingTimesExpireTime(String deviceId, String apiType) {
         DeviceQrcodeDO deviceQrcodeDO = deviceQrcodeMapper.queryByDeviceId(deviceId);
         RemainingTimesExpireTimeRespVO remainingTimesExpireTimeVO = null;
         if (Objects.nonNull(deviceQrcodeDO)) {
             remainingTimesExpireTimeVO = QrCodeConvert.INSTANCE.convertRemainingTimesExpireTimeVO(deviceQrcodeDO);
             int remainingDays = 0;
-            /*if (Objects.isNull(remainingTimesExpireTimeVO.getPlansValidity()) && Objects.nonNull(remainingTimesExpireTimeVO.getRemainingDays())) {
+            *//*if (Objects.isNull(remainingTimesExpireTimeVO.getPlansValidity()) && Objects.nonNull(remainingTimesExpireTimeVO.getRemainingDays())) {
                 // 普通用户
                 remainingDays = remainingTimesExpireTimeVO.getRemainingDays();
             } else {
                 // 会员用户
                 remainingDays = DateToolUtil.calculateRemainingDays(remainingTimesExpireTimeVO.getExpireTime());
-            }*/
+            }
 
             if (Objects.nonNull(remainingTimesExpireTimeVO.getPlansValidity())) {
                 // 会员用户
-                remainingDays = DateToolUtil.calculateRemainingDays(remainingTimesExpireTimeVO.getExpireTime());
+                remainingDays = DateTolUtil.calculateRemainingDays(remainingTimesExpireTimeVO.getExpireTime());
             }
             remainingTimesExpireTimeVO.setRemainingDays(remainingDays);
         }
         log.info("[查询每天剩余次数,到期时间]设备编码:{},返回数据:{}", deviceId, deviceQrcodeDO);
         return CommonResult.success(remainingTimesExpireTimeVO);
-    }
+    }*/
 
     /**
      * 更新剩余次数
@@ -125,11 +116,11 @@ public class QRCodeServiceImpl implements QRCodeService {
      * @param expireTime 有效期
      * @return
      */
-    @Override
+    /*@Override
     public CommonResult<Void> updateRemainingTimesExpireTime(String deviceId, String expireTime, int remainingTimes, int plansValidity) {
         deviceQrcodeMapper.updateRemainingTimesExpireTime(deviceId, expireTime, remainingTimes, plansValidity);
         return CommonResult.success();
-    }
+    }*/
 
     /**
      * 更新设备二维码
@@ -148,7 +139,7 @@ public class QRCodeServiceImpl implements QRCodeService {
      * @param deviceId 设备编码
      * @return
      */
-    @Override
+    /*@Override
     public RemainingTimesExpireTimeRespVO queryDeviceQrcodeDOByDeviceId(String deviceId) {
         DeviceQrcodeDO deviceQrcodeDO = deviceQrcodeMapper.queryByDeviceId(deviceId);
         RemainingTimesExpireTimeRespVO remainingTimesExpireTimeVO = null;
@@ -170,6 +161,6 @@ public class QRCodeServiceImpl implements QRCodeService {
             remainingTimesExpireTimeVO.setApiSecret(apiSecret);
         }
         return remainingTimesExpireTimeVO;
-    }
+    }*/
 
 }

+ 9 - 3
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/tuling/TuLingService.java

@@ -1,3 +1,4 @@
+/*
 package cn.sikey.hmd.service.tuling;
 
 import cn.sikey.hmd.api.hmd.tuling.ApiResponse;
@@ -8,18 +9,21 @@ import cn.sikey.hmd.util.AESUtil;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.stereotype.Service;
 
+*/
 /**
  * @Author: qin
  * @Date: 2025/4/21
  * @Description: 升级
- */
+ *//*
+
 @Service
 public interface TuLingService {
     ApiResponse<QueryUpgradeResponse> upgradeDevice(String deviceId, Integer level,String apiKey, String secret);
 
     ApiResponse<QueryUpgradeResponse> getDeviceMenu(String deviceId,String apiKey, String secret);
 
-    /**
+    */
+/**
      * 设置请求参数
      *
      * @param dataRequest 数据请求
@@ -27,7 +31,8 @@ public interface TuLingService {
      * @param apiKey      key
      * @return
      * @throws Exception
-     */
+     *//*
+
     default QueryUpgradeRequest setRequest(DataRequest dataRequest, String secret, String apiKey) throws Exception {
         // AES加密
         String encryptedData = AESUtil.encrypt(
@@ -43,3 +48,4 @@ public interface TuLingService {
     }
 
 }
+*/

+ 21 - 9
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/service/tuling/TuLingServiceImpl.java

@@ -1,3 +1,4 @@
+/*
 package cn.sikey.hmd.service.tuling;
 
 import cn.hutool.json.JSONUtil;
@@ -13,11 +14,13 @@ import org.apache.http.HttpStatus;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+*/
 /**
  * @Author: qin
  * @Date: 2025/4/21
  * @Description: 调用图灵API
- */
+ *//*
+
 @Slf4j
 @Service
 public class TuLingServiceImpl implements TuLingService {
@@ -31,16 +34,21 @@ public class TuLingServiceImpl implements TuLingService {
     @Value("${tuling.getDeviceMenuPath}")
     private String getDeviceMenuPath;
 
-    /*@Value("${tuling.apiKey}")
-    private String apiKey;*/
+    */
+/*@Value("${tuling.apiKey}")
+    private String apiKey;*//*
+
+
+    */
+/*@Value("${tuling.secret}")
+    private String secret;*//*
 
-    /*@Value("${tuling.secret}")
-    private String secret;*/
 
     @Resource
     private HttpUtil httpUtil;
 
-    /**
+    */
+/**
      * 升级
      *
      * @param deviceId 设备编号
@@ -53,7 +61,8 @@ public class TuLingServiceImpl implements TuLingService {
      *                 (2)年包: 每天调用次数 > 5次(无限制次数) 启用日期起,365天内有效
      *                 (3)终身包:每天调用次数 > 5次(无限制次数) 启用日期起,8年使用周期
      * @return
-     */
+     *//*
+
     @Override
     public ApiResponse<QueryUpgradeResponse> upgradeDevice(String deviceId, Integer level, String apiKey, String secret) {
         try {
@@ -71,14 +80,16 @@ public class TuLingServiceImpl implements TuLingService {
         }
     }
 
-    /**
+    */
+/**
      * 获取设备菜单
      *
      * @param deviceId 设备编号
      * @param apiKey   apiKey
      * @param secret   secret
      * @return
-     */
+     *//*
+
     @Override
     public ApiResponse<QueryUpgradeResponse> getDeviceMenu(String deviceId, String apiKey, String secret) {
         try {
@@ -96,3 +107,4 @@ public class TuLingServiceImpl implements TuLingService {
     }
 
 }
+*/

+ 57 - 17
sikey-hmd-business/sikey-hmd-business-biz/src/main/java/cn/sikey/hmd/util/DateToolUtil.java

@@ -1,14 +1,14 @@
 package cn.sikey.hmd.util;
 
-import cn.hutool.core.date.DateTime;
-import cn.hutool.core.date.DateUnit;
-import cn.hutool.core.date.DateUtil;
+import cn.sikey.framework.common.exception.ServiceException;
 import lombok.experimental.UtilityClass;
+import org.apache.http.HttpStatus;
 
 import java.time.Instant;
+import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
-import java.util.Date;
+import java.time.temporal.ChronoUnit;
 
 /**
  * @Author: qin
@@ -19,26 +19,23 @@ import java.util.Date;
 public class DateToolUtil {
 
     /**
-     * 剩余天数
+     * 剩余天数计算
      *
-     * @param expireDate 过期日期
-     * @return
+     * @param expireDateTime 过期日期时间
+     * @return 剩余天数
      */
-    public static int calculateRemainingDays(Date expireDate) {
-        if (expireDate == null) {
+    public static int calculateRemainingDays(LocalDateTime expireDateTime) {
+        if (expireDateTime == null) {
             return 0;
         }
-        Date nowDate = Date.from(Instant.now());
 
-        // 获取两个日期的开始时间(零点)
-        DateTime expireStart = DateUtil.beginOfDay(expireDate);
-        DateTime nowStart = DateUtil.beginOfDay(nowDate);
+        LocalDateTime now = LocalDateTime.now();
+        LocalDateTime expireStart = expireDateTime.truncatedTo(ChronoUnit.DAYS);
+        LocalDateTime nowStart = now.truncatedTo(ChronoUnit.DAYS);
 
-        // 计算天数差,若expireStart在nowStart之后,则差值为正
-        long days = DateUtil.between(nowStart, expireStart, DateUnit.DAY, false);
+        long days = ChronoUnit.DAYS.between(nowStart, expireStart);
 
-        // 剩余天数不能为负数
-        return Math.max((int) days, 0);
+        return (int) Math.max(days, 0);
     }
 
     /**
@@ -53,4 +50,47 @@ public class DateToolUtil {
         return zonedDateTime.plusYears(year).toInstant();
     }
 
+    /**
+     * 计算几天后的未来日期
+     *
+     * @param totalFreeDays 天数
+     * @param localDateTime 当前日期
+     * @return
+     */
+    public static LocalDateTime calculateFutureDate(Integer totalFreeDays, LocalDateTime localDateTime) {
+        if (totalFreeDays == null || totalFreeDays < 0 || localDateTime == null) {
+            throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "参数总免费天数,当前日期有误");
+        }
+
+        return localDateTime.plusDays(totalFreeDays);
+    }
+
+    /**
+     * 计算最终到期时间
+     *
+     * @param freeExpireTime  普通用户过期时间
+     * @param finalExpireTime 最终过期时间
+     * @param now             当前时间
+     * @return
+     */
+    public static LocalDateTime calculateFinalExpireTime(LocalDateTime freeExpireTime,
+                                                         LocalDateTime finalExpireTime,
+                                                         LocalDateTime now) {
+        // 首次购买VIP(通过时间戳相等性判断)
+        if (freeExpireTime.isEqual(finalExpireTime)) {
+            // 处理普通用户剩余权益
+            if (freeExpireTime.isAfter(now)) {
+                long remainingDays = ChronoUnit.DAYS.between(now, freeExpireTime);
+                return now.plusYears(1).plusDays(remainingDays);
+            }
+            // 统一处理过期逻辑(包含当天过期)
+            return now.plusYears(1);
+        }
+
+        // 非首次购买VIP(直接续期逻辑)
+        return finalExpireTime.isBefore(now)
+                ? now.plusYears(1)                // 已过期:从当前时间续期
+                : finalExpireTime.plusYears(1);    // 未过期:延续原有效期
+    }
+
 }

+ 30 - 21
sikey-hmd-business/sikey-hmd-business-biz/src/main/resources/application.yml

@@ -152,32 +152,41 @@ tcmPulseDiagnosis:
   url: http://api.tecanswer.com/trade/api/v1/alipay/gateway
 
 # 图灵
-tuling:
-  url: http://stat.turingos.cn
-  upgradeDevicePath: /open/deviceManage/upgradeDeviceMenu
-  getDeviceMenuPath: /open/deviceManage/getDeviceMenu
+#tuling:
+ # url: http://stat.turingos.cn
+  #upgradeDevicePath: /open/deviceManage/upgradeDeviceMenu
+ # getDeviceMenuPath: /open/deviceManage/getDeviceMenu
   #  apiKey: 5af60716dc0847018da04bdcc248abb4
   # secret: c0N0459vI9x0N09Z
 
 ---
 # 图灵
-tuling:
-  apiKeys:
-    - apiType: wonka
-      apiKey: 4407e3dc086c42b080d78c5a40c500bb
-      apiSecret: 455zyq968Sk5qg65
-    - apiType: leia
-      apiKey: 003d3becbb6b48a7947231770e5da3ca
-      apiSecret: N3IN8Sxp80i16tTi
-    - apiType: skywal
-      apiKey: f90aabf8a48d4eaba79c54d1a202534a
-      apiSecret: 7LL7f8oJa69n7mB8
-    - apiType: fcb
-      apiKey: 5af60716dc0847018da04bdcc248abb4
-      apiSecret: c0N0459vI9x0N09Z
-
-
-
+#tuling:
+ # apiKeys:
+ #   - apiType: wonka
+ #     apiKey: 4407e3dc086c42b080d78c5a40c500bb
+ #     apiSecret: 455zyq968Sk5qg65
+ #   - apiType: leia
+ #     apiKey: 003d3becbb6b48a7947231770e5da3ca
+ #     apiSecret: N3IN8Sxp80i16tTi
+ #   - apiType: skywal
+ #     apiKey: f90aabf8a48d4eaba79c54d1a202534a
+  #    apiSecret: 7LL7f8oJa69n7mB8
+ #   - apiType: fcb
+  #    apiKey: 5af60716dc0847018da04bdcc248abb4
+  #    apiSecret: c0N0459vI9x0N09Z
+
+
+# Spring Data Redis 配置
+#spring:
+  #data:
+  #  redis:
+   #   repositories:
+   #     enabled: true
+   #   host: 106.75.230.4
+   #   port: 6379
+   #   password: sikey!Q@W#E456
+  #    timeout: 5000
 
 ---
 #熔断器配置

+ 30 - 20
sikey-hmd-business/sikey-hmd-business-biz/src/main/resources/templates/index.html

@@ -24,7 +24,7 @@
         /* 容器样式 */
         .container {
             /*max-width: 600px;*/
-            margin: 170px auto;
+            margin: -20% auto;
             background: #F5F5F5;
             border-radius: 15px;
             box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
@@ -32,7 +32,7 @@
             position: relative;
             top: 10%;
             width: 100%;
-            height: 111%;
+            height: 96%;
         }
 
         /* 页头区域 */
@@ -166,7 +166,7 @@
 
         .feature-grid_out {
             display: grid;
-            grid-template-columns: 2fr repeat(3, 1fr);
+            grid-template-columns: 2fr repeat(2, 1fr);
             gap: 1px;
             background: #FFFFFF;
             margin: 0.8rem;
@@ -608,16 +608,18 @@
         </div>
     </header>
 
-    <div class="middle">
+    <!--<div class="middle">
         <img th:src="@{/images/开通终身服务超级划算背景.png}" alt="AI助手" class="middle_picture">
         <div>
             <img th:src="@{/images/红包.png}" alt="AI助手" class="middle_red_envelope">
         </div>
         <div class="text">开通终身服务超级划算</div>
-    </div>
+    </div>-->
 
-    <!-- 价格套餐动态渲染 -->
-    <section class="price-cards">
+    <!-- 年套餐价格 -->
+    <input type="hidden" class="yearPrice" th:value="${yearPrice}"/>
+
+    <!--<section class="price-cards">
         <div th:each="plan : ${pricingPlans}" class="price-card" onclick="selectPlan(this)">
             <p>
                 <input type="hidden" class="priceCard" th:value="${plan.type}"/>
@@ -625,7 +627,7 @@
                 <span th:text="${plan.price}" class="price price-number"></span>元
             </p>
         </div>
-    </section>
+    </section>-->
 
     <!-- 功能对比表动态生成 -->
     <section class="feature-grid_out">
@@ -704,10 +706,10 @@
             </div>
         </div>-->
         <div class="background-container">
-            <div class="price-display"><span class="price-number">0.0</span>元/年</div>
+            <div class="price-display"><span class="price-number"></span>元/年</div>
             <button class="purchase-button" id="purchase-button">立即购买</button>
         </div>
-        <input class="price-display-price" type="hidden"/>
+        <input class="validity" type="hidden" th:value="${validity}"/>
 
         <!-- 在background-container下方添加联系客服链接 -->
         <div class="contact-service"
@@ -821,7 +823,7 @@
 
 <script>
     // 获取选择的套餐
-    function selectPlan(clickedElement) {
+    /*function selectPlan(clickedElement) {
         // 1. 移除所有卡片的选中样式(通过删除 CSS 类名)
         const allCards = document.querySelectorAll('.price-card');
         allCards.forEach(card => card.classList.remove('selected'));
@@ -844,7 +846,7 @@
         priceDisplay.innerHTML = `
     <span class="price-number">${price}</span>
     <span class="price-unit">${unit}</span>`;
-    }
+    }*/
 
     // 定义获取付费方式的函数
     function getSelectedPayment() {
@@ -862,15 +864,23 @@
         const purchaseButton = document.getElementById('purchase-button');
         const errorTip = document.getElementById('errorTip');
 
+        const yearPrice = document.querySelector('.yearPrice').value;
+        const priceDisplay = document.querySelector('.price-display'); // 使用 querySelector 直接获取元素
+        // priceDisplay.textContent = `${yearPrice}`;  // 使用 textContent 修改内容
+        // 使用模板字符串构建带样式的HTML
+        priceDisplay.innerHTML = `
+    <span class="price-number">${yearPrice}</span>
+    <span class="price-unit">元/年</span>`;
+
         // 表单验证函数
         function validateForm() {
             let errors = [];
 
             // 1. 校验套餐选择
-            const selectedPlan = document.querySelector('.price-card.selected');
+            /*const selectedPlan = document.querySelector('.price-card.selected');
             if (!selectedPlan) {
                 errors.push("请选择套餐类型(包年或终身服务)");
-            }
+            }*/
 
             // 2. 校验支付方式
             const paymentSelected = document.querySelector('input[name="payment"]:checked');
@@ -914,14 +924,14 @@
                 // 获取单个参数
                 const imei = params.get('imei');
 
+                const validity = document.querySelector('.validity').value;
+
                 if (paymentMethod === 'alipay') {
                     path = "/app-api/hmd/alipay/alipayTradeWapPay";
                     const pathWithDomain = urlObj.origin + path;
-                    const priceInput = document.querySelector('.price-display-price');
-
                     const responseHtml = axios.get(pathWithDomain, {
                         params: {
-                            validity: priceInput.value,
+                            validity: validity,
                             deviceId: imei,
                             subject: '思奇智能AI助手',
                             merchantProjectApplication: '1:hmd:1'
@@ -951,7 +961,7 @@
                     const pathWithDomain = urlObj.origin + path;
                     const responseHtml = axios.get(pathWithDomain, {
                         params: {
-                            validity: document.querySelector('.priceCard').value,
+                            validity: validity,
                             deviceId: imei,
                             description: '思奇智能AI助手',
                             merchantProjectApplication: '1:hmd:2'
@@ -1038,7 +1048,7 @@
     }
 
     // 复制功能
-    document.getElementById('copy-email').addEventListener('click', function() {
+    document.getElementById('copy-email').addEventListener('click', function () {
         const email = 'service@sikey.com.cn';
 
         // 现代浏览器方案
@@ -1077,7 +1087,7 @@
 
         try {
             const successful = document.execCommand('copy');
-            if(successful) {
+            if (successful) {
                 showCopyFeedback('✓ 已复制');
             } else {
                 showErrorFeedback();