hookehuyr

refactor(search): 将搜索结果中的资料改为文章展示

- 替换 MaterialCard 为 ArticleCard 组件
- 更新 Tab 名称:资料 → 文章
- 更新数据字段:data.files → data.article
- 映射 API 字段:post_title, post_excerpt, post_date, is_favorite
- 同步更新 mock 数据使用 generateArticleItem

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
...@@ -3,6 +3,71 @@ ...@@ -3,6 +3,71 @@
3 记录项目开发过程中的重要变更和完成任务。 3 记录项目开发过程中的重要变更和完成任务。
4 4
5 ## 2026-02-28 5 ## 2026-02-28
6 +### 19:54:54 - docs
7 +
8 +- 更新搜索 API 响应字段:files → article
9 +- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
10 +- 文章详情 API 添加 file_list 字段类型定义
11 +- 计划书 API 完善参数文档说明
12 +
13 +Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>(api
14 +
15 +- 更新搜索 API 响应字段:files → article
16 +- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
17 +- 文章详情 API 添加 file_list 字段类型定义
18 +- 计划书 API 完善参数文档说明
19 +
20 +Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>): 同步搜索 API 文档,将 file 类型改为 article
21 +
22 +- 更新搜索 API 响应字段:files → article
23 +- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
24 +- 文章详情 API 添加 file_list 字段类型定义
25 +- 计划书 API 完善参数文档说明
26 +
27 +Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
28 +
29 +**影响文件**:
30 +- `docs/api-specs/search/search.md`
31 +- `src/api/article.js`
32 +- `src/api/plan.js`
33 +
34 +**变更摘要**:
35 +- 同步搜索 API 文档,将 file 类型改为 article
36 +
37 +- 更新搜索 API 响应字段:files → article
38 +- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
39 +- 文章详情 API 添加 file_list 字段类型定义
40 +- 计划书 API 完善参数文档说明
41 +
42 +Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
43 +
44 +**相关提交**:
45 +- `a4ef54a` - docs
46 +
47 +- 更新搜索 API 响应字段:files → article
48 +- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
49 +- 文章详情 API 添加 file_list 字段类型定义
50 +- 计划书 API 完善参数文档说明
51 +
52 +Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>(api
53 +
54 +- 更新搜索 API 响应字段:files → article
55 +- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
56 +- 文章详情 API 添加 file_list 字段类型定义
57 +- 计划书 API 完善参数文档说明
58 +
59 +Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>): 同步搜索 API 文档,将 file 类型改为 article
60 +
61 +- 更新搜索 API 响应字段:files → article
62 +- 字段名规范化:name/value/extension → post_title/post_excerpt/post_link
63 +- 文章详情 API 添加 file_list 字段类型定义
64 +- 计划书 API 完善参数文档说明
65 +
66 +Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
67 +
68 +---
69 +
70 +
6 ### 17:11:05 - fix 71 ### 17:11:05 - fix
7 72
8 - 删除 if/else 块外部的重复 mv 命令 73 - 删除 if/else 块外部的重复 mv 命令
......
1 <!-- 1 <!--
2 * @Date: 2026-02-08 2 * @Date: 2026-02-08
3 * @Description: 搜索页面 - 使用 LoadMoreList 组件重构版本 3 * @Description: 搜索页面 - 使用 LoadMoreList 组件重构版本
4 - * @description 支持产品和资料搜索,实时查询API,自动切换分类 4 + * @description 支持产品和文章搜索,实时查询API,自动切换分类
5 --> 5 -->
6 <template> 6 <template>
7 <view class="bg-[#FFF] search-page-container"> 7 <view class="bg-[#FFF] search-page-container">
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
27 <view class="px-[40rpx] mt-[32rpx]"> 27 <view class="px-[40rpx] mt-[32rpx]">
28 <SearchBar 28 <SearchBar
29 v-model="searchKeyword" 29 v-model="searchKeyword"
30 - placeholder="搜索培训资料、案例、产品..." 30 + placeholder="搜索文章、产品..."
31 variant="rounded" 31 variant="rounded"
32 :show-border="true" 32 :show-border="true"
33 :show-clear="true" 33 :show-clear="true"
...@@ -80,18 +80,18 @@ ...@@ -80,18 +80,18 @@
80 )" 80 )"
81 /> 81 />
82 82
83 - <!-- File Results --> 83 + <!-- Article Results -->
84 - <MaterialCard 84 + <ArticleCard
85 - v-else-if="activeTab === 'file'" 85 + v-else-if="activeTab === 'article'"
86 :id="item.id" 86 :id="item.id"
87 :title="item.title" 87 :title="item.title"
88 - :file-name="item.fileName" 88 + :excerpt="item.excerpt"
89 - :file-size="item.fileSize" 89 + :cover-url="item.coverUrl"
90 + :date="item.date"
90 :learners="item.learners" 91 :learners="item.learners"
91 :read-people-percent="item.readPeoplePercent" 92 :read-people-percent="item.readPeoplePercent"
92 :collected="item.collected" 93 :collected="item.collected"
93 - :extension="item.extension" 94 + :show-cover="!!item.coverUrl"
94 - :download-url="item.downloadUrl"
95 class="search-result-item" 95 class="search-result-item"
96 @collect-changed="handleCollectChanged(item, $event)" 96 @collect-changed="handleCollectChanged(item, $event)"
97 /> 97 />
...@@ -102,7 +102,7 @@ ...@@ -102,7 +102,7 @@
102 <!-- Initial State (从未搜索过) --> 102 <!-- Initial State (从未搜索过) -->
103 <view v-if="!hasSearched" class="flex flex-col items-center justify-center py-[120rpx]"> 103 <view v-if="!hasSearched" class="flex flex-col items-center justify-center py-[120rpx]">
104 <IconFont name="search" class="text-gray-300 mb-[24rpx]" size="64" /> 104 <IconFont name="search" class="text-gray-300 mb-[24rpx]" size="64" />
105 - <view class="text-[#6B7280] text-[28rpx]">搜索产品或资料</view> 105 + <view class="text-[#6B7280] text-[28rpx]">搜索产品或文章</view>
106 <view class="text-[#9CA3AF] text-[24rpx] mt-[12rpx]">输入关键词开始搜索,自动切换分类</view> 106 <view class="text-[#9CA3AF] text-[24rpx] mt-[12rpx]">输入关键词开始搜索,自动切换分类</view>
107 </view> 107 </view>
108 108
...@@ -136,7 +136,7 @@ import NavHeader from '@/components/navigation/NavHeader.vue' ...@@ -136,7 +136,7 @@ import NavHeader from '@/components/navigation/NavHeader.vue'
136 import IconFont from '@/components/icons/IconFont.vue' 136 import IconFont from '@/components/icons/IconFont.vue'
137 import SearchBar from '@/components/forms/SearchBar.vue' 137 import SearchBar from '@/components/forms/SearchBar.vue'
138 import ProductCard from '@/components/cards/ProductCard.vue' 138 import ProductCard from '@/components/cards/ProductCard.vue'
139 -import MaterialCard from '@/components/cards/MaterialCard.vue' 139 +import ArticleCard from '@/components/cards/ArticleCard.vue'
140 import PlanFormContainer from '@/components/plan/PlanFormContainer.vue' 140 import PlanFormContainer from '@/components/plan/PlanFormContainer.vue'
141 import { searchAPI } from '@/api/search' 141 import { searchAPI } from '@/api/search'
142 import { mockSearchAPI } from '@/utils/mockData' 142 import { mockSearchAPI } from '@/utils/mockData'
...@@ -169,7 +169,7 @@ onMounted(() => { ...@@ -169,7 +169,7 @@ onMounted(() => {
169 169
170 /** 170 /**
171 * 搜索页面状态管理 171 * 搜索页面状态管理
172 - * @description 支持双类型(产品/资料)搜索,自动切换分类 172 + * @description 支持双类型(产品/文章)搜索,自动切换分类
173 */ 173 */
174 174
175 // Plan Popup State 175 // Plan Popup State
...@@ -183,9 +183,9 @@ const hasSearched = ref(false) // 是否已经搜索过 ...@@ -183,9 +183,9 @@ const hasSearched = ref(false) // 是否已经搜索过
183 183
184 // 数据状态 - 双列表系统 184 // 数据状态 - 双列表系统
185 const products = ref([]) // 产品列表 185 const products = ref([]) // 产品列表
186 -const files = ref([]) // 资料列表 186 +const articles = ref([]) // 文章列表
187 const productsTotal = ref(0) // 产品总数 187 const productsTotal = ref(0) // 产品总数
188 -const filesTotal = ref(0) // 资料总数 188 +const articlesTotal = ref(0) // 文章总数
189 189
190 // 分页状态 190 // 分页状态
191 const loading = ref(false) // 首次加载状态 191 const loading = ref(false) // 首次加载状态
...@@ -195,11 +195,11 @@ const currentPage = ref(0) // 当前页码(从0开始) ...@@ -195,11 +195,11 @@ const currentPage = ref(0) // 当前页码(从0开始)
195 const pageSize = 20 // 每页数量 195 const pageSize = 20 // 每页数量
196 196
197 /** 197 /**
198 - * Tab 数据源(只保留产品和资料 198 + * Tab 数据源(只保留产品和文章
199 */ 199 */
200 const tabsData = ref([ 200 const tabsData = ref([
201 { id: 'product', name: '产品' }, 201 { id: 'product', name: '产品' },
202 - { id: 'file', name: '资料' }, 202 + { id: 'article', name: '文章' },
203 ]) 203 ])
204 204
205 /** 205 /**
...@@ -213,7 +213,7 @@ const currentList = computed(() => { ...@@ -213,7 +213,7 @@ const currentList = computed(() => {
213 if (activeTab.value === 'product') { 213 if (activeTab.value === 'product') {
214 return products.value 214 return products.value
215 } else { 215 } else {
216 - return files.value 216 + return articles.value
217 } 217 }
218 }) 218 })
219 219
...@@ -227,7 +227,7 @@ const currentTotal = computed(() => { ...@@ -227,7 +227,7 @@ const currentTotal = computed(() => {
227 if (activeTab.value === 'product') { 227 if (activeTab.value === 'product') {
228 return productsTotal.value 228 return productsTotal.value
229 } else { 229 } else {
230 - return filesTotal.value 230 + return articlesTotal.value
231 } 231 }
232 }) 232 })
233 233
...@@ -244,7 +244,7 @@ const shouldEnableScrollLoad = computed(() => { ...@@ -244,7 +244,7 @@ const shouldEnableScrollLoad = computed(() => {
244 * 执行搜索 244 * 执行搜索
245 * 245 *
246 * @param {string} keyword - 搜索关键字 246 * @param {string} keyword - 搜索关键字
247 - * @param {string} type - 可选,'product' | 'file' | undefined 247 + * @param {string} type - 可选,'product' | 'article' | undefined
248 * @param {number} page - 页码(从0开始) 248 * @param {number} page - 页码(从0开始)
249 * @param {number} limit - 每页数量 249 * @param {number} limit - 每页数量
250 * @param {boolean} isLoadMore - 是否为加载更多 250 * @param {boolean} isLoadMore - 是否为加载更多
...@@ -273,43 +273,39 @@ const performSearch = async (keyword, type, page = 0, limit = pageSize, isLoadMo ...@@ -273,43 +273,39 @@ const performSearch = async (keyword, type, page = 0, limit = pageSize, isLoadMo
273 // 映射产品列表 273 // 映射产品列表
274 const newProducts = res.data.products.list || [] 274 const newProducts = res.data.products.list || []
275 275
276 - // 映射资料列表(进行字段映射,与首页保持一致) 276 + // 映射文章列表(参考本周热门文章的映射方式)
277 - const newFiles = (res.data.files.list || []).map(item => { 277 + const newArticles = (res.data.article.list || []).map(item => ({
278 - return { 278 + id: item.id,
279 - id: item.meta_id || item.id, 279 + title: item.post_title || '未命名文章',
280 - title: item.name, 280 + excerpt: item.post_excerpt || '',
281 - fileName: item.name || '未命名文件', 281 + coverUrl: '', // API 未返回封面图,留空
282 - fileSize: item.size || item.file_size, 282 + date: item.post_date || '',
283 - downloadUrl: item.src || item.value, 283 + collected: item.is_favorite === 1 || item.is_favorite === '1' || item.is_favorite === true,
284 - // 不手动提取 extension,让 MaterialCard 内部使用 extractExtensionFromFile 自动从 URL 解析 284 + learners: '', // API 未返回学习人数,留空
285 - learners: item.read_people_count ? `${item.read_people_count }人学习` : '', 285 + readPeoplePercent: null // API 未返回热度百分比,留空
286 - readPeoplePercent: item.read_people_percent, 286 + }))
287 - is_favorite: item.is_favorite, // 保留原始字段
288 - collected: Boolean(item.is_favorite) // 转换为 Boolean 供 MaterialCard 使用
289 - }
290 - })
291 287
292 // 根据是否为加载更多来处理数据 288 // 根据是否为加载更多来处理数据
293 if (isLoadMore) { 289 if (isLoadMore) {
294 // 加载更多:追加数据 290 // 加载更多:追加数据
295 products.value = [...products.value, ...newProducts] 291 products.value = [...products.value, ...newProducts]
296 - files.value = [...files.value, ...newFiles] 292 + articles.value = [...articles.value, ...newArticles]
297 } else { 293 } else {
298 // 首次加载或刷新:替换数据 294 // 首次加载或刷新:替换数据
299 products.value = newProducts 295 products.value = newProducts
300 - files.value = newFiles 296 + articles.value = newArticles
301 } 297 }
302 298
303 productsTotal.value = res.data.products.total || 0 299 productsTotal.value = res.data.products.total || 0
304 - filesTotal.value = res.data.files.total || 0 300 + articlesTotal.value = res.data.article.total || 0
305 301
306 // ⚠️ 重要:必须先自动选择 tab,然后再计算 hasMore 302 // ⚠️ 重要:必须先自动选择 tab,然后再计算 hasMore
307 // 如果不传 type,自动选择有数据的 tab(仅首次搜索时) 303 // 如果不传 type,自动选择有数据的 tab(仅首次搜索时)
308 if (!type && !isLoadMore) { 304 if (!type && !isLoadMore) {
309 if (productsTotal.value > 0) { 305 if (productsTotal.value > 0) {
310 activeTab.value = 'product' 306 activeTab.value = 'product'
311 - } else if (filesTotal.value > 0) { 307 + } else if (articlesTotal.value > 0) {
312 - activeTab.value = 'file' 308 + activeTab.value = 'article'
313 } 309 }
314 // 如果都为 0,默认 product 310 // 如果都为 0,默认 product
315 } 311 }
...@@ -320,8 +316,8 @@ const performSearch = async (keyword, type, page = 0, limit = pageSize, isLoadMo ...@@ -320,8 +316,8 @@ const performSearch = async (keyword, type, page = 0, limit = pageSize, isLoadMo
320 const actualTab = type || activeTab.value 316 const actualTab = type || activeTab.value
321 if (actualTab === 'product') { 317 if (actualTab === 'product') {
322 hasMore.value = products.value.length < productsTotal.value 318 hasMore.value = products.value.length < productsTotal.value
323 - } else if (actualTab === 'file') { 319 + } else if (actualTab === 'article') {
324 - hasMore.value = files.value.length < filesTotal.value 320 + hasMore.value = articles.value.length < articlesTotal.value
325 } else { 321 } else {
326 // 如果都没有选中,保守设置为false 322 // 如果都没有选中,保守设置为false
327 hasMore.value = false 323 hasMore.value = false
...@@ -331,7 +327,7 @@ const performSearch = async (keyword, type, page = 0, limit = pageSize, isLoadMo ...@@ -331,7 +327,7 @@ const performSearch = async (keyword, type, page = 0, limit = pageSize, isLoadMo
331 327
332 console.log('[Search] 搜索成功', { 328 console.log('[Search] 搜索成功', {
333 productsTotal: productsTotal.value, 329 productsTotal: productsTotal.value,
334 - filesTotal: filesTotal.value, 330 + articlesTotal: articlesTotal.value,
335 activeTab: activeTab.value, 331 activeTab: activeTab.value,
336 isLoadMore, 332 isLoadMore,
337 hasMore: hasMore.value 333 hasMore: hasMore.value
...@@ -437,9 +433,9 @@ const clearSearch = () => { ...@@ -437,9 +433,9 @@ const clearSearch = () => {
437 searchKeyword.value = '' 433 searchKeyword.value = ''
438 hasSearched.value = false 434 hasSearched.value = false
439 products.value = [] 435 products.value = []
440 - files.value = [] 436 + articles.value = []
441 productsTotal.value = 0 437 productsTotal.value = 0
442 - filesTotal.value = 0 438 + articlesTotal.value = 0
443 activeTab.value = '' // 重置为空,不选中任何tab 439 activeTab.value = '' // 重置为空,不选中任何tab
444 currentPage.value = 0 440 currentPage.value = 0
445 hasMore.value = true 441 hasMore.value = true
...@@ -500,15 +496,15 @@ const { handlePlanSubmit } = usePlanSubmit({ ...@@ -500,15 +496,15 @@ const { handlePlanSubmit } = usePlanSubmit({
500 /** 496 /**
501 * 处理收藏状态改变 497 * 处理收藏状态改变
502 * 498 *
503 - * @param {Object} item - 资料对象 499 + * @param {Object} item - 文章对象
504 * @param {Object} newStatus - 新的状态 { collected: boolean } 500 * @param {Object} newStatus - 新的状态 { collected: boolean }
505 */ 501 */
506 const handleCollectChanged = (item, newStatus) => { 502 const handleCollectChanged = (item, newStatus) => {
507 console.log('[Search] 收藏状态改变:', item.title, newStatus.collected) 503 console.log('[Search] 收藏状态改变:', item.title, newStatus.collected)
508 // 找到对应的项并更新状态 504 // 找到对应的项并更新状态
509 - const file = files.value.find(f => f.id === item.id) 505 + const article = articles.value.find(a => a.id === item.id)
510 - if (file) { 506 + if (article) {
511 - file.collected = newStatus.collected 507 + article.collected = newStatus.collected
512 } 508 }
513 } 509 }
514 </script> 510 </script>
......
...@@ -516,9 +516,9 @@ export async function mockSearchAPI(params) { ...@@ -516,9 +516,9 @@ export async function mockSearchAPI(params) {
516 516
517 if (!keyword) { 517 if (!keyword) {
518 // 🔧 优化:如果没有关键词,返回更多推荐数据用于测试 518 // 🔧 优化:如果没有关键词,返回更多推荐数据用于测试
519 - // 生成20个产品和20个资料作为默认搜索结果 519 + // 生成20个产品和20个文章作为默认搜索结果
520 const defaultProducts = [] 520 const defaultProducts = []
521 - const defaultFiles = [] 521 + const defaultArticles = []
522 522
523 for (let i = 0; i < 20; i++) { 523 for (let i = 0; i < 20; i++) {
524 const productItem = generateProductItem(i + 1) 524 const productItem = generateProductItem(i + 1)
...@@ -528,32 +528,17 @@ export async function mockSearchAPI(params) { ...@@ -528,32 +528,17 @@ export async function mockSearchAPI(params) {
528 cover_image: productItem.cover_image 528 cover_image: productItem.cover_image
529 }) 529 })
530 530
531 - const materialItem = generateMaterialItem(i + 1) 531 + const articleItem = generateArticleItem(i + 1)
532 - // 确保使用真实的测试文件地址 532 + defaultArticles.push(articleItem)
533 - const testFileUrl = getTestFileUrl(materialItem.extension, i)
534 -
535 - defaultFiles.push({
536 - ...materialItem,
537 - id: i + 1,
538 - fileName: materialItem.fileName,
539 - fileSize: materialItem.size,
540 - learners: `${materialItem.read_people_count}人学习`,
541 - readPeoplePercent: materialItem.read_people_percent,
542 - collected: materialItem.collected,
543 - extension: materialItem.extension,
544 - downloadUrl: testFileUrl, // 覆盖为真实的测试文件地址
545 - title: materialItem.title,
546 - src: materialItem.src
547 - })
548 } 533 }
549 534
550 - console.log(`[Mock] searchAPI - 无关键词,返回默认数据:产品${defaultProducts.length}条,资料${defaultFiles.length}条`) 535 + console.log(`[Mock] searchAPI - 无关键词,返回默认数据:产品${defaultProducts.length}条,文章${defaultArticles.length}条`)
551 return { 536 return {
552 code: 1, 537 code: 1,
553 msg: 'success', 538 msg: 'success',
554 data: { 539 data: {
555 products: { list: defaultProducts, total: defaultProducts.length * 5 }, 540 products: { list: defaultProducts, total: defaultProducts.length * 5 },
556 - files: { list: defaultFiles, total: defaultFiles.length * 5 } 541 + article: { list: defaultArticles, total: defaultArticles.length * 5 }
557 } 542 }
558 } 543 }
559 } 544 }
...@@ -566,13 +551,13 @@ export async function mockSearchAPI(params) { ...@@ -566,13 +551,13 @@ export async function mockSearchAPI(params) {
566 msg: 'success', 551 msg: 'success',
567 data: { 552 data: {
568 products: { list: [], total: 0 }, 553 products: { list: [], total: 0 },
569 - files: { list: [], total: 0 } 554 + article: { list: [], total: 0 }
570 } 555 }
571 } 556 }
572 } 557 }
573 558
574 const products = [] 559 const products = []
575 - const files = [] 560 + const articles = []
576 const startIndex = page * limit 561 const startIndex = page * limit
577 562
578 // 🔧 优化:每次循环都生成数据和尝试匹配,增加命中率 563 // 🔧 优化:每次循环都生成数据和尝试匹配,增加命中率
...@@ -598,35 +583,20 @@ export async function mockSearchAPI(params) { ...@@ -598,35 +583,20 @@ export async function mockSearchAPI(params) {
598 }) 583 })
599 } 584 }
600 585
601 - // 资料 586 + // 文章
602 - const materialItem = generateMaterialItem(startIndex + i + 100) 587 + const articleItem = generateArticleItem(startIndex + i + 100)
603 - const materialName = materialItem.name.toLowerCase() 588 + const articleTitle = articleItem.post_title.toLowerCase()
604 - 589 +
605 - const hasAnyCharMaterial = keywords.length > 0 && keywords.some(k => materialName.includes(k)) 590 + const hasAnyCharArticle = keywords.length > 0 && keywords.some(k => articleTitle.includes(k))
606 - const hasBigramMaterial = searchKeyword.length >= 2 && keywords.slice(0, -1).some((k, idx) => materialName.includes(k + keywords[idx + 1])) 591 + const hasBigramArticle = searchKeyword.length >= 2 && keywords.slice(0, -1).some((k, idx) => articleTitle.includes(k + keywords[idx + 1]))
607 - 592 +
608 - if (materialName.includes(searchKeyword) || hasAnyCharMaterial || hasBigramMaterial) { 593 + if (articleTitle.includes(searchKeyword) || hasAnyCharArticle || hasBigramArticle) {
609 - // 确保使用真实的测试文件地址 594 + articles.push(articleItem)
610 - const testFileUrl = getTestFileUrl(materialItem.extension, startIndex + i + 100)
611 -
612 - files.push({
613 - ...materialItem,
614 - id: startIndex + i + 100,
615 - fileName: materialItem.fileName,
616 - fileSize: materialItem.size,
617 - learners: `${materialItem.read_people_count}人学习`,
618 - readPeoplePercent: materialItem.read_people_percent,
619 - collected: materialItem.collected,
620 - extension: materialItem.extension,
621 - downloadUrl: testFileUrl, // 覆盖为真实的测试文件地址
622 - title: materialItem.title,
623 - src: materialItem.src
624 - })
625 } 595 }
626 } 596 }
627 597
628 // 🔧 优化:如果没有匹配到任何数据,返回一些推荐数据 598 // 🔧 优化:如果没有匹配到任何数据,返回一些推荐数据
629 - if (products.length === 0 && files.length === 0) { 599 + if (products.length === 0 && articles.length === 0) {
630 console.log(`[Mock] searchAPI - 无匹配结果,返回推荐数据`) 600 console.log(`[Mock] searchAPI - 无匹配结果,返回推荐数据`)
631 // 生成 5 个推荐产品 601 // 生成 5 个推荐产品
632 for (let i = 0; i < 5; i++) { 602 for (let i = 0; i < 5; i++) {
...@@ -637,34 +607,19 @@ export async function mockSearchAPI(params) { ...@@ -637,34 +607,19 @@ export async function mockSearchAPI(params) {
637 cover_image: productItem.cover_image 607 cover_image: productItem.cover_image
638 }) 608 })
639 609
640 - const materialItem = generateMaterialItem(startIndex + i + 100) 610 + const articleItem = generateArticleItem(startIndex + i + 100)
641 - // 确保使用真实的测试文件地址 611 + articles.push(articleItem)
642 - const testFileUrl = getTestFileUrl(materialItem.extension, startIndex + i + 100)
643 -
644 - files.push({
645 - ...materialItem,
646 - id: startIndex + i + 100,
647 - fileName: materialItem.fileName,
648 - fileSize: materialItem.size,
649 - learners: `${materialItem.read_people_count}人学习`,
650 - readPeoplePercent: materialItem.read_people_percent,
651 - collected: materialItem.collected,
652 - extension: materialItem.extension,
653 - downloadUrl: testFileUrl, // 覆盖为真实的测试文件地址
654 - title: materialItem.title,
655 - src: materialItem.src
656 - })
657 } 612 }
658 } 613 }
659 614
660 - console.log(`[Mock] searchAPI - 第${page}页,关键词"${keyword}",产品${products.length}条,资料${files.length}条`) 615 + console.log(`[Mock] searchAPI - 第${page}页,关键词"${keyword}",产品${products.length}条,文章${articles.length}条`)
661 616
662 return { 617 return {
663 code: 1, 618 code: 1,
664 msg: 'success', 619 msg: 'success',
665 data: { 620 data: {
666 products: { list: products, total: products.length * totalPages }, 621 products: { list: products, total: products.length * totalPages },
667 - files: { list: files, total: files.length * totalPages } 622 + article: { list: articles, total: articles.length * totalPages }
668 } 623 }
669 } 624 }
670 } 625 }
......