import { request, redirectToLogin } from '../../utils/request' import * as auth from '../../utils/auth' import { PagedResult, ClosetShareItem } from '../../types/models' import { ShareStatus, ShareType } from '../../utils/config' import { normalizePaged, mergePaged, hasMorePaged } from '../../utils/paged' import { setTabBarSelected } from '../../utils/tabbar' import { logger } from '../../utils/logger' // 日志模块名 const LOG = 'closet-share' Page({ data: { tabs: [ { name: '我的分享' }, { name: '分享给我的' }, ], activeTab: 0, // 0 我的分享 1 分享给我的 list: [] as ClosetShareItem[], loading: true, loadingMore: false, page: 1, pageSize: 20, hasMore: true, }, onShow() { this.syncTabBar() // 未登录直接回登录页(幂等跳转),不再发出必然 401 的请求 if (!auth.isLoggedIn()) { redirectToLogin() return } this.refresh() }, syncTabBar() { setTabBarSelected(3) }, onTabTap(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) }, onReachBottom() { if (!this.data.hasMore || this.data.loading || this.data.loadingMore) return this.fetchList(this.data.page + 1) }, fetchList(page: number) { const url = this.data.activeTab === 0 ? '/closet-share' : '/closet-share/received' // 请求序号:切 tab 时旧响应可能后到,序号不匹配直接丢弃 const seq = ((this as any).reqSeq || 0) + 1 ;(this as any).reqSeq = seq if (page > 1) this.setData({ loadingMore: true }) request>({ url, data: { page, page_size: this.data.pageSize } }) .then((res) => { if ((this as any).reqSeq !== seq) return const { list: raw, total } = normalizePaged(res) logger.debug(LOG, '列表加载成功, tab=', this.data.activeTab, 'page=', page, '条数=', raw && raw.length) const list = raw.map((it) => this.decorate(it)) const merged = mergePaged(this.data.list, list, page === 1) this.setData({ list: merged, hasMore: hasMorePaged(merged, total, this.data.pageSize), loading: false, loadingMore: false, page, }) }) .catch((e: any) => { if ((this as any).reqSeq !== seq) return logger.warn(LOG, '列表加载失败, tab=', this.data.activeTab, 'page=', page, 'code=', e && e.code) this.setData({ loading: false, loadingMore: false }) }) }, decorate(it: ClosetShareItem) { const now = Math.floor(Date.now() / 1000) let status = it.status if (status === ShareStatus.NORMAL && it.expire_time > 0 && it.expire_time < now) { status = ShareStatus.EXPIRED } let expireText = '长期有效' if (status === ShareStatus.CANCELLED) expireText = '已取消' else if (status === ShareStatus.EXPIRED) expireText = '已过期' else if (status === ShareStatus.BANNED) expireText = '已封禁' else if (it.expire_time > 0) { const days = Math.ceil((it.expire_time - now) / 86400) expireText = days > 0 ? `${days} 天后过期` : '已过期' } return { ...it, _status: status, _expireText: expireText, _typeText: it.share_type === ShareType.PARTIAL ? '部分衣物' : '全量衣橱', _invalid: status === ShareStatus.CANCELLED || status === ShareStatus.EXPIRED || status === ShareStatus.BANNED, } }, onCreate() { wx.navigateTo({ url: '/pages/closet-share-create/closet-share-create', fail: (e) => logger.warn(LOG, 'navigateTo 创建分享失败, err=', e && e.errMsg), }) }, onItemTap(e: WechatMiniprogram.TouchEvent) { const uuid = e.currentTarget.dataset.uuid as string logger.debug(LOG, '点击分享项, uuid=', uuid) wx.navigateTo({ url: `/pages/closet-share-detail/closet-share-detail?uuid=${uuid}`, fail: (err) => logger.warn(LOG, 'navigateTo 分享详情失败, err=', err && err.errMsg), }) }, })