瀏覽代碼

feat(purchase): 付费墙拦截+前端API+页面注册

Sisyphus 4 周之前
父節點
當前提交
e84a5bb775

+ 10 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/HealthPlanController.java

@@ -1,6 +1,7 @@
 package com.etotem.cfc.controller;
 
 import com.etotem.cfc.common.Result;
+import com.etotem.cfc.service.PurchaseService;
 import com.etotem.cfc.entity.HealthPlan;
 import com.etotem.cfc.service.HealthPlanService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -20,11 +21,20 @@ public class HealthPlanController {
     @Resource
     private HealthPlanService healthPlanService;
 
+    @Resource
+    private com.etotem.cfc.service.PurchaseService purchaseService;
+
     @Operation(summary = "生成健康方案(文本)")
     @PostMapping("/generate")
     public Result<String> generate(@RequestBody Map<String, Object> params,
                                    @RequestAttribute("userId") Long userId,
                                    @RequestAttribute(value = "familyId", required = false) Long familyId) {
+        // 付费墙拦截
+        java.util.Map<String, Object> purchaseCheck = purchaseService.checkPurchase(userId);
+        if (!Boolean.TRUE.equals(purchaseCheck.get("isActive"))) {
+            return Result.error("请先购买健康启航计划体验包");
+        }
+        
         String memberIds = (String) params.get("memberIds");
         String dimensions = (String) params.get("dimensions");
         String goal = (String) params.get("goal");

+ 10 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/HealthReportController.java

@@ -1,6 +1,7 @@
 package com.etotem.cfc.controller;
 
 import com.etotem.cfc.common.Result;
+import com.etotem.cfc.service.PurchaseService;
 import com.etotem.cfc.dto.HealthAnalysisResult;
 import com.etotem.cfc.dto.MemberMatchResult;
 import com.etotem.cfc.dto.ParsedDiseaseRisk;
@@ -155,6 +156,9 @@ public class HealthReportController {
     @Resource
     private ReportBlockAssembler reportBlockAssembler;
 
+    @Resource
+    private com.etotem.cfc.service.PurchaseService purchaseService;
+
     /**
      * 创建健康报告(含指标明细)
      */
@@ -166,6 +170,12 @@ public class HealthReportController {
             @RequestAttribute(value = "familyId", required = false) Long familyId,
             @RequestAttribute(value = "currentMemberId", required = false) Long currentMemberId) {
 
+        // 付费墙拦截:检查是否购买健康启航计划
+        java.util.Map<String, Object> purchaseCheck = purchaseService.checkPurchase(userId);
+        if (!Boolean.TRUE.equals(purchaseCheck.get("isActive"))) {
+            return Result.error("请先购买健康启航计划体验包");
+        }
+
         if (familyId == null) {
             return Result.noFamily("请先创建或加入家庭");
         }

+ 100 - 0
cfc-frontend/utils/api.js

@@ -2605,3 +2605,103 @@ export const sttTranscribe = (filePath) => {
     })
   })
 }
+
+// 健康启航计划
+export function checkPurchase() {
+  return new Promise((resolve, reject) => {
+    const token = uni.getStorageSync('token')
+    uni.request({
+      url: config.API_BASE_URL + '/api/purchase/check',
+      method: 'POST',
+      data: {},
+      header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
+      success: (res) => {
+        if (res.data && res.data.code === 200) {
+          resolve(res.data)
+        } else {
+          reject(res.data || { code: -1, message: '检查购买状态失败' })
+        }
+      },
+      fail: (err) => reject(err)
+    })
+  })
+}
+
+export function createPurchaseOrder() {
+  return new Promise((resolve, reject) => {
+    const token = uni.getStorageSync('token')
+    uni.request({
+      url: config.API_BASE_URL + '/api/purchase/create',
+      method: 'POST',
+      data: {},
+      header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
+      success: (res) => {
+        if (res.data && res.data.code === 200) {
+          resolve(res.data)
+        } else {
+          reject(res.data || { code: -1, message: '创建订单失败' })
+        }
+      },
+      fail: (err) => reject(err)
+    })
+  })
+}
+
+export function confirmPurchase(data) {
+  return new Promise((resolve, reject) => {
+    const token = uni.getStorageSync('token')
+    uni.request({
+      url: config.API_BASE_URL + '/api/purchase/confirm',
+      method: 'POST',
+      data: data,
+      header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
+      success: (res) => {
+        if (res.data && res.data.code === 200) {
+          resolve(res.data)
+        } else {
+          reject(res.data || { code: -1, message: '确认支付失败' })
+        }
+      },
+      fail: (err) => reject(err)
+    })
+  })
+}
+
+export function getRenewalInfo() {
+  return new Promise((resolve, reject) => {
+    const token = uni.getStorageSync('token')
+    uni.request({
+      url: config.API_BASE_URL + '/api/purchase/renewal-info',
+      method: 'POST',
+      data: {},
+      header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
+      success: (res) => {
+        if (res.data && res.data.code === 200) {
+          resolve(res.data)
+        } else {
+          reject(res.data || { code: -1, message: '获取续费信息失败' })
+        }
+      },
+      fail: (err) => reject(err)
+    })
+  })
+}
+
+export function getChallengeProgress(memberId) {
+  return new Promise((resolve, reject) => {
+    const token = uni.getStorageSync('token')
+    uni.request({
+      url: config.API_BASE_URL + '/api/purchase/challenge/progress?memberId=' + memberId,
+      method: 'GET',
+      header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
+      success: (res) => {
+        if (res.data && res.data.code === 200) {
+          resolve(res.data)
+        } else {
+          reject(res.data || { code: -1, message: '获取闯关进度失败' })
+        }
+      },
+      fail: (err) => reject(err)
+    })
+  })
+}