App.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <template>
  2. <div id="app">
  3. <a-layout style="min-height: 100vh">
  4. <a-layout-header style="background: #001529; padding: 0 50px; display: flex; align-items: center; justify-content: space-between;">
  5. <div style="color: white; font-size: 24px; font-weight: bold; cursor: pointer;" @click="goHome">
  6. 🌍 HelloAgents智能旅行助手
  7. </div>
  8. <div style="display: flex; align-items: center; gap: 12px;">
  9. <a-button v-if="isLoggedIn" type="text" style="color: white;" @click="goHistory">
  10. 📋 历史记录
  11. </a-button>
  12. <a-button v-if="isLoggedIn" type="text" style="color: white;" @click="goChat">
  13. 💬 AI对话
  14. </a-button>
  15. <span v-if="isLoggedIn" style="color: rgba(255,255,255,0.65);">👤 {{ username }}</span>
  16. <a-button v-if="!isLoggedIn" type="primary" ghost @click="goLogin">登录</a-button>
  17. <a-button v-else type="text" style="color: rgba(255,255,255,0.65);" @click="handleLogout">退出</a-button>
  18. </div>
  19. </a-layout-header>
  20. <a-layout-content style="padding: 24px">
  21. <router-view />
  22. </a-layout-content>
  23. <a-layout-footer style="text-align: center">
  24. HelloAgents智能旅行助手 ©2025 基于HelloAgents框架
  25. </a-layout-footer>
  26. </a-layout>
  27. </div>
  28. </template>
  29. <script setup lang="ts">
  30. import { ref, onMounted } from 'vue'
  31. import { useRouter } from 'vue-router'
  32. import { message } from 'ant-design-vue'
  33. const router = useRouter()
  34. const isLoggedIn = ref(false)
  35. const username = ref('')
  36. /** 从 document.cookie 读取用户名(由后端设置,非 HttpOnly,零请求) */
  37. function getUsernameFromCookie(): string | null {
  38. const match = document.cookie.match(/(?:^|;\s*)auth_username=([^;]*)/)
  39. return match ? decodeURIComponent(match[1]) : null
  40. }
  41. function checkAuth() {
  42. // 直接从 Cookie 读取,无需调 /api/auth/profile 接口
  43. const name = getUsernameFromCookie()
  44. isLoggedIn.value = !!name
  45. username.value = name || ''
  46. }
  47. // 每次路由切换时检查 Cookie
  48. router.afterEach(() => {
  49. checkAuth()
  50. })
  51. function goHome() {
  52. router.push('/')
  53. }
  54. function goLogin() {
  55. router.push('/login')
  56. }
  57. function goHistory() {
  58. if (!isLoggedIn.value) {
  59. message.warning('请先登录')
  60. router.push('/login')
  61. return
  62. }
  63. router.push('/history')
  64. }
  65. function goChat() {
  66. if (!isLoggedIn.value) {
  67. message.warning('请先登录')
  68. router.push('/login')
  69. return
  70. }
  71. router.push('/chat')
  72. }
  73. async function handleLogout() {
  74. try {
  75. await fetch(`${import.meta.env.VITE_API_BASE_URL || 'https://localhost:8000'}/api/auth/logout`, {
  76. method: 'POST',
  77. credentials: 'include',
  78. })
  79. } catch {}
  80. localStorage.removeItem('auth_username')
  81. isLoggedIn.value = false
  82. username.value = ''
  83. message.success('已退出登录')
  84. router.push('/')
  85. }
  86. onMounted(checkAuth)
  87. </script>
  88. <style>
  89. #app {
  90. font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
  91. 'Noto Sans', sans-serif;
  92. }
  93. </style>