整合api请求、添加购买会员卡页面、登陆页面

This commit is contained in:
future
2026-06-23 22:17:53 +08:00
parent 1c547a717e
commit 8d8c823616
70 changed files with 7666 additions and 2656 deletions
+315 -152
View File
@@ -5,7 +5,9 @@
<MemberInfoHeader
:user-info="userInfo"
:stats="stats"
:isLogin="isLogin"
@user-info="goUserInfo"
@guest-login="handleGuestLogin"
/>
<view class="member-page__body">
<view class="member-page__sections">
@@ -13,35 +15,41 @@
:card-info="cardInfo"
@view-all="goMemberCard"
@renew="onRenewCard"
@purchase="goPurchaseCard"
/>
<MemberInfoQuickActions @action="onQuickAction" />
<MemberInfoBookingList
v-if="isLogin"
:items="bookingPreview"
@view-all="goBooking"
@item-tap="goBooking"
/>
<MemberInfoCheckInList
v-if="isLogin"
:items="checkIns"
@view-all="onCheckInViewAll"
@item-tap="onCheckInTap"
/>
<MemberInfoBodyReport
v-if="isLogin"
:report="bodyReport"
@view-history="onBodyReportHistory"
@view-report="onBodyReportView"
/>
<MemberInfoCouponPoints
v-if="isLogin"
:data="couponPoints"
@view-all="onCouponViewAll"
@use-coupon="onUseCoupon"
@redeem-points="onRedeemPoints"
/>
<MemberInfoReferral
v-if="isLogin"
:data="referral"
@view-rules="onReferralRules"
/>
<MemberInfoSettings @setting="onSetting" />
<MemberInfoLogout @logout="handleLogout" />
<MemberInfoSettings v-if="isLogin" @setting="onSetting" />
<MemberInfoLogout v-if="isLogin" @logout="handleLogout" />
</view>
</view>
</view>
@@ -53,13 +61,19 @@
</view>
</template>
<script>
<script setup>
import { ref, onMounted } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { PAGE, navigateToPage } from '@/common/constants/routes.js'
import {
loadMemberStore,
getCenterPageData,
renewMemberCard
renewMemberCard,
saveMemberStore,
getDefaultStore
} from '@/common/memberInfo/store.js'
import { login as miniappLogin, getUserInfo, getMemberDetail, getCheckInStats, updateUserInfo } from '@/api/main.js'
import { setToken, getToken, clearToken } from '@/utils/request.js'
import MemberInfoHeader from '@/components/memberInfo/MemberInfoHeader.vue'
import MemberInfoMemberCard from '@/components/memberInfo/MemberInfoMemberCard.vue'
import MemberInfoQuickActions from '@/components/memberInfo/MemberInfoQuickActions.vue'
@@ -72,162 +86,311 @@ import MemberInfoSettings from '@/components/memberInfo/MemberInfoSettings.vue'
import MemberInfoLogout from '@/components/memberInfo/MemberInfoLogout.vue'
import TabBar from '@/components/TabBar.vue'
export default {
components: {
MemberInfoHeader,
MemberInfoMemberCard,
MemberInfoQuickActions,
MemberInfoBookingList,
MemberInfoCheckInList,
MemberInfoBodyReport,
MemberInfoCouponPoints,
MemberInfoReferral,
MemberInfoSettings,
MemberInfoLogout,
TabBar
},
data() {
return {
userInfo: {},
stats: {},
cardInfo: {},
bookingPreview: [],
checkIns: [],
bodyReport: {},
couponPoints: {},
referral: {}
}
},
onShow() {
this.refreshFromStore()
},
methods: {
refreshFromStore() {
const userInfo = ref({})
const stats = ref({})
const cardInfo = ref({})
const bookingPreview = ref([])
const checkIns = ref([])
const bodyReport = ref({})
const couponPoints = ref({})
const referral = ref({})
const loading = ref(false)
const hasActiveCard = ref(false)
const isLogin = ref(false)
// 页面加载时检查token
onMounted(() => {
const token = getToken()
const isLoginStorage = uni.getStorageSync('isLogin')
if (token || isLoginStorage) {
isLogin.value = true
}
})
async function fetchMemberInfo() {
if (loading.value) return
loading.value = true
console.log('[memberInfo] fetchMemberInfo 开始执行')
try {
const res = await getUserInfo({ cache: false })
console.log('[memberInfo] API返回,res =', res)
const apiData = res.data || res
console.log('[memberInfo] apiData =', apiData)
if (apiData && (apiData.nickname !== undefined || apiData.phone !== undefined || apiData.id !== undefined)) {
console.log('[memberInfo] 收到有效数据,更新store')
const store = loadMemberStore()
const pageData = getCenterPageData(store)
this.userInfo = pageData.userInfo
this.stats = pageData.stats
this.cardInfo = pageData.cardInfo
this.bookingPreview = pageData.bookingPreview
this.checkIns = pageData.checkIns
this.bodyReport = pageData.bodyReport
this.couponPoints = pageData.couponPoints
this.referral = pageData.referral
},
goMemberCard() {
navigateToPage(PAGE.MEMBER_CARD)
},
goBooking() {
navigateToPage(PAGE.BOOKING)
},
goUserInfo() {
navigateToPage(PAGE.USER_INFO)
},
onRenewCard() {
uni.showModal({
title: '续费会员卡',
content: '确认续费 90 天?',
success: (res) => {
if (!res.confirm) return
const store = loadMemberStore()
renewMemberCard(store, 90)
this.refreshFromStore()
uni.showToast({ title: '续费成功', icon: 'success' })
// 更新memberProfile
store.memberProfile = {
...store.memberProfile,
id: apiData.id,
name: apiData.nickname || apiData.name,
phone: apiData.phone,
avatar: apiData.avatar,
memberLevel: apiData.memberLevel || '普通会员'
}
// 更新profile
store.profile = {
...store.profile,
id: apiData.id,
name: apiData.nickname || apiData.name,
phone: apiData.phone,
avatar: apiData.avatar,
gender: apiData.gender,
genderDesc: apiData.genderDesc,
birthday: apiData.birthday,
height: apiData.height,
weight: apiData.weight,
hasPhone: apiData.hasPhone,
isSubscribed: apiData.isSubscribed,
memberLevel: apiData.memberLevel || '普通会员'
}
// 获取会员详细信息(会员卡、积分)
try {
const detailRes = await getMemberDetail()
console.log('[memberInfo] getMemberDetail 返回:', JSON.stringify(detailRes, null, 2))
const detailData = detailRes.data || {}
store.card = detailData.memberCards ? detailData.memberCards[0] || {} : {}
store.cardInfo = {
name: detailData.memberCards?.[0]?.memberCardName || '暂无会员卡',
type: detailData.memberCards?.[0]?.memberCardTypeDesc || '',
remainingTimes: detailData.memberCards?.[0]?.memberCardTotalTimes || 0,
status: detailData.memberCards?.[0]?.memberCardStatusDesc || ''
}
})
},
onQuickAction(type) {
const routes = {
booking: PAGE.COURSE_LIST,
bodyTest: PAGE.BODY_TEST_HOME,
bodyReport: PAGE.BODY_TEST_HISTORY,
trainReport: PAGE.TRAIN_REPORT,
coupon: PAGE.COUPONS,
points: PAGE.POINTS,
referral: PAGE.REFERRAL,
course: PAGE.MY_COURSES
}
if (routes[type]) {
navigateToPage(routes[type])
}
},
onCheckInViewAll() {
navigateToPage(PAGE.CHECK_IN_HISTORY)
},
onCheckInTap(item) {
uni.showModal({
title: item.title,
content: item.time,
showCancel: false
})
},
onBodyReportHistory() {
navigateToPage(PAGE.BODY_TEST_HISTORY)
},
onBodyReportView() {
const id = this.bodyReport?.recordId
const url = id
? `${PAGE.BODY_TEST_REPORT}?id=${id}`
: PAGE.BODY_TEST_HISTORY
navigateToPage(url)
},
onCouponViewAll() {
navigateToPage(PAGE.COUPONS)
},
onUseCoupon() {
navigateToPage(PAGE.COUPONS)
},
onRedeemPoints() {
navigateToPage(PAGE.POINTS)
},
onReferralRules() {
navigateToPage(PAGE.REFERRAL)
},
onSetting(key) {
const labels = {
notify: '通知设置',
password: '修改密码',
privacy: '隐私政策',
nfc: 'NFC 门禁卡',
delete: '注销账户'
}
if (key === 'delete') {
uni.showModal({
title: '注销账户',
content: '注销后数据将无法恢复,确定继续吗?',
confirmColor: '#E74C3C'
})
return
}
if (key === 'privacy') {
uni.showModal({
title: '隐私政策',
content: '我们重视您的隐私,详细政策请前往官网查看。',
showCancel: false
})
return
}
uni.showToast({
title: `${labels[key] || '设置'}开发中`,
icon: 'none'
})
},
handleLogout() {
uni.showModal({
title: '退出登录',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
uni.showToast({ title: '已退出', icon: 'success' })
}
hasActiveCard.value = (detailData.activeCardCount || 0) > 0
store.stats = {
...store.stats,
pointsBalance: detailData.pointsBalance || 0
}
})
} catch (e) {
console.error('[memberInfo] 获取会员详情失败:', e)
}
// 获取签到统计
try {
const statsRes = await getCheckInStats()
console.log('[memberInfo] getCheckInStats 返回:', JSON.stringify(statsRes, null, 2))
const statsData = statsRes.data || {}
store.stats.checkInCount = statsData.totalCount || 0
} catch (e) {
console.error('[memberInfo] 获取签到统计失败:', e)
store.stats.checkInCount = 0
}
saveMemberStore(store)
refreshFromStore()
console.log('[memberInfo] store已更新')
} else {
console.log('[memberInfo] 未登录或数据无效,使用默认空数据')
const store = loadMemberStore()
store.memberProfile = {}
store.profile = {}
store.stats.checkInCount = 0
hasActiveCard.value = false
saveMemberStore(store)
refreshFromStore()
}
} catch (err) {
console.error('[memberInfo] 获取会员信息失败:', err)
// 失败时使用默认空数据
const store = loadMemberStore()
store.memberProfile = {}
store.profile = {}
store.stats.checkInCount = 0
hasActiveCard.value = false
saveMemberStore(store)
refreshFromStore()
} finally {
loading.value = false
console.log('[memberInfo] fetchMemberInfo 执行完成')
}
}
function refreshFromStore() {
const store = loadMemberStore()
const pageData = getCenterPageData(store)
console.log('[memberInfo] refreshFromStore - pageData.userInfo:', JSON.stringify(pageData.userInfo))
userInfo.value = pageData.userInfo
stats.value = pageData.stats
cardInfo.value = pageData.cardInfo
bookingPreview.value = pageData.bookingPreview
checkIns.value = pageData.checkIns
bodyReport.value = pageData.bodyReport
couponPoints.value = pageData.couponPoints
referral.value = pageData.referral
console.log('[memberInfo] refreshFromStore - userInfo.value:', JSON.stringify(userInfo.value))
}
function goMemberCard() {
navigateToPage(PAGE.MEMBER_CARD)
}
function goPurchaseCard() {
navigateToPage(PAGE.PURCHASE_CARD)
}
function goBooking() {
navigateToPage(PAGE.BOOKING)
}
function goUserInfo() {
navigateToPage(PAGE.USER_INFO)
}
function handleGuestLogin() {
console.log('[memberInfo] 用户点击登录区域')
uni.navigateTo({
url: '/pages/memberInfo/login'
})
}
function onRenewCard() {
uni.showModal({
title: '续费会员卡',
content: '确认续费 90 天?',
success: (res) => {
if (!res.confirm) return
const store = loadMemberStore()
renewMemberCard(store, 90)
refreshFromStore()
uni.showToast({ title: '续费成功', icon: 'success' })
}
})
}
function onQuickAction(type) {
const routes = {
booking: PAGE.COURSE_LIST,
bodyTest: PAGE.BODY_TEST_HOME,
bodyReport: PAGE.BODY_TEST_HISTORY,
trainReport: PAGE.TRAIN_REPORT,
coupon: PAGE.COUPONS,
points: PAGE.POINTS,
referral: PAGE.REFERRAL,
course: PAGE.MY_COURSES
}
if (routes[type]) {
navigateToPage(routes[type])
}
}
function onCheckInViewAll() {
navigateToPage(PAGE.CHECK_IN_HISTORY)
}
function onCheckInTap(item) {
uni.showModal({
title: item.title,
content: item.time,
showCancel: false
})
}
function onBodyReportHistory() {
navigateToPage(PAGE.BODY_TEST_HISTORY)
}
function onBodyReportView() {
const id = bodyReport.value?.recordId
const url = id
? `${PAGE.BODY_TEST_REPORT}?id=${id}`
: PAGE.BODY_TEST_HISTORY
navigateToPage(url)
}
function onCouponViewAll() {
navigateToPage(PAGE.COUPONS)
}
function onUseCoupon() {
navigateToPage(PAGE.COUPONS)
}
function onRedeemPoints() {
navigateToPage(PAGE.POINTS)
}
function onReferralRules() {
navigateToPage(PAGE.REFERRAL)
}
function onSetting(key) {
const labels = {
notify: '通知设置',
password: '修改密码',
privacy: '隐私政策',
nfc: 'NFC 门禁卡',
delete: '注销账户'
}
if (key === 'delete') {
uni.showModal({
title: '注销账户',
content: '注销后数据将无法恢复,确定继续吗?',
confirmColor: '#E74C3C'
})
return
}
if (key === 'privacy') {
uni.showModal({
title: '隐私政策',
content: '我们重视您的隐私,详细政策请前往官网查看。',
showCancel: false
})
return
}
uni.showToast({
title: `${labels[key] || '设置'}开发中`,
icon: 'none'
})
}
function handleLogout() {
uni.showModal({
title: '退出登录',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
// 清除token
clearToken()
// 重置登录状态
isLogin.value = false
// 重置store为默认状态
const defaultStore = getDefaultStore()
saveMemberStore(defaultStore)
// 重置页面数据
userInfo.value = {}
stats.value = {}
cardInfo.value = {}
bookingPreview.value = []
checkIns.value = []
bodyReport.value = {}
couponPoints.value = {}
referral.value = {}
hasActiveCard.value = false
refreshFromStore()
uni.showToast({ title: '已退出', icon: 'success' })
}
}
})
}
refreshFromStore()
onShow(() => {
console.log('[memberInfo] onShow 被调用')
// 检查登录状态
const token = getToken()
const isLoginStorage = uni.getStorageSync('isLogin')
if (token || isLoginStorage) {
isLogin.value = true
} else {
isLogin.value = false
}
fetchMemberInfo()
})
</script>
<style>
<style lang="scss">
@import '@/common/style/base.css';
@import '@/common/style/memberInfo/member-info-component-reset.css';
@import '@/common/style/memberInfo/member-info-tap.css';