Przeglądaj źródła

feat(frontend): 改版v1 C类前端 - 首页旅程集成(F1) + 分包注册

pages.json: 新增pages/problem(7页)+pages/notification(1页)两个分包。index-home.vue: 登录后顶栏显示JourneyCard旅程卡,首次访问弹出IntentPicker意图选择层(A/B/C),teacher角色不弹。handleJourneyAction支持6种action导航。依赖 getUserIntent/chooseUserIntent API。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
E2E Test Bot 1 miesiąc temu
rodzic
commit
c1540037e2
2 zmienionych plików z 166 dodań i 3 usunięć
  1. 59 0
      cfc-frontend/pages.json
  2. 107 3
      cfc-frontend/pages/index-home/index.vue

+ 59 - 0
cfc-frontend/pages.json

@@ -1575,6 +1575,65 @@
           }
         }
       ]
+    },
+    {
+      "root": "pages/problem",
+      "pages": [
+        {
+          "path": "domain-list",
+          "style": {
+            "navigationBarTitleText": "选择关注的问题"
+          }
+        },
+        {
+          "path": "flow-intro",
+          "style": {
+            "navigationBarTitleText": "服务流程"
+          }
+        },
+        {
+          "path": "survey",
+          "style": {
+            "navigationBarTitleText": "专项调研"
+          }
+        },
+        {
+          "path": "package-match",
+          "style": {
+            "navigationBarTitleText": "推荐方案"
+          }
+        },
+        {
+          "path": "package-detail",
+          "style": {
+            "navigationBarTitleText": "套餐详情"
+          }
+        },
+        {
+          "path": "logistics",
+          "style": {
+            "navigationBarTitleText": "物流进度"
+          }
+        },
+        {
+          "path": "plan-confirm",
+          "style": {
+            "navigationBarTitleText": "方案确认"
+          }
+        }
+      ]
+    },
+    {
+      "root": "pages/notification",
+      "pages": [
+        {
+          "path": "index",
+          "style": {
+            "navigationBarTitleText": "消息通知",
+            "enablePullDownRefresh": true
+          }
+        }
+      ]
     }
   ],
   "globalStyle": {

+ 107 - 3
cfc-frontend/pages/index-home/index.vue

@@ -44,6 +44,12 @@
     </view>
   </view>
 
+  <!-- 首次选择意图弹层 — 改版v1 -->
+  <IntentPicker
+    :show="showIntentPicker"
+    @select="handleIntentSelect"
+    @close="handleIntentClose" />
+
   <!-- 登录态 — 直接内嵌,保持底签可见 -->
   <view v-if="currentRole" class="logged-in-container">
     <!-- 品牌头部 -->
@@ -51,6 +57,12 @@
       tagline="知行合一 · 快乐成长"
       quote="千里之行,始于足下" />
 
+    <!-- 旅程状态卡 — 改版v1 需求驱动 -->
+    <JourneyCard
+      v-if="userIntent"
+      :intent="userIntent"
+      @action="handleJourneyAction" />
+
     <!-- 能量沙盘 — Canvas 五行星图 -->
     <WuxingSandbox
       v-if="sandboxData"
@@ -331,7 +343,9 @@ import FamilyFeed from '../../components/FamilyFeed.vue'
 import DimensionProducts from '../../components/DimensionProducts.vue'
 import ArticleBookshelf from '../../components/ArticleBookshelf.vue'
 import FamilyChallengeCard from '../../components/FamilyChallengeCard.vue'
-import { acceptParentInvite, productList, getActivityList, getFeaturedArticles, getFamilyEnergySandbox, getVisibleFamilyMembers, getChildren, getChallengeList, switchToFamilyMember, getMyMembership, updateChallengeProgress, respondChallenge, getTodayTasks, completeTask as completeTaskApi, getTodayParentTasks, completeParentTask as completeParentTaskApi, getTaskHistory, getNotices } from '../../utils/api.js'
+import IntentPicker from '../../components/intent-picker.vue'
+import JourneyCard from '../../components/journey-card.vue'
+import { acceptParentInvite, productList, getActivityList, getFeaturedArticles, getFamilyEnergySandbox, getVisibleFamilyMembers, getChildren, getChallengeList, switchToFamilyMember, getMyMembership, updateChallengeProgress, respondChallenge, getTodayTasks, completeTask as completeTaskApi, getTodayParentTasks, completeParentTask as completeParentTaskApi, getTaskHistory, getNotices, getUserIntent, chooseUserIntent } from '../../utils/api.js'
 import nav from '../../utils/nav.js'
 import config from '@/config.js'
 
@@ -342,7 +356,9 @@ export default {
     FamilyFeed,
     DimensionProducts,
     ArticleBookshelf,
-    FamilyChallengeCard
+    FamilyChallengeCard,
+    IntentPicker,
+    JourneyCard
   },
   data() {
     // 从 storage 预取登录态/角色,确保首次渲染即正确(WeChat 渲染层/逻辑层分离架构下 onLoad 执行前已渲染)
@@ -403,7 +419,12 @@ export default {
       // 会员状态(沙盘下方会员入口使用)
       isMember: false,
       isLifetime: false,
-      membershipDays: 0
+      membershipDays: 0,
+
+      // 改版v1 用户意图/旅程
+      userIntent: null,
+      showIntentPicker: false,
+      intentPickerDismissed: false
     }
   },
   computed: {
@@ -803,6 +824,7 @@ export default {
         this.loadLoggedInData()
       }
       this.checkMemberStatus()
+      this.checkUserIntent()
       this._watchPageReady()
     },
     _watchPageReady() {
@@ -997,6 +1019,88 @@ export default {
     },
     getImageUrl: function(path) {
       return config.API_BASE_URL + path
+    },
+
+    // ===== 改版v1 用户意图/旅程 =====
+    checkUserIntent: function() {
+      var self = this
+      var role = uni.getStorageSync('currentRole') || uni.getStorageSync('role') || ''
+      // teacher 角色不弹意图选择
+      if (role === 'teacher') return
+      getUserIntent().then(function(res) {
+        var intent = res && res.data
+        if (intent) {
+          self.userIntent = intent
+        } else {
+          // 无意图且未跳过,弹选择层
+          if (!self.intentPickerDismissed) {
+            self.intentPickerDismissed = true
+            self.showIntentPicker = true
+          }
+        }
+      }).catch(function() {
+        // 静默:接口异常时不弹
+      })
+    },
+    handleIntentSelect: function(payload) {
+      var self = this
+      self.showIntentPicker = false
+      uni.showLoading({ title: '处理中...', mask: true })
+      var data = { intentType: payload.intentType }
+      if (payload.intentType === 'C' && payload.problemDomainCode) {
+        data.problemDomainCode = payload.problemDomainCode
+      }
+      chooseUserIntent(data).then(function(res) {
+        uni.hideLoading()
+        if (res && (res.code === 0 || res.code === 200)) {
+          // 选择成功后刷新意图
+          getUserIntent().then(function(r) {
+            self.userIntent = r && r.data
+          }).catch(function() {})
+          // 按类型跳转
+          if (payload.intentType === 'A') {
+            uni.navigateTo({ url: '/pages/assessment/purchase' })
+          } else if (payload.intentType === 'B') {
+            uni.navigateTo({ url: '/pages/problem/domain-list' })
+          } else if (payload.intentType === 'C') {
+            uni.navigateTo({
+              url: '/pages/problem/flow-intro?code=' + (payload.problemDomainCode || '')
+            })
+          }
+        } else {
+          uni.showToast({ title: res.message || '选择失败', icon: 'none' })
+        }
+      }).catch(function() {
+        uni.hideLoading()
+        uni.showToast({ title: '选择失败,请重试', icon: 'none' })
+      })
+    },
+    handleIntentClose: function() {
+      this.showIntentPicker = false
+      uni.setStorageSync('intent_skipped', '1')
+    },
+    handleJourneyAction: function(payload) {
+      var action = payload && payload.action
+      var code = payload && payload.code
+      if (action === 'flow-intro') {
+        uni.navigateTo({ url: '/pages/problem/flow-intro?code=' + (code || '') })
+      } else if (action === 'survey') {
+        uni.navigateTo({ url: '/pages/problem/survey?code=' + (code || '') })
+      } else if (action === 'package') {
+        uni.navigateTo({ url: '/pages/problem/package-match?code=' + (code || '') })
+      } else if (action === 'logistics') {
+        uni.navigateTo({ url: '/pages/problem/logistics?code=' + (code || '') })
+      } else if (action === 'report') {
+        uni.navigateTo({ url: '/pages/problem/plan-confirm?code=' + (code || '') })
+      } else if (action === 'plan-confirm') {
+        uni.navigateTo({ url: '/pages/problem/plan-confirm?code=' + (code || '') })
+      } else if (action === 'tasks') {
+        uni.navigateTo({ url: '/pages/tasks/tasks' })
+      } else if (action === 'purchase') {
+        uni.navigateTo({ url: '/pages/assessment/purchase' })
+      } else if (action === 'recommend') {
+        uni.navigateTo({ url: '/pages/problem/domain-list' })
+      }
     }
 
   }