feat: 接入内容服务端真实接口并优化页面交互
- 迁移内容数据到服务端接口,移除本地模拟数据 - 首页新增推荐课程加载与未读消息检查 - 资讯、课程、搜索页面支持分页加载与错误重试 - 登录页新增恢复课程、消息、帮助页的路由逻辑 - 评估分析页新增处理中状态动效与阶段提示 - API 环境切换到正式域名 airz.hqling.cloud
This commit is contained in:
@@ -1,48 +1 @@
|
||||
import { API_DEMO_ENABLED, API_BASE_URL, requestJson } from '@/services/api.uts'
|
||||
import { newsArticles, financeLessons, ContentSection } from './content.uts'
|
||||
|
||||
export type ContentSearchResult = {
|
||||
id: string, type: string, title: string, summary: string, category: string, meta: string, image: string
|
||||
}
|
||||
|
||||
const sectionText = (sections: ContentSection[]): string => sections.map((item: ContentSection): string => item.title + ' ' + item.body).join(' ')
|
||||
const matches = (text: string, words: string[]): boolean => words.every((word: string): boolean => text.toLowerCase().includes(word))
|
||||
const readText = (item: UTSJSONObject, key: string): string => typeof item[key] == 'string' ? item[key] as string : ''
|
||||
|
||||
// type: all / news / lesson。接入后端时返回相同类型的 items,详情沿用内容 ID。
|
||||
export async function searchContent(keyword: string, type: string): Promise<ContentSearchResult[]> {
|
||||
const query = keyword.trim().replace(/\s+/g, ' ')
|
||||
const results: ContentSearchResult[] = []
|
||||
if (query.length == 0) return results
|
||||
if (!API_DEMO_ENABLED) {
|
||||
const response = await requestJson('/content/search', 'GET', { keyword: query, type })
|
||||
const items = response['items'] as UTSJSONObject[] | null
|
||||
if (items == null) throw new Error('搜索结果加载失败,请重试')
|
||||
items.forEach((item: UTSJSONObject) => {
|
||||
const kind = readText(item, 'type'); const id = readText(item, 'id'); const title = readText(item, 'title')
|
||||
if ((kind == 'news' || kind == 'lesson') && (type == 'all' || type == kind) && id.length > 0 && title.length > 0) {
|
||||
const result: ContentSearchResult = { id, type: kind, title, summary: readText(item, 'summary'), category: readText(item, 'category'), meta: readText(item, 'meta'), image: readText(item, 'image') }
|
||||
results.push(result)
|
||||
}
|
||||
})
|
||||
return results
|
||||
}
|
||||
const words = query.toLowerCase().split(' ')
|
||||
if (type == 'all' || type == 'news') {
|
||||
newsArticles.forEach((item) => {
|
||||
if (matches(item.title + ' ' + item.summary + ' ' + item.category + ' ' + sectionText(item.sections), words)) {
|
||||
const result: ContentSearchResult = { id: item.id, type: 'news', title: item.title, summary: item.summary, category: item.category, meta: item.date, image: item.image }
|
||||
results.push(result)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (type == 'all' || type == 'lesson') {
|
||||
financeLessons.forEach((item) => {
|
||||
if (matches(item.title + ' ' + item.desc + ' ' + item.tag + ' ' + item.intro + ' ' + sectionText(item.chapters), words)) {
|
||||
const result: ContentSearchResult = { id: item.id, type: 'lesson', title: item.title, summary: item.desc, category: item.tag, meta: item.duration + ' · ' + item.chapters.length + ' 节', image: item.image }
|
||||
results.push(result)
|
||||
}
|
||||
})
|
||||
}
|
||||
return results
|
||||
}
|
||||
export { ContentSearchResult, SearchPage, searchContent } from '@/services/content.uts'
|
||||
|
||||
Reference in New Issue
Block a user