Parcourir la source

fix(health-plan): 免费用户生成方案付费墙改为家庭会员或购买健康启航计划二选一,前端弹三选一引导购买后自动继续生成

liaoxg il y a 6 jours
Parent
commit
7128d7419c

+ 11 - 3
cfc-backend/src/main/java/com/etotem/cfc/controller/HealthPlanController.java

@@ -25,15 +25,23 @@ public class HealthPlanController {
     @Resource
     private com.etotem.cfc.service.PurchaseService purchaseService;
 
+    @Resource
+    private com.etotem.cfc.service.MembershipService membershipService;
+
     @Operation(summary = "生成健康方案(文本)")
     @PostMapping("/generate")
     public Result<String> generate(@RequestBody Map<String, Object> params,
                                    @RequestAttribute("userId") Long userId,
                                    @RequestAttribute(value = "familyId", required = false) Long familyId) {
-        // 付费墙拦截
+        // 付费墙拦截:家庭会员 或 健康启航计划 任一有效即可生成
+        boolean isMember = false;
+        if (familyId != null) {
+            com.etotem.cfc.dto.MembershipLevelDTO level = membershipService.getCurrentLevel(familyId);
+            isMember = level != null && !"FREE".equals(level.getLevelCode());
+        }
         java.util.Map<String, Object> purchaseCheck = purchaseService.checkPurchase(userId);
-        if (!Boolean.TRUE.equals(purchaseCheck.get("isActive"))) {
-            return Result.error(4001, "请先购买健康启航计划体验包");
+        if (!isMember && !Boolean.TRUE.equals(purchaseCheck.get("isActive"))) {
+            return Result.error(4001, "请升级为家庭会员或购买健康启航计划");
         }
         
         String memberIds = (String) params.get("memberIds");

+ 30 - 15
cfc-frontend/pages/health/health-plan-summary.vue

@@ -488,6 +488,14 @@ selectedMembers: function() {
     }
   },
   onShow: function() {
+    var self = this
+    // 从购买/开通页返回:自动继续生成方案
+    if (uni.getStorageSync('PLAN_RESUME_AFTER_PURCHASE') === '1') {
+      uni.removeStorageSync('PLAN_RESUME_AFTER_PURCHASE')
+      if (this.selectedMemberIds && this.selectedMemberIds.length > 0 && !this.viewMode) {
+        setTimeout(function() { self.doAutoExecute() }, 800)
+      }
+    }
     if (this.needReloadMembers) {
       this.needReloadMembers = false
       if (this.$refs.memberPicker && this.$refs.memberPicker.reload) {
@@ -894,25 +902,32 @@ selectedMembers: function() {
           } else {
             uni.showToast({ title: '生成失败,请重试', icon: 'none' })
           }
-        } else if (res.code === 4001) {
-          // 付费墙:未购买健康启航计划体验包,提示购买
-          uni.showModal({
-            title: '需要购买体验会员',
-            content: '生成健康方案需先购买「健康启航计划体验会员」(¥199/7天),是否前往购买?',
-            confirmText: '去购买',
-            cancelText: '暂不',
-            success: function(modalRes) {
-              if (modalRes.confirm) {
-                uni.navigateTo({ url: '/pages/purchase/index' })
-              }
-            }
-          })
         } else {
           uni.showToast({ title: res && res.message ? res.message : '生成失败', icon: 'none' })
         }
-      }).catch(function() {
+      }).catch(function(err) {
         self.loading = false
-        uni.showToast({ title: '请求失败,请检查网络', icon: 'none' })
+        // 付费墙:家庭会员或健康启航计划均未开通(request 封装对非 200 code 统一 reject,此处拿到 err.code)
+        if (err && err.code === 4001) {
+          self.showPaywallSheet()
+        } else {
+          uni.showToast({ title: '请求失败,请检查网络', icon: 'none' })
+        }
+      })
+    },
+    // 付费墙引导:三选一(购买家庭会员 / 购买健康启航计划 / 取消)
+    showPaywallSheet: function() {
+      uni.showActionSheet({
+        itemList: ['购买家庭会员', '购买健康启航计划'],
+        success: function(sheetRes) {
+          if (sheetRes.tapIndex === 0) {
+            uni.setStorageSync('PLAN_RESUME_AFTER_PURCHASE', '1')
+            uni.navigateTo({ url: '/pages/membership/upgrade' })
+          } else if (sheetRes.tapIndex === 1) {
+            uni.setStorageSync('PLAN_RESUME_AFTER_PURCHASE', '1')
+            uni.navigateTo({ url: '/pages/purchase/index' })
+          }
+        }
       })
     },
     doAutoExecute: function() {

+ 16 - 2
cfc-frontend/pages/membership/result.vue

@@ -18,7 +18,8 @@
         </view>
       </view>
       <view class="btn-group">
-        <button class="btn-primary" @click="goBenefits">查看我的权益</button>
+        <button class="btn-primary" v-if="fromPlan" @click="goBackToPlan">返回继续生成方案</button>
+        <button class="btn-primary" v-else @click="goBenefits">查看我的权益</button>
         <button class="btn-secondary" @click="goHome">返回会员中心</button>
       </view>
     </view>
@@ -54,7 +55,8 @@ export default {
       giftCoupons: [],
       failReason: '支付未完成,请重试',
       canContinue: false,
-      nextPayParams: null
+      nextPayParams: null,
+      fromPlan: false
     }
   },
   computed: {
@@ -68,6 +70,8 @@ export default {
   onLoad: function(options) {
     this.orderNo = options.orderNo || ''
     this.status = options.status || 'success'
+    // 从方案制定页跳来购买:开通成功后返回并自动继续生成
+    this.fromPlan = uni.getStorageSync('PLAN_RESUME_AFTER_PURCHASE') === '1'
     if (this.status === 'success') {
       this.loadSuccess()
     } else {
@@ -90,6 +94,12 @@ export default {
             self.levelName = mem.levelName || self.levelName
             self.expireText = self.formatDate(mem.endDate)
             self.loadGiftCoupons()
+            // 从方案制定页跳来购买:开通成功后返回方案页(页面栈 [方案页, upgrade, result]),由方案页 onShow 自动继续生成
+            if (self.fromPlan) {
+              setTimeout(function() {
+                uni.navigateBack({ delta: 2 })
+              }, 1200)
+            }
           } else if (times >= 8) {
             clearInterval(timer)
             self.loadGiftCoupons()
@@ -161,6 +171,10 @@ export default {
     goBenefits: function() {
       uni.redirectTo({ url: '/pages/membership/benefits' })
     },
+    goBackToPlan: function() {
+      // 页面栈 [方案页, upgrade, result],delta 2 返回方案制定页
+      uni.navigateBack({ delta: 2 })
+    },
     goHome: function() {
       uni.switchTab({ url: '/pages/index/index' })
     },

+ 11 - 1
cfc-frontend/pages/purchase/index.vue

@@ -121,6 +121,11 @@ export default {
       try {
         var res = await checkPurchase()
         if (res.data && res.data.hasPurchased && res.data.isActive) {
+          // 从方案制定页来购买:返回方案页,由 onShow 自动继续生成
+          if (uni.getStorageSync('PLAN_RESUME_AFTER_PURCHASE') === '1') {
+            uni.navigateBack()
+            return
+          }
           // 已有有效购买,跳转闯关进度
           uni.redirectTo({ url: '/pages/growth/challenge-progress' })
         }
@@ -143,7 +148,12 @@ export default {
                   self.submitting = false
                   uni.showToast({ title: '支付成功,开通中…', icon: 'none' })
                   setTimeout(function() {
-                    uni.redirectTo({ url: '/pages/growth/challenge-progress' })
+                    if (uni.getStorageSync('PLAN_RESUME_AFTER_PURCHASE') === '1') {
+                      // 从方案制定页来购买:返回方案页,由 onShow 自动继续生成
+                      uni.navigateBack()
+                    } else {
+                      uni.redirectTo({ url: '/pages/growth/challenge-progress' })
+                    }
                   }, 800)
                 },
                 fail: function(err) {