hookehuyr

feat(product): 添加热卖产品Mock数据支持

...@@ -581,6 +581,82 @@ const store = useYourStore() ...@@ -581,6 +581,82 @@ const store = useYourStore()
581 store.setState('新值') 581 store.setState('新值')
582 ``` 582 ```
583 583
584 +### 使用 Mock 数据工具
585 +
586 +项目提供了统一的 Mock 数据工具(`src/utils/mockData.js`),用于开发阶段测试分页加载等功能。
587 +
588 +**支持的 Mock API**:
589 +
590 +| API 名称 | 功能说明 | 使用页面 |
591 +|---------|---------|---------|
592 +| `mockWeekHotAPI` | 周热门资料 | 周热门资料页 |
593 +| `mockFileListAPI` | 资料列表 | 资料列表页 |
594 +| `mockProductListAPI` | 产品列表 | 产品中心页 |
595 +| `mockSearchAPI` | 搜索(产品+资料) | 搜索页 |
596 +| `mockMessageListAPI` | 消息列表 | 消息列表页 |
597 +| `mockFavoriteListAPI` | 收藏列表 | 收藏页 |
598 +| `mockFeedbackListAPI` | 意见反馈列表 | 意见反馈页 |
599 +
600 +**使用方式**:
601 +
602 +1. **在页面中导入 Mock 函数**:
603 +```javascript
604 +import { mockWeekHotAPI } from '@/utils/mockData'
605 +```
606 +
607 +2. **设置 Mock 开关**:
608 +```javascript
609 +// 开发环境使用 Mock,生产环境使用真实 API
610 +const USE_MOCK_DATA = process.env.NODE_ENV === 'development'
611 +```
612 +
613 +3. **在数据获取函数中使用**:
614 +```javascript
615 +const fetchWeekHot = async (page = 0) => {
616 + loading.value = true
617 +
618 + try {
619 + // 根据 USE_MOCK_DATA 开关决定使用 Mock 数据还是真实 API
620 + const res = USE_MOCK_DATA
621 + ? await mockWeekHotAPI({ page, limit: 20 })
622 + : await fn(weekHotAPI({ page, limit: 20 }))
623 +
624 + if (res.code === 1) {
625 + weekHotList.value.push(...res.data.list)
626 + hasMore.value = res.data.list.length >= 20
627 + }
628 + } catch (err) {
629 + console.error('获取周热门资料失败:', err)
630 + } finally {
631 + loading.value = false
632 + }
633 +}
634 +```
635 +
636 +**Mock 数据特性**:
637 +
638 +- ✅ **模拟网络延迟**:100-300ms 随机延迟
639 +- ✅ **支持分页加载**:可配置 `page` 和 `limit` 参数
640 +- ✅ **随机数据生成**:文件大小、学习人数、收藏状态等
641 +- ✅ **支持关键词搜索**:搜索 API 会根据关键词过滤数据
642 +- ✅ **真实数据结构**:返回的数据结构与真实 API 一致
643 +- ✅ **控制台日志**:每次请求都会打印 `[Mock]` 日志便于调试
644 +
645 +**统一调用器**(可选):
646 +
647 +也可以使用 `mockAPI()` 统一调用器:
648 +```javascript
649 +import { mockAPI } from '@/utils/mockData'
650 +
651 +// 调用指定的 Mock API
652 +const res = await mockAPI('weekHotAPI', { page: 0, limit: 20 })
653 +```
654 +
655 +**注意事项**
656 +- ⚠️ **生产环境关闭**:部署时确保 `USE_MOCK_DATA = false`
657 +- ⚠️ **数据结构对齐**:Mock 数据结构必须与真实 API 保持一致
658 +- ⚠️ **分页逻辑**:Mock API 返回的 `list` 为空时表示没有更多数据
659 +
584 ## 关键文件总结 660 ## 关键文件总结
585 661
586 ### 修改前必须理解 662 ### 修改前必须理解
...@@ -621,10 +697,14 @@ store.setState('新值') ...@@ -621,10 +697,14 @@ store.setState('新值')
621 3. **`src/composables/useListItemClick.js`** - 列表点击处理 697 3. **`src/composables/useListItemClick.js`** - 列表点击处理
622 698
623 ### 工具函数 699 ### 工具函数
624 -1. **`src/utils/documentIcons.js`** - 文档类型图标识别 700 +1. **`src/utils/mockData.js`** - Mock 数据生成工具(开发测试用)
625 -2. **`src/utils/tools.js`** - 通用工具函数集合 701 + - 支持多个 API 的 Mock:周热门资料、资料列表、产品列表、搜索、消息列表、收藏列表、意见反馈
626 -3. **`src/utils/network.js`** - 网络状态工具 702 + - 统一调用器:`mockAPI(apiName, params)`
627 -4. **`src/hooks/useGo.js`** - 增强导航 hook 703 + - 支持分页加载、模拟网络延迟、随机数据生成
704 +2. **`src/utils/documentIcons.js`** - 文档类型图标识别
705 +3. **`src/utils/tools.js`** - 通用工具函数集合
706 +4. **`src/utils/network.js`** - 网络状态工具
707 +5. **`src/hooks/useGo.js`** - 增强导航 hook
628 708
629 ## 调试技巧 709 ## 调试技巧
630 710
......
...@@ -5,6 +5,45 @@ ...@@ -5,6 +5,45 @@
5 5
6 --- 6 ---
7 7
8 +## [2026-02-09] - 添加热卖产品 Mock 数据支持
9 +
10 +### 新增
11 +- **Mock 数据模块**`src/api/mock/`):
12 + - 新增 `hotProducts.js`:包含 9 种产品的 Mock 数据
13 + - 覆盖所有计划书模板类型(人寿、重疾、储蓄)
14 + - 支持 `form_sn` 字段,对应不同的计划书模板
15 + - 包含完整的产品信息(名称、分类、标签、封面图)
16 +
17 +### 优化
18 +- **首页 Mock 数据支持**`src/pages/index/index.vue`):
19 + - 添加 `USE_MOCK_DATA` 开关控制数据来源
20 + - 开发环境使用 Mock 数据测试计划书功能
21 + - 生产环境调用真实 API(`listAPI`
22 + - 添加详细的 JSDoc 注释和使用说明
23 +
24 +### 文档
25 +- **CLAUDE.md 更新**
26 + - 添加 Mock 数据工具使用指南
27 + - 说明支持的 Mock API 列表
28 + - 提供使用示例和注意事项
29 +
30 +---
31 +
32 +**详细信息**
33 +- **影响文件**: src/api/mock/hotProducts.js, src/pages/index/index.vue, CLAUDE.md
34 +- **技术栈**: Vue 3, Mock 数据
35 +- **测试状态**: 开发环境已测试
36 +- **备注**: ⚠️ 生产环境请设置 `USE_MOCK_DATA = false`
37 +
38 +---
39 +
40 +# Changelog
41 +
42 +> 本文档记录 Manulife WeApp项目的所有重要变更。
43 +> 格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
44 +
45 +---
46 +
8 ## [2026-02-09] - 更新 API 集成日志和经验教训文档 47 ## [2026-02-09] - 更新 API 集成日志和经验教训文档
9 48
10 ### 文档 49 ### 文档
......
1 +/**
2 + * 热卖产品 Mock 数据
3 + *
4 + * @description 包含项目所有保险类型的产品 mock 数据,用于测试计划书模板显示
5 + * 遵循项目 mock 数据规范,集成到 src/utils/mockData.js
6 + * @module api/mock/hotProducts
7 + * @author Claude Code
8 + * @created 2026-02-09
9 + */
10 +
11 +/**
12 + * 热卖产品 Mock 数据列表
13 + * @description 包含 9 种产品,覆盖所有计划书模板类型
14 + */
15 +const HOT_PRODUCTS = [
16 + // ====== 人寿保险 (LifeInsuranceTemplate) ======
17 +
18 + {
19 + id: 1,
20 + product_name: 'WIOP3E 盈传创富保障计划 3 - 优选版',
21 + name: 'WIOP3E 盈传创富保障计划 3 - 优选版',
22 + recommend: 'hot',
23 + form_sn: 'life-insurance-wiop3e', // 对应 LifeInsuranceTemplate
24 + categories: [
25 + { id: 'life', name: '人寿保险' }
26 + ],
27 + tags: [
28 + { id: 't1', name: '终身寿险', bg_color: '#DBEAFE', text_color: '#1E40AF' },
29 + { id: 't2', name: '美元产品', bg_color: '#DCFCE7', text_color: '#166534' }
30 + ],
31 + cover_image: 'https://picsum.photos/seed/wiop3e/400/300'
32 + },
33 +
34 + {
35 + id: 2,
36 + product_name: 'WIOP3 盈传创富保障计划 3',
37 + name: 'WIOP3 盈传创富保障计划 3',
38 + recommend: 'hot',
39 + form_sn: 'life-insurance-wiop3', // 对应 LifeInsuranceTemplate
40 + categories: [
41 + { id: 'life', name: '人寿保险' }
42 + ],
43 + tags: [
44 + { id: 't1', name: '终身寿险', bg_color: '#DBEAFE', text_color: '#1E40AF' },
45 + { id: 't2', name: '美元产品', bg_color: '#DCFCE7', text_color: '#166534' }
46 + ],
47 + cover_image: 'https://picsum.photos/seed/wiop3/400/300'
48 + },
49 +
50 + // ====== 重疾保险 (CriticalIllnessTemplate) ======
51 +
52 + {
53 + id: 3,
54 + product_name: 'MPC 守护无间重疾',
55 + name: 'MPC 守护无间重疾',
56 + recommend: 'hot',
57 + form_sn: 'critical-illness-mpc', // 对应 CriticalIllnessTemplate
58 + categories: [
59 + { id: 'critical', name: '重疾保险' }
60 + ],
61 + tags: [
62 + { id: 't1', name: '重疾保障', bg_color: '#FEF3C7', text_color: '#92400E' },
63 + { id: 't2', name: '终身保障', bg_color: '#E0E7FF', text_color: '#3730A3' }
64 + ],
65 + cover_image: 'https://picsum.photos/seed/mpc/400/300'
66 + },
67 +
68 + {
69 + id: 4,
70 + product_name: 'MBC PRO 活跃人生重疾保 PRO',
71 + name: 'MBC PRO 活跃人生重疾保 PRO',
72 + recommend: 'hot',
73 + form_sn: 'critical-illness-mbc-pro', // 对应 CriticalIllnessTemplate
74 + categories: [
75 + { id: 'critical', name: '重疾保险' }
76 + ],
77 + tags: [
78 + { id: 't1', name: '重疾保障', bg_color: '#FEF3C7', text_color: '#92400E' },
79 + { id: 't2', name: 'PRO 版本', bg_color: '#FEE2E2', text_color: '#991B1B' }
80 + ],
81 + cover_image: 'https://picsum.photos/seed/mbc-pro/400/300'
82 + },
83 +
84 + {
85 + id: 5,
86 + product_name: 'MBC2 活跃人生重疾保 2',
87 + name: 'MBC2 活跃人生重疾保 2',
88 + recommend: 'hot',
89 + form_sn: 'critical-illness-mbc2', // 对应 CriticalIllnessTemplate
90 + categories: [
91 + { id: 'critical', name: '重疾保险' }
92 + ],
93 + tags: [
94 + { id: 't1', name: '重疾保障', bg_color: '#FEF3C7', text_color: '#92400E' },
95 + { id: 't2', name: '升级版', bg_color: '#DCFCE7', text_color: '#166534' }
96 + ],
97 + cover_image: 'https://picsum.photos/seed/mbc2/400/300'
98 + },
99 +
100 + // ====== 储蓄型产品 (SavingsTemplate) ======
101 +
102 + {
103 + id: 6,
104 + product_name: 'GS 宏挚传承保障计划',
105 + name: 'GS 宏挚传承保障计划',
106 + recommend: 'hot',
107 + form_sn: 'savings-gs', // 对应 SavingsTemplate
108 + categories: [
109 + { id: 'savings', name: '储蓄保险' }
110 + ],
111 + tags: [
112 + { id: 't1', name: '储蓄型', bg_color: '#E0E7FF', text_color: '#3730A3' },
113 + { id: 't2', name: '传承规划', bg_color: '#F3E8FF', text_color: '#6B21A8' }
114 + ],
115 + cover_image: 'https://picsum.photos/seed/gs/400/300'
116 + },
117 +
118 + {
119 + id: 7,
120 + product_name: 'GC 宏挚家传保险计划',
121 + name: 'GC 宏挚家传保险计划',
122 + recommend: 'hot',
123 + form_sn: 'savings-gc', // 对应 SavingsTemplate
124 + categories: [
125 + { id: 'savings', name: '储蓄保险' }
126 + ],
127 + tags: [
128 + { id: 't1', name: '储蓄型', bg_color: '#E0E7FF', text_color: '#3730A3' },
129 + { id: 't2', name: '家庭保障', bg_color: '#FEE2E2', text_color: '#991B1B' }
130 + ],
131 + cover_image: 'https://picsum.photos/seed/gc/400/300'
132 + },
133 +
134 + {
135 + id: 8,
136 + product_name: 'FA 宏浚传承保障计划',
137 + name: 'FA 宏浚传承保障计划',
138 + recommend: 'hot',
139 + form_sn: 'savings-fa', // 对应 SavingsTemplate
140 + categories: [
141 + { id: 'savings', name: '储蓄保险' }
142 + ],
143 + tags: [
144 + { id: 't1', name: '储蓄型', bg_color: '#E0E7FF', text_color: '#3730A3' },
145 + { id: 't2', name: '财富传承', bg_color: '#FEF3C7', text_color: '#92400E' }
146 + ],
147 + cover_image: 'https://picsum.photos/seed/fa/400/300'
148 + },
149 +
150 + {
151 + id: 9,
152 + product_name: 'LV2 赤霞珠终身寿险计划2',
153 + name: 'LV2 赤霞珠终身寿险计划2',
154 + recommend: 'hot',
155 + form_sn: 'savings-lv2', // 对应 SavingsTemplate
156 + categories: [
157 + { id: 'savings', name: '储蓄保险' }
158 + ],
159 + tags: [
160 + { id: 't1', name: '储蓄型', bg_color: '#E0E7FF', text_color: '#3730A3' },
161 + { id: 't2', name: '终身寿险', bg_color: '#DBEAFE', text_color: '#1E40AF' }
162 + ],
163 + cover_image: 'https://picsum.photos/seed/lv2/400/300'
164 + }
165 +]
166 +
167 +/**
168 + * Mock: listAPI (热卖产品)
169 + * @description 专门用于首页热卖产品的 Mock API,支持 form_sn 字段
170 + * @param {Object} params - 请求参数
171 + * @param {string} params.recommend - 推荐位(必须为 'hot')
172 + * @returns {Promise<Object>} 模拟的 API 响应
173 + */
174 +export async function mockHotProductsListAPI(params) {
175 + const { recommend } = params
176 +
177 + // 只返回热卖产品
178 + if (recommend !== 'hot') {
179 + return { code: 0, msg: '只支持热卖产品查询', data: { list: [], total: 0 } }
180 + }
181 +
182 + // 模拟网络延迟
183 + await new Promise(resolve => setTimeout(resolve, 200))
184 +
185 + console.log('[Mock] hotProductsListAPI - 返回热卖产品', HOT_PRODUCTS.length, '条')
186 +
187 + return {
188 + code: 1,
189 + msg: 'success',
190 + data: {
191 + list: HOT_PRODUCTS,
192 + total: HOT_PRODUCTS.length,
193 + categories: [
194 + { id: 'life', name: '人寿保险' },
195 + { id: 'critical', name: '重疾保险' },
196 + { id: 'savings', name: '储蓄保险' }
197 + ]
198 + }
199 + }
200 +}
201 +
202 +/**
203 + * 导出 Mock API 函数供其他模块使用
204 + */
205 +export default {
206 + mockHotProductsListAPI
207 +}
1 +/**
2 + * 热卖产品 Mock 数据
3 + *
4 + * @description 包含项目所有保险类型的产品 mock 数据,用于测试计划书模板显示
5 + * 涵盖人寿保险、重疾保险、储蓄型产品三大类
6 + * @module mock/hotProducts
7 + * @author Claude Code
8 + * @created 2026-02-09
9 + */
10 +
11 +/**
12 + * 热卖产品 Mock 数据列表
13 + *
14 + * @description 包含 9 种产品,覆盖所有计划书模板类型:
15 + * - 人寿保险 (2 种): WIOP3E、WIOP3
16 + * - 重疾保险 (3 种): MPC、MBC PRO、MBC2
17 + * - 储蓄型产品 (4 种): GS、GC、FA、LV2
18 + */
19 +export const hotProductsMockData = [
20 + // ====== 人寿保险 (LifeInsuranceTemplate) ======
21 +
22 + {
23 + id: 1,
24 + product_name: 'WIOP3E 盈传创富保障计划 3 - 优选版',
25 + recommend: 'hot',
26 + form_sn: 'life-insurance-wiop3e', // 对应 LifeInsuranceTemplate
27 + categories: [
28 + { id: 'life', name: '人寿保险' }
29 + ],
30 + tags: [
31 + { id: 't1', name: '终身寿险', bg_color: '#DBEAFE', text_color: '#1E40AF' },
32 + { id: 't2', name: '美元产品', bg_color: '#DCFCE7', text_color: '#166534' }
33 + ],
34 + cover_image: 'https://picsum.photos/seed/wiop3e/400/300',
35 + created_time: '2026-01-01 00:00:00'
36 + },
37 +
38 + {
39 + id: 2,
40 + product_name: 'WIOP3 盈传创富保障计划 3',
41 + recommend: 'hot',
42 + form_sn: 'life-insurance-wiop3', // 对应 LifeInsuranceTemplate
43 + categories: [
44 + { id: 'life', name: '人寿保险' }
45 + ],
46 + tags: [
47 + { id: 't1', name: '终身寿险', bg_color: '#DBEAFE', text_color: '#1E40AF' },
48 + { id: 't2', name: '美元产品', bg_color: '#DCFCE7', text_color: '#166534' }
49 + ],
50 + cover_image: 'https://picsum.photos/seed/wiop3/400/300',
51 + created_time: '2026-01-02 00:00:00'
52 + },
53 +
54 + // ====== 重疾保险 (CriticalIllnessTemplate) ======
55 +
56 + {
57 + id: 3,
58 + product_name: 'MPC 守护无间重疾',
59 + recommend: 'hot',
60 + form_sn: 'critical-illness-mpc', // 对应 CriticalIllnessTemplate
61 + categories: [
62 + { id: 'critical', name: '重疾保险' }
63 + ],
64 + tags: [
65 + { id: 't1', name: '重疾保障', bg_color: '#FEF3C7', text_color: '#92400E' },
66 + { id: 't2', name: '终身保障', bg_color: '#E0E7FF', text_color: '#3730A3' }
67 + ],
68 + cover_image: 'https://picsum.photos/seed/mpc/400/300',
69 + created_time: '2026-01-03 00:00:00'
70 + },
71 +
72 + {
73 + id: 4,
74 + product_name: 'MBC PRO 活跃人生重疾保 PRO',
75 + recommend: 'hot',
76 + form_sn: 'critical-illness-mbc-pro', // 对应 CriticalIllnessTemplate
77 + categories: [
78 + { id: 'critical', name: '重疾保险' }
79 + ],
80 + tags: [
81 + { id: 't1', name: '重疾保障', bg_color: '#FEF3C7', text_color: '#92400E' },
82 + { id: 't2', name: 'PRO 版本', bg_color: '#FEE2E2', text_color: '#991B1B' }
83 + ],
84 + cover_image: 'https://picsum.photos/seed/mbc-pro/400/300',
85 + created_time: '2026-01-04 00:00:00'
86 + },
87 +
88 + {
89 + id: 5,
90 + product_name: 'MBC2 活跃人生重疾保 2',
91 + recommend: 'hot',
92 + form_sn: 'critical-illness-mbc2', // 对应 CriticalIllnessTemplate
93 + categories: [
94 + { id: 'critical', name: '重疾保险' }
95 + ],
96 + tags: [
97 + { id: 't1', name: '重疾保障', bg_color: '#FEF3C7', text_color: '#92400E' },
98 + { id: 't2', name: '升级版', bg_color: '#DCFCE7', text_color: '#166534' }
99 + ],
100 + cover_image: 'https://picsum.photos/seed/mbc2/400/300',
101 + created_time: '2026-01-05 00:00:00'
102 + },
103 +
104 + // ====== 储蓄型产品 (SavingsTemplate) ======
105 +
106 + {
107 + id: 6,
108 + product_name: 'GS 宏挚传承保障计划',
109 + recommend: 'hot',
110 + form_sn: 'savings-gs', // 对应 SavingsTemplate
111 + categories: [
112 + { id: 'savings', name: '储蓄保险' }
113 + ],
114 + tags: [
115 + { id: 't1', name: '储蓄型', bg_color: '#E0E7FF', text_color: '#3730A3' },
116 + { id: 't2', name: '传承规划', bg_color: '#F3E8FF', text_color: '#6B21A8' }
117 + ],
118 + cover_image: 'https://picsum.photos/seed/gs/400/300',
119 + created_time: '2026-01-06 00:00:00'
120 + },
121 +
122 + {
123 + id: 7,
124 + product_name: 'GC 宏挚家传保险计划',
125 + recommend: 'hot',
126 + form_sn: 'savings-gc', // 对应 SavingsTemplate
127 + categories: [
128 + { id: 'savings', name: '储蓄保险' }
129 + ],
130 + tags: [
131 + { id: 't1', name: '储蓄型', bg_color: '#E0E7FF', text_color: '#3730A3' },
132 + { id: 't2', name: '家庭保障', bg_color: '#FEE2E2', text_color: '#991B1B' }
133 + ],
134 + cover_image: 'https://picsum.photos/seed/gc/400/300',
135 + created_time: '2026-01-07 00:00:00'
136 + },
137 +
138 + {
139 + id: 8,
140 + product_name: 'FA 宏浚传承保障计划',
141 + recommend: 'hot',
142 + form_sn: 'savings-fa', // 对应 SavingsTemplate
143 + categories: [
144 + { id: 'savings', name: '储蓄保险' }
145 + ],
146 + tags: [
147 + { id: 't1', name: '储蓄型', bg_color: '#E0E7FF', text_color: '#3730A3' },
148 + { id: 't2', name: '财富传承', bg_color: '#FEF3C7', text_color: '#92400E' }
149 + ],
150 + cover_image: 'https://picsum.photos/seed/fa/400/300',
151 + created_time: '2026-01-08 00:00:00'
152 + },
153 +
154 + {
155 + id: 9,
156 + product_name: 'LV2 赤霞珠终身寿险计划2',
157 + recommend: 'hot',
158 + form_sn: 'savings-lv2', // 对应 SavingsTemplate
159 + categories: [
160 + { id: 'savings', name: '储蓄保险' }
161 + ],
162 + tags: [
163 + { id: 't1', name: '储蓄型', bg_color: '#E0E7FF', text_color: '#3730A3' },
164 + { id: 't2', name: '终身寿险', bg_color: '#DBEAFE', text_color: '#1E40AF' }
165 + ],
166 + cover_image: 'https://picsum.photos/seed/lv2/400/300',
167 + created_time: '2026-01-09 00:00:00'
168 + }
169 +]
170 +
171 +/**
172 + * 获取热卖产品 Mock 数据
173 + *
174 + * @description 模拟 API 返回格式,包含完整的产品列表数据
175 + * @returns {Object} 模拟的 API 响应对象
176 + * @example
177 + * const mockResponse = getHotProductsMock()
178 + * // 返回: { code: 1, data: { list: [...], total: 9 }, msg: 'success' }
179 + */
180 +export function getHotProductsMock() {
181 + return {
182 + code: 1,
183 + msg: 'success',
184 + data: {
185 + list: hotProductsMockData,
186 + total: hotProductsMockData.length,
187 + // 分类统计(可选,用于筛选)
188 + categories: [
189 + { id: 'life', name: '人寿保险' },
190 + { id: 'critical', name: '重疾保险' },
191 + { id: 'savings', name: '储蓄保险' }
192 + ]
193 + }
194 + }
195 +}
196 +
197 +/**
198 + * 根据 form_sn 获取产品 Mock 数据
199 + *
200 + * @description 用于测试特定计划书模板
201 + * @param {string} formSn - 表单模板标识
202 + * @returns {Object|null} 产品对象,未找到返回 null
203 + * @example
204 + * const product = getProductByFormSn('life-insurance-wiop3e')
205 + * // 返回: { id: 1, product_name: 'WIOP3E...', form_sn: 'life-insurance-wiop3e', ... }
206 + */
207 +export function getProductByFormSn(formSn) {
208 + return hotProductsMockData.find(p => p.form_sn === formSn) || null
209 +}
210 +
211 +/**
212 + * 获取所有计划书模板类型
213 + *
214 + * @description 返回项目中所有支持的计划书模板类型
215 + * @returns {Array} 模板类型列表
216 + * @example
217 + * const templates = getAllTemplateTypes()
218 + * // 返回: ['life-insurance-wiop3e', 'life-insurance-wiop3', 'critical-illness-mpc', ...]
219 + */
220 +export function getAllTemplateTypes() {
221 + return hotProductsMockData.map(p => ({
222 + form_sn: p.form_sn,
223 + product_name: p.product_name,
224 + category: p.categories[0]?.name
225 + }))
226 +}
227 +
228 +/**
229 + * Mock 数据使用说明
230 + *
231 + * @description 在开发环境中使用 mock 数据测试计划书功能
232 + *
233 + * ## 使用方式
234 + *
235 + * ### 方式 1: 直接替换 API 调用(推荐)
236 + * ```javascript
237 + * // src/pages/index/index.vue
238 + * import { getHotProductsMock } from '@/mock/hotProducts'
239 + *
240 + * const fetchHotProducts = async () => {
241 + * // 开发环境使用 mock 数据
242 + * if (process.env.NODE_ENV === 'development') {
243 + * const res = getHotProductsMock()
244 + * if (res.code === 1 && res.data) {
245 + * hotProducts.value = res.data.list
246 + * }
247 + * return
248 + * }
249 + *
250 + * // 生产环境调用真实 API
251 + * const res = await listAPI({ recommend: 'hot' })
252 + * // ...
253 + * }
254 + * ```
255 + *
256 + * ### 方式 2: 使用环境变量控制
257 + * ```javascript
258 + * // config/index.js
259 + * const config = {
260 + * useMock: process.env.USE_MOCK === 'true' // 环境变量控制
261 + * }
262 + *
263 + * // src/pages/index/index.vue
264 + * const fetchHotProducts = async () => {
265 + * if (config.useMock) {
266 + * const res = getHotProductsMock()
267 + * // ...
268 + * }
269 + * // ...
270 + * }
271 + * ```
272 + *
273 + * ## 测试覆盖
274 + *
275 + * Mock 数据覆盖以下计划书模板:
276 + *
277 + * ### 人寿保险 (LifeInsuranceTemplate)
278 + * - ✅ life-insurance-wiop3e - WIOP3E 盈传创富保障计划 3 - 优选版
279 + * - ✅ life-insurance-wiop3 - WIOP3 盈传创富保障计划 3
280 + *
281 + * ### 重疾保险 (CriticalIllnessTemplate)
282 + * - ✅ critical-illness-mpc - MPC 守护无间重疾
283 + * - ✅ critical-illness-mbc-pro - MBC PRO 活跃人生重疾保 PRO
284 + * - ✅ critical-illness-mbc2 - MBC2 活跃人生重疾保 2
285 + *
286 + * ### 储蓄型产品 (SavingsTemplate)
287 + * - ✅ savings-gs - GS 宏挚传承保障计划
288 + * - ✅ savings-gc - GC 宏挚家传保险计划
289 + * - ✅ savings-fa - FA 宏浚传承保障计划
290 + * - ✅ savings-lv2 - LV2 赤霞珠终身寿险计划2
291 + *
292 + * ## 测试步骤
293 + *
294 + * 1. 在首页点击任意产品的"计划书"按钮
295 + * 2. 验证弹窗标题是否正确显示产品名称
296 + * 3. 验证表单字段是否与产品类型匹配
297 + * 4. 测试表单提交功能
298 + * 5. 验证错误提示和校验规则
299 + */
...@@ -120,8 +120,8 @@ import ProductCard from '@/components/cards/ProductCard.vue'; ...@@ -120,8 +120,8 @@ import ProductCard from '@/components/cards/ProductCard.vue';
120 import MaterialCard from '@/components/cards/MaterialCard.vue'; 120 import MaterialCard from '@/components/cards/MaterialCard.vue';
121 import { listAPI } from '@/api/get_product'; 121 import { listAPI } from '@/api/get_product';
122 import { weekHotAPI } from '@/api/file'; 122 import { weekHotAPI } from '@/api/file';
123 -import { useCollectOperation } from '@/composables/useCollectOperation';
124 import { homeIconAPI } from '@/api/home'; 123 import { homeIconAPI } from '@/api/home';
124 +import { mockHotProductsListAPI } from '@/api/mock/hotProducts';
125 125
126 126
127 // User Store 127 // User Store
...@@ -246,12 +246,33 @@ const fetchHomeIcons = async () => { ...@@ -246,12 +246,33 @@ const fetchHomeIcons = async () => {
246 const hotProducts = ref([]); 246 const hotProducts = ref([]);
247 247
248 /** 248 /**
249 + * Mock 数据开关
250 + * @description 开发环境默认使用 mock 数据测试计划书功能
251 + * 生产环境必须设置为 false
252 + */
253 +const USE_MOCK_DATA = true; // ⚠️ 生产环境请设置为 false
254 +
255 +/**
249 * 获取热卖产品列表 256 * 获取热卖产品列表
250 * 257 *
251 - * @description 调用 listAPI 获取热卖产品列表 258 + * @description 根据 USE_MOCK_DATA 开关决定使用 mock 数据还是调用 API
259 + * - 开发环境使用 mock 数据测试计划书功能
260 + * - 生产环境调用 listAPI 获取真实数据
252 */ 261 */
253 const fetchHotProducts = async () => { 262 const fetchHotProducts = async () => {
254 try { 263 try {
264 + // 开发测试环境:使用 mock 数据
265 + if (USE_MOCK_DATA) {
266 + console.log('[Index] 使用 mock 数据获取热卖产品');
267 + const res = await mockHotProductsListAPI({ recommend: 'hot' });
268 + if (res.code === 1 && res.data && res.data.list) {
269 + hotProducts.value = res.data.list;
270 + console.log('[Index] Mock 数据加载成功,产品数量:', res.data.list.length);
271 + }
272 + return;
273 + }
274 +
275 + // 生产环境:调用真实 API
255 const res = await listAPI({ 276 const res = await listAPI({
256 recommend: 'hot' 277 recommend: 'hot'
257 }); 278 });
......