Explorar o código

fix: tabbar 图标、退出登录和顶部操作栏

- BottomNav 将图标名绑定到 class,修复显示为文本的问题
- 统一并修复三端我的页/个人中心的退出登录逻辑
- TopBar 增加状态栏安全区域,补充缺失的组件引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
xuyunhui hai 2 semanas
pai
achega
90d1562dae

+ 6 - 5
src/components/common/BottomNav.vue

@@ -14,16 +14,17 @@
         >
           <text
             class="uni-icons text-xl"
-            :class="isActive(item.path) ? 'text-primary' : 'text-gray-400'"
-          >
-            {{ isActive(item.path) && item.activeIcon ? item.activeIcon : item.icon }}
-          </text>
+            :class="[
+              isActive(item.path) ? 'text-primary' : 'text-gray-400',
+              isActive(item.path) && item.activeIcon ? item.activeIcon : item.icon,
+            ]"
+          />
         </view>
         <text
           class="text-xs"
           :class="isActive(item.path) ? 'text-primary font-medium' : 'text-gray-400'"
         >
-          {{ item.text }}
+          {{ item.text || item.name }}
         </text>
       </view>
     </view>

+ 20 - 13
src/components/common/TopBar.vue

@@ -1,18 +1,21 @@
 <template>
-  <view class="top-bar bg-white px-4 h-12 flex items-center justify-between sticky top-0 z-40 border-b border-gray-100">
-    <view class="flex items-center flex-1">
-      <view
-        v-if="showBack"
-        class="mr-2 p-2 -ml-2 clickable rounded-lg"
-        @click="goBack"
-      >
-        <text class="text-gray-600 text-lg">←</text>
+  <view class="sticky top-0 z-40 bg-white border-b border-gray-100">
+    <view class="status-bar"></view>
+    <view class="top-bar px-4 h-12 flex items-center justify-between">
+      <view class="flex items-center flex-1">
+        <view
+          v-if="showBack"
+          class="mr-2 p-2 -ml-2 clickable rounded-lg"
+          @click="goBack"
+        >
+          <text class="text-gray-600 text-lg">←</text>
+        </view>
+        <slot name="left" />
+        <text class="text-base font-semibold text-gray-800 truncate">{{ title }}</text>
+      </view>
+      <view class="flex items-center">
+        <slot name="right" />
       </view>
-      <slot name="left" />
-      <text class="text-base font-semibold text-gray-800 truncate">{{ title }}</text>
-    </view>
-    <view class="flex items-center">
-      <slot name="right" />
     </view>
   </view>
 </template>
@@ -39,4 +42,8 @@ function goBack() {
 .top-bar {
   height: 44px;
 }
+
+.status-bar {
+  height: var(--status-bar-height);
+}
 </style>

+ 8 - 11
src/pages/common/profile.vue

@@ -71,6 +71,7 @@
 <script setup lang="ts">
 import { computed } from 'vue'
 import { useAuthStore } from '../../stores/auth'
+import TopBar from '../../components/common/TopBar.vue'
 import UniCard from '../../components/uni-card/uni-card.vue'
 import UniList from '../../components/uni-list/uni-list.vue'
 import UniListItem from '../../components/uni-list/uni-list-item.vue'
@@ -122,19 +123,15 @@ function goToHelp() {
   uni.navigateTo({ url: '/pages/construction/helpCenter' })
 }
 
-function handleLogout() {
-  uni.showModal({
+async function handleLogout() {
+  const res = await uni.showModal({
     title: '确认退出',
     content: '确定要退出登录吗?',
-    success: (res) => {
-      if (res.confirm) {
-        authStore.logout()
-        // 清除本地存储并跳转到登录页
-        uni.removeStorageSync('token')
-        uni.removeStorageSync('user')
-        uni.reLaunch({ url: '/pages/login/login' })
-      }
-    },
   })
+  if (res.confirm) {
+    await authStore.doLogout()
+    uni.showToast({ title: '已退出登录', icon: 'none' })
+    uni.reLaunch({ url: '/pages/login/login' })
+  }
 }
 </script>

+ 1 - 0
src/pages/common/projectList.vue

@@ -89,6 +89,7 @@
 import { ref, computed, onMounted } from 'vue'
 import { useProjectStore } from '../../stores/project'
 import EmptyState from '../../components/common/EmptyState.vue'
+import TopBar from '../../components/common/TopBar.vue'
 import UniList from '../../components/uni-list/uni-list.vue'
 import UniListItem from '../../components/uni-list/uni-list-item.vue'
 import UniSwipeAction from '../../components/uni-swipe-action/uni-swipe-action.vue'

+ 9 - 8
src/pages/construction/myPage.vue

@@ -91,7 +91,7 @@ import { ref, computed } from 'vue'
 import BottomNav from '../../components/common/BottomNav.vue'
 import { useAuthStore } from '../../stores/auth'
 import { useNotificationStore } from '../../stores/notification'
-import { navigateTo, redirectTo, showModal } from '../../utils'
+import { navigateTo, showModal, showToast } from '../../utils'
 
 const authStore = useAuthStore()
 const notificationStore = useNotificationStore()
@@ -107,13 +107,13 @@ const userPhone = computed(() => {
 const unreadCount = computed(() => notificationStore.unreadCount)
 
 const navItems = [
-  { text: '首页', path: '/pages/construction/home', icon: '' },
-  { text: '任务', path: '/pages/construction/taskList', icon: '' },
-  { text: '我的', path: '/pages/construction/myPage', icon: '' },
+  { text: '首页', path: '/pages/construction/home', icon: 'uniui-home-filled' },
+  { text: '任务', path: '/pages/construction/taskList', icon: 'uniui-flag-filled' },
+  { text: '我的', path: '/pages/construction/myPage', icon: 'uniui-person-filled' },
 ]
 
 function onNavChange(path: string) {
-  uni.navigateTo({ url: path })
+  uni.reLaunch({ url: path })
 }
 
 function goToBasicInfo() {
@@ -138,10 +138,11 @@ function logout() {
     content: '确定要退出登录吗?',
     showCancel: true,
     confirmText: '退出',
-    success: (res) => {
+    success: async (res: any) => {
       if (res.confirm) {
-        authStore.logout()
-        redirectTo('/pages/login/login')
+        await authStore.doLogout()
+        showToast('已退出登录')
+        uni.reLaunch({ url: '/pages/login/login' })
       }
     }
   })

+ 5 - 5
src/pages/dispatch/myPage.vue

@@ -81,13 +81,13 @@ const userPhone = computed(() => authStore.userInfo?.phone)
 const unreadCount = computed(() => notificationStore.unreadCount)
 
 const navItems = [
-  { text: '首页', path: '/pages/dispatch/home', icon: '' },
-  { text: '任务', path: '/pages/dispatch/taskList', icon: '' },
-  { text: '我的', path: '/pages/dispatch/myPage', icon: '' },
+  { text: '首页', path: '/pages/dispatch/home', icon: 'uniui-home-filled' },
+  { text: '任务', path: '/pages/dispatch/taskList', icon: 'uniui-flag-filled' },
+  { text: '我的', path: '/pages/dispatch/myPage', icon: 'uniui-person-filled' },
 ]
 
 function onNavChange(path: string) {
-  navigateTo(path)
+  uni.reLaunch({ url: path })
 }
 
 function goToBasicInfo() {
@@ -112,7 +112,7 @@ async function logout() {
     content: '确定要退出登录吗?'
   })
   if (res.confirm) {
-    authStore.logout()
+    await authStore.doLogout()
     showToast('已退出登录')
     uni.reLaunch({ url: '/pages/login/login' })
   }

+ 2 - 1
src/types/index.ts

@@ -140,7 +140,8 @@ export interface NavItem {
   path: string
   icon: string
   activeIcon?: string
-  text: string
+  text?: string
+  name?: string
 }
 
 export interface ToastOptions {