| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- <template>
- <view class="mine-page">
- <view class="mine-header" @click="onHeaderClick">
- <view class="mine-header__row">
- <image class="mine-header__avatar" :src="avatarUrl" mode="aspectFill" />
- <view class="mine-header__info">
- <text class="mine-header__name">{{ headerTitle }}</text>
- <text v-if="loggedIn && mobileText" class="mine-header__sub">{{ mobileText }}</text>
- <text v-else-if="!loggedIn" class="mine-header__sub">登录后管理资料与地址</text>
- </view>
- <u-icon v-if="loggedIn" name="arrow-right" color="#fff" size="18" class="mine-header__arrow" />
- </view>
- </view>
- <scroll-view class="mine-scroll" scroll-y :style="{ height: scrollHeight }">
- <view class="mine-body">
- <view v-if="!loggedIn" class="mine-guest">
- <text class="mine-guest__title">登录后享受完整购物服务</text>
- <text class="mine-guest__tip">下单、加购需登录会员账号</text>
- <view class="mine-guest__btns">
- <button class="mine-btn-primary" @click="goLogin">登录</button>
- <button class="mine-btn-outline" @click="goRegister">注册会员</button>
- </view>
- </view>
- <template v-else>
- <view class="mine-order-card">
- <view class="mine-order-head" @click="goOrderListAll">
- <text class="mine-order-head__title">我的订单</text>
- <view class="mine-order-head__all">
- <text>全部</text>
- <u-icon name="arrow-right" color="#ccc" size="14" />
- </view>
- </view>
- <view class="mine-order-shortcuts">
- <view
- v-for="item in orderShortcuts"
- :key="item.key"
- class="mine-order-shortcut"
- @click="onOrderShortcut(item.key)"
- >
- <view class="mine-order-shortcut__icon-wrap">
- <u-icon :name="item.icon" color="#2e7d32" size="26" />
- <text
- v-if="getOrderBadge(item.key) > 0"
- class="mine-order-shortcut__badge"
- >{{ formatBadge(getOrderBadge(item.key)) }}</text>
- </view>
- <text class="mine-order-shortcut__label">{{ item.label }}</text>
- </view>
- </view>
- </view>
- <view v-for="section in menuSections" :key="section.title" class="mine-card">
- <text class="mine-card__title">{{ section.title }}</text>
- <view
- v-for="item in section.items"
- :key="item.path"
- class="mine-menu-item"
- @click="goPage(item.path)"
- >
- <u-icon :name="item.icon" color="#5c5652" size="22" />
- <text class="mine-menu-item__label">{{ item.label }}</text>
- <text
- v-if="item.showUnreadBadge && messageUnreadCount > 0"
- class="mine-menu-badge"
- >{{ formatMessageBadge(messageUnreadCount) }}</text>
- <u-icon name="arrow-right" color="#ccc" size="16" />
- </view>
- </view>
- <view class="mine-logout">
- <button class="mine-btn-outline" @click="handleLogout">退出登录</button>
- </view>
- </template>
- </view>
- </scroll-view>
- </view>
- </template>
- <script setup>
- import { ref, computed, onMounted } from 'vue'
- import { onShow } from '@dcloudio/uni-app'
- import { getToken } from '@/utils/auth'
- import { useUserStore } from '@/store/user'
- import { navigateMinePage } from '@/utils/mineNav'
- import { getOrderBadges } from '@/api/order'
- import { getMessageUnreadCount } from '@/api/message'
- import { formatMessageBadge } from '@/utils/messageDisplay'
- import { ORDER_MINE_SHORTCUTS, ORDER_TAB } from '@/constants/order'
- import { goOrderList, goAftersaleList } from '@/utils/orderNav'
- import {
- PAGE_LOGIN,
- PAGE_REGISTER,
- PAGE_PROFILE,
- PAGE_PASSWORD,
- PAGE_ADDRESS_LIST,
- PAGE_ENTRY_APPLY,
- PAGE_ENTRY_LIST,
- PAGE_SHOP_FOLLOW_LIST,
- PAGE_MESSAGE_LIST,
- PAGE_MESSAGE_DETAIL,
- PAGE_ABOUT_MALL
- } from '@/utils/pageRoute'
- const loggedIn = ref(false)
- const displayName = ref('点击登录')
- const mobileText = ref('')
- const avatarUrl = ref('/static/logo.png')
- const userStore = useUserStore()
- const orderShortcuts = ORDER_MINE_SHORTCUTS
- const orderBadges = ref({
- pendingPayCount: 0,
- pendingShipCount: 0,
- pendingReceiveCount: 0,
- aftersaleInProgressCount: 0
- })
- const messageUnreadCount = ref(0)
- const scrollHeight = ref('500px')
- const headerTitle = computed(() => {
- if (!loggedIn.value) return '未登录'
- return displayName.value
- })
- /** 我的服务菜单(对齐功能需求 §3) */
- const menuSections = [
- {
- title: '消息中心',
- items: [
- {
- label: '站内消息',
- path: PAGE_MESSAGE_LIST,
- icon: 'bell',
- showUnreadBadge: true
- }
- ]
- },
- {
- title: '账号管理',
- items: [
- { label: '编辑个人资料', path: PAGE_PROFILE, icon: 'account' },
- { label: '修改密码', path: PAGE_PASSWORD, icon: 'lock' }
- ]
- },
- {
- title: '收货地址',
- items: [{ label: '收货地址', path: PAGE_ADDRESS_LIST, icon: 'map' }]
- },
- {
- title: '店铺关注',
- items: [{ label: '我的店铺关注', path: PAGE_SHOP_FOLLOW_LIST, icon: 'heart' }]
- },
- {
- title: '商家入驻',
- items: [
- { label: '我要入驻', path: PAGE_ENTRY_APPLY, icon: 'home' },
- { label: '我的入驻申请', path: PAGE_ENTRY_LIST, icon: 'list' }
- ]
- },
- {
- title: '关于',
- items: [{ label: '关于商城', path: PAGE_ABOUT_MALL, icon: 'info-circle' }]
- }
- ]
- function calcScrollHeight() {
- try {
- const sys = uni.getSystemInfoSync()
- const windowH = sys.windowHeight || 600
- const tabBarH = uni.upx2px(188)
- const headerH = uni.upx2px(232)
- const overlapH = uni.upx2px(40)
- scrollHeight.value = `${Math.max(windowH - tabBarH - headerH + overlapH, 200)}px`
- } catch (e) {
- scrollHeight.value = '400px'
- }
- }
- onMounted(() => {
- calcScrollHeight()
- })
- onShow(() => {
- calcScrollHeight()
- loggedIn.value = !!getToken()
- if (!loggedIn.value) {
- displayName.value = '点击登录'
- mobileText.value = ''
- avatarUrl.value = '/static/logo.png'
- return
- }
- refreshUser()
- loadOrderBadges()
- loadMessageUnread()
- })
- function loadMessageUnread() {
- getMessageUnreadCount()
- .then((res) => {
- messageUnreadCount.value = Number((res.data && res.data.unreadCount) || 0)
- })
- .catch(() => {
- messageUnreadCount.value = 0
- })
- }
- function loadOrderBadges() {
- getOrderBadges()
- .then((res) => {
- const data = res.data || {}
- orderBadges.value = {
- pendingPayCount: Number(data.pendingPayCount) || 0,
- pendingShipCount: Number(data.pendingShipCount) || 0,
- pendingReceiveCount: Number(data.pendingReceiveCount) || 0,
- aftersaleInProgressCount: Number(data.aftersaleInProgressCount) || 0
- }
- })
- .catch(() => {
- orderBadges.value = {
- pendingPayCount: 0,
- pendingShipCount: 0,
- pendingReceiveCount: 0,
- aftersaleInProgressCount: 0
- }
- })
- }
- function getOrderBadge(key) {
- const map = {
- [ORDER_TAB.PENDING_PAY]: orderBadges.value.pendingPayCount,
- [ORDER_TAB.PENDING_SHIP]: orderBadges.value.pendingShipCount,
- [ORDER_TAB.PENDING_RECEIVE]: orderBadges.value.pendingReceiveCount,
- AFTERSALE: orderBadges.value.aftersaleInProgressCount
- }
- return map[key] || 0
- }
- function formatBadge(n) {
- return n > 99 ? '99+' : String(n)
- }
- function goOrderListAll() {
- goOrderList(ORDER_TAB.ALL)
- }
- function onOrderShortcut(key) {
- if (key === 'AFTERSALE') {
- goAftersaleList('IN_PROGRESS')
- return
- }
- goOrderList(key)
- }
- function refreshUser() {
- displayName.value = userStore.displayName() || '会员'
- mobileText.value = userStore.state.mobile || ''
- avatarUrl.value = userStore.state.avatar || '/static/logo.png'
- if (!userStore.state.memberId) {
- userStore.fetchUserInfo().then(() => {
- displayName.value = userStore.displayName() || '会员'
- mobileText.value = userStore.state.mobile || ''
- avatarUrl.value = userStore.state.avatar || '/static/logo.png'
- })
- }
- }
- function onHeaderClick() {
- if (!loggedIn.value) {
- goLogin()
- return
- }
- navigateMinePage(PAGE_PROFILE)
- }
- function goPage(path) {
- navigateMinePage(path)
- }
- function goLogin() {
- uni.navigateTo({ url: PAGE_LOGIN })
- }
- function goRegister() {
- uni.navigateTo({ url: PAGE_REGISTER })
- }
- function handleLogout() {
- uni.showModal({
- title: '提示',
- content: '确定退出当前账号吗?',
- success: (res) => {
- if (res.confirm) {
- userStore.logOut().then(() => {
- loggedIn.value = false
- displayName.value = '点击登录'
- mobileText.value = ''
- uni.showToast({ title: '已退出', icon: 'none' })
- })
- }
- }
- })
- }
- </script>
- <style lang="scss" scoped>
- @import '@/styles/mine.scss';
- .mine-menu-item u-icon:first-child {
- margin-right: 16rpx;
- }
- .mine-menu-item {
- gap: 16rpx;
- }
- </style>
|