topfans/docs/superpowers/plans/2026-03-25-guide-modification.md
2026-04-07 22:28:50 +08:00

7.4 KiB
Raw Permalink Blame History

新手引导修改实现计划

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 修改新手引导流程:点击"去做"后直接从第一项引导开始,存储步骤进度,高亮区域支持点击触发动作

Architecture: 修改 GuideStartModal 的 start 事件触发逻辑,添加步骤进度存储,支持高亮区域点击事件

Tech Stack: Vue 3 / Vuex / uni-app


Task 1: 修改 GuideStartModal 点击"去做"后直接开始引导

Files:

  • Modify: frontend/pages/square/square.vue:751-754

  • Modify: frontend/components/GuideStartModal.vue:39-45

  • Step 1: 修改 square.vue 的 handleGuideStart 方法

// 原本代码
const handleGuideStart = () => {
  showGuideStartModal.value = false;
  showGuideListModal.value = true;
};

// 修改为:直接开始第一个未完成的引导
const handleGuideStart = () => {
  showGuideStartModal.value = false;

  // 获取所有引导keys按顺序获取第一个未完成的
  const keys = getAllGuideKeys();
  const firstUndoneKey = keys.find(key => !isGuideDone(key));

  if (firstUndoneKey) {
    store.dispatch('guide/initGuide', firstUndoneKey);
  }
};

需要 import

import { getAllGuideKeys, isGuideDone } from '@/utils/guideConfig.js';
  • Step 2: 验证修改

运行项目,点击"去做"按钮,验证是否直接进入第一个引导而不是显示列表弹窗。

  • Step 3: 提交

Task 2: 添加引导步骤进度存储功能

Files:

  • Modify: frontend/utils/guideConfig.js:252-315

  • Modify: frontend/store/modules/guide.js:60-74

  • Step 1: 在 guideConfig.js 添加步骤进度存储函数

/**
 * 获取引导的当前步骤
 * @param {string} key 引导key
 * @returns {number} 当前步骤索引默认0
 */
export function getGuideCurrentStep(key) {
  return uni.getStorageSync(`guide_step_${key}`) || 0
}

/**
 * 设置引导的当前步骤
 * @param {string} key 引导key
 * @param {number} step 步骤索引
 */
export function setGuideCurrentStep(key, step) {
  uni.setStorageSync(`guide_step_${key}`, step)
}

/**
 * 获取下一个未完成的引导key
 * @returns {string|null} 引导key或null
 */
export function getNextUndoneGuideKey() {
  const keys = getAllGuideKeys()
  return keys.find(key => !isGuideDone(key)) || null
}
  • Step 2: 修改 store/modules/guide.js 的 END_GUIDE mutation
// 在 mutations 中修改
END_GUIDE(state) {
  if (state.currentGuide) {
    const key = state.currentGuide.key
    markGuideAsShown(key)
    markGuideDone(key)

    // 重置步骤进度
    setGuideCurrentStep(key, 0)
  }
  state.currentGuide = null
  state.currentStep = 0
  state.isActive = false
  state.isNavigating = false
},
  • Step 3: 修改 NEXT_STEP mutation 添加步骤存储
NEXT_STEP(state) {
  if (state.currentGuide && state.currentStep < state.currentGuide.steps.length - 1) {
    state.currentStep++
    // 存储当前步骤
    setGuideCurrentStep(state.currentGuide.key, state.currentStep)
  }
},
  • Step 4: 修改 START_GUIDE mutation 恢复步骤进度
START_GUIDE(state, guideConfig) {
  state.currentGuide = guideConfig
  // 恢复之前保存的步骤进度
  state.currentStep = getGuideCurrentStep(guideConfig.key) || 0
  state.isActive = true
  state.isNavigating = false
},
  • Step 5: 提交

Task 3: 高亮区域支持点击触发动作

Files:

  • Modify: frontend/utils/guideConfig.js:37-157 (steps 配置)

  • Modify: frontend/components/GuideOverlay.vue:245-248

  • Step 1: 扩展 step 配置结构

在 guideConfig.js 的 steps 配置中添加 action 字段:

// action 支持的类型:
// 1. { type: 'navigate', url: '/pages/xxx/xxx' } - 路由跳转
// 2. { type: 'component', name: 'xxx' } - 打开组件
// 3. { type: 'function', handler: 'xxx' } - 执行函数

// 示例配置:
{
  target: '.banner-carousel',
  content: '这里是轮播图,点击可以查看排行榜和活动',
  center: true,
  buttons: ['next'],
  action: {
    type: 'navigate',
    url: '/pages/rank/rank'
  }
}
  • Step 2: 修改 GuideOverlay 的 handleHighlightClick 方法
// 点击高亮区域
function handleHighlightClick() {
  const stepConfigVal = stepConfig.value
  if (stepConfigVal && stepConfigVal.action) {
    const { action } = stepConfigVal

    if (action.type === 'navigate' && action.url) {
      // 路由跳转
      uni.navigateTo({
        url: action.url,
        fail: (err) => {
          console.error('[Guide] 页面跳转失败:', err)
        }
      })
    } else if (action.type === 'component' && action.name) {
      // 打开组件(通过事件通知父组件)
      store.dispatch('guide/openComponent', action.name)
    } else if (action.type === 'function' && action.handler) {
      // 执行函数
      store.dispatch('guide/executeFunction', action.handler)
    }
  }
}
  • Step 3: 在 store 中添加处理 action 的 actions
// 在 store/modules/guide.js 中添加
actions: {
  // ... existing actions ...

  /**
   * 打开组件
   */
  openComponent({ commit }, componentName) {
    console.log(`[Guide] 打开组件: ${componentName}`)
    commit('OPEN_COMPONENT', componentName)
  },

  /**
   * 执行函数
   */
  executeFunction({ commit }, handler) {
    console.log(`[Guide] 执行函数: ${handler}`)
    commit('EXECUTE_FUNCTION', handler)
  }
}

// 添加对应的 mutations
mutations: {
  // ... existing mutations ...

  OPEN_COMPONENT(state, componentName) {
    state.pendingAction = { type: 'component', name: componentName }
  },

  EXECUTE_FUNCTION(state, handler) {
    state.pendingAction = { type: 'function', handler }
  }
}

// 在 state 中添加
state: {
  // ... existing state ...
  pendingAction: null, // 待执行的行动
}
  • Step 4: 提交

Task 4: 验证个人中心引导列表弹窗不受影响

Files:

  • Review: frontend/pages/profile/profile.vue:914-936

  • Step 1: 检查 profile.vue 中 handleDoGuide 方法

当前代码:

const handleDoGuide = (key) => {
  showGuideListModal.value = false;
  if (isFirstEntry) {
    store.dispatch("guide/initGuide", key);
  } else {
    store.dispatch("guide/initGuide", key);
  }
};

验证逻辑保持不变:用户从个人中心点击进入某个引导时,触发 initGuide 动作。这与 Task 1 的修改不冲突,因为:

  • square.vue 的修改只影响新用户首次点击"去做"的行为

  • profile.vue 中的 GuideListModal 保持原有逻辑

  • Step 2: 测试验证

  1. 从个人中心进入引导列表
  2. 点击某个引导的"去做"按钮
  3. 确认引导能正常启动,且列表弹窗行为不变
  • Step 3: 提交

Task 5: 端到端测试

  • Step 1: 测试完整流程
  1. 模拟新用户登录
  2. 验证 GuideStartModal 显示
  3. 点击"去做"
  4. 验证直接进入第一个引导而不是显示列表
  5. 完成引导步骤
  6. 验证步骤进度被正确存储
  7. 验证高亮区域点击能触发相应动作(配置了 action 的情况下)
  • Step 2: 测试个人中心入口
  1. 进入个人中心
  2. 点击引导按钮
  3. 验证 GuideListModal 正常显示
  4. 选择一个引导执行
  5. 验证行为与之前一致
  • Step 3: 提交