gateway tomcat去除
This commit is contained in:
18
urbanLifelineWeb/.vscode/launch.json
vendored
18
urbanLifelineWeb/.vscode/launch.json
vendored
@@ -31,6 +31,21 @@
|
||||
"clear": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "启动 workcase 开发服务器",
|
||||
"type": "node-terminal",
|
||||
"request": "launch",
|
||||
"command": "npm run dev",
|
||||
"cwd": "${workspaceFolder}/packages/workcase",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "new",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "启动 Bidding 开发服务器",
|
||||
"type": "node-terminal",
|
||||
@@ -53,7 +68,8 @@
|
||||
"configurations": [
|
||||
"启动 Shared 开发服务器",
|
||||
"启动 Platform 开发服务器",
|
||||
"启动 Bidding 开发服务器"
|
||||
"启动 workcase 开发服务器",
|
||||
// "启动 Bidding 开发服务器"
|
||||
],
|
||||
"stopAll": true,
|
||||
"presentation": {
|
||||
|
||||
@@ -98,8 +98,10 @@ declare module 'shared/api/ai' {
|
||||
|
||||
declare module 'shared/api/workcase' {
|
||||
export const workcaseAPI: any
|
||||
export const workcaseChatAPI: any
|
||||
}
|
||||
|
||||
|
||||
// ============ types模块 ==================
|
||||
declare module 'shared/types' {
|
||||
import type { BaseDTO } from '../../../shared/src/types/base'
|
||||
@@ -143,15 +145,30 @@ declare module 'shared/types' {
|
||||
TbWorkcaseDeviceDTO,
|
||||
// 聊天室相关
|
||||
TbChatRoomDTO,
|
||||
TbChatMessageDTO,
|
||||
TbChatRoomMessageDTO,
|
||||
TbChatRoomMemberDTO,
|
||||
TbVideoMeetingDTO,
|
||||
TbMeetingParticipantDTO,
|
||||
TbMeetingTranscriptionDTO,
|
||||
ChatRoomVO,
|
||||
ChatMessageVO,
|
||||
ChatRoomMessageVO,
|
||||
ChatMemberVO,
|
||||
VideoMeetingVO,
|
||||
MeetingParticipantVO,
|
||||
SendMessageParam,
|
||||
CreateMeetingParam,
|
||||
MarkReadParam
|
||||
MarkReadParam,
|
||||
// 客服相关
|
||||
TbCustomerServiceDTO,
|
||||
CustomerServiceVO,
|
||||
// 词云
|
||||
TbWordCloudDTO,
|
||||
// 来客相关
|
||||
TbGuestDTO,
|
||||
GuestVO,
|
||||
CustomerVO,
|
||||
ConversationVO
|
||||
} from '../../../shared/src/types/workcase'
|
||||
|
||||
// 重新导出 menu
|
||||
|
||||
11
urbanLifelineWeb/packages/platform/pnpm-lock.yaml
generated
11
urbanLifelineWeb/packages/platform/pnpm-lock.yaml
generated
@@ -17,6 +17,9 @@ dependencies:
|
||||
element-plus:
|
||||
specifier: ^2.12.0
|
||||
version: 2.12.0(vue@3.5.25)
|
||||
lucide-vue-next:
|
||||
specifier: ^0.561.0
|
||||
version: 0.561.0(vue@3.5.25)
|
||||
pinia:
|
||||
specifier: ^2.2.8
|
||||
version: 2.3.1(typescript@5.9.3)(vue@3.5.25)
|
||||
@@ -1464,6 +1467,14 @@ packages:
|
||||
yallist: 3.1.1
|
||||
dev: true
|
||||
|
||||
/lucide-vue-next@0.561.0(vue@3.5.25):
|
||||
resolution: {integrity: sha512-c5HUckO0qHklVSOf/0vaSR3pEb8fYImRDCRDLde56uqS9js0D/e3RAvq0/YFWjkmyOBKCb0/IdskdoHZQEkT5g==}
|
||||
peerDependencies:
|
||||
vue: '>=3.0.1'
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.9.3)
|
||||
dev: false
|
||||
|
||||
/magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
dependencies:
|
||||
|
||||
@@ -98,8 +98,10 @@ declare module 'shared/api/ai' {
|
||||
|
||||
declare module 'shared/api/workcase' {
|
||||
export const workcaseAPI: any
|
||||
export const workcaseChatAPI: any
|
||||
}
|
||||
|
||||
|
||||
// ============ types模块 ==================
|
||||
declare module 'shared/types' {
|
||||
import type { BaseDTO } from '../../../shared/src/types/base'
|
||||
@@ -143,15 +145,30 @@ declare module 'shared/types' {
|
||||
TbWorkcaseDeviceDTO,
|
||||
// 聊天室相关
|
||||
TbChatRoomDTO,
|
||||
TbChatMessageDTO,
|
||||
TbChatRoomMessageDTO,
|
||||
TbChatRoomMemberDTO,
|
||||
TbVideoMeetingDTO,
|
||||
TbMeetingParticipantDTO,
|
||||
TbMeetingTranscriptionDTO,
|
||||
ChatRoomVO,
|
||||
ChatMessageVO,
|
||||
ChatRoomMessageVO,
|
||||
ChatMemberVO,
|
||||
VideoMeetingVO,
|
||||
MeetingParticipantVO,
|
||||
SendMessageParam,
|
||||
CreateMeetingParam,
|
||||
MarkReadParam
|
||||
MarkReadParam,
|
||||
// 客服相关
|
||||
TbCustomerServiceDTO,
|
||||
CustomerServiceVO,
|
||||
// 词云
|
||||
TbWordCloudDTO,
|
||||
// 来客相关
|
||||
TbGuestDTO,
|
||||
GuestVO,
|
||||
CustomerVO,
|
||||
ConversationVO
|
||||
} from '../../../shared/src/types/workcase'
|
||||
|
||||
// 重新导出 menu
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.2",
|
||||
"@stomp/stompjs": "^7.2.1",
|
||||
"cors": "^2.8.5",
|
||||
"element-plus": "^2.12.0",
|
||||
"express": "^4.18.2",
|
||||
"lucide-vue-next": "^0.561.0",
|
||||
"ofetch": "^1.4.1",
|
||||
"sockjs-client": "^1.6.1",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0"
|
||||
},
|
||||
|
||||
90
urbanLifelineWeb/packages/shared/pnpm-lock.yaml
generated
90
urbanLifelineWeb/packages/shared/pnpm-lock.yaml
generated
@@ -8,6 +8,9 @@ dependencies:
|
||||
'@element-plus/icons-vue':
|
||||
specifier: ^2.3.2
|
||||
version: 2.3.2(vue@3.5.25)
|
||||
'@stomp/stompjs':
|
||||
specifier: ^7.2.1
|
||||
version: 7.2.1
|
||||
cors:
|
||||
specifier: ^2.8.5
|
||||
version: 2.8.5
|
||||
@@ -17,9 +20,15 @@ dependencies:
|
||||
express:
|
||||
specifier: ^4.18.2
|
||||
version: 4.22.1
|
||||
lucide-vue-next:
|
||||
specifier: ^0.561.0
|
||||
version: 0.561.0(vue@3.5.25)
|
||||
ofetch:
|
||||
specifier: ^1.4.1
|
||||
version: 1.5.1
|
||||
sockjs-client:
|
||||
specifier: ^1.6.1
|
||||
version: 1.6.1
|
||||
vue:
|
||||
specifier: ^3.5.13
|
||||
version: 3.5.25(typescript@5.9.3)
|
||||
@@ -1000,6 +1009,10 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@stomp/stompjs@7.2.1:
|
||||
resolution: {integrity: sha512-DLd/WeicnHS5SsWWSk3x6/pcivqchNaEvg9UEGVqAcfYEBVmS9D6980ckXjTtfpXLjdLDsd96M7IuX4w7nzq5g==}
|
||||
dev: false
|
||||
|
||||
/@sxzz/popperjs-es@2.11.7:
|
||||
resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==}
|
||||
dev: false
|
||||
@@ -1464,6 +1477,17 @@ packages:
|
||||
ms: 2.0.0
|
||||
dev: false
|
||||
|
||||
/debug@3.2.7:
|
||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
dev: false
|
||||
|
||||
/debug@4.4.3:
|
||||
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -1729,6 +1753,11 @@ packages:
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/eventsource@2.0.2:
|
||||
resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
dev: false
|
||||
|
||||
/express@4.22.1:
|
||||
resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
@@ -1768,6 +1797,13 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/faye-websocket@0.11.4:
|
||||
resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dependencies:
|
||||
websocket-driver: 0.7.4
|
||||
dev: false
|
||||
|
||||
/fdir@6.5.0(picomatch@4.0.3):
|
||||
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@@ -1976,6 +2012,10 @@ packages:
|
||||
toidentifier: 1.0.1
|
||||
dev: false
|
||||
|
||||
/http-parser-js@0.5.10:
|
||||
resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==}
|
||||
dev: false
|
||||
|
||||
/iconv-lite@0.4.24:
|
||||
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -2262,6 +2302,14 @@ packages:
|
||||
yallist: 3.1.1
|
||||
dev: true
|
||||
|
||||
/lucide-vue-next@0.561.0(vue@3.5.25):
|
||||
resolution: {integrity: sha512-c5HUckO0qHklVSOf/0vaSR3pEb8fYImRDCRDLde56uqS9js0D/e3RAvq0/YFWjkmyOBKCb0/IdskdoHZQEkT5g==}
|
||||
peerDependencies:
|
||||
vue: '>=3.0.1'
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.9.3)
|
||||
dev: false
|
||||
|
||||
/magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
dependencies:
|
||||
@@ -2533,6 +2581,10 @@ packages:
|
||||
side-channel: 1.1.0
|
||||
dev: false
|
||||
|
||||
/querystringify@2.2.0:
|
||||
resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
|
||||
dev: false
|
||||
|
||||
/range-parser@1.2.1:
|
||||
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -2588,6 +2640,10 @@ packages:
|
||||
set-function-name: 2.0.2
|
||||
dev: true
|
||||
|
||||
/requires-port@1.0.0:
|
||||
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
|
||||
dev: false
|
||||
|
||||
/resolve@1.22.11:
|
||||
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -3054,6 +3110,19 @@ packages:
|
||||
side-channel-map: 1.0.1
|
||||
side-channel-weakmap: 1.0.2
|
||||
|
||||
/sockjs-client@1.6.1:
|
||||
resolution: {integrity: sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
eventsource: 2.0.2
|
||||
faye-websocket: 0.11.4
|
||||
inherits: 2.0.4
|
||||
url-parse: 1.5.10
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/source-map-js@1.2.1:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -3294,6 +3363,13 @@ packages:
|
||||
picocolors: 1.1.1
|
||||
dev: true
|
||||
|
||||
/url-parse@1.5.10:
|
||||
resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
|
||||
dependencies:
|
||||
querystringify: 2.2.0
|
||||
requires-port: 1.0.0
|
||||
dev: false
|
||||
|
||||
/utils-merge@1.0.1:
|
||||
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
||||
engines: {node: '>= 0.4.0'}
|
||||
@@ -3407,6 +3483,20 @@ packages:
|
||||
'@vue/shared': 3.5.25
|
||||
typescript: 5.9.3
|
||||
|
||||
/websocket-driver@0.7.4:
|
||||
resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dependencies:
|
||||
http-parser-js: 0.5.10
|
||||
safe-buffer: 5.2.1
|
||||
websocket-extensions: 0.1.4
|
||||
dev: false
|
||||
|
||||
/websocket-extensions@0.1.4:
|
||||
resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dev: false
|
||||
|
||||
/which-boxed-primitive@1.1.1:
|
||||
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from './workcase'
|
||||
export * from './workcaseChat'
|
||||
@@ -0,0 +1,301 @@
|
||||
import { api } from '@/api/index'
|
||||
import type { ResultDomain, PageRequest } from '@/types'
|
||||
import type { TbChat, TbChatMessage, ChatPrepareData } from '@/types/ai'
|
||||
import type { TbWorkcaseDTO } from '@/types/workcase/workcase'
|
||||
import type {
|
||||
TbChatRoomDTO,
|
||||
TbChatRoomMemberDTO,
|
||||
TbChatRoomMessageDTO,
|
||||
TbCustomerServiceDTO,
|
||||
TbWordCloudDTO,
|
||||
ChatRoomVO,
|
||||
ChatMemberVO,
|
||||
ChatRoomMessageVO,
|
||||
CustomerServiceVO
|
||||
} from '@/types/workcase/chatRoom'
|
||||
|
||||
/**
|
||||
* @description 工单对话相关接口
|
||||
* @filename workcaseChat.ts
|
||||
* @author cascade
|
||||
* @copyright xyzh
|
||||
* @since 2025-12-22
|
||||
*/
|
||||
export const workcaseChatAPI = {
|
||||
baseUrl: '/urban-lifeline/workcase/chat',
|
||||
|
||||
// ====================== AI对话管理 ======================
|
||||
|
||||
/**
|
||||
* 创建对话
|
||||
*/
|
||||
async createChat(chat: TbChat): Promise<ResultDomain<TbChat>> {
|
||||
const response = await api.post<TbChat>(`${this.baseUrl}`, chat)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新对话
|
||||
*/
|
||||
async updateChat(chat: TbChat): Promise<ResultDomain<TbChat>> {
|
||||
const response = await api.put<TbChat>(`${this.baseUrl}`, chat)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 查询对话列表
|
||||
*/
|
||||
async getChatList(filter: TbChat): Promise<ResultDomain<TbChat>> {
|
||||
const response = await api.post<TbChat>(`${this.baseUrl}/list`, filter)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取对话消息列表
|
||||
*/
|
||||
async getChatMessageList(filter: TbChat): Promise<ResultDomain<TbChatMessage>> {
|
||||
const response = await api.post<TbChatMessage>(`${this.baseUrl}/message/list`, filter)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 准备对话会话
|
||||
*/
|
||||
async prepareChatMessageSession(prepareData: ChatPrepareData): Promise<ResultDomain<string>> {
|
||||
const response = await api.post<string>(`${this.baseUrl}/prepare`, prepareData)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 流式对话(SSE)- 返回EventSource URL
|
||||
*/
|
||||
getStreamUrl(sessionId: string): string {
|
||||
return `${this.baseUrl}/stream/${sessionId}`
|
||||
},
|
||||
|
||||
/**
|
||||
* 停止对话
|
||||
*/
|
||||
async stopChat(filter: TbChat, taskId: string): Promise<ResultDomain<boolean>> {
|
||||
const response = await api.post<boolean>(`${this.baseUrl}/stop/${taskId}`, filter)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 评论对话消息
|
||||
*/
|
||||
async commentChatMessage(filter: TbChat, messageId: string, comment: string): Promise<ResultDomain<boolean>> {
|
||||
const response = await api.post<boolean>(`${this.baseUrl}/comment`, filter, {
|
||||
params: { messageId, comment }
|
||||
})
|
||||
return response.data
|
||||
},
|
||||
|
||||
// ====================== 对话分析 ======================
|
||||
|
||||
/**
|
||||
* 分析对话(AI预填工单信息)
|
||||
*/
|
||||
async analyzeChat(chatId: string): Promise<ResultDomain<TbWorkcaseDTO>> {
|
||||
const response = await api.get<TbWorkcaseDTO>(`${this.baseUrl}/analyze/${chatId}`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 总结对话
|
||||
*/
|
||||
async summaryChat(chatId: string): Promise<ResultDomain<TbWorkcaseDTO>> {
|
||||
const response = await api.post<TbWorkcaseDTO>(`${this.baseUrl}/summary/${chatId}`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
// ====================== ChatRoom聊天室管理 ======================
|
||||
|
||||
/**
|
||||
* 创建聊天室
|
||||
*/
|
||||
async createChatRoom(chatRoom: TbChatRoomDTO): Promise<ResultDomain<TbChatRoomDTO>> {
|
||||
const response = await api.post<TbChatRoomDTO>(`${this.baseUrl}/room`, chatRoom)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新聊天室
|
||||
*/
|
||||
async updateChatRoom(chatRoom: TbChatRoomDTO): Promise<ResultDomain<TbChatRoomDTO>> {
|
||||
const response = await api.put<TbChatRoomDTO>(`${this.baseUrl}/room`, chatRoom)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 关闭聊天室
|
||||
*/
|
||||
async closeChatRoom(roomId: string, closedBy: string): Promise<ResultDomain<boolean>> {
|
||||
const response = await api.post<boolean>(`${this.baseUrl}/room/${roomId}/close`, null, {
|
||||
params: { closedBy }
|
||||
})
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取聊天室详情
|
||||
*/
|
||||
async getChatRoomById(roomId: string): Promise<ResultDomain<TbChatRoomDTO>> {
|
||||
const response = await api.get<TbChatRoomDTO>(`${this.baseUrl}/room/${roomId}`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 分页查询聊天室
|
||||
*/
|
||||
async getChatRoomPage(pageRequest: PageRequest<TbChatRoomDTO>): Promise<ResultDomain<ChatRoomVO>> {
|
||||
const response = await api.post<ChatRoomVO>(`${this.baseUrl}/room/page`, pageRequest)
|
||||
return response.data
|
||||
},
|
||||
|
||||
// ====================== ChatRoom成员管理 ======================
|
||||
|
||||
/**
|
||||
* 添加聊天室成员
|
||||
*/
|
||||
async addChatRoomMember(member: TbChatRoomMemberDTO): Promise<ResultDomain<TbChatRoomMemberDTO>> {
|
||||
const response = await api.post<TbChatRoomMemberDTO>(`${this.baseUrl}/room/member`, member)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 移除聊天室成员
|
||||
*/
|
||||
async removeChatRoomMember(memberId: string): Promise<ResultDomain<boolean>> {
|
||||
const response = await api.delete<boolean>(`${this.baseUrl}/room/member/${memberId}`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取聊天室成员列表
|
||||
*/
|
||||
async getChatRoomMemberList(roomId: string): Promise<ResultDomain<ChatMemberVO>> {
|
||||
const response = await api.get<ChatMemberVO>(`${this.baseUrl}/room/${roomId}/members`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
// ====================== ChatRoom消息管理 ======================
|
||||
|
||||
/**
|
||||
* 发送聊天室消息
|
||||
*/
|
||||
async sendMessage(message: TbChatRoomMessageDTO): Promise<ResultDomain<TbChatRoomMessageDTO>> {
|
||||
const response = await api.post<TbChatRoomMessageDTO>(`${this.baseUrl}/room/message`, message)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 分页查询聊天室消息
|
||||
*/
|
||||
async getChatMessagePage(pageRequest: PageRequest<TbChatRoomMessageDTO>): Promise<ResultDomain<ChatRoomMessageVO>> {
|
||||
const response = await api.post<ChatRoomMessageVO>(`${this.baseUrl}/room/message/page`, pageRequest)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除聊天室消息
|
||||
*/
|
||||
async deleteMessage(messageId: string): Promise<ResultDomain<boolean>> {
|
||||
const response = await api.delete<boolean>(`${this.baseUrl}/room/message/${messageId}`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
// ====================== 客服人员管理 ======================
|
||||
|
||||
/**
|
||||
* 添加客服人员
|
||||
*/
|
||||
async addCustomerService(customerService: TbCustomerServiceDTO): Promise<ResultDomain<TbCustomerServiceDTO>> {
|
||||
const response = await api.post<TbCustomerServiceDTO>(`${this.baseUrl}/customer-service`, customerService)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新客服人员
|
||||
*/
|
||||
async updateCustomerService(customerService: TbCustomerServiceDTO): Promise<ResultDomain<TbCustomerServiceDTO>> {
|
||||
const response = await api.put<TbCustomerServiceDTO>(`${this.baseUrl}/customer-service`, customerService)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除客服人员
|
||||
*/
|
||||
async deleteCustomerService(userId: string): Promise<ResultDomain<boolean>> {
|
||||
const response = await api.delete<boolean>(`${this.baseUrl}/customer-service/${userId}`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 分页查询客服人员
|
||||
*/
|
||||
async getCustomerServicePage(pageRequest: PageRequest<TbCustomerServiceDTO>): Promise<ResultDomain<CustomerServiceVO>> {
|
||||
const response = await api.post<CustomerServiceVO>(`${this.baseUrl}/customer-service/page`, pageRequest)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新客服在线状态
|
||||
*/
|
||||
async updateCustomerServiceStatus(userId: string, status: string): Promise<ResultDomain<boolean>> {
|
||||
const response = await api.post<boolean>(`${this.baseUrl}/customer-service/${userId}/status`, null, {
|
||||
params: { status }
|
||||
})
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取可接待客服列表
|
||||
*/
|
||||
async getAvailableCustomerServices(): Promise<ResultDomain<CustomerServiceVO>> {
|
||||
const response = await api.get<CustomerServiceVO>(`${this.baseUrl}/customer-service/available`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 自动分配客服
|
||||
*/
|
||||
async assignCustomerService(roomId: string): Promise<ResultDomain<CustomerServiceVO>> {
|
||||
const response = await api.post<CustomerServiceVO>(`${this.baseUrl}/room/${roomId}/assign`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
// ====================== 词云管理 ======================
|
||||
|
||||
/**
|
||||
* 添加词云
|
||||
*/
|
||||
async addWordCloud(wordCloud: TbWordCloudDTO): Promise<ResultDomain<TbWordCloudDTO>> {
|
||||
const response = await api.post<TbWordCloudDTO>(`${this.baseUrl}/wordcloud`, wordCloud)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新词云
|
||||
*/
|
||||
async updateWordCloud(wordCloud: TbWordCloudDTO): Promise<ResultDomain<TbWordCloudDTO>> {
|
||||
const response = await api.put<TbWordCloudDTO>(`${this.baseUrl}/wordcloud`, wordCloud)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 查询词云列表
|
||||
*/
|
||||
async getWordCloudList(filter: TbWordCloudDTO): Promise<ResultDomain<TbWordCloudDTO>> {
|
||||
const response = await api.post<TbWordCloudDTO>(`${this.baseUrl}/wordcloud/list`, filter)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* 分页查询词云
|
||||
*/
|
||||
async getWordCloudPage(pageRequest: PageRequest<TbWordCloudDTO>): Promise<ResultDomain<TbWordCloudDTO>> {
|
||||
const response = await api.post<TbWordCloudDTO>(`${this.baseUrl}/wordcloud/page`, pageRequest)
|
||||
return response.data
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick } from 'vue'
|
||||
import { FileText, Video, Paperclip, Send } from 'lucide-vue-next'
|
||||
import IframeView from 'shared/components/iframe/IframeView.vue'
|
||||
import IframeView from '@/components/iframe/IframeView.vue'
|
||||
|
||||
interface ChatMessageVO {
|
||||
messageId: string
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { default as ChatRoom } from './ChatRoom.vue';
|
||||
export { default as ChatRoom } from './chatRoom/ChatRoom.vue';
|
||||
@@ -28,7 +28,7 @@ export interface TbChatRoomDTO extends BaseDTO {
|
||||
/**
|
||||
* 聊天消息DTO
|
||||
*/
|
||||
export interface TbChatMessageDTO extends BaseDTO {
|
||||
export interface TbChatRoomMessageDTO extends BaseDTO {
|
||||
messageId?: string
|
||||
roomId?: string
|
||||
senderId?: string
|
||||
@@ -174,7 +174,7 @@ export interface ChatRoomVO extends BaseVO {
|
||||
* 聊天消息VO
|
||||
* 用于前端展示聊天消息
|
||||
*/
|
||||
export interface ChatMessageVO extends BaseVO {
|
||||
export interface ChatRoomMessageVO extends BaseVO {
|
||||
messageId?: string
|
||||
roomId?: string
|
||||
senderId?: string
|
||||
@@ -292,3 +292,60 @@ export interface MarkReadParam {
|
||||
roomId: string
|
||||
messageIds?: string[]
|
||||
}
|
||||
|
||||
// ==================== 客服相关 ====================
|
||||
|
||||
/**
|
||||
* 客服人员DTO
|
||||
*/
|
||||
export interface TbCustomerServiceDTO extends BaseDTO {
|
||||
userId?: string
|
||||
userName?: string
|
||||
status?: string
|
||||
maxConcurrentChats?: number
|
||||
currentChatCount?: number
|
||||
totalServedCount?: number
|
||||
avgResponseTime?: number
|
||||
avgRating?: number
|
||||
skills?: string[]
|
||||
priority?: number
|
||||
lastOnlineTime?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 客服人员VO
|
||||
*/
|
||||
export interface CustomerServiceVO extends BaseVO {
|
||||
userId?: string
|
||||
userName?: string
|
||||
userAvatar?: string
|
||||
status?: string
|
||||
statusName?: string
|
||||
maxConcurrentChats?: number
|
||||
currentChatCount?: number
|
||||
totalServedCount?: number
|
||||
avgResponseTime?: number
|
||||
avgResponseTimeFormatted?: string
|
||||
avgRating?: number
|
||||
skills?: string[]
|
||||
skillNames?: string[]
|
||||
priority?: number
|
||||
lastOnlineTime?: string
|
||||
isAvailable?: boolean
|
||||
}
|
||||
|
||||
// ==================== 词云相关 ====================
|
||||
|
||||
/**
|
||||
* 词云DTO
|
||||
*/
|
||||
export interface TbWordCloudDTO extends BaseDTO {
|
||||
wordCloudId?: string
|
||||
word?: string
|
||||
category?: string
|
||||
weight?: number
|
||||
frequency?: number
|
||||
sentiment?: string
|
||||
source?: string
|
||||
relatedWords?: string[]
|
||||
}
|
||||
|
||||
@@ -10,17 +10,20 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.2",
|
||||
"@stomp/stompjs": "^7.2.1",
|
||||
"@vueuse/core": "^11.3.0",
|
||||
"axios": "^1.7.9",
|
||||
"element-plus": "^2.8.6",
|
||||
"lucide-vue-next": "^0.561.0",
|
||||
"pinia": "^2.2.8",
|
||||
"sockjs-client": "^1.6.1",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@module-federation/vite": "^1.9.3",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/sockjs-client": "^1.5.4",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vitejs/plugin-vue-jsx": "^4.1.1",
|
||||
"typescript": "^5.7.2",
|
||||
|
||||
106
urbanLifelineWeb/packages/workcase/pnpm-lock.yaml
generated
106
urbanLifelineWeb/packages/workcase/pnpm-lock.yaml
generated
@@ -8,6 +8,9 @@ dependencies:
|
||||
'@element-plus/icons-vue':
|
||||
specifier: ^2.3.2
|
||||
version: 2.3.2(vue@3.5.25)
|
||||
'@stomp/stompjs':
|
||||
specifier: ^7.2.1
|
||||
version: 7.2.1
|
||||
'@vueuse/core':
|
||||
specifier: ^11.3.0
|
||||
version: 11.3.0(vue@3.5.25)
|
||||
@@ -17,9 +20,15 @@ dependencies:
|
||||
element-plus:
|
||||
specifier: ^2.8.6
|
||||
version: 2.12.0(vue@3.5.25)
|
||||
lucide-vue-next:
|
||||
specifier: ^0.561.0
|
||||
version: 0.561.0(vue@3.5.25)
|
||||
pinia:
|
||||
specifier: ^2.2.8
|
||||
version: 2.3.1(typescript@5.9.3)(vue@3.5.25)
|
||||
sockjs-client:
|
||||
specifier: ^1.6.1
|
||||
version: 1.6.1
|
||||
vue:
|
||||
specifier: ^3.5.13
|
||||
version: 3.5.25(typescript@5.9.3)
|
||||
@@ -34,6 +43,9 @@ devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^22.0.0
|
||||
version: 22.19.1
|
||||
'@types/sockjs-client':
|
||||
specifier: ^1.5.4
|
||||
version: 1.5.4
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^5.2.1
|
||||
version: 5.2.4(vite@6.4.1)(vue@3.5.25)
|
||||
@@ -841,6 +853,10 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@stomp/stompjs@7.2.1:
|
||||
resolution: {integrity: sha512-DLd/WeicnHS5SsWWSk3x6/pcivqchNaEvg9UEGVqAcfYEBVmS9D6980ckXjTtfpXLjdLDsd96M7IuX4w7nzq5g==}
|
||||
dev: false
|
||||
|
||||
/@sxzz/popperjs-es@2.11.7:
|
||||
resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==}
|
||||
dev: false
|
||||
@@ -865,6 +881,10 @@ packages:
|
||||
undici-types: 6.21.0
|
||||
dev: true
|
||||
|
||||
/@types/sockjs-client@1.5.4:
|
||||
resolution: {integrity: sha512-zk+uFZeWyvJ5ZFkLIwoGA/DfJ+pYzcZ8eH4H/EILCm2OBZyHH6Hkdna1/UWL/CFruh5wj6ES7g75SvUB0VsH5w==}
|
||||
dev: true
|
||||
|
||||
/@types/web-bluetooth@0.0.16:
|
||||
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
|
||||
dev: false
|
||||
@@ -1188,6 +1208,17 @@ packages:
|
||||
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
|
||||
dev: true
|
||||
|
||||
/debug@3.2.7:
|
||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
dev: false
|
||||
|
||||
/debug@4.4.3:
|
||||
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -1319,6 +1350,18 @@ packages:
|
||||
/estree-walker@2.0.2:
|
||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||
|
||||
/eventsource@2.0.2:
|
||||
resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
dev: false
|
||||
|
||||
/faye-websocket@0.11.4:
|
||||
resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dependencies:
|
||||
websocket-driver: 0.7.4
|
||||
dev: false
|
||||
|
||||
/fdir@6.5.0(picomatch@4.0.3):
|
||||
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@@ -1422,6 +1465,14 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/http-parser-js@0.5.10:
|
||||
resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==}
|
||||
dev: false
|
||||
|
||||
/inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
dev: false
|
||||
|
||||
/js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
dev: true
|
||||
@@ -1464,6 +1515,14 @@ packages:
|
||||
yallist: 3.1.1
|
||||
dev: true
|
||||
|
||||
/lucide-vue-next@0.561.0(vue@3.5.25):
|
||||
resolution: {integrity: sha512-c5HUckO0qHklVSOf/0vaSR3pEb8fYImRDCRDLde56uqS9js0D/e3RAvq0/YFWjkmyOBKCb0/IdskdoHZQEkT5g==}
|
||||
peerDependencies:
|
||||
vue: '>=3.0.1'
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.9.3)
|
||||
dev: false
|
||||
|
||||
/magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
dependencies:
|
||||
@@ -1499,7 +1558,6 @@ packages:
|
||||
|
||||
/ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
dev: true
|
||||
|
||||
/muggle-string@0.4.1:
|
||||
resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
|
||||
@@ -1563,6 +1621,14 @@ packages:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
dev: false
|
||||
|
||||
/querystringify@2.2.0:
|
||||
resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
|
||||
dev: false
|
||||
|
||||
/requires-port@1.0.0:
|
||||
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
|
||||
dev: false
|
||||
|
||||
/rollup@4.53.3:
|
||||
resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
@@ -1595,11 +1661,28 @@ packages:
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
dev: false
|
||||
|
||||
/semver@6.3.1:
|
||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/sockjs-client@1.6.1:
|
||||
resolution: {integrity: sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
eventsource: 2.0.2
|
||||
faye-websocket: 0.11.4
|
||||
inherits: 2.0.4
|
||||
url-parse: 1.5.10
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/source-map-js@1.2.1:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -1632,6 +1715,13 @@ packages:
|
||||
picocolors: 1.1.1
|
||||
dev: true
|
||||
|
||||
/url-parse@1.5.10:
|
||||
resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
|
||||
dependencies:
|
||||
querystringify: 2.2.0
|
||||
requires-port: 1.0.0
|
||||
dev: false
|
||||
|
||||
/vite@6.4.1(@types/node@22.19.1):
|
||||
resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==}
|
||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||
@@ -1737,6 +1827,20 @@ packages:
|
||||
'@vue/shared': 3.5.25
|
||||
typescript: 5.9.3
|
||||
|
||||
/websocket-driver@0.7.4:
|
||||
resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dependencies:
|
||||
http-parser-js: 0.5.10
|
||||
safe-buffer: 5.2.1
|
||||
websocket-extensions: 0.1.4
|
||||
dev: false
|
||||
|
||||
/websocket-extensions@0.1.4:
|
||||
resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dev: false
|
||||
|
||||
/yallist@3.1.1:
|
||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||
dev: true
|
||||
|
||||
@@ -98,8 +98,10 @@ declare module 'shared/api/ai' {
|
||||
|
||||
declare module 'shared/api/workcase' {
|
||||
export const workcaseAPI: any
|
||||
export const workcaseChatAPI: any
|
||||
}
|
||||
|
||||
|
||||
// ============ types模块 ==================
|
||||
declare module 'shared/types' {
|
||||
import type { BaseDTO } from '../../../shared/src/types/base'
|
||||
@@ -143,21 +145,30 @@ declare module 'shared/types' {
|
||||
TbWorkcaseDeviceDTO,
|
||||
// 聊天室相关
|
||||
TbChatRoomDTO,
|
||||
TbChatMessageDTO,
|
||||
TbChatRoomMessageDTO,
|
||||
TbChatRoomMemberDTO,
|
||||
TbVideoMeetingDTO,
|
||||
TbMeetingParticipantDTO,
|
||||
TbMeetingTranscriptionDTO,
|
||||
ChatRoomVO,
|
||||
ChatMessageVO,
|
||||
ChatRoomMessageVO,
|
||||
ChatMemberVO,
|
||||
VideoMeetingVO,
|
||||
MeetingParticipantVO,
|
||||
SendMessageParam,
|
||||
CreateMeetingParam,
|
||||
MarkReadParam,
|
||||
// 客服相关
|
||||
TbCustomerServiceDTO,
|
||||
CustomerServiceVO,
|
||||
// 词云
|
||||
TbWordCloudDTO,
|
||||
// 来客相关
|
||||
TbGuestDTO,
|
||||
GuestVO
|
||||
GuestVO,
|
||||
CustomerVO,
|
||||
ConversationVO
|
||||
} from '../../../shared/src/types/workcase'
|
||||
|
||||
// 重新导出 menu
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
>
|
||||
<!-- 头像 -->
|
||||
<div class="room-avatar">
|
||||
{{ room.guestName.substring(0, 1) }}
|
||||
{{ room.guestName?.substring(0, 1) || '?' }}
|
||||
</div>
|
||||
|
||||
<!-- 信息 -->
|
||||
@@ -114,67 +114,50 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { ElButton, ElInput, ElDialog } from 'element-plus'
|
||||
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
||||
import { ElButton, ElInput, ElDialog, ElMessage } from 'element-plus'
|
||||
import { Search, FileText, MessageSquare } from 'lucide-vue-next'
|
||||
import ChatRoom from 'shared/components/chatRoom/ChatRoom.vue'
|
||||
import WorkcaseDetail from '@/views/public/workcase/WorkcaseDetail/WorkcaseDetail.vue'
|
||||
import { workcaseChatAPI } from 'shared/api/workcase'
|
||||
import { fileAPI } from 'shared/api/file'
|
||||
import { FILE_DOWNLOAD_URL } from '@/config'
|
||||
import type { ChatRoomVO, ChatRoomMessageVO, TbChatRoomMessageDTO } from 'shared/types'
|
||||
import SockJS from 'sockjs-client'
|
||||
import { Client } from '@stomp/stompjs'
|
||||
|
||||
interface ChatRoomVO {
|
||||
roomId: string
|
||||
workcaseId: string
|
||||
roomName: string
|
||||
guestName: string
|
||||
lastMessage: string | null
|
||||
lastMessageTime: string | null
|
||||
unreadCount: number
|
||||
// WebSocket配置 (通过网关代理访问workcase服务)
|
||||
// 原生WebSocket URL (ws://或wss://)
|
||||
const getWsUrl = () => {
|
||||
const token = localStorage.getItem('token') || ''
|
||||
// 直接连接网关,跳过Nginx调试
|
||||
return `ws://localhost:8180/urban-lifeline/workcase/ws/chat?token=${encodeURIComponent(token)}`
|
||||
}
|
||||
|
||||
interface ChatMessageVO {
|
||||
messageId: string
|
||||
senderId: string
|
||||
senderName: string
|
||||
senderAvatar: string
|
||||
content: string
|
||||
files: string[]
|
||||
sendTime: string
|
||||
}
|
||||
// STOMP客户端
|
||||
let stompClient: any = null
|
||||
let roomSubscription: any = null
|
||||
let listSubscription: any = null
|
||||
|
||||
// 当前用户ID
|
||||
const userId = ref('CURRENT_USER_ID')
|
||||
// 当前用户ID(从登录状态获取)
|
||||
const userId = ref(localStorage.getItem('userId') || '')
|
||||
|
||||
// 搜索文本
|
||||
const searchText = ref('')
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(false)
|
||||
const messageLoading = ref(false)
|
||||
|
||||
// 聊天室列表
|
||||
const chatRooms = ref<ChatRoomVO[]>([
|
||||
{
|
||||
roomId: 'ROOM001',
|
||||
workcaseId: 'WC001',
|
||||
roomName: '工单#WC001 - 电源故障',
|
||||
guestName: '张三',
|
||||
lastMessage: '好的,谢谢您的帮助',
|
||||
lastMessageTime: new Date().toISOString(),
|
||||
unreadCount: 3
|
||||
},
|
||||
{
|
||||
roomId: 'ROOM002',
|
||||
workcaseId: 'WC002',
|
||||
roomName: '工单#WC002 - 设备维修',
|
||||
guestName: '李四',
|
||||
lastMessage: '请问什么时候能来处理?',
|
||||
lastMessageTime: new Date(Date.now() - 3600000).toISOString(),
|
||||
unreadCount: 0
|
||||
}
|
||||
])
|
||||
const chatRooms = ref<ChatRoomVO[]>([])
|
||||
|
||||
// 当前选中的聊天室ID
|
||||
const currentRoomId = ref<string | null>(null)
|
||||
|
||||
// 当前聊天室
|
||||
const currentRoom = computed(() =>
|
||||
chatRooms.value.find(r => r.roomId === currentRoomId.value)
|
||||
chatRooms.value.find((r: ChatRoomVO) => r.roomId === currentRoomId.value)
|
||||
)
|
||||
|
||||
// 当前工单ID
|
||||
@@ -184,15 +167,15 @@ const currentWorkcaseId = computed(() => currentRoom.value?.workcaseId || '')
|
||||
const filteredRooms = computed(() => {
|
||||
if (!searchText.value) return chatRooms.value
|
||||
const keyword = searchText.value.toLowerCase()
|
||||
return chatRooms.value.filter(room =>
|
||||
room.roomName.toLowerCase().includes(keyword) ||
|
||||
room.guestName.toLowerCase().includes(keyword) ||
|
||||
room.workcaseId.toLowerCase().includes(keyword)
|
||||
return chatRooms.value.filter((room: ChatRoomVO) =>
|
||||
room.roomName?.toLowerCase().includes(keyword) ||
|
||||
room.guestName?.toLowerCase().includes(keyword) ||
|
||||
room.workcaseId?.toLowerCase().includes(keyword)
|
||||
)
|
||||
})
|
||||
|
||||
// 消息列表
|
||||
const messages = ref<ChatMessageVO[]>([])
|
||||
const messages = ref<ChatRoomMessageVO[]>([])
|
||||
|
||||
// 工单详情对话框
|
||||
const showWorkcaseDetail = ref(false)
|
||||
@@ -201,66 +184,93 @@ const showWorkcaseDetail = ref(false)
|
||||
const currentMeetingUrl = ref('')
|
||||
const showMeetingIframe = ref(false)
|
||||
|
||||
// 获取聊天室列表
|
||||
const fetchChatRooms = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const result = await workcaseChatAPI.getChatRoomPage({
|
||||
filter: { status: 'active' },
|
||||
pageParam: { page: 1, pageSize: 100, total: 0 }
|
||||
})
|
||||
if (result.success && result.pageDomain) {
|
||||
chatRooms.value = result.pageDomain.dataList || []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取聊天室列表失败:', error)
|
||||
ElMessage.error('获取聊天室列表失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 选择聊天室
|
||||
const selectRoom = (roomId: string) => {
|
||||
currentRoomId.value = roomId
|
||||
// TODO: 加载该聊天室的消息
|
||||
loadMessages(roomId)
|
||||
}
|
||||
|
||||
// 加载消息
|
||||
const loadMessages = async (roomId: string) => {
|
||||
// TODO: 调用API加载消息
|
||||
messages.value = [
|
||||
{
|
||||
messageId: 'MSG001',
|
||||
senderId: 'OTHER_USER',
|
||||
senderName: '张三',
|
||||
senderAvatar: 'avatar.jpg',
|
||||
content: '你好,我的设备出现故障了',
|
||||
files: [],
|
||||
sendTime: new Date().toISOString()
|
||||
},
|
||||
{
|
||||
messageId: 'MSG002',
|
||||
senderId: userId.value,
|
||||
senderName: '客服',
|
||||
senderAvatar: 'avatar.jpg',
|
||||
content: '您好,请问是什么故障?',
|
||||
files: [],
|
||||
sendTime: new Date().toISOString()
|
||||
messageLoading.value = true
|
||||
try {
|
||||
const result = await workcaseChatAPI.getChatMessagePage({
|
||||
filter: { roomId },
|
||||
pageParam: { page: 1, pageSize: 100, total: 0 }
|
||||
})
|
||||
if (result.success && result.pageDomain) {
|
||||
messages.value = result.pageDomain.dataList || []
|
||||
}
|
||||
]
|
||||
scrollToBottom()
|
||||
scrollToBottom()
|
||||
} catch (error) {
|
||||
console.error('加载消息失败:', error)
|
||||
ElMessage.error('加载消息失败')
|
||||
} finally {
|
||||
messageLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 处理发送消息(从ChatRoom组件触发)
|
||||
const handleSendMessage = async (content: string, files: File[]) => {
|
||||
if (!currentRoomId.value) return
|
||||
|
||||
// TODO: 上传文件获取fileIds
|
||||
const fileIds: string[] = []
|
||||
|
||||
const newMessage: ChatMessageVO = {
|
||||
messageId: 'MSG' + Date.now(),
|
||||
senderId: userId.value,
|
||||
senderName: '客服',
|
||||
senderAvatar: 'avatar.jpg',
|
||||
content,
|
||||
files: fileIds,
|
||||
sendTime: new Date().toISOString()
|
||||
try {
|
||||
// 上传文件获取fileIds
|
||||
let fileIds: string[] = []
|
||||
if (files.length > 0) {
|
||||
const uploadResult = await fileAPI.batchUpload(files, 'chatroom')
|
||||
if (uploadResult.success && uploadResult.dataList) {
|
||||
fileIds = uploadResult.dataList.map((f: any) => f.fileId)
|
||||
}
|
||||
}
|
||||
|
||||
// 构造消息
|
||||
const messageData: TbChatRoomMessageDTO = {
|
||||
roomId: currentRoomId.value,
|
||||
senderId: userId.value,
|
||||
senderType: 'agent',
|
||||
content,
|
||||
files: fileIds,
|
||||
messageType: 'text'
|
||||
}
|
||||
|
||||
// 发送消息
|
||||
const result = await workcaseChatAPI.sendMessage(messageData)
|
||||
if (result.success && result.data) {
|
||||
// 添加到消息列表
|
||||
messages.value.push(result.data as ChatRoomMessageVO)
|
||||
scrollToBottom()
|
||||
} else {
|
||||
ElMessage.error(result.message || '发送失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('发送消息失败:', error)
|
||||
ElMessage.error('发送消息失败')
|
||||
}
|
||||
|
||||
messages.value.push(newMessage)
|
||||
|
||||
// TODO: 通过WebSocket发送到服务器
|
||||
console.log('发送消息:', { content, files })
|
||||
}
|
||||
|
||||
// 下载文件
|
||||
const downloadFile = (fileId: string) => {
|
||||
// TODO: 下载文件
|
||||
console.log('下载文件:', fileId)
|
||||
window.open(`${FILE_DOWNLOAD_URL}/${fileId}`, '_blank')
|
||||
}
|
||||
|
||||
// 发起会议
|
||||
@@ -268,14 +278,9 @@ const startMeeting = async () => {
|
||||
if (!currentRoomId.value) return
|
||||
|
||||
// TODO: 调用后端API创建Jitsi会议
|
||||
// const meeting = await createMeeting(currentRoomId.value)
|
||||
|
||||
// 模拟会议URL
|
||||
const meetingId = 'meeting-' + Date.now()
|
||||
const meetingId = 'meeting-' + currentRoomId.value + '-' + Date.now()
|
||||
currentMeetingUrl.value = `https://meet.jit.si/${meetingId}`
|
||||
showMeetingIframe.value = true
|
||||
|
||||
console.log('发起会议:', currentMeetingUrl.value)
|
||||
}
|
||||
|
||||
// 滚动到底部
|
||||
@@ -284,7 +289,7 @@ const scrollToBottom = () => {
|
||||
}
|
||||
|
||||
// 格式化时间(用于聊天室列表)
|
||||
const formatTime = (time: string | null) => {
|
||||
const formatTime = (time: string | null | undefined) => {
|
||||
if (!time) return ''
|
||||
const date = new Date(time)
|
||||
const now = new Date()
|
||||
@@ -296,6 +301,122 @@ const formatTime = (time: string | null) => {
|
||||
|
||||
return date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' })
|
||||
}
|
||||
|
||||
// ==================== WebSocket连接管理 ====================
|
||||
|
||||
// 初始化WebSocket连接(使用原生WebSocket,不降级)
|
||||
const initWebSocket = () => {
|
||||
const token = localStorage.getItem('token') || ''
|
||||
const wsUrl = getWsUrl()
|
||||
|
||||
console.log('WebSocket连接URL:', wsUrl)
|
||||
|
||||
// 创建STOMP客户端,使用原生WebSocket
|
||||
stompClient = new Client({
|
||||
brokerURL: wsUrl, // 使用原生WebSocket URL
|
||||
connectHeaders: {
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
reconnectDelay: 5000,
|
||||
heartbeatIncoming: 4000,
|
||||
heartbeatOutgoing: 4000,
|
||||
debug: (str: string) => {
|
||||
console.log('[STOMP]', str)
|
||||
},
|
||||
onConnect: () => {
|
||||
console.log('WebSocket已连接')
|
||||
// 订阅聊天室列表更新
|
||||
subscribeToListUpdate()
|
||||
// 如果当前有选中的聊天室,订阅该聊天室消息
|
||||
if (currentRoomId.value) {
|
||||
subscribeToRoom(currentRoomId.value)
|
||||
}
|
||||
},
|
||||
onDisconnect: () => {
|
||||
console.log('WebSocket已断开')
|
||||
},
|
||||
onStompError: (frame: any) => {
|
||||
console.error('STOMP错误:', frame)
|
||||
},
|
||||
onWebSocketError: (event: any) => {
|
||||
console.error('WebSocket错误:', event)
|
||||
}
|
||||
})
|
||||
|
||||
stompClient.activate()
|
||||
}
|
||||
|
||||
// 订阅聊天室列表更新 (用于更新列表中的lastMessage)
|
||||
const subscribeToListUpdate = () => {
|
||||
if (!stompClient || !stompClient.connected) return
|
||||
|
||||
listSubscription = stompClient.subscribe('/topic/chat/list-update', (message: any) => {
|
||||
const chatMessage = JSON.parse(message.body)
|
||||
// 更新对应聊天室的lastMessage和lastMessageTime
|
||||
const roomIndex = chatRooms.value.findIndex((r: ChatRoomVO) => r.roomId === chatMessage.roomId)
|
||||
if (roomIndex !== -1) {
|
||||
chatRooms.value[roomIndex] = {
|
||||
...chatRooms.value[roomIndex],
|
||||
lastMessage: chatMessage.content,
|
||||
lastMessageTime: chatMessage.sendTime
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 订阅指定聊天室消息 (用于实时接收消息)
|
||||
const subscribeToRoom = (roomId: string) => {
|
||||
if (!stompClient || !stompClient.connected) return
|
||||
|
||||
// 先取消之前的订阅
|
||||
if (roomSubscription) {
|
||||
roomSubscription.unsubscribe()
|
||||
roomSubscription = null
|
||||
}
|
||||
|
||||
roomSubscription = stompClient.subscribe(`/topic/chat/${roomId}`, (message: any) => {
|
||||
const chatMessage = JSON.parse(message.body) as ChatRoomMessageVO
|
||||
// 避免重复添加自己发送的消息
|
||||
if (chatMessage.senderId !== userId.value) {
|
||||
messages.value.push(chatMessage)
|
||||
scrollToBottom()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 断开WebSocket连接
|
||||
const disconnectWebSocket = () => {
|
||||
if (roomSubscription) {
|
||||
roomSubscription.unsubscribe()
|
||||
roomSubscription = null
|
||||
}
|
||||
if (listSubscription) {
|
||||
listSubscription.unsubscribe()
|
||||
listSubscription = null
|
||||
}
|
||||
if (stompClient) {
|
||||
stompClient.deactivate()
|
||||
stompClient = null
|
||||
}
|
||||
}
|
||||
|
||||
// 监听currentRoomId变化,切换聊天室时重新订阅
|
||||
watch(currentRoomId, (newRoomId) => {
|
||||
if (newRoomId && stompClient?.connected) {
|
||||
subscribeToRoom(newRoomId)
|
||||
}
|
||||
})
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
fetchChatRooms()
|
||||
initWebSocket()
|
||||
})
|
||||
|
||||
// 组件卸载时断开连接
|
||||
onUnmounted(() => {
|
||||
disconnectWebSocket()
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import url("./ChatRoomView.scss");
|
||||
|
||||
@@ -41,7 +41,8 @@ export default defineConfig(({ mode }) => ({
|
||||
define: {
|
||||
__VUE_OPTIONS_API__: true,
|
||||
__VUE_PROD_DEVTOOLS__: true,
|
||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true
|
||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true,
|
||||
global: 'globalThis'
|
||||
},
|
||||
|
||||
resolve: {
|
||||
@@ -64,6 +65,7 @@ export default defineConfig(({ mode }) => ({
|
||||
'/api': {
|
||||
target: 'http://localhost:8180',
|
||||
changeOrigin: true,
|
||||
ws: true, // 启用 WebSocket 代理
|
||||
rewrite: (path: string) => path.replace(/^\/api/, '')
|
||||
},
|
||||
// 代理共享模块请求到 shared 服务
|
||||
|
||||
6
urbanLifelineWeb/packages/workcase_wechat/package.json
Normal file
6
urbanLifelineWeb/packages/workcase_wechat/package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"sockjs-client": "^1.6.1",
|
||||
"@stomp/stompjs": "^7.2.1"
|
||||
}
|
||||
}
|
||||
100
urbanLifelineWeb/packages/workcase_wechat/pnpm-lock.yaml
generated
Normal file
100
urbanLifelineWeb/packages/workcase_wechat/pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,100 @@
|
||||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@stomp/stompjs':
|
||||
specifier: ^7.2.1
|
||||
version: 7.2.1
|
||||
sockjs-client:
|
||||
specifier: ^1.6.1
|
||||
version: 1.6.1
|
||||
|
||||
packages:
|
||||
|
||||
/@stomp/stompjs@7.2.1:
|
||||
resolution: {integrity: sha512-DLd/WeicnHS5SsWWSk3x6/pcivqchNaEvg9UEGVqAcfYEBVmS9D6980ckXjTtfpXLjdLDsd96M7IuX4w7nzq5g==}
|
||||
dev: false
|
||||
|
||||
/debug@3.2.7:
|
||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
dev: false
|
||||
|
||||
/eventsource@2.0.2:
|
||||
resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
dev: false
|
||||
|
||||
/faye-websocket@0.11.4:
|
||||
resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dependencies:
|
||||
websocket-driver: 0.7.4
|
||||
dev: false
|
||||
|
||||
/http-parser-js@0.5.10:
|
||||
resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==}
|
||||
dev: false
|
||||
|
||||
/inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
dev: false
|
||||
|
||||
/ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
dev: false
|
||||
|
||||
/querystringify@2.2.0:
|
||||
resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
|
||||
dev: false
|
||||
|
||||
/requires-port@1.0.0:
|
||||
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
|
||||
dev: false
|
||||
|
||||
/safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
dev: false
|
||||
|
||||
/sockjs-client@1.6.1:
|
||||
resolution: {integrity: sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
eventsource: 2.0.2
|
||||
faye-websocket: 0.11.4
|
||||
inherits: 2.0.4
|
||||
url-parse: 1.5.10
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/url-parse@1.5.10:
|
||||
resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
|
||||
dependencies:
|
||||
querystringify: 2.2.0
|
||||
requires-port: 1.0.0
|
||||
dev: false
|
||||
|
||||
/websocket-driver@0.7.4:
|
||||
resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dependencies:
|
||||
http-parser-js: 0.5.10
|
||||
safe-buffer: 5.2.1
|
||||
websocket-extensions: 0.1.4
|
||||
dev: false
|
||||
|
||||
/websocket-extensions@0.1.4:
|
||||
resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dev: false
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user