**客服在线状态:** - 后端:添加 admin_users.support_status 字段(online/offline/busy) - 接口:PUT /admin/me/support-status 更新状态 - 前端:管理员顶部导航显示状态切换器(仅客服权限可见) - 转接对话框显示客服在线状态和智能排序(在线优先) **聊天粘贴图片:** - 用户端、移动端、管理端聊天输入框支持 Ctrl+V/Cmd+V 直接粘贴图片 - 自动调用图片压缩和上传逻辑,与文件选择上传保持一致 - 最多支持粘贴9张图片 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
84 lines
3.1 KiB
TypeScript
84 lines
3.1 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
|
|
import { fetchAdminMe, loginAdmin, type AdminRole, type AdminUser } from '@/features/admin/api/adminAuth'
|
|
import { clearAuthStorage, getAccessToken, getRefreshToken, setAuthTokens } from '@/utils/authStorage'
|
|
|
|
export const useAdminSessionStore = defineStore('adminSession', {
|
|
state: () => ({
|
|
token: getAccessToken('admin'),
|
|
refreshToken: getRefreshToken('admin'),
|
|
adminId: Number(localStorage.getItem('admin_id') || 0),
|
|
username: localStorage.getItem('admin_username') || '',
|
|
nickname: '',
|
|
supportStatus: (localStorage.getItem('admin_support_status') || 'offline') as 'online' | 'offline' | 'busy',
|
|
roles: [] as AdminRole[],
|
|
permissions: [] as string[],
|
|
}),
|
|
getters: {
|
|
hasPermission: (state) => {
|
|
return (code: string) => state.permissions.includes(code) || state.permissions.includes('*')
|
|
},
|
|
hasRole: (state) => {
|
|
return (code: string) => state.roles.some((r) => r.code === code)
|
|
},
|
|
isSuperAdmin: (state) => {
|
|
return state.roles.some((r) => r.code === 'super_admin') || state.permissions.includes('*')
|
|
},
|
|
},
|
|
actions: {
|
|
async login(username: string, password: string, captchaId: string, captchaCode: string) {
|
|
const result = await loginAdmin(username, password, captchaId, captchaCode)
|
|
this.applySession(result.admin, result.tokens.access_token, result.tokens.refresh_token)
|
|
return result
|
|
},
|
|
async loadMe() {
|
|
const admin = await fetchAdminMe()
|
|
this.applyAdmin(admin)
|
|
return admin
|
|
},
|
|
logout() {
|
|
this.token = ''
|
|
this.refreshToken = ''
|
|
this.adminId = 0
|
|
this.username = ''
|
|
this.nickname = ''
|
|
this.supportStatus = 'offline'
|
|
this.roles = []
|
|
this.permissions = []
|
|
clearAuthStorage('admin')
|
|
localStorage.removeItem('admin_support_status')
|
|
},
|
|
syncFromStorage() {
|
|
this.token = getAccessToken('admin')
|
|
this.refreshToken = getRefreshToken('admin')
|
|
this.adminId = Number(localStorage.getItem('admin_id') || 0)
|
|
this.username = localStorage.getItem('admin_username') || ''
|
|
this.supportStatus = (localStorage.getItem('admin_support_status') || 'offline') as 'online' | 'offline' | 'busy'
|
|
},
|
|
applySession(admin: AdminUser, accessToken: string, refreshToken: string) {
|
|
this.token = accessToken
|
|
this.refreshToken = refreshToken
|
|
setAuthTokens('admin', {
|
|
access_token: accessToken,
|
|
refresh_token: refreshToken,
|
|
})
|
|
this.applyAdmin(admin)
|
|
},
|
|
applyAdmin(admin: AdminUser) {
|
|
this.adminId = admin.id
|
|
this.username = admin.username
|
|
this.nickname = admin.nickname
|
|
this.supportStatus = admin.support_status || 'offline'
|
|
this.roles = admin.roles || []
|
|
this.permissions = admin.permissions || []
|
|
localStorage.setItem('admin_id', String(admin.id))
|
|
localStorage.setItem('admin_username', admin.username)
|
|
localStorage.setItem('admin_support_status', admin.support_status || 'offline')
|
|
},
|
|
setSupportStatus(status: 'online' | 'offline' | 'busy') {
|
|
this.supportStatus = status
|
|
localStorage.setItem('admin_support_status', status)
|
|
},
|
|
},
|
|
})
|