xiangqinxiaochengxu/miniprogram/pages/my-matches/my-matches.js

137 lines
4.4 KiB
JavaScript

const request = require('../../utils/request')
const { resolveImageUrl } = require('../../utils/media')
Page({
data: {
activityId: null,
activeTab: 'my_choices',
activityTitle: '',
tabs: [
{ key: 'my_choices', label: '我的选择' },
{ key: 'liked_me', label: '谁选了我' },
{ key: 'mutual_matches', label: '匹配成功' }
],
matches: [],
loading: false
},
onLoad(options) {
const storedEntry = wx.getStorageSync('match_entry_context') || {}
const activityId = options.activity_id
? Number(options.activity_id)
: storedEntry.activity_id
? Number(storedEntry.activity_id)
: null
this.setData({
activityId
})
if (storedEntry.activity_id) {
wx.removeStorageSync('match_entry_context')
}
},
onShow() {
this.loadMatches()
},
switchTab(e) {
const tab = e.currentTarget.dataset.tab
if (!tab || tab === this.data.activeTab) {
return
}
this.setData({ activeTab: tab })
this.loadMatches()
},
normalizeMatch(item) {
const hobbies = Array.isArray(item.hobbies) ? item.hobbies : Array.isArray(item.other_user && item.other_user.hobbies) ? item.other_user.hobbies : []
const nickname = item.nickname || (item.other_user && item.other_user.nickname) || ''
const avatarUrl = resolveImageUrl(item.avatar_url || (item.other_user && item.other_user.avatar_url) || '')
const city = item.city || (item.other_user && item.other_user.city) || ''
const education = item.education || (item.other_user && item.other_user.education) || ''
const statusMap = {
success: { text: '匹配成功', statusClass: 'success-badge', itemClass: 'success-item' },
pending: { text: '待回应', statusClass: 'pending-badge', itemClass: 'pending-item' }
}
const matchStatus = item.match_status || 'pending'
const statusConfig = statusMap[matchStatus] || statusMap.pending
return {
...item,
match_status: matchStatus,
match_status_text: item.match_status_text || statusConfig.text,
match_status_class: statusConfig.statusClass,
match_item_class: statusConfig.itemClass,
nicknameText: nickname || '匿名用户',
avatar_url: avatarUrl,
cityText: city || '城市未知',
educationText: education || '学历未知',
hobbiesText: hobbies.length ? hobbies.join('、') : '未填写爱好',
timeText: item.matched_at || item.selected_at || ''
}
},
async loadMatches() {
this.setData({ loading: true })
try {
let remoteMatches = []
if (this.data.activityId) {
const endpointMap = {
my_choices: 'my-choices',
liked_me: 'liked-me',
mutual_matches: 'mutual-matches'
}
remoteMatches = await request({ url: `/activities/${this.data.activityId}/${endpointMap[this.data.activeTab]}` })
} else {
remoteMatches = await request({ url: '/matches/my' })
}
const normalizedMatches = Array.isArray(remoteMatches) ? remoteMatches.map((item) => this.normalizeMatch(item)) : []
this.setData({ matches: normalizedMatches })
} catch (err) {
console.error('Load my matches failed:', err)
wx.showToast({ title: err.message || '加载失败', icon: 'none' })
this.setData({ matches: [] })
} finally {
this.setData({ loading: false })
}
},
viewDetail(e) {
const userId = e.currentTarget.dataset.userId
const status = e.currentTarget.dataset.status
if (!userId) {
return
}
if (status !== 'success') {
wx.showToast({ title: '互选成功后才可查看完整资料', icon: 'none' })
return
}
if (this.data.activityId) {
wx.navigateTo({
url: `/pages/match-detail/match-detail?activity_id=${this.data.activityId}&target_user_id=${userId}`
})
return
}
wx.showToast({ title: '当前入口仅支持活动内详情', icon: 'none' })
},
async cancelChoice(e) {
const userId = e.currentTarget.dataset.userId
if (!this.data.activityId || !userId) {
return
}
try {
await request({
url: `/activities/${this.data.activityId}/choices/${userId}`,
method: 'DELETE'
})
wx.showToast({ title: '已撤销选择', icon: 'success' })
this.loadMatches()
} catch (err) {
console.error('Cancel choice failed:', err)
wx.showToast({ title: err.message || '撤销失败', icon: 'none' })
}
}
})