hookehuyr

docs: 整理文档结构并使用中文命名

**主要变更**:
- 将组件相关文档移动到 guides/components/
  - LoadMoreList 迁移指南.md
  - LoadMoreList 完整使用指南.md
- 将 API/Mock 相关文档移动到 api-specs/数据文档/
  - Mock 数据完整总结.md
  - Mock 数据设置指南.md
  - API 集成日志.md
- 将测试相关文档移动到相应目录
  - 滚动加载测试指南.md → guides/testing/
  - 计划测试实施报告.md → reports/测试报告/
- 更新所有文档中的相对路径引用
- 添加文档命名使用中文规则到全局规则

**详细信息**:
- **影响文件**: docs/ 目录下所有文档
- **技术栈**: 文档组织
- **测试状态**: N/A
- **备注**: 提升文档可维护性和查找效率

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
...@@ -302,7 +302,7 @@ console.log(product.form_sn) // 应该有值,如 "life-insurance-wiop3e" ...@@ -302,7 +302,7 @@ console.log(product.form_sn) // 应该有值,如 "life-insurance-wiop3e"
302 302
303 - [完整架构文档](./plan-entry-architecture.md) 303 - [完整架构文档](./plan-entry-architecture.md)
304 - [经验教训总结](../lessons-learned/plan-entry-module-summary.md) 304 - [经验教训总结](../lessons-learned/plan-entry-module-summary.md)
305 -- [API 联调日志](../api-integration-log.md) 305 +- [API 联调日志](../api-specs/API 集成日志.md)
306 306
307 --- 307 ---
308 308
......
...@@ -9,7 +9,6 @@ docs/ ...@@ -9,7 +9,6 @@ docs/
9 ├── CHANGELOG.md # 项目变更日志(核心文档) 9 ├── CHANGELOG.md # 项目变更日志(核心文档)
10 ├── README.md # 本文件(文档导航索引) 10 ├── README.md # 本文件(文档导航索引)
11 ├── lessons-learned.md # 经验教训总结(核心文档) 11 ├── lessons-learned.md # 经验教训总结(核心文档)
12 -├── api-integration-log.md # API 联调日志
13 12
14 ├── guides/ # 📘 使用指南和教程 13 ├── guides/ # 📘 使用指南和教程
15 │ ├── START_HERE.md # 新人入门指南 14 │ ├── START_HERE.md # 新人入门指南
...@@ -77,7 +76,7 @@ docs/ ...@@ -77,7 +76,7 @@ docs/
77 ### 核心文档 76 ### 核心文档
78 - 📖 [项目变更日志](CHANGELOG.md) - 所有功能、修复和优化的记录 77 - 📖 [项目变更日志](CHANGELOG.md) - 所有功能、修复和优化的记录
79 - 📖 [经验教训总结](lessons-learned.md) - 开发中的最佳实践和常见陷阱 78 - 📖 [经验教训总结](lessons-learned.md) - 开发中的最佳实践和常见陷阱
80 -- 📖 [API 联调日志](api-integration-log.md) - 接口联调状态记录 79 +- 📖 [API 联调日志](api-specs/API 集成日志.md) - 接口联调状态记录
81 80
82 ### 新手入门 81 ### 新手入门
83 👉 **[guides/START_HERE.md](guides/START_HERE.md)** - 快速了解项目功能 82 👉 **[guides/START_HERE.md](guides/START_HERE.md)** - 快速了解项目功能
...@@ -163,7 +162,7 @@ UI/UX 设计稿和生成的代码: ...@@ -163,7 +162,7 @@ UI/UX 设计稿和生成的代码:
163 162
164 ### 更新日志 163 ### 更新日志
165 - 项目级别的更新:修改 `CHANGELOG.md` 164 - 项目级别的更新:修改 `CHANGELOG.md`
166 -- API 联调记录:修改 `api-integration-log.md` 165 +- API 联调记录:修改 `api-specs/API 集成日志.md`
167 166
168 --- 167 ---
169 168
......
1 +# 原始页面备份
2 +
3 +> **备份时间**: 2026-02-08
4 +> **备份原因**: LoadMoreList 组件迁移前的代码备份
5 +> **迁移提交**: ce4b99b refactor: 迁移所有剩余页面到 LoadMoreList 组件
6 +
7 +---
8 +
9 +## 📁 备份文件列表
10 +
11 +| 文件 | 大小 | 说明 |
12 +|------|------|------|
13 +| `message-index.vue.bak` | 3.7 KB | 消息列表页(迁移前) |
14 +| `product-center-index.vue.bak` | 13.9 KB | 产品中心页(迁移前) |
15 +| `material-list-index.vue.bak` | 24.6 KB | 资料列表页(迁移前) |
16 +| `search-index.vue.bak` | 17 KB | 搜索页(迁移前) |
17 +
18 +---
19 +
20 +## 🔄 如何恢复原始代码
21 +
22 +### 方法 1: 手动恢复(推荐)
23 +
24 +如果新组件有问题,可以手动恢复:
25 +
26 +```bash
27 +# 1. 删除当前文件
28 +rm src/pages/message/index.vue
29 +
30 +# 2. 从备份恢复
31 +cp docs/backups/original-pages/message-index.vue.bak src/pages/message/index.vue
32 +
33 +# 3. 重复其他文件...
34 +```
35 +
36 +### 方法 2: 使用 Git 恢复
37 +
38 +使用 Git 命令恢复到迁移前的版本:
39 +
40 +```bash
41 +# 恢复单个文件
42 +git checkout ce4b99b^ -- src/pages/message/index.vue
43 +
44 +# 恢复所有文件
45 +git checkout ce4b99b^ -- src/pages/message/index.vue \
46 + src/pages/product-center/index.vue \
47 + src/pages/material-list/index.vue \
48 + src/pages/search/index.vue
49 +```
50 +
51 +---
52 +
53 +## 📋 迁移前后对比
54 +
55 +### message 页面
56 +
57 +| 指标 | 迁移前 | 迁移后 |
58 +|------|--------|--------|
59 +| 代码行数 | 149 行 | 229 行 |
60 +| 分页逻辑 | 手动实现 | LoadMoreList 组件 |
61 +| 下拉刷新 | ❌ 无 | ✅ 有 |
62 +
63 +### product-center 页面
64 +
65 +| 指标 | 迁移前 | 迁移后 |
66 +|------|--------|--------|
67 +| 代码行数 | 510 行 | 592 行 |
68 +| 分页逻辑 | 手动实现 | LoadMoreList 组件 |
69 +| 搜索功能 | ✅ 有 | ✅ 保留 |
70 +| Tabs | ✅ 有 | ✅ 保留 |
71 +
72 +### material-list 页面
73 +
74 +| 指标 | 迁移前 | 迁移后 |
75 +|------|--------|--------|
76 +| 代码行数 | 888 行 | 828 行 |
77 +| 分页逻辑 | 手动实现 | LoadMoreList 组件 |
78 +| 分类缓存 | ✅ 有 | ✅ 保留 |
79 +| 搜索防抖 | ✅ 有 | ✅ 保留 |
80 +
81 +### search 页面
82 +
83 +| 指标 | 迁移前 | 迁移后 |
84 +|------|--------|--------|
85 +| 代码行数 | 603 行 | 549 行 |
86 +| 分页逻辑 | 手动实现 | LoadMoreList 组件 |
87 +| 双列表系统 | ✅ 有 | ✅ 保留 |
88 +| 自动 tab 选择 | ✅ 有 | ✅ 保留 |
89 +
90 +---
91 +
92 +## ⚠️ 注意事项
93 +
94 +1. **备份文件只读**: 这些是 `.bak` 文件,只用于参考,不应直接修改
95 +2. **使用 Git 版本控制**: 建议使用 Git 命令恢复,而不是手动复制
96 +3. **测试新组件**: 如果新组件有问题,先检查是否可以通过修改解决
97 +4. **保留备份**: 建议保留这些备份文件,直到确认新组件完全稳定
98 +
99 +---
100 +
101 +## 🔍 迁移问题排查
102 +
103 +如果新组件有问题,按以下步骤排查:
104 +
105 +### 1. 检查 Props 是否正确
106 +
107 +```vue
108 +<!-- ❌ 错误:缺少必需 props -->
109 +<LoadMoreList :list="products" @load-more="handleLoadMore">
110 +
111 +<!-- ✅ 正确:包含所有必需 props -->
112 +<LoadMoreList
113 + :list="products"
114 + :page="page"
115 + :has-more="hasMore"
116 + :loading="loading"
117 + :loading-more="loadingMore"
118 + @load-more="handleLoadMore"
119 +>
120 +```
121 +
122 +### 2. 检查数据加载逻辑
123 +
124 +```javascript
125 +// ❌ 错误:未正确处理追加数据
126 +const handleLoadMore = async (page) => {
127 + const newData = await fetchData({ page })
128 + currentList.value = newData // 错误:会覆盖之前的数据
129 +}
130 +
131 +// ✅ 正确:追加数据
132 +const handleLoadMore = async (page) => {
133 + const newData = await fetchData({ page })
134 + currentList.value = [...currentList.value, ...newData]
135 +}
136 +```
137 +
138 +### 3. 检查 hasMore 判断逻辑
139 +
140 +```javascript
141 +// ❌ 错误:使用总数量判断
142 +hasMore.value = currentList.value.length < total
143 +
144 +// ✅ 正确:使用返回数据量判断
145 +hasMore.value = newData.length >= pageSize
146 +```
147 +
148 +### 4. 检查 page 初始值
149 +
150 +```javascript
151 +// 如果 API 页码从 1 开始
152 +const page = ref(1)
153 +
154 +// 如果 API 页码从 0 开始
155 +const page = ref(0)
156 +
157 +// 组件会自动 +1,所以不需要手动 +1
158 +```
159 +
160 +---
161 +
162 +## 📖 相关文档
163 +
164 +- [LoadMoreList 完整指南](../guides/components/LoadMoreList 完整使用指南.md)
165 +- [LoadMoreList 迁移指南](../guides/components/LoadMoreList 迁移指南.md)
166 +- [项目 CLAUDE.md](../../CLAUDE.md)
167 +
168 +---
169 +
170 +**创建时间**: 2026-02-08
171 +**维护者**: Claude Code
This diff is collapsed. Click to expand it.
1 +<template>
2 + <view class="min-h-screen bg-[#F9FAFB] pb-safe">
3 + <NavHeader title="我的消息" />
4 +
5 + <!-- 列表区域 -->
6 + <view class="p-4">
7 + <template v-if="messageList.length > 0">
8 + <view
9 + v-for="item in messageList"
10 + :key="item.id"
11 + class="bg-white rounded-xl p-4 mb-3 shadow-sm active:opacity-70 transition-opacity"
12 + @tap="handleItemClick(item)"
13 + >
14 + <view class="flex justify-between items-start mb-2">
15 + <view class="flex-1 mr-2">
16 + <view class="text-base font-bold text-gray-900 line-clamp-1">
17 + {{ item.title }}
18 + </view>
19 + </view>
20 + <text class="text-xs text-gray-400 shrink-0 mt-1">
21 + {{ item.create_time }}
22 + </text>
23 + </view>
24 +
25 + <view class="text-sm text-gray-600 line-clamp-2 leading-relaxed">
26 + {{ item.intro || item.content || '暂无简介' }}
27 + </view>
28 + </view>
29 +
30 + <!-- 加载更多/没有更多 -->
31 + <view class="py-4 text-center text-[24rpx] text-gray-400">
32 + <text v-if="loading">加载中...</text>
33 + <text v-else-if="!hasMore">没有更多了</text>
34 + <text v-else>上拉加载更多</text>
35 + </view>
36 + </template>
37 +
38 + <!-- 空状态 -->
39 + <nut-empty
40 + v-else-if="!loading && messageList.length === 0"
41 + description="暂无消息"
42 + image="empty"
43 + />
44 + </view>
45 + </view>
46 +</template>
47 +
48 +<script setup>
49 +import { ref } from 'vue'
50 +import { useLoad, usePullDownRefresh, useReachBottom, stopPullDownRefresh } from '@tarojs/taro'
51 +import { useGo } from '@/hooks/useGo'
52 +import NavHeader from '@/components/NavHeader.vue'
53 +import { myListAPI } from '@/api/news'
54 +import { mockMessageListAPI } from '@/utils/mockData'
55 +
56 +// ⚠️ MOCK 数据开关 - 开发环境使用 mock 数据,生产环境使用真实 API
57 +const USE_MOCK_DATA = process.env.NODE_ENV === 'development'
58 +
59 +const go = useGo()
60 +
61 +const messageList = ref([])
62 +const page = ref(1)
63 +const limit = ref(10)
64 +const hasMore = ref(true)
65 +const loading = ref(false)
66 +
67 +/**
68 + * @description 加载消息列表
69 + * @param {boolean} refresh 是否刷新
70 + */
71 +const fetchMessageList = async (refresh = false) => {
72 + if (loading.value) return
73 +
74 + if (refresh) {
75 + page.value = 1
76 + hasMore.value = true
77 + } else if (!hasMore.value) {
78 + return
79 + }
80 +
81 + loading.value = true
82 +
83 + try {
84 + console.log('[Message] 使用 Mock 数据:', USE_MOCK_DATA)
85 +
86 + // 根据开关选择使用真实 API 或 Mock 数据
87 + const res = USE_MOCK_DATA
88 + ? await mockMessageListAPI({
89 + page: page.value,
90 + limit: limit.value
91 + })
92 + : await myListAPI({
93 + page: page.value,
94 + limit: limit.value
95 + })
96 +
97 + if (res.code === 1) {
98 + const list = res.data?.list || []
99 +
100 + if (refresh) {
101 + messageList.value = list
102 + } else {
103 + messageList.value = [...messageList.value, ...list]
104 + }
105 +
106 + if (list.length < limit.value) {
107 + hasMore.value = false
108 + } else {
109 + page.value++
110 + }
111 + }
112 + } catch (err) {
113 + console.error('获取消息列表失败:', err)
114 + } finally {
115 + loading.value = false
116 + if (refresh) {
117 + stopPullDownRefresh()
118 + }
119 + }
120 +}
121 +
122 +/**
123 + * @description 跳转到详情页
124 + * @param {Object} item 消息对象
125 + */
126 +const handleItemClick = (item) => {
127 + go('/pages/message-detail/index', { id: item.id })
128 +}
129 +
130 +// 页面加载
131 +useLoad(() => {
132 + fetchMessageList(true)
133 +})
134 +
135 +// 下拉刷新
136 +usePullDownRefresh(() => {
137 + fetchMessageList(true)
138 +})
139 +
140 +// 上拉加载更多
141 +useReachBottom(() => {
142 + fetchMessageList()
143 +})
144 +</script>
145 +
146 +<style lang="less">
147 +/* Scoped styles if needed */
148 +</style>
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
...@@ -670,7 +670,7 @@ if (!Number.isNaN(birthDate.getTime())) { ...@@ -670,7 +670,7 @@ if (!Number.isNaN(birthDate.getTime())) {
670 670
671 ### 项目文档 671 ### 项目文档
672 - [计划书架构设计](../plan/plan-entry-architecture.md) 672 - [计划书架构设计](../plan/plan-entry-architecture.md)
673 -- [API 联调日志](../api-integration-log.md) 673 +- [API 联调日志](../api-specs/API 集成日志.md)
674 - [变更日志](../CHANGELOG.md) 674 - [变更日志](../CHANGELOG.md)
675 675
676 ### 技术文档 676 ### 技术文档
......