创建项目
This commit is contained in:
216
Web/src/stores/app.ts
Normal file
216
Web/src/stores/app.ts
Normal file
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* 应用状态仓库
|
||||
* 管理全局应用状态,如主题、加载态、配置等
|
||||
*/
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
// 主题类型
|
||||
export type ThemeMode = 'light' | 'dark' | 'auto'
|
||||
|
||||
// 语言类型
|
||||
export type Locale = 'zh-CN' | 'en-US'
|
||||
|
||||
// 应用配置
|
||||
export interface IAppConfig {
|
||||
theme: ThemeMode
|
||||
locale: Locale
|
||||
sidebarCollapsed: boolean
|
||||
showDebug: boolean
|
||||
}
|
||||
|
||||
// localStorage key
|
||||
const STORAGE_KEY = 'app-config-store'
|
||||
|
||||
export const useAppStore = defineStore('app', {
|
||||
// 1. 原始状态
|
||||
state: () => ({
|
||||
// 主题模式
|
||||
theme: 'light' as ThemeMode,
|
||||
// 当前语言
|
||||
locale: 'zh-CN' as Locale,
|
||||
// 侧边栏是否收起
|
||||
sidebarCollapsed: false,
|
||||
// 是否显示调试信息
|
||||
showDebug: false,
|
||||
// 全局加载态
|
||||
isLoading: false,
|
||||
// 加载提示文字
|
||||
loadingText: '',
|
||||
// 设备类型
|
||||
device: 'desktop' as 'desktop' | 'mobile' | 'tablet',
|
||||
// 浏览器是否在线
|
||||
isOnline: true,
|
||||
// 屏幕宽度
|
||||
screenWidth: 0,
|
||||
// 屏幕高度
|
||||
screenHeight: 0
|
||||
}),
|
||||
|
||||
// 2. 只读计算属性
|
||||
getters: {
|
||||
// 判断是否为浅色主题
|
||||
isLightTheme: (state) => state.theme === 'light',
|
||||
|
||||
// 判断是否为深色主题
|
||||
isDarkTheme: (state) => state.theme === 'dark',
|
||||
|
||||
// 判断是否为移动端
|
||||
isMobile: (state) => state.device === 'mobile',
|
||||
|
||||
// 判断是否为平板
|
||||
isTablet: (state) => state.device === 'tablet',
|
||||
|
||||
// 判断是否为桌面端
|
||||
isDesktop: (state) => state.device === 'desktop',
|
||||
|
||||
// 获取主题class
|
||||
themeClass: (state) => `theme-${state.theme}`,
|
||||
|
||||
// 判断是否有加载态
|
||||
hasLoading: (state) => state.isLoading
|
||||
},
|
||||
|
||||
// 3. 状态修改入口
|
||||
actions: {
|
||||
// 设置主题
|
||||
setTheme(theme: ThemeMode) {
|
||||
this.theme = theme
|
||||
this.syncToLocalStorage()
|
||||
// 应用主题到html元素
|
||||
if (typeof document !== 'undefined') {
|
||||
document.documentElement.setAttribute('data-theme', theme)
|
||||
}
|
||||
},
|
||||
|
||||
// 切换主题
|
||||
toggleTheme() {
|
||||
this.theme = this.theme === 'light' ? 'dark' : 'light'
|
||||
this.syncToLocalStorage()
|
||||
if (typeof document !== 'undefined') {
|
||||
document.documentElement.setAttribute('data-theme', this.theme)
|
||||
}
|
||||
},
|
||||
|
||||
// 设置语言
|
||||
setLocale(locale: Locale) {
|
||||
this.locale = locale
|
||||
this.syncToLocalStorage()
|
||||
},
|
||||
|
||||
// 切换侧边栏收起状态
|
||||
toggleSidebar() {
|
||||
this.sidebarCollapsed = !this.sidebarCollapsed
|
||||
this.syncToLocalStorage()
|
||||
},
|
||||
|
||||
// 设置侧边栏收起状态
|
||||
setSidebarCollapsed(collapsed: boolean) {
|
||||
this.sidebarCollapsed = collapsed
|
||||
this.syncToLocalStorage()
|
||||
},
|
||||
|
||||
// 设置调试模式
|
||||
setShowDebug(show: boolean) {
|
||||
this.showDebug = show
|
||||
this.syncToLocalStorage()
|
||||
},
|
||||
|
||||
// 开始加载
|
||||
startLoading(text: string = '加载中...') {
|
||||
this.isLoading = true
|
||||
this.loadingText = text
|
||||
},
|
||||
|
||||
// 结束加载
|
||||
endLoading() {
|
||||
this.isLoading = false
|
||||
this.loadingText = ''
|
||||
},
|
||||
|
||||
// 设置设备类型
|
||||
setDevice(device: 'desktop' | 'mobile' | 'tablet') {
|
||||
this.device = device
|
||||
},
|
||||
|
||||
// 设置网络状态
|
||||
setOnlineStatus(isOnline: boolean) {
|
||||
this.isOnline = isOnline
|
||||
},
|
||||
|
||||
// 更新屏幕尺寸
|
||||
updateScreenSize(width: number, height: number) {
|
||||
this.screenWidth = width
|
||||
this.screenHeight = height
|
||||
|
||||
// 根据宽度自动判断设备类型
|
||||
if (width < 768) {
|
||||
this.device = 'mobile'
|
||||
} else if (width < 1024) {
|
||||
this.device = 'tablet'
|
||||
} else {
|
||||
this.device = 'desktop'
|
||||
}
|
||||
},
|
||||
|
||||
// 初始化应用配置
|
||||
initConfig(config: Partial<IAppConfig>) {
|
||||
if (config.theme) this.setTheme(config.theme)
|
||||
if (config.locale) this.setLocale(config.locale)
|
||||
if (config.sidebarCollapsed !== undefined) this.setSidebarCollapsed(config.sidebarCollapsed)
|
||||
if (config.showDebug !== undefined) this.setShowDebug(config.showDebug)
|
||||
},
|
||||
|
||||
// 重置所有状态
|
||||
reset() {
|
||||
this.theme = 'light'
|
||||
this.locale = 'zh-CN'
|
||||
this.sidebarCollapsed = false
|
||||
this.showDebug = false
|
||||
this.isLoading = false
|
||||
this.loadingText = ''
|
||||
this.clearLocalStorage()
|
||||
},
|
||||
|
||||
// 同步到localStorage
|
||||
syncToLocalStorage() {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
const data = {
|
||||
theme: this.theme,
|
||||
locale: this.locale,
|
||||
sidebarCollapsed: this.sidebarCollapsed,
|
||||
showDebug: this.showDebug
|
||||
}
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(data))
|
||||
}
|
||||
},
|
||||
|
||||
// 从localStorage恢复
|
||||
restoreFromLocalStorage() {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
const stored = localStorage.getItem(STORAGE_KEY)
|
||||
if (stored) {
|
||||
try {
|
||||
const data = JSON.parse(stored)
|
||||
this.theme = data.theme || 'light'
|
||||
this.locale = data.locale || 'zh-CN'
|
||||
this.sidebarCollapsed = data.sidebarCollapsed || false
|
||||
this.showDebug = data.showDebug || false
|
||||
// 应用主题
|
||||
if (typeof document !== 'undefined') {
|
||||
document.documentElement.setAttribute('data-theme', this.theme)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('恢复应用配置失败:', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 清除localStorage
|
||||
clearLocalStorage() {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
localStorage.removeItem(STORAGE_KEY)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
106
Web/src/stores/user.ts
Normal file
106
Web/src/stores/user.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* 用户状态仓库
|
||||
* 管理用户登录信息、Token等核心状态
|
||||
*/
|
||||
import { defineStore } from 'pinia'
|
||||
import type { IUserInfo } from '~/types/user'
|
||||
|
||||
// 仓库命名规范:use+业务域+Store
|
||||
export const useUserStore = defineStore('user', {
|
||||
// 1. 原始状态:仅存基础数据,不做任何计算、判断
|
||||
state: () => ({
|
||||
userInfo: null as IUserInfo | null,
|
||||
token: '',
|
||||
isLoading: false as boolean
|
||||
}),
|
||||
|
||||
// 2. 只读计算属性:封装派生逻辑,全局只读
|
||||
getters: {
|
||||
// 判断是否登录
|
||||
isLogin: (state) => !!state.token,
|
||||
|
||||
// 获取用户ID
|
||||
userId: (state) => state.userInfo?.id ?? 0,
|
||||
|
||||
// 格式化用户昵称
|
||||
userNickname: (state) => state.userInfo?.nickname || state.userInfo?.username || '未知用户',
|
||||
|
||||
// 获取用户头像
|
||||
userAvatar: (state) => state.userInfo?.avatar || '',
|
||||
|
||||
// 获取用户角色
|
||||
userRole: (state) => state.userInfo?.role || 'user'
|
||||
},
|
||||
|
||||
// 3. 唯一状态修改入口:所有状态变更必须走actions
|
||||
actions: {
|
||||
// 设置用户信息与Token
|
||||
setUserInfo(data: IUserInfo, token: string) {
|
||||
this.userInfo = data
|
||||
this.token = token
|
||||
this.isLoading = false
|
||||
// 同步到localStorage
|
||||
this.syncToLocalStorage()
|
||||
},
|
||||
|
||||
// 仅更新Token
|
||||
setToken(token: string) {
|
||||
this.token = token
|
||||
this.syncToLocalStorage()
|
||||
},
|
||||
|
||||
// 退出登录:清空用户状态
|
||||
clearUserInfo() {
|
||||
this.userInfo = null
|
||||
this.token = ''
|
||||
this.isLoading = false
|
||||
this.clearLocalStorage()
|
||||
},
|
||||
|
||||
// 设置登录加载态
|
||||
setLoginLoading(loading: boolean) {
|
||||
this.isLoading = loading
|
||||
},
|
||||
|
||||
// 更新用户信息(部分更新)
|
||||
updateUserInfo(partialData: Partial<IUserInfo>) {
|
||||
if (this.userInfo) {
|
||||
this.userInfo = { ...this.userInfo, ...partialData }
|
||||
this.syncToLocalStorage()
|
||||
}
|
||||
},
|
||||
|
||||
// 同步到localStorage
|
||||
syncToLocalStorage() {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
localStorage.setItem('user-auth-store', JSON.stringify({
|
||||
token: this.token,
|
||||
userInfo: this.userInfo
|
||||
}))
|
||||
}
|
||||
},
|
||||
|
||||
// 从localStorage恢复
|
||||
restoreFromLocalStorage() {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
const stored = localStorage.getItem('user-auth-store')
|
||||
if (stored) {
|
||||
try {
|
||||
const data = JSON.parse(stored)
|
||||
this.token = data.token || ''
|
||||
this.userInfo = data.userInfo || null
|
||||
} catch (e) {
|
||||
console.error('恢复用户状态失败:', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 清除localStorage
|
||||
clearLocalStorage() {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
localStorage.removeItem('user-auth-store')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user