feat: migrate comprehensive venue module
This commit is contained in:
@@ -0,0 +1,453 @@
|
||||
<template>
|
||||
<view class="profile-page container">
|
||||
<view v-if="!session.isLoggedIn" class="unlogged">
|
||||
<text class="brand">星河综合运动中心</text>
|
||||
<text class="desc">登录后查看余额、订单、门票权益与个人资料。</text>
|
||||
<button class="primary-button login-btn" @tap="login">微信一键登录</button>
|
||||
</view>
|
||||
|
||||
<block v-else>
|
||||
<view class="user-profile-hero" @tap="go('/pages/comprehensive/profile/detail')">
|
||||
<view class="hero-left">
|
||||
<image v-if="session.member?.avatar_url" :src="session.member.avatar_url" mode="aspectFill" class="hero-avatar" />
|
||||
<view v-else class="hero-avatar placeholder">
|
||||
<text>{{ avatarInitial }}</text>
|
||||
</view>
|
||||
<view class="hero-meta">
|
||||
<text class="hero-name">{{ session.member?.nickname }}</text>
|
||||
<view v-if="session.member?.phone" class="hero-sub-row">
|
||||
<text class="hero-phone">{{ session.member.phone }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hero-right">
|
||||
<view class="hero-arrow" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="menu-group-card">
|
||||
<view v-for="item in menuItems" :key="item.title" class="menu-item" @tap="go(item.url)">
|
||||
<view class="item-left">
|
||||
<view class="item-icon-container" :class="item.theme">
|
||||
<view class="icon-order" v-if="item.icon === 'order'">
|
||||
<view class="icon-order-line" />
|
||||
<view class="icon-order-line short" />
|
||||
</view>
|
||||
<view class="icon-private" v-else-if="item.icon === 'private'">
|
||||
<view class="icon-private-net" />
|
||||
</view>
|
||||
<view class="icon-ticket" v-else-if="item.icon === 'ticket'">
|
||||
<view class="icon-ticket-dot" />
|
||||
</view>
|
||||
<view class="icon-profile" v-else>
|
||||
<view class="icon-profile-head" />
|
||||
<view class="icon-profile-body" />
|
||||
</view>
|
||||
</view>
|
||||
<text class="menu-title">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="item-right">
|
||||
<view class="menu-arrow" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="menu-item logout" @tap="logout">
|
||||
<view class="item-left">
|
||||
<view class="item-icon-container logout-theme">
|
||||
<view class="icon-logout">
|
||||
<view class="icon-logout-door" />
|
||||
<view class="icon-logout-arrow" />
|
||||
</view>
|
||||
</view>
|
||||
<text class="menu-title">退出登录</text>
|
||||
</view>
|
||||
<view class="item-right">
|
||||
<view class="menu-arrow" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted } from 'vue'
|
||||
import { useComprehensiveSessionStore } from '@/modules/comprehensive/stores/session'
|
||||
|
||||
const session = useComprehensiveSessionStore()
|
||||
const avatarInitial = computed(() => (session.member?.nickname || '用户').slice(0, 1))
|
||||
|
||||
const menuItems = [
|
||||
{ title: '包场预约', url: '/pages/comprehensive/private/index', theme: 'private-theme', icon: 'private' },
|
||||
{ title: '篮球门票', url: '/pages/comprehensive/tickets/index', theme: 'ticket-theme', icon: 'ticket' },
|
||||
{ title: '我的订单', url: '/pages/comprehensive/profile/orders', theme: 'order-theme', icon: 'order' },
|
||||
{ title: '个人信息', url: '/pages/comprehensive/profile/detail', theme: 'profile-theme', icon: 'profile' },
|
||||
{ title: '切换场馆', url: '/pages/venue-select/index', theme: 'profile-theme', icon: 'profile' }
|
||||
]
|
||||
|
||||
onMounted(async () => {
|
||||
await session.init()
|
||||
})
|
||||
|
||||
const login = async () => {
|
||||
await session.login()
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
session.logout()
|
||||
uni.showToast({ title: '已退出', icon: 'none' })
|
||||
}
|
||||
|
||||
const go = (url) => {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.unlogged {
|
||||
min-height: 80vh;
|
||||
padding-top: 180rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.brand {
|
||||
color: $text-color-main;
|
||||
font-size: 42rpx;
|
||||
font-weight: 900;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin-top: $spacing-md;
|
||||
color: $text-color-muted;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
width: 520rpx;
|
||||
margin-top: 100rpx;
|
||||
}
|
||||
|
||||
.user-profile-hero {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 160rpx;
|
||||
padding: $spacing-lg;
|
||||
border: 1rpx solid rgba(241, 245, 249, 0.9);
|
||||
border-radius: $border-radius-lg;
|
||||
background-color: $bg-color-main;
|
||||
box-shadow: 0 10rpx 40rpx rgba(15, 23, 42, 0.02);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.user-profile-hero:active {
|
||||
opacity: 0.96;
|
||||
transform: scale(0.99);
|
||||
}
|
||||
|
||||
.hero-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $spacing-md;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.hero-avatar {
|
||||
width: 104rpx;
|
||||
height: 104rpx;
|
||||
flex-shrink: 0;
|
||||
border-radius: 50%;
|
||||
background: $bg-color-hover;
|
||||
}
|
||||
|
||||
.hero-avatar.placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: $text-color-main;
|
||||
font-size: 36rpx;
|
||||
font-weight: 900;
|
||||
background: $color-primary-light;
|
||||
}
|
||||
|
||||
.hero-meta {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6rpx;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.hero-name,
|
||||
.hero-phone,
|
||||
.menu-title {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.hero-name {
|
||||
color: $text-color-main;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.hero-phone {
|
||||
color: $text-color-muted;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.hero-arrow,
|
||||
.menu-arrow {
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
border-top: 3rpx solid $text-color-light;
|
||||
border-right: 3rpx solid $text-color-light;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.menu-group-card {
|
||||
margin-top: $spacing-lg;
|
||||
overflow: hidden;
|
||||
border: 1rpx solid rgba(241, 245, 249, 0.9);
|
||||
border-radius: $border-radius-lg;
|
||||
background-color: $bg-color-main;
|
||||
box-shadow: 0 10rpx 40rpx rgba(15, 23, 42, 0.02);
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
min-height: 112rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 $spacing-lg;
|
||||
border-bottom: 1rpx solid rgba(241, 245, 249, 0.9);
|
||||
}
|
||||
|
||||
.menu-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item-left,
|
||||
.item-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.item-left {
|
||||
gap: $spacing-md;
|
||||
}
|
||||
|
||||
.item-icon-container {
|
||||
width: 58rpx;
|
||||
height: 58rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: $border-radius-base;
|
||||
background: $bg-color-soft;
|
||||
color: $text-color-muted;
|
||||
}
|
||||
|
||||
.item-icon-container.order-theme {
|
||||
background: $color-primary-light;
|
||||
color: $color-primary;
|
||||
}
|
||||
|
||||
.item-icon-container.profile-theme {
|
||||
background: $color-success-light;
|
||||
color: $color-success;
|
||||
}
|
||||
|
||||
.item-icon-container.private-theme {
|
||||
background: rgba(14, 165, 233, 0.12);
|
||||
color: #0284C7;
|
||||
}
|
||||
|
||||
.item-icon-container.ticket-theme {
|
||||
background: rgba(245, 158, 11, 0.14);
|
||||
color: #D97706;
|
||||
}
|
||||
|
||||
.item-icon-container.logout-theme {
|
||||
background: $color-danger-light;
|
||||
color: $color-danger;
|
||||
}
|
||||
|
||||
.icon-order,
|
||||
.icon-private,
|
||||
.icon-ticket,
|
||||
.icon-profile,
|
||||
.icon-logout {
|
||||
position: relative;
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
|
||||
.icon-order {
|
||||
border: 3rpx solid currentColor;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.icon-order::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -8rpx;
|
||||
left: 7rpx;
|
||||
width: 14rpx;
|
||||
height: 10rpx;
|
||||
border: 3rpx solid currentColor;
|
||||
border-bottom: none;
|
||||
border-radius: 4rpx 4rpx 0 0;
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
.icon-order-line {
|
||||
position: absolute;
|
||||
left: 7rpx;
|
||||
right: 7rpx;
|
||||
top: 10rpx;
|
||||
height: 3rpx;
|
||||
border-radius: 2rpx;
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
.icon-order-line.short {
|
||||
top: 19rpx;
|
||||
right: 12rpx;
|
||||
}
|
||||
|
||||
.icon-private {
|
||||
border: 3rpx solid currentColor;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.icon-private::before,
|
||||
.icon-private::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 5rpx;
|
||||
right: 5rpx;
|
||||
height: 3rpx;
|
||||
border-radius: 2rpx;
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
.icon-private::before {
|
||||
top: 9rpx;
|
||||
}
|
||||
|
||||
.icon-private::after {
|
||||
bottom: 9rpx;
|
||||
}
|
||||
|
||||
.icon-private-net {
|
||||
position: absolute;
|
||||
top: 3rpx;
|
||||
bottom: 3rpx;
|
||||
left: 12rpx;
|
||||
width: 4rpx;
|
||||
border-radius: 2rpx;
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
.icon-ticket {
|
||||
border: 3rpx solid currentColor;
|
||||
border-radius: 6rpx;
|
||||
transform: rotate(-8deg);
|
||||
}
|
||||
|
||||
.icon-ticket::before,
|
||||
.icon-ticket::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 9rpx;
|
||||
bottom: 9rpx;
|
||||
width: 3rpx;
|
||||
border-radius: 2rpx;
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
.icon-ticket::before {
|
||||
left: 8rpx;
|
||||
}
|
||||
|
||||
.icon-ticket::after {
|
||||
right: 8rpx;
|
||||
}
|
||||
|
||||
.icon-ticket-dot {
|
||||
position: absolute;
|
||||
top: 12rpx;
|
||||
left: 13rpx;
|
||||
width: 6rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 50%;
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
.icon-profile-head {
|
||||
position: absolute;
|
||||
top: 3rpx;
|
||||
left: 10rpx;
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border: 3rpx solid currentColor;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.icon-profile-body {
|
||||
position: absolute;
|
||||
left: 5rpx;
|
||||
right: 5rpx;
|
||||
bottom: 3rpx;
|
||||
height: 12rpx;
|
||||
border: 3rpx solid currentColor;
|
||||
border-radius: 16rpx 16rpx 4rpx 4rpx;
|
||||
}
|
||||
|
||||
.icon-logout-door {
|
||||
position: absolute;
|
||||
left: 4rpx;
|
||||
top: 4rpx;
|
||||
width: 15rpx;
|
||||
height: 24rpx;
|
||||
border: 3rpx solid currentColor;
|
||||
border-right: none;
|
||||
border-radius: 4rpx 0 0 4rpx;
|
||||
}
|
||||
|
||||
.icon-logout-arrow {
|
||||
position: absolute;
|
||||
right: 2rpx;
|
||||
top: 14rpx;
|
||||
width: 20rpx;
|
||||
height: 3rpx;
|
||||
border-radius: 2rpx;
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
.icon-logout-arrow::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -6rpx;
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
border-top: 3rpx solid currentColor;
|
||||
border-right: 3rpx solid currentColor;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.menu-title {
|
||||
color: $text-color-main;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.logout .menu-title {
|
||||
color: $color-danger;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user