This commit is contained in:
yison 2025-07-11 18:28:43 +08:00
parent dc24d5b6ed
commit cd11b355bb
25 changed files with 3632 additions and 186 deletions

View file

@ -57,13 +57,35 @@
<view class="location-bar">
<view class="location-content">
<text class="location-pin">📍</text>
<text class="location-text">杭州市文一西路未来科技城万利大厦0701</text>
<text class="location-switch" @tap="switchLocation">切换</text>
<text class="location-text" :class="{ 'location-loading': locationLoading }">{{ currentLocation.address }}</text>
<text class="location-switch" @tap="switchLocation">{{ locationLoading ? '定位中' : (currentLocation.address.includes('请选择') ? '选择' : '切换') }}</text>
</view>
</view>
<!-- Venue Cards -->
<view class="venue-section">
<!-- 根据定位状态显示不同内容 -->
<!-- 定位中状态 -->
<view v-if="locationLoading" class="location-status-section">
<view class="status-container">
<view class="loading-spinner"></view>
<text class="status-title">正在定位</text>
<text class="status-subtitle">获取您的位置信息为您推荐附近场馆</text>
</view>
</view>
<!-- 选择位置状态 -->
<view v-else-if="locationError" class="location-status-section">
<view class="status-container">
<text class="status-icon">📍</text>
<text class="status-title">选择您的位置</text>
<text class="status-subtitle">在地图上选择位置为您推荐附近的运动场馆</text>
<view class="retry-button" @tap="chooseLocationOnMap">
<text class="retry-text">在地图上选择</text>
</view>
</view>
</view>
<!-- 定位成功显示场馆列表 -->
<view v-else-if="locationReady" class="venue-section">
<!-- Timeline -->
<view class="timeline-container">
<view class="timeline-line"></view>
@ -215,18 +237,14 @@
<!-- Stats Cards -->
<view class="stats-section">
<view class="stats-grid">
<view class="stat-card">
<view class="stat-card" @tap="goToHistory">
<text class="stat-number">12</text>
<text class="stat-label">观看场次</text>
<text class="stat-label">观看数量</text>
</view>
<view class="stat-card">
<view class="stat-card" @tap="goToFavorites">
<text class="stat-number">5</text>
<text class="stat-label">收藏场馆</text>
</view>
<view class="stat-card">
<text class="stat-number">28</text>
<text class="stat-label">观看时长(h)</text>
</view>
</view>
</view>
@ -235,7 +253,7 @@
<view class="menu-card">
<view class="menu-item" @tap="goToFavorites">
<view class="menu-content">
<text class="menu-title">我的下载</text>
<text class="menu-title">我的收藏</text>
</view>
<text class="menu-arrow"></text>
</view>
@ -256,6 +274,13 @@
<text class="menu-arrow"></text>
</view>
</view>
<view class="menu-item" @tap="goToOrders">
<view class="menu-content">
<text class="menu-title">我的订单</text>
</view>
<text class="menu-arrow"></text>
</view>
</view>
</view>
@ -272,16 +297,17 @@
<text class="activity-title-text">观看了 RONIN黄金篮球馆</text>
<text class="activity-subtitle">2小时前 · 观看时长 45分钟</text>
</view>
<text class="activity-points">+10</text>
</view>
<view class="activity-item">
<view class="activity-content">
<text class="activity-title-text">收藏了 Panda惊怒熊猫运动俱乐部</text>
<text class="activity-subtitle">1天前</text>
</view>
<text class="activity-points">+5</text>
</view>
</view>
<view class="activity-more-link" @tap="goToActivityHistory">
<text class="more-link-text">查看历史活动</text>
</view>
</view>
</view>
</view>
@ -304,12 +330,23 @@
<text class="nav-label" :class="{ active: currentPage === 'profile' }">我的</text>
</view>
</view>
<!-- 授权弹窗 -->
<AuthModal
:visible="authModalVisible"
:auth-type="authType"
@close="closeAuthModal"
@success="onAuthSuccess"
@skip="onAuthSkip"
/>
</view>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ref, onMounted, defineAsyncComponent } from 'vue'
import Taro from '@tarojs/taro'
// AuthModal
const AuthModal = defineAsyncComponent(() => import('../../components/AuthModal/index.vue'))
import './index.scss'
//
@ -323,27 +360,284 @@ const roninLogoSrc = 'https://qiniu.drip.im/gh_09bd6126eab8/20250711/upload/4d0e
const selectedSport = ref('all')
const currentPage = ref('home') // 'home' | 'profile'
//
const currentLocation = ref({
name: '定位中...',
address: '正在获取位置信息',
latitude: 0,
longitude: 0
})
const locationLoading = ref(false)
const locationReady = ref(false) //
const locationError = ref(false) //
//
const authModalVisible = ref(false)
const authType = ref<'login' | 'video'>('login')
const isUserAuthorized = ref(false) //
//
const selectSport = (sport: string) => {
selectedSport.value = sport
console.log('选择运动项目:', sport)
}
//
const saveLocationToStorage = (locationData: any) => {
try {
Taro.setStorageSync('userLocation', {
...locationData,
timestamp: Date.now() //
})
console.log('位置信息已保存到本地存储:', locationData)
} catch (error) {
console.error('保存位置信息失败:', error)
}
}
const loadLocationFromStorage = () => {
try {
const savedLocation = Taro.getStorageSync('userLocation')
if (savedLocation && savedLocation.address) {
// 7
const sevenDaysInMs = 7 * 24 * 60 * 60 * 1000
const now = Date.now()
if (savedLocation.timestamp && (now - savedLocation.timestamp) < sevenDaysInMs) {
console.log('从本地存储加载位置信息:', savedLocation)
return savedLocation
} else {
console.log('位置信息已过期,清除本地存储')
clearLocationFromStorage()
}
}
} catch (error) {
console.error('读取位置信息失败:', error)
}
return null
}
const clearLocationFromStorage = () => {
try {
Taro.removeStorageSync('userLocation')
console.log('已清除本地存储的位置信息')
} catch (error) {
console.error('清除位置信息失败:', error)
}
}
const switchLocation = () => {
console.log('🔥 switchLocation 方法被调用!')
Taro.showActionSheet({
itemList: ['杭州市文一西路未来科技城万利大厦0701', '杭州市西湖区文三路123号', '杭州市滨江区江南大道456号'],
//
chooseLocationOnMap()
}
//
const chooseLocationOnMap = () => {
Taro.chooseLocation({
success: (res) => {
console.log('选择位置:', res.tapIndex)
console.log('选择位置成功:', res)
//
const locationData = {
name: res.name || res.address,
address: res.address,
latitude: res.latitude,
longitude: res.longitude
}
currentLocation.value = locationData
//
saveLocationToStorage(locationData)
locationReady.value = true
locationError.value = false
Taro.showToast({
title: '位置已更新',
icon: 'success'
})
},
fail: (err) => {
console.error('选择位置失败:', err)
//
locationReady.value = false
locationError.value = true
currentLocation.value = {
name: '未选择位置',
address: '请选择您的位置以查看附近场馆',
latitude: 0,
longitude: 0
}
if (err.errMsg.includes('auth')) {
Taro.showModal({
title: '授权提示',
content: '需要授权位置信息才能选择地点,是否前往设置?',
success: (modalRes) => {
if (modalRes.confirm) {
Taro.openSetting()
}
}
})
} else if (!err.errMsg.includes('cancel')) {
//
Taro.showToast({
title: '选择位置失败',
icon: 'none'
})
}
}
})
}
//
const getCurrentLocation = (showToast = true, showLoading = false) => {
if (!locationLoading.value) {
locationLoading.value = true
}
locationReady.value = false
locationError.value = false
if (showLoading) {
Taro.showLoading({
title: '定位中...'
})
}
Taro.getLocation({
type: 'gcj02', //
success: (res) => {
console.log('获取位置成功:', res)
// API
const formattedAddress = `当前位置 (${res.latitude.toFixed(4)}, ${res.longitude.toFixed(4)})`
const locationData = {
name: '当前位置',
address: formattedAddress,
latitude: res.latitude,
longitude: res.longitude
}
currentLocation.value = locationData
//
saveLocationToStorage(locationData)
locationLoading.value = false
locationReady.value = true
locationError.value = false
if (showLoading) {
Taro.hideLoading()
}
if (showToast) {
Taro.showToast({
title: '定位成功',
icon: 'success'
})
}
},
fail: (err) => {
locationLoading.value = false
locationReady.value = false
locationError.value = true
if (showLoading) {
Taro.hideLoading()
}
console.error('获取位置失败:', err)
//
currentLocation.value = {
name: '定位失败',
address: '无法获取位置信息,点击重试',
latitude: 0,
longitude: 0
}
if (err.errMsg.includes('auth')) {
Taro.showModal({
title: '授权提示',
content: '需要授权位置信息才能获取当前位置,是否前往设置?',
success: (modalRes) => {
if (modalRes.confirm) {
Taro.openSetting()
}
}
})
} else {
if (showToast) {
Taro.showToast({
title: '定位失败',
icon: 'none'
})
}
}
}
})
}
//
const chooseDeliveryAddress = () => {
Taro.chooseAddress({
success: (res) => {
console.log('选择地址成功:', res)
const fullAddress = `${res.provinceName}${res.cityName}${res.countyName}${res.detailInfo}`
const locationData = {
name: res.userName,
address: fullAddress,
latitude: 0, // API
longitude: 0
}
currentLocation.value = locationData
//
saveLocationToStorage(locationData)
locationReady.value = true
locationError.value = false
Taro.showToast({
title: '地址已更新',
icon: 'success'
})
},
fail: (err) => {
console.error('选择地址失败:', err)
if (err.errMsg.includes('auth')) {
Taro.showModal({
title: '授权提示',
content: '需要授权地址信息才能选择收货地址,是否前往设置?',
success: (modalRes) => {
if (modalRes.confirm) {
Taro.openSetting()
}
}
})
} else {
Taro.showToast({
title: '选择地址失败',
icon: 'none'
})
}
}
})
}
const playVideo = () => {
Taro.showToast({
title: '播放视频',
icon: 'none'
})
if (checkAuthRequired('video')) {
Taro.showToast({
title: '播放视频',
icon: 'none'
})
}
}
const enterZone = (venueType: string) => {
@ -375,7 +669,9 @@ const goHome = () => {
}
const goProfile = () => {
currentPage.value = 'profile'
if (checkAuthRequired('login')) {
currentPage.value = 'profile'
}
}
//
@ -399,16 +695,14 @@ const goToVip = () => {
}
const goToFavorites = () => {
Taro.showToast({
title: '我的收藏',
icon: 'none'
Taro.navigateTo({
url: '/pages/favorites/index'
})
}
const goToHistory = () => {
Taro.showToast({
title: '观看历史',
icon: 'none'
Taro.navigateTo({
url: '/pages/history/index'
})
}
@ -420,9 +714,20 @@ const goToAddress = () => {
}
const goToNotifications = () => {
Taro.showToast({
title: '消息通知',
icon: 'none'
Taro.navigateTo({
url: '/pages/notifications/index'
})
}
const goToOrders = () => {
Taro.navigateTo({
url: '/pages/orders/index'
})
}
const goToActivityHistory = () => {
Taro.navigateTo({
url: '/pages/activity/index'
})
}
@ -433,10 +738,98 @@ const goToPrivacy = () => {
})
}
//
const showAuthModal = (type: 'login' | 'video') => {
authType.value = type
authModalVisible.value = true
}
const closeAuthModal = () => {
authModalVisible.value = false
}
const onAuthSuccess = (data: { phone?: string, userInfo?: any }) => {
console.log('授权成功:', data)
isUserAuthorized.value = true
//
if (data.phone) {
Taro.setStorageSync('userPhone', data.phone)
}
if (data.userInfo) {
Taro.setStorageSync('userInfo', data.userInfo)
}
Taro.showToast({
title: '授权成功',
icon: 'success'
})
}
const onAuthSkip = () => {
console.log('用户跳过授权')
//
}
//
const checkAuthRequired = (action: 'login' | 'video') => {
//
const hasPhone = Taro.getStorageSync('userPhone')
const hasUserInfo = Taro.getStorageSync('userInfo')
if (!hasPhone || !hasUserInfo) {
showAuthModal(action)
return false
}
isUserAuthorized.value = true
return true
}
// : playVideo goProfile
onMounted(() => {
console.log('LIMO来刻首页已加载')
console.log('Vue组件已挂载方法可用')
//
const hasPhone = Taro.getStorageSync('userPhone')
const hasUserInfo = Taro.getStorageSync('userInfo')
if (hasPhone && hasUserInfo) {
isUserAuthorized.value = true
}
//
const savedLocation = loadLocationFromStorage()
if (savedLocation) {
// 使
currentLocation.value = {
name: savedLocation.name,
address: savedLocation.address,
latitude: savedLocation.latitude,
longitude: savedLocation.longitude
}
locationLoading.value = false
locationReady.value = true
locationError.value = false
console.log('使用已保存的位置信息')
} else {
//
locationLoading.value = false
locationReady.value = false
locationError.value = true
currentLocation.value = {
name: '未选择位置',
address: '请选择您的位置以查看附近场馆',
latitude: 0,
longitude: 0
}
console.log('未找到保存的位置信息,显示选择引导')
}
})
</script>