feat: 添加客服在线状态和聊天粘贴图片功能

**客服在线状态:**
- 后端:添加 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>
This commit is contained in:
yml
2026-06-05 19:23:34 +08:00
co-authored by Claude Opus 4.6
parent b380817940
commit 59093f8fd5
18 changed files with 308 additions and 36 deletions
+10
View File
@@ -10,6 +10,7 @@ export const useAdminSessionStore = defineStore('adminSession', {
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[],
}),
@@ -41,15 +42,18 @@ export const useAdminSessionStore = defineStore('adminSession', {
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
@@ -64,10 +68,16 @@ export const useAdminSessionStore = defineStore('adminSession', {
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)
},
},
})