You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

180 lines
4.6 KiB

import { defineStore } from 'pinia'
import { DEFAULT_ADMIN_ACCESS } from '~/utils/menus'
export const IDENTITY_LABELS: Record<number, string> = {
1: '超管',
2: '管理员',
3: '代理',
4: '运营',
}
interface AppBind {
id: number
name: string
region: string
}
interface LoginData {
account: string
identity: number
token: string
access: string
apps: string
regions: string
products: string
appbinds: AppBind[]
}
const STORAGE_KEY = 'auth_state'
function parseComma(val: string): string[] {
if (!val) return []
return val.split(',').map((s) => s.trim()).filter(Boolean)
}
function saveToStorage(data: object) {
if (import.meta.client) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(data))
}
}
function loadFromStorage(): Record<string, unknown> | null {
if (!import.meta.client) return null
try {
const raw = localStorage.getItem(STORAGE_KEY)
if (!raw) return null
return JSON.parse(raw)
} catch {
return null
}
}
export const useAuthStore = defineStore('auth', {
state: () => ({
token: '' as string,
account: '' as string,
identity: 0 as number,
access: [] as string[],
apps: [] as string[],
regions: [] as string[],
products: [] as string[],
appbinds: [] as AppBind[],
currentAppId: 0 as number,
siteTitle: '' as string,
}),
getters: {
isSuperAdmin(): boolean {
return this.identity === 1
},
isAdmin(): boolean {
return this.identity === 1 || this.identity === 2
},
identityLabel(): string {
return IDENTITY_LABELS[this.identity] ?? ''
},
isLoggedIn(): boolean {
return !!this.token
},
},
actions: {
setLoginData(data: LoginData) {
this.token = data.token
this.account = data.account
this.identity = data.identity
this.access = parseComma(data.access)
this.apps = parseComma(data.apps)
this.regions = parseComma(data.regions)
this.products = parseComma(data.products)
this.appbinds = data.appbinds ?? []
if (this.appbinds.length > 0 && !this.currentAppId) {
this.currentAppId = this.appbinds[0].id
}
saveToStorage({
token: this.token,
account: this.account,
identity: this.identity,
access: this.access,
apps: this.apps,
regions: this.regions,
products: this.products,
appbinds: this.appbinds,
currentAppId: this.currentAppId,
siteTitle: this.siteTitle,
})
},
setCurrentApp(id: number) {
this.currentAppId = id
saveToStorage({
token: this.token,
account: this.account,
identity: this.identity,
access: this.access,
apps: this.apps,
regions: this.regions,
products: this.products,
appbinds: this.appbinds,
currentAppId: this.currentAppId,
siteTitle: this.siteTitle,
})
},
setSiteTitle(title: string) {
this.siteTitle = title
saveToStorage({
token: this.token,
account: this.account,
identity: this.identity,
access: this.access,
apps: this.apps,
regions: this.regions,
products: this.products,
appbinds: this.appbinds,
currentAppId: this.currentAppId,
siteTitle: this.siteTitle,
})
},
logout() {
this.token = ''
this.account = ''
this.identity = 0
this.access = []
this.apps = []
this.regions = []
this.products = []
this.appbinds = []
this.currentAppId = 0
this.siteTitle = ''
if (import.meta.client) {
localStorage.removeItem(STORAGE_KEY)
}
},
restore() {
const stored = loadFromStorage()
if (!stored) return
this.token = (stored.token as string) ?? ''
this.account = (stored.account as string) ?? ''
this.identity = (stored.identity as number) ?? 0
this.access = (stored.access as string[]) ?? []
this.apps = (stored.apps as string[]) ?? []
this.regions = (stored.regions as string[]) ?? []
this.products = (stored.products as string[]) ?? []
this.appbinds = (stored.appbinds as AppBind[]) ?? []
this.currentAppId = (stored.currentAppId as number) ?? 0
this.siteTitle = (stored.siteTitle as string) ?? ''
},
hasAccess(pageId: string): boolean {
if (this.identity === 1) return true // 超管全量
// 管理员未显式配置权限时,按默认权限集放行(除 SaaS 管理 / 系统管理 外全部)。
if (this.identity === 2 && this.access.length === 0) {
return DEFAULT_ADMIN_ACCESS.includes(pageId)
}
return this.access.includes(pageId)
},
},
})