/** * 我的缘分页 U22(重构:用 matchStore + ui-user-card + ui-nav-bar) * * 3 Tab:互相喜欢(Mutual)/ 我喜欢的 / 喜欢我的(脱敏) * 游标分页:下拉刷新 + onReachBottom 加载更多 * like-back:喜欢我的人 → 表达喜欢 → 若 Mutual 自动跳聊天 * * 不变量(AGENTS.md): * - 第 3 条:Mutual Match 后才能聊天——Mutual Tab 点击进入会话;未 Mutual 不可发起会话。 * - 第 6 条:单向意向不泄露——"喜欢我的"仅展示后端返回的脱敏字段(昵称/年龄/地区/是否已 Mutual), * Store 与页面均不做二次身份还原。 * - 第 5 条:红娘不可替用户 Like——like-back 仅当前用户本人操作。 * - 第 9 条:PostgreSQL 是 Source of Truth——列表状态以 matchStore 同步服务端返回为准。 */ const { matchStore, appStore, likeUser } = require('../../stores'); const { to, ROUTE } = require('../../constants'); const TAB_MUTUAL = 'mutual'; const TAB_LIKED = 'liked'; const TAB_LIKERS = 'likers'; const PAGE_SIZE = 20; Page({ data: { activeTab: TAB_MUTUAL, // 来自 matchStore 的列表(bindToPage 同步) mutualList: [], mutualHasMore: true, likedList: [], likedHasMore: true, likersList: [], likersHasMore: true, likersCount: 0, // 页面局部状态 loading: false, loadingMore: false, actionLoadingUserId: '', statusBarHeight: 20, navBarHeight: 44, }, onLoad() { try { const info = (wx.getWindowInfo && wx.getWindowInfo()) || wx.getSystemInfoSync(); this.setData({ statusBarHeight: info.statusBarHeight || 20, navBarHeight: info.platform === 'android' ? 48 : 44, }); } catch (e) { /* 使用默认值 */ } // 绑定 matchStore 列表字段到页面 this._unsub = matchStore.bindToPage(this, { mutualList: 'mutualList', mutualHasMore: 'mutualHasMore', likedList: 'likedList', likedHasMore: 'likedHasMore', likersList: 'likersList', likersHasMore: 'likersHasMore', likersCount: 'likersCount', }); this._fetchTab(TAB_MUTUAL, true); }, onUnload() { if (this._unsub) this._unsub(); }, onShow() { // 返回页面时刷新当前 Tab(状态可能已变化) this._fetchTab(this.data.activeTab, true); }, // ============ Tab 切换 ============ onTabChange(e) { const tab = e.currentTarget.dataset.tab; if (!tab || tab === this.data.activeTab) return; this.setData({ activeTab: tab }); this._fetchTab(tab, true); }, /** 按当前 Tab 拉取首页 */ async _fetchTab(tab, first) { if (this.data.loading) return; this.setData({ loading: true }); try { const params = { pageSize: PAGE_SIZE }; if (tab === TAB_MUTUAL) { await matchStore.fetchMutualList(params); } else if (tab === TAB_LIKED) { await matchStore.fetchLikedList(params); } else if (tab === TAB_LIKERS) { await matchStore.fetchLikersList(params); } } catch (err) { appStore.toastError(err); } finally { this.setData({ loading: false }); } }, // ============ 列表交互 ============ onPullDownRefresh() { this._fetchTab(this.data.activeTab, true).finally(() => wx.stopPullDownRefresh()); }, onReachBottom() { if (this.data.loadingMore) return; const tab = this.data.activeTab; const hasMore = tab === TAB_MUTUAL ? this.data.mutualHasMore : tab === TAB_LIKED ? this.data.likedHasMore : this.data.likersHasMore; if (!hasMore) return; this.setData({ loadingMore: true }); (async () => { try { if (tab === TAB_MUTUAL) await matchStore.loadMoreMutualList(); else if (tab === TAB_LIKED) await matchStore.loadMoreLikedList(); else await matchStore.loadMoreLikersList(); } catch (err) { appStore.toastError(err); } finally { this.setData({ loadingMore: false }); } })(); }, // ============ 卡片操作 ============ /** * 互相喜欢 / 我喜欢的 → 查看资料详情 * 互相喜欢还可直接进入会话(已 Mutual,允许聊天) */ onViewDetail(e) { const userId = e.detail && e.detail.userId; if (!userId) return; wx.navigateTo({ url: to.detail(userId) }); }, /** 互相喜欢 → 查看资料和公益服务 */ /** * 喜欢我的人 → 喜欢 TA(like-back) * 若达成 Mutual,likeUser 会自动刷新会话列表,此处跳转到聊天 */ async onLikeBack(e) { const userId = e.currentTarget.dataset.userId; if (!userId || this.data.actionLoadingUserId) return; this.setData({ actionLoadingUserId: userId }); try { const result = await likeUser(userId); // 从"喜欢我的"列表移除(已做出判断) matchStore.setState({ likersList: matchStore.state.likersList.filter((u) => u.userId !== userId), }); if (result && result.mutualMatch) { appStore.toastSuccess('双向意向匹配成功,可查看公益服务'); // 刷新互相喜欢列表 try { await matchStore.fetchMutualList({ pageSize: PAGE_SIZE }); } catch (e2) { /* ignore */ } } else { appStore.toastSuccess('已表达喜欢'); } } catch (err) { appStore.toastError(err); } finally { this.setData({ actionLoadingUserId: '' }); } }, onBack() { wx.navigateBack(); }, /** 空状态动作 */ onEmptyAction() { wx.switchTab({ url: ROUTE.TAB.DISCOVER }); }, });