221 lines
6.4 KiB
TypeScript
221 lines
6.4 KiB
TypeScript
import { loadBackendAuthTokens, loadBackendBaseUrl } from '../../utils/backendAuth'
|
|
import {
|
|
getEntryHome,
|
|
type BackendCardResult,
|
|
type BackendContentBundleSummary,
|
|
type BackendPresentationSummary,
|
|
} from '../../utils/backendApi'
|
|
import { reportBackendClientLog } from '../../utils/backendClientLogs'
|
|
|
|
const DEFAULT_CHANNEL_CODE = 'mini-demo'
|
|
const DEFAULT_CHANNEL_TYPE = 'wechat_mini'
|
|
|
|
type EventListFilter = 'all' | 'experience'
|
|
|
|
type EventCardView = {
|
|
id: string
|
|
eventId: string
|
|
titleText: string
|
|
subtitleText: string
|
|
summaryText: string
|
|
statusText: string
|
|
timeWindowText: string
|
|
ctaText: string
|
|
badgeText: string
|
|
eventTypeText: string
|
|
presentationText: string
|
|
contentBundleText: string
|
|
coverUrl: string
|
|
disabled: boolean
|
|
}
|
|
|
|
type EventsPageData = {
|
|
loading: boolean
|
|
statusText: string
|
|
currentFilter: EventListFilter
|
|
cards: EventCardView[]
|
|
}
|
|
|
|
function requireAuthToken(): string | null {
|
|
const app = getApp<IAppOption>()
|
|
const tokens = app.globalData && app.globalData.backendAuthTokens
|
|
? app.globalData.backendAuthTokens
|
|
: loadBackendAuthTokens()
|
|
return tokens && tokens.accessToken ? tokens.accessToken : null
|
|
}
|
|
|
|
function formatPresentationSummary(summary?: BackendPresentationSummary | null): string {
|
|
if (!summary) {
|
|
return '当前未声明展示版本'
|
|
}
|
|
|
|
return summary.version || summary.templateKey || summary.presentationId || '当前未声明展示版本'
|
|
}
|
|
|
|
function formatContentBundleSummary(summary?: BackendContentBundleSummary | null): string {
|
|
if (!summary) {
|
|
return '当前未声明内容包版本'
|
|
}
|
|
|
|
return summary.version || summary.bundleType || summary.bundleId || '当前未声明内容包版本'
|
|
}
|
|
|
|
function buildCardView(card: BackendCardResult): EventCardView {
|
|
const eventId = card.event && card.event.id ? card.event.id : ''
|
|
const statusText = card.status || card.statusCode || '状态待确认'
|
|
const badgeText = card.isDefaultExperience ? '体验' : '活动'
|
|
const eventTypeText = card.eventType || '类型待确认'
|
|
const subtitleText = card.subtitle || (card.event && card.event.displayName ? card.event.displayName : '')
|
|
|
|
return {
|
|
id: card.id,
|
|
eventId,
|
|
titleText: card.title || '未命名活动',
|
|
subtitleText,
|
|
summaryText: card.summary || (card.event && card.event.summary ? card.event.summary : '当前暂无活动摘要'),
|
|
statusText,
|
|
timeWindowText: card.timeWindow || '时间待公布',
|
|
ctaText: card.ctaText || '查看详情',
|
|
badgeText,
|
|
eventTypeText,
|
|
presentationText: formatPresentationSummary(card.currentPresentation),
|
|
contentBundleText: formatContentBundleSummary(card.currentContentBundle),
|
|
coverUrl: card.coverUrl || '',
|
|
disabled: !eventId,
|
|
}
|
|
}
|
|
|
|
function applyFilter(cards: BackendCardResult[], filter: EventListFilter): EventCardView[] {
|
|
const filtered = filter === 'experience'
|
|
? cards.filter((item) => item.isDefaultExperience === true)
|
|
: cards
|
|
|
|
return filtered
|
|
.slice()
|
|
.sort((left, right) => {
|
|
const leftPriority = typeof left.displayPriority === 'number' ? left.displayPriority : 0
|
|
const rightPriority = typeof right.displayPriority === 'number' ? right.displayPriority : 0
|
|
return rightPriority - leftPriority
|
|
})
|
|
.map(buildCardView)
|
|
}
|
|
|
|
Page({
|
|
data: {
|
|
loading: false,
|
|
statusText: '准备加载活动列表',
|
|
currentFilter: 'all',
|
|
cards: [],
|
|
} as EventsPageData,
|
|
|
|
onLoad() {
|
|
this.loadCards()
|
|
},
|
|
|
|
onShow() {
|
|
this.loadCards()
|
|
},
|
|
|
|
async loadCards() {
|
|
const accessToken = requireAuthToken()
|
|
if (!accessToken) {
|
|
wx.redirectTo({ url: '/pages/login/login' })
|
|
return
|
|
}
|
|
|
|
this.setData({
|
|
loading: true,
|
|
statusText: '正在加载活动列表',
|
|
})
|
|
|
|
try {
|
|
const result = await getEntryHome({
|
|
baseUrl: loadBackendBaseUrl(),
|
|
accessToken,
|
|
channelCode: DEFAULT_CHANNEL_CODE,
|
|
channelType: DEFAULT_CHANNEL_TYPE,
|
|
})
|
|
this.applyCards(result.cards || [])
|
|
} catch (error) {
|
|
const message = error && (error as { message?: string }).message ? (error as { message: string }).message : '未知错误'
|
|
this.setData({
|
|
loading: false,
|
|
statusText: `活动列表加载失败:${message}`,
|
|
cards: [],
|
|
})
|
|
}
|
|
},
|
|
|
|
applyCards(cards: BackendCardResult[]) {
|
|
reportBackendClientLog({
|
|
level: 'info',
|
|
category: 'event-cards',
|
|
message: 'event cards loaded',
|
|
details: {
|
|
filter: this.data.currentFilter,
|
|
cardCount: cards.length,
|
|
experienceCount: cards.filter((item) => item.isDefaultExperience === true).length,
|
|
cardEventIds: cards.map((item) => (item.event && item.event.id ? item.event.id : '')),
|
|
},
|
|
})
|
|
|
|
const filteredCards = applyFilter(cards, this.data.currentFilter)
|
|
this.setData({
|
|
loading: false,
|
|
statusText: filteredCards.length ? '活动列表加载完成' : '当前没有可显示活动',
|
|
cards: filteredCards,
|
|
})
|
|
const pageInstance = this as unknown as WechatMiniprogram.Page.Instance<EventsPageData, Record<string, never>> & {
|
|
rawCards?: BackendCardResult[]
|
|
}
|
|
pageInstance.rawCards = cards
|
|
},
|
|
|
|
handleSwitchFilter(event: WechatMiniprogram.TouchEvent) {
|
|
const filter = event.currentTarget.dataset.filter as EventListFilter | undefined
|
|
if (!filter || filter === this.data.currentFilter) {
|
|
return
|
|
}
|
|
|
|
const pageInstance = this as unknown as WechatMiniprogram.Page.Instance<EventsPageData, Record<string, never>> & {
|
|
rawCards?: BackendCardResult[]
|
|
}
|
|
const rawCards = pageInstance.rawCards || []
|
|
const filteredCards = applyFilter(rawCards, filter)
|
|
this.setData({
|
|
currentFilter: filter,
|
|
statusText: filteredCards.length ? '活动列表加载完成' : '当前筛选下没有活动',
|
|
cards: filteredCards,
|
|
})
|
|
},
|
|
|
|
handleRefresh() {
|
|
this.loadCards()
|
|
},
|
|
|
|
handleOpenCard(event: WechatMiniprogram.TouchEvent) {
|
|
const eventId = event.currentTarget.dataset.eventId as string | undefined
|
|
reportBackendClientLog({
|
|
level: 'info',
|
|
category: 'event-cards',
|
|
message: 'event card clicked',
|
|
eventId: eventId || '',
|
|
details: {
|
|
clickedEventId: eventId || '',
|
|
filter: this.data.currentFilter,
|
|
},
|
|
})
|
|
if (!eventId) {
|
|
wx.showToast({
|
|
title: '该卡片暂无活动入口',
|
|
icon: 'none',
|
|
})
|
|
return
|
|
}
|
|
|
|
wx.navigateTo({
|
|
url: `/pages/event/event?eventId=${encodeURIComponent(eventId)}`,
|
|
})
|
|
},
|
|
})
|