diff --git a/source/clients/uniapp/src/App.vue b/source/clients/uniapp/src/App.vue
index da1e71b..85fdb98 100644
--- a/source/clients/uniapp/src/App.vue
+++ b/source/clients/uniapp/src/App.vue
@@ -1,13 +1,15 @@
diff --git a/source/clients/uniapp/src/pages/login/index.vue b/source/clients/uniapp/src/pages/login/index.vue
index 262594c..73f3186 100644
--- a/source/clients/uniapp/src/pages/login/index.vue
+++ b/source/clients/uniapp/src/pages/login/index.vue
@@ -65,6 +65,7 @@ export default {
}
userStore.setToken(token)
+ await userStore.fetchProfile({ force: true })
uni.showToast({ title: '登录成功', icon: 'none' })
uni.navigateBack({
diff --git a/source/clients/uniapp/src/pages/mine/index.vue b/source/clients/uniapp/src/pages/mine/index.vue
index 03751f2..d3b8edc 100644
--- a/source/clients/uniapp/src/pages/mine/index.vue
+++ b/source/clients/uniapp/src/pages/mine/index.vue
@@ -11,6 +11,37 @@
+
+
+ 用户ID
+ {{ isLoggedIn ? (profile.id || '-') : '-' }}
+
+
+ 用户名
+ {{ isLoggedIn ? (profile.username || '-') : '-' }}
+
+
+ 昵称
+ {{ isLoggedIn ? (profile.nickname || '-') : '-' }}
+
+
+ 手机号
+ {{ isLoggedIn ? (profile.phone || '-') : '-' }}
+
+
+ 备注
+ {{ isLoggedIn ? (profile.remark || '-') : '-' }}
+
+
+ 头像
+ {{ isLoggedIn ? (profile.head_img || '-') : '-' }}
+
+
+ 读取状态
+ {{ isLoggedIn ? (profileLoading ? '读取中...' : '已读取') : '-' }}
+
+
+
@@ -32,12 +63,20 @@ export default {
isLoggedIn() {
return this.userStore.isLoggedIn
},
+ profile() {
+ return this.userStore.profile || {}
+ },
+ profileLoading() {
+ return this.userStore.profileLoading
+ },
},
onShow() {
this.userStore.init()
if (!this.isLoggedIn) {
this.goLogin()
+ return
}
+ this.userStore.fetchProfile({ force: true })
},
methods: {
goLogin() {
diff --git a/source/clients/uniapp/src/store/user.js b/source/clients/uniapp/src/store/user.js
index cc72929..fcd0bf4 100644
--- a/source/clients/uniapp/src/store/user.js
+++ b/source/clients/uniapp/src/store/user.js
@@ -1,11 +1,99 @@
import { defineStore } from 'pinia'
+import { env } from '../config/env'
const TOKEN_KEY = 'ULTHON_ADMIN_TOKEN'
+const PROFILE_KEY = 'ULTHON_ADMIN_PROFILE'
+const PROFILE_FETCHED_AT_KEY = 'ULTHON_ADMIN_PROFILE_FETCHED_AT'
+
+const AUTH_REQUIRED_CODE = 40101
+const AUTH_EXPIRED_CODE = 40102
+
+function buildUrl(url) {
+ if (!url) return ''
+ if (/^https?:\/\//i.test(url)) return url
+ const baseUrl = env.apiBaseUrl || ''
+ if (url.startsWith('/')) return `${baseUrl}${url}`
+ return `${baseUrl}/${url}`
+}
+
+function getCurrentRoutePath() {
+ try {
+ const pages = getCurrentPages()
+ const current = pages && pages[pages.length - 1]
+ const route = (current && (current.route || (current.$page && current.$page.fullPath))) || ''
+ return String(route)
+ } catch (e) {
+ return ''
+ }
+}
+
+function redirectToLoginIfNeeded() {
+ const route = getCurrentRoutePath()
+ if (route.includes('pages/login/index')) return
+
+ uni.navigateTo({
+ url: '/pages/login/index',
+ fail: () => {
+ uni.reLaunch({ url: '/pages/login/index' })
+ },
+ })
+}
+
+function requestJson(options) {
+ const url = buildUrl(options.url)
+ const method = (options.method || 'GET').toUpperCase()
+ const header = {
+ Accept: 'application/json',
+ ...(options.header || {}),
+ }
+
+ if (options.token && !header.Authorization) {
+ header.Authorization = `Bearer ${options.token}`
+ }
+
+ return new Promise((resolve, reject) => {
+ uni.request({
+ url,
+ method,
+ data: options.data || {},
+ header,
+ timeout: options.timeout || env.timeout || 60000,
+ success: (res) => {
+ const resData = res.data
+
+ if (!res || typeof res !== 'object') {
+ reject(new Error('Invalid response'))
+ return
+ }
+
+ if (res.statusCode && res.statusCode >= 400) {
+ reject(new Error(`HTTP ${res.statusCode}`))
+ return
+ }
+
+ if (resData && typeof resData === 'object' && 'code' in resData) {
+ if (resData.code === 0) {
+ resolve(resData)
+ return
+ }
+ reject(resData)
+ return
+ }
+
+ resolve(resData)
+ },
+ fail: (err) => reject(err),
+ })
+ })
+}
export const useUserStore = defineStore('user', {
state: () => ({
token: '',
inited: false,
+ profile: null,
+ profileFetchedAt: 0,
+ profileLoading: false,
}),
getters: {
isLoggedIn: (state) => !!state.token,
@@ -14,16 +102,90 @@ export const useUserStore = defineStore('user', {
init() {
if (this.inited) return
this.token = uni.getStorageSync(TOKEN_KEY) || ''
+ this.profile = uni.getStorageSync(PROFILE_KEY) || null
+ this.profileFetchedAt = Number(uni.getStorageSync(PROFILE_FETCHED_AT_KEY) || 0) || 0
this.inited = true
},
+ async bootstrap(options = {}) {
+ this.init()
+ if (!this.token) return
+ await this.fetchProfile({ force: !!options.forceProfile })
+ },
setToken(token) {
this.token = token || ''
uni.setStorageSync(TOKEN_KEY, this.token)
+ if (!this.token) {
+ this.profile = null
+ this.profileFetchedAt = 0
+ uni.removeStorageSync(PROFILE_KEY)
+ uni.removeStorageSync(PROFILE_FETCHED_AT_KEY)
+ }
+ },
+ async fetchProfile(options = {}) {
+ this.init()
+ if (!this.token) {
+ this.profile = null
+ this.profileFetchedAt = 0
+ return null
+ }
+
+ const now = Date.now()
+ const cacheMs = Number(options.cacheMs || 60 * 1000) || 60 * 1000
+ if (!options.force && this.profileFetchedAt && now - this.profileFetchedAt < cacheMs) {
+ return this.profile
+ }
+
+ if (this._profilePromise) {
+ return this._profilePromise
+ }
+
+ this.profileLoading = true
+ this._profilePromise = (async () => {
+ try {
+ const res = await requestJson({
+ url: '/admin/index/editAdmin',
+ method: 'GET',
+ data: { get_page_data: 1 },
+ token: this.token,
+ })
+
+ const payload = (res && res.data) || {}
+ const profile = payload.row || payload.admin || payload.session_admin || null
+
+ this.profile = profile
+ this.profileFetchedAt = Date.now()
+
+ uni.setStorageSync(PROFILE_KEY, this.profile || null)
+ uni.setStorageSync(PROFILE_FETCHED_AT_KEY, this.profileFetchedAt)
+
+ return this.profile
+ } catch (e) {
+ const code = e && typeof e === 'object' ? e.code : null
+ if (code === AUTH_REQUIRED_CODE || code === AUTH_EXPIRED_CODE) {
+ this.logout()
+ redirectToLoginIfNeeded()
+ return null
+ }
+
+ return this.profile
+ } finally {
+ this.profileLoading = false
+ }
+ })()
+
+ try {
+ return await this._profilePromise
+ } finally {
+ this._profilePromise = null
+ }
},
logout() {
this.token = ''
+ this.profile = null
+ this.profileFetchedAt = 0
uni.removeStorageSync(TOKEN_KEY)
+ uni.removeStorageSync(PROFILE_KEY)
+ uni.removeStorageSync(PROFILE_FETCHED_AT_KEY)
},
},
})
-