104 lines
2.9 KiB
TypeScript
104 lines
2.9 KiB
TypeScript
import api from '../../utils/api'
|
|||
|
|
|
||
|
|
interface ContentCategory {
|
||
|
|
id: string
|
||
|
|
name: string
|
||
|
|
}
|
||
|
|
|
||
|
|
interface ContentArticle {
|
||
|
|
id: string
|
||
|
|
title: string
|
||
|
|
summary?: string
|
||
|
|
categoryId?: string
|
||
|
|
categoryName?: string
|
||
|
|
coverFileId?: string
|
||
|
|
viewCount?: number
|
||
|
|
publishAt?: string
|
||
|
|
createdAt?: string
|
||
|
|
publishAtText?: string
|
||
|
|
}
|
||
|
|
|
||
|
|
interface ContentPageData {
|
||
|
|
categories: ContentCategory[]
|
||
|
|
activeCategoryId: string
|
||
|
|
articles: ContentArticle[]
|
||
|
|
loading: boolean
|
||
|
|
loadError: boolean
|
||
|
|
}
|
||
|
|
|
||
|
|
const formatDate = (value: string | undefined): string => {
|
||
|
|
if (!value) return ''
|
||
|
|
const date = new Date(value)
|
||
|
|
if (Number.isNaN(date.getTime())) return ''
|
||
|
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||
|
|
const day = String(date.getDate()).padStart(2, '0')
|
||
|
|
return `${date.getFullYear()}-${month}-${day}`
|
||
|
|
}
|
||
|
|
|
||
|
|
Page({
|
||
|
|
data: {
|
||
|
|
categories: [{ id: '', name: '推荐' }],
|
||
|
|
activeCategoryId: '',
|
||
|
|
articles: [],
|
||
|
|
loading: true,
|
||
|
|
loadError: false,
|
||
|
|
},
|
||
|
|
|
||
|
|
onLoad() {
|
||
|
|
this.loadPage()
|
||
|
|
},
|
||
|
|
|
||
|
|
async loadPage() {
|
||
|
|
this.setData({ loading: true, loadError: false })
|
||
|
|
try {
|
||
|
|
const [categories, articles] = await Promise.all([
|
||
|
|
api.get<ContentCategory[]>('/content/categories'),
|
||
|
|
api.get<ContentArticle[]>('/content/articles'),
|
||
|
|
])
|
||
|
|
this.setData({
|
||
|
|
categories: [{ id: '', name: '推荐' }, ...(categories || [])],
|
||
|
|
articles: this.normalizeArticles(articles || [], categories || []),
|
||
|
|
loading: false,
|
||
|
|
})
|
||
|
|
} catch (error) {
|
||
|
|
console.error('加载婚恋课堂失败', error)
|
||
|
|
this.setData({ loading: false, loadError: true })
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
normalizeArticles(articles: ContentArticle[], categories: ContentCategory[]): ContentArticle[] {
|
||
|
|
const categoryNames = new Map<string, string>()
|
||
|
|
categories.forEach((item) => categoryNames.set(item.id, item.name))
|
||
|
|
return articles.map((item) => ({
|
||
|
|
...item,
|
||
|
|
categoryName: categoryNames.get(item.categoryId || '') || '婚恋课堂',
|
||
|
|
publishAtText: formatDate(item.publishAt || item.createdAt),
|
||
|
|
}))
|
||
|
|
},
|
||
|
|
|
||
|
|
async select(e: WechatMiniprogram.TouchEvent) {
|
||
|
|
const categoryId = (e.currentTarget.dataset.id as string) || ''
|
||
|
|
if (categoryId === this.data.activeCategoryId) return
|
||
|
|
this.setData({ activeCategoryId: categoryId, loading: true, loadError: false })
|
||
|
|
try {
|
||
|
|
const articles = await api.get<ContentArticle[]>('/content/articles', categoryId ? { categoryId } : undefined)
|
||
|
|
this.setData({
|
||
|
|
articles: this.normalizeArticles(articles || [], this.data.categories),
|
||
|
|
loading: false,
|
||
|
|
})
|
||
|
|
} catch (error) {
|
||
|
|
console.error('加载课堂分类失败', error)
|
||
|
|
this.setData({ loading: false, loadError: true })
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
open(e: WechatMiniprogram.TouchEvent) {
|
||
|
|
const id = e.currentTarget.dataset.id as string
|
||
|
|
if (id) wx.navigateTo({ url: `/pages/content-detail/content-detail?id=${id}` })
|
||
|
|
},
|
||
|
|
|
||
|
|
onRetry() {
|
||
|
|
this.loadPage()
|
||
|
|
},
|
||
|
|
})
|