Files
zt-closet-wxmini-frontend/miniprogram/pages/closet-share/closet-share.ts
T
2026-09-13 02:28:46 +08:00

132 lines
4.2 KiB
TypeScript

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<PagedResult<ClosetShareItem>>({ url, data: { page, page_size: this.data.pageSize } })
.then((res) => {
if ((this as any).reqSeq !== seq) return
const { list: raw, total } = normalizePaged<ClosetShareItem>(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),
})
},
})