Signed-off-by: 吴文峰 <kevin@lmve.net>

This commit is contained in:
2026-06-09 18:59:16 +08:00
parent 33469dc746
commit 51f3f917f9
62 changed files with 12690 additions and 1 deletions
+54
View File
@@ -0,0 +1,54 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useConfigStore = defineStore('config', () => {
// API 配置
const apiBaseUrl = ref('')
// 应用配置
const appName = ref('OPS')
const version = ref('1.0.0')
// 主题配置
const theme = ref('light')
// 设置 API 地址
const setApiBaseUrl = (url) => {
apiBaseUrl.value = url
uni.setStorageSync('baseUrl', url)
}
const getApiBaseUrl=()=>{
if(apiBaseUrl.value==='')
{
apiBaseUrl.value=uni.getStorageSync('baseUrl')
}
return apiBaseUrl.value
}
// 获取图片基础 URL(去掉末尾的 /api 部分)
const getFileBaseUrl = () => {
const base = getApiBaseUrl()
if (base) {
return base.replace(/\/api$/, '')
}
return base
}
// 设置主题
const setTheme = (newTheme) => {
theme.value = newTheme
}
return {
apiBaseUrl,
appName,
version,
theme,
setApiBaseUrl,
getApiBaseUrl,
getFileBaseUrl,
setTheme
}
})
+151
View File
@@ -0,0 +1,151 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useConfigStore } from './config'
// Storage Keys
const STORAGE_KEY_COOKIE = 'userCookie'
const STORAGE_KEY_COOKIE_SESSION = 'userCookieSession'
/**
* 加载 JSON(永久存储)
*/
function loadJson(key) {
try {
const raw = uni.getStorageSync(key)
return raw ? JSON.parse(raw) : null
} catch {
return null
}
}
/**
* 清除存储
*/
function removeStorage() {
uni.removeStorageSync(STORAGE_KEY_COOKIE)
uni.removeStorageSync(STORAGE_KEY_COOKIE_SESSION)
}
export const useUserStore = defineStore('user', () => {
// ── State ──
const userCookie = ref(null) // Cookie 对象 { Value, Name, ExpiresAt, Remember }
const user = ref(null) // 用户基本信息 { ID, Name, ... }
const userInfo = ref(null) // 用户详细信息 { Username, FirstName, ... }
// ── Getters ──
/** Cookie 值字符串 */
const cookieValue = computed(() => userCookie.value?.Value ?? '')
/** 是否已登录 */
const isLoggedIn = computed(() => !!userCookie.value)
/** 用户名 */
const username = computed(() => {
return userInfo.value?.Username || user.value?.Name || ''
})
/** 头像 URL */
const avatarUrl = computed(() => {
if (userInfo.value?.AvatarPath) {
const configStore = useConfigStore()
return configStore.getApiBaseUrl() + '/static/avatar/' + userInfo.value.AvatarPath
}
return null
})
// ── Actions ──
/**
* 登录 - 保存 Cookie 并获取用户信息
* @param {Object} cookie - 后端返回的 cookie 对象
*/
function login(cookie) {
userCookie.value = cookie
// 持久化存储
if (cookie.Remember) {
uni.setStorageSync(STORAGE_KEY_COOKIE, JSON.stringify(cookie))
}
// 会话存储(始终保存)
uni.setStorageSync(STORAGE_KEY_COOKIE_SESSION, JSON.stringify(cookie))
// 检查 cookie 是否过期
if (cookie.ExpiresAt && new Date(cookie.ExpiresAt) < new Date()) {
logout()
return
}
// 获取用户信息
fetchUserInfo()
}
/**
* 退出登录
*/
function logout() {
userCookie.value = null
user.value = null
userInfo.value = null
removeStorage()
}
/**
* 获取用户信息
*/
async function fetchUserInfo() {
try {
const { api } = await import('../api/index.js')
const res = await api.post('/users/getinfo', {})
if (res.errCode === 0 && res.data) {
user.value = res.data.user ?? null
userInfo.value = res.data.userInfo ?? null
}
} catch (e) {
console.error('获取用户信息失败', e)
}
}
/**
* 应用启动时恢复登录状态
*/
function restoreSession() {
// 优先使用会话存储,否则用永久存储
let cookieStr = uni.getStorageSync(STORAGE_KEY_COOKIE_SESSION)
if (!cookieStr) {
cookieStr = uni.getStorageSync(STORAGE_KEY_COOKIE)
}
if (cookieStr) {
try {
const cookie = JSON.parse(cookieStr)
// 检查是否过期
if (cookie.ExpiresAt && new Date(cookie.ExpiresAt) < new Date()) {
logout()
return
}
// 直接设置状态并获取用户信息
userCookie.value = cookie
fetchUserInfo()
} catch {
logout()
}
}
}
return {
// State
userCookie,
user,
userInfo,
// Getters
cookieValue,
isLoggedIn,
username,
avatarUrl,
// Actions
login,
logout,
fetchUserInfo,
restoreSession
}
})
+60
View File
@@ -0,0 +1,60 @@
/**
* 用户信息缓存
*/
import { ref } from 'vue'
import { usersApi } from '../api/users'
// 全局缓存
const usersInfo = ref({})
// 请求中的 promiseMap,防止重复请求
const inflightRequests = {}
/**
* 根据用户ID获取用户信息(带缓存)
* @param {number} userID
* @returns {Promise<{Username, UserEmail} | null>}
*/
export async function fetchUserInfo(userID) {
if (!userID) return null
// 已有缓存
if (usersInfo.value[userID]) {
return usersInfo.value[userID]
}
// 请求中,等待完成
if (inflightRequests[userID]) {
return inflightRequests[userID]
}
// 发起请求
const promise = usersApi.getUserInfoFromUserID(userID).then((res) => {
if (res.errCode === 0 && res.raw?.return?.userinfo) {
const info = res.raw.return.userinfo
usersInfo.value[userID] = info
return info
}
return null
}).finally(() => {
delete inflightRequests[userID]
})
inflightRequests[userID] = promise
return promise
}
/**
* 根据用户ID获取用户名(同步,需先调用 fetchUserInfo
* @param {number} userID
* @returns {string}
*/
export function getUsername(userID) {
if (!userID) return ''
const user = usersInfo.value[userID]
return user?.Username || `用户${userID}`
}
export default {
fetchUserInfo,
getUsername
}