import { request, redirectToLogin } from '../../utils/request' import * as auth from '../../utils/auth' import { PagedResult, OutfitItem } from '../../types/models' import { OutfitSource, IsPublic, STORAGE_KEYS } from '../../utils/config' import { normalizePaged, mergePaged, hasMorePaged } from '../../utils/paged' Page({ data: { activeTab: 0, list: [] as OutfitItem[], loading: true, refreshing: false, loadingMore: false, page: 1, pageSize: 20, hasMore: true, }, onShow() { this.syncTabBar() // 未登录直接回登录页(幂等跳转),不再发出必然 401 的请求 if (!auth.isLoggedIn()) { redirectToLogin() return } const openCollect = wx.getStorageSync(STORAGE_KEYS.OPEN_COLLECT) if (openCollect) { wx.removeStorageSync(STORAGE_KEYS.OPEN_COLLECT) if (this.data.activeTab !== 1) { this.setData({ activeTab: 1, list: [], loading: true }) } } this.refresh() }, syncTabBar() { const tabBar = (this as any).getTabBar && (this as any).getTabBar() if (tabBar) tabBar.setData({ selected: 1 }) }, onTabChange(e: WechatMiniprogram.TouchEvent) { const index = Number(e.currentTarget.dataset.index) if (index === this.data.activeTab) return this.setData({ activeTab: index, list: [], loading: true }) this.refresh() }, refresh() { this.setData({ page: 1, hasMore: true, loading: this.data.list.length === 0 }) this.fetchList(1) }, onRefresh() { this.setData({ refreshing: true }) this.fetchList(1).finally(() => this.setData({ refreshing: false })) }, onReachBottom() { if (!this.data.hasMore || this.data.loading || this.data.loadingMore) return this.fetchList(this.data.page + 1) }, fetchList(page: number): Promise { const isCollect = this.data.activeTab === 1 const url = isCollect ? '/collect' : '/outfit' const seq = ((this as any).reqSeq || 0) + 1 ;(this as any).reqSeq = seq if (page > 1) this.setData({ loadingMore: true }) return request>({ url, data: { page, page_size: this.data.pageSize } }) .then(async (res) => { const { list: raw, total } = normalizePaged(res) const items = await this.decorateList(raw) // decorateList 是异步的,期间可能已切换 tab:序号不匹配则丢弃 if ((this as any).reqSeq !== seq) return const merged = mergePaged(this.data.list, items, page === 1) this.setData({ list: merged, hasMore: hasMorePaged(merged, total, this.data.pageSize), loading: false, loadingMore: false, page, }) }) .catch(() => { if ((this as any).reqSeq !== seq) return this.setData({ loading: false, loadingMore: false }) }) }, decorateList(list: OutfitItem[]): Promise { return Promise.all( list.map(async (it) => { let likeCount = 0 try { const like = await request<{ is_liked: boolean; like_count: number }>({ url: `/like/${it.outfit_uuid}`, showError: false, }) likeCount = like.like_count } catch (e) {} return { ...it, _likeCount: likeCount, _status: this.getStatusText(it) } }) ) }, getStatusText(it: OutfitItem): { text: string; type: string } { if (it.source === OutfitSource.AI) return { text: 'AI 推荐', type: 'indigo' } if (it.is_public === IsPublic.PUBLIC) return { text: '已公开', type: 'blue' } return { text: '仅自己可见', type: 'gray' } }, onCreate() { wx.navigateTo({ url: '/pages/outfit-edit/outfit-edit' }) }, onAiRecommend() { wx.navigateTo({ url: '/pages/ai-recommend/ai-recommend' }) }, onOutfitTap(e: WechatMiniprogram.TouchEvent) { const uuid = e.currentTarget.dataset.uuid as string const owner = this.data.activeTab === 0 ? '1' : '0' wx.navigateTo({ url: `/pages/outfit-detail/outfit-detail?uuid=${uuid}&owner=${owner}` }) }, })