import { request } from '../../utils/request' import { ClothesItem, PagedResult, UserInfo } from '../../types/models' import { STORAGE_KEYS } from '../../utils/config' import { normalizePaged, hasMorePaged } from '../../utils/paged' const CATEGORIES = [ { name: '全部', value: '' }, { name: '上装', value: '上装' }, { name: '下装', value: '下装' }, { name: '连衣裙', value: '连衣裙' }, { name: '外套', value: '外套' }, { name: '鞋', value: '鞋' }, { name: '配饰', value: '配饰' }, ] const EXPIRE_OPTIONS = [ { label: '1 天', days: 1 }, { label: '7 天', days: 7 }, { label: '30 天', days: 30 }, { label: '长期有效', days: 0 }, ] const PAGE_SIZE = 50 Page({ data: { view: 'config' as 'config' | 'select' | 'success', shareType: 1, expireDays: 7, expireOptions: EXPIRE_OPTIONS, selectedUuids: [] as string[], categories: CATEGORIES, activeCategory: 0, allClothes: [] as ClothesItem[], selectLoading: true, loadingMore: false, hasMore: true, page: 1, submitting: false, shareUuid: '', nickname: '微信用户', avatar: '', selectedCount: 0, }, onLoad() { this.loadUserInfo() }, loadUserInfo() { const cached = wx.getStorageSync(STORAGE_KEYS.USER_INFO) as Record if (cached) { this.setData({ nickname: cached.username || '微信用户', avatar: cached.avatar || '' }) } // 头像为带时间戳的签名 URL,缓存可能过期,实时刷新并回写缓存。 request({ url: '/user/info', showError: false }) .then((user) => { wx.setStorageSync(STORAGE_KEYS.USER_INFO, user) this.setData({ nickname: user.username || '微信用户', avatar: user.avatar || '' }) }) .catch(() => {}) }, selectPartial() { this.setData({ shareType: 1 }) }, selectFull() { this.setData({ shareType: 2 }) }, selectExpire(e: WechatMiniprogram.TouchEvent) { const days = Number(e.currentTarget.dataset.days) this.setData({ expireDays: days }) }, openSelect() { this.setData({ view: 'select', selectLoading: true, page: 1, hasMore: true }) this.fetchAllClothes(1) }, fetchAllClothes(page = 1) { const cat = CATEGORIES[this.data.activeCategory].value const params: Record = { page, page_size: PAGE_SIZE } if (cat) params.category_main = cat // 请求序号:切换分类时旧响应可能后到,序号不匹配直接丢弃 const seq = ((this as any).reqSeq || 0) + 1 ;(this as any).reqSeq = seq if (page > 1) this.setData({ loadingMore: true }) request>({ url: '/clothes', data: params }) .then((res) => { if ((this as any).reqSeq !== seq) return const { list: raw, total } = normalizePaged(res) const list = raw.map((it) => ({ ...it, _selected: this.data.selectedUuids.indexOf(it.clothes_uuid) >= 0, })) const merged = page === 1 ? list : this.data.allClothes.concat(list) this.setData({ allClothes: merged, selectLoading: false, loadingMore: false, page, hasMore: hasMorePaged(merged, total, PAGE_SIZE), }) }) .catch(() => { if ((this as any).reqSeq !== seq) return this.setData({ selectLoading: false, loadingMore: false }) }) }, onCategoryTap(e: WechatMiniprogram.TouchEvent) { const index = Number(e.currentTarget.dataset.index) if (index === this.data.activeCategory) return this.setData({ activeCategory: index, selectLoading: true, page: 1, hasMore: true }) this.fetchAllClothes(1) }, onReachBottom() { if (this.data.view !== 'select') return if (!this.data.hasMore || this.data.selectLoading || this.data.loadingMore) return this.fetchAllClothes(this.data.page + 1) }, onToggleSelect(e: WechatMiniprogram.CustomEvent) { const item = e.detail.item as ClothesItem const uuids = this.data.selectedUuids const idx = uuids.indexOf(item.clothes_uuid) if (idx >= 0) { this.syncSelect(uuids.filter((u) => u !== item.clothes_uuid)) } else { this.syncSelect([...uuids, item.clothes_uuid]) } }, syncSelect(uuids: string[]) { this.setData({ selectedUuids: uuids, allClothes: this.data.allClothes.map((it) => ({ ...it, _selected: uuids.indexOf(it.clothes_uuid) >= 0, })), }) }, confirmSelect() { this.setData({ view: 'config', selectedCount: this.data.selectedUuids.length }) }, backToConfig() { this.setData({ view: 'config' }) }, onConfirm() { if (this.data.submitting) return const body: Record = { share_type: this.data.shareType } if (this.data.shareType === 1) { if (!this.data.selectedUuids.length) { wx.showToast({ title: '请选择要分享的衣物', icon: 'none' }) return } body.clothes_uuids = this.data.selectedUuids } const days = this.data.expireDays body.expire_time = days > 0 ? Math.floor(Date.now() / 1000) + days * 86400 : 0 // 提交加锁:连点会重复创建分享、重复扣额度 this.setData({ submitting: true }) request<{ share_uuid: string }>({ url: '/closet-share', method: 'POST', data: body }) .then((res) => this.setData({ shareUuid: res.share_uuid, view: 'success', submitting: false })) .catch(() => this.setData({ submitting: false })) }, onViewShare() { wx.redirectTo({ url: `/pages/closet-share-detail/closet-share-detail?uuid=${this.data.shareUuid}` }) }, onDone() { wx.navigateBack() }, })