Files
mp-pilates/packages/app/src/components/ProfileMenu.vue
2026-09-16 22:49:47 +08:00

131 lines
3.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="profile-menu">
<slot />
<view class="profile-menu__links">
<template v-for="item in menuItems" :key="item.key">
<view v-if="item.type === 'separator'" class="profile-menu__separator" />
<view v-else class="profile-menu__item" :class="{ 'profile-menu__item--admin': item.isAdmin }"
hover-class="profile-menu__item--hover" hover-stay-time="150" @tap="handleTap(item)">
<text class="profile-menu__title">{{ item.title }}</text>
<text class="profile-menu__arrow">›</text>
</view>
</template>
</view>
</view>
</template>
<script setup lang="ts">
import { computed } from 'vue'
interface MenuItem {
key: string
type: 'item' | 'separator'
title?: string
path?: string
isAdmin?: boolean
action?: 'clear' | 'notifications'
requireAuth?: boolean
}
const props = defineProps<{
isAdmin: boolean
requireAuth?: boolean
}>()
const emit = defineEmits<{
(e: 'clear-cache'): void
(e: 'require-login'): void
(e: 'open-notifications'): void
}>()
const menuItems = computed<MenuItem[]>(() => {
const items: MenuItem[] = [
{ key: 'shop-orders', type: 'item', title: '我的商品订单', path: '/pages/shop/orders', requireAuth: true },
{ key: 'progress', type: 'item', title: '我的成长档案', path: '/pages/profile/progress', requireAuth: true },
{ key: 'portrait', type: 'item', title: '身体状态评估', path: '/pages/portrait/index' },
{ key: 'plan', type: 'item', title: '我的改善计划', path: '/pages/portrait/plan', requireAuth: true },
...(props.isAdmin
? [{
key: 'teaching-schedule',
type: 'item' as const,
title: '我的课表',
path: '/pages/profile/teaching-schedule',
requireAuth: true,
}]
: []),
{
key: 'bookings',
type: 'item',
title: '我的预约',
path: '/pages/profile/bookings',
requireAuth: true,
},
{
key: 'info',
type: 'item',
title: '个人信息',
path: '/pages/profile/info',
requireAuth: true,
},
{
key: 'notifications',
type: 'item',
title: '消息提醒设置',
action: 'notifications',
requireAuth: true,
},
{
key: 'sep1',
type: 'separator',
},
{
key: 'clear',
type: 'item',
title: '清除缓存',
action: 'clear',
},
]
if (props.isAdmin) {
items.push({ key: 'sep2', type: 'separator' })
items.push({
key: 'admin',
type: 'item',
title: '管理中心',
path: '/pages/admin/index',
isAdmin: true,
requireAuth: true,
})
}
return items
})
function handleTap(item: MenuItem) {
if (item.requireAuth && !props.requireAuth) {
emit('require-login')
return
}
if (item.action === 'clear') {
emit('clear-cache')
} else if (item.action === 'notifications') {
emit('open-notifications')
} else if (item.path) {
uni.navigateTo({ url: item.path })
}
}
</script>
<style lang="scss" scoped>
.profile-menu {
&__links { margin: 24rpx 32rpx 0; border-radius: 26rpx; background: #fff; overflow: hidden; }
&__item { display: flex; align-items: center; gap: 20rpx; min-height: 96rpx; padding: 0 28rpx; box-sizing: border-box; border-bottom: 1rpx solid #f2ede8; &:last-child { border-bottom: none; } }
&__item--hover { background: #f4f1ec; }
&__item--admin { background: #eff3ed; .profile-menu__title { color: #617d73; } }
&__title { flex: 1; font-size: 27rpx; font-weight: 400; color: #6f655e; }
&__arrow { font-size: 30rpx; color: #b2a79e; line-height: 1; }
&__separator { height: 12rpx; background: #fbf9f6; }
}
</style>