优化:登录信息显示
This commit is contained in:
parent
99c75a7f69
commit
ae495ef9ab
22
src/App.vue
22
src/App.vue
@ -1,8 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useUserStore } from './stores/user'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
const currentRoute = computed(() => {
|
const currentRoute = computed(() => {
|
||||||
return route.path
|
return route.path
|
||||||
@ -14,9 +16,23 @@ const currentRoute = computed(() => {
|
|||||||
<v-app-bar color="primary" dark>
|
<v-app-bar color="primary" dark>
|
||||||
<v-app-bar-title>PolyMarket</v-app-bar-title>
|
<v-app-bar-title>PolyMarket</v-app-bar-title>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn text to="/" :class="{ active: currentRoute === '/' }"> Home </v-btn>
|
<v-btn v-if="!userStore.isLoggedIn" text to="/login" :class="{ active: currentRoute === '/login' }">
|
||||||
<v-btn text to="/trade" :class="{ active: currentRoute === '/trade' }"> Trade </v-btn>
|
Login
|
||||||
<v-btn text to="/login" :class="{ active: currentRoute === '/login' }"> Login </v-btn>
|
</v-btn>
|
||||||
|
<v-menu v-else location="bottom" :close-on-content-click="false">
|
||||||
|
<template #activator="{ props }">
|
||||||
|
<v-btn v-bind="props" icon variant="text" class="avatar-btn">
|
||||||
|
<v-avatar size="36" color="primary">
|
||||||
|
<v-img v-if="userStore.avatarUrl" :src="userStore.avatarUrl" cover alt="avatar" />
|
||||||
|
<v-icon v-else>mdi-account</v-icon>
|
||||||
|
</v-avatar>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
<v-list density="compact">
|
||||||
|
<v-list-item :title="userStore.user?.nickName || userStore.user?.userName || 'User'" disabled />
|
||||||
|
<v-list-item title="退出登录" @click="userStore.logout()" />
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
</v-app-bar>
|
</v-app-bar>
|
||||||
<v-main>
|
<v-main>
|
||||||
<router-view />
|
<router-view />
|
||||||
|
|||||||
63
src/stores/user.ts
Normal file
63
src/stores/user.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export interface UserInfo {
|
||||||
|
headerImg?: string
|
||||||
|
nickName?: string
|
||||||
|
userName?: string
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'poly-user'
|
||||||
|
|
||||||
|
function loadStored(): { token: string; user: UserInfo } | null {
|
||||||
|
try {
|
||||||
|
const raw = localStorage.getItem(STORAGE_KEY)
|
||||||
|
if (!raw) return null
|
||||||
|
return JSON.parse(raw) as { token: string; user: UserInfo }
|
||||||
|
} catch {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveToStorage(token: string, user: UserInfo) {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(STORAGE_KEY, JSON.stringify({ token, user }))
|
||||||
|
} catch {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearStorage() {
|
||||||
|
try {
|
||||||
|
localStorage.removeItem(STORAGE_KEY)
|
||||||
|
} catch {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useUserStore = defineStore('user', () => {
|
||||||
|
const stored = loadStored()
|
||||||
|
const token = ref<string>(stored?.token ?? '')
|
||||||
|
const user = ref<UserInfo | null>(stored?.user ?? null)
|
||||||
|
|
||||||
|
const isLoggedIn = computed(() => !!token.value && !!user.value)
|
||||||
|
const avatarUrl = computed(() => user.value?.headerImg ?? '')
|
||||||
|
|
||||||
|
function setUser(loginData: { token?: string; user?: UserInfo }) {
|
||||||
|
const t = loginData.token ?? ''
|
||||||
|
const u = loginData.user ?? null
|
||||||
|
token.value = t
|
||||||
|
user.value = u
|
||||||
|
if (t && u) saveToStorage(t, u)
|
||||||
|
else clearStorage()
|
||||||
|
}
|
||||||
|
|
||||||
|
function logout() {
|
||||||
|
token.value = ''
|
||||||
|
user.value = null
|
||||||
|
clearStorage()
|
||||||
|
}
|
||||||
|
|
||||||
|
return { token, user, isLoggedIn, avatarUrl, setUser, logout }
|
||||||
|
})
|
||||||
@ -66,8 +66,10 @@ import { ref } from 'vue'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { BrowserProvider } from 'ethers'
|
import { BrowserProvider } from 'ethers'
|
||||||
import { SiweMessage } from 'siwe'
|
import { SiweMessage } from 'siwe'
|
||||||
|
import { useUserStore } from '../stores/user'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const userStore = useUserStore()
|
||||||
const email = ref('')
|
const email = ref('')
|
||||||
const password = ref('')
|
const password = ref('')
|
||||||
const isConnecting = ref(false)
|
const isConnecting = ref(false)
|
||||||
@ -185,8 +187,13 @@ const connectWithWallet = async () => {
|
|||||||
const loginData = await loginResponse.json()
|
const loginData = await loginResponse.json()
|
||||||
console.log('Login API response:', loginData)
|
console.log('Login API response:', loginData)
|
||||||
|
|
||||||
// For demo purposes, we'll just navigate to the home page
|
if (loginData.code === 0 && loginData.data) {
|
||||||
// In a real application, you would store the token or session data here
|
userStore.setUser({
|
||||||
|
token: loginData.data.token,
|
||||||
|
user: loginData.data.user ?? null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
router.push('/')
|
router.push('/')
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('Error connecting to wallet:', error)
|
console.error('Error connecting to wallet:', error)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user