first commit

This commit is contained in:
2026-06-02 10:42:33 +08:00
commit dd4975fd2c
1084 changed files with 442416 additions and 0 deletions

255
stores/friend-socket.js Normal file
View File

@@ -0,0 +1,255 @@
import {
defineStore
} from "pinia";
import {
computed,
ref
} from "vue";
import {
friendSocketManager
} from '@/utils/friend-socket.js'
import {
getToken,
getUserId
} from "../utils/user-info";
export const useFriendSocketStore = defineStore('friendSocket', () => {
// ==================== 状态定义 ====================
const connectionStatus = ref('disconnected') //connecting | connected | disconnected | error
const messages = ref([])
const messageString = ref('')
const config = ref({
token: '',
UserId: ''
})
const taskCallId = ref('')
const command = ref(null)
const groupId = ref(null)
// 收到消息
const MessageReceived = ref(false)
// 日志数组和最大值
const logs = ref([])
const maxLogCount = ref(20)
// ==================== 计算属性 ====================
const isConnected = computed(() => connectionStatus.value === 'connected')
const isConnecting = computed(() => connectionStatus.value === 'connecting')
const isDisconnected = computed(() => connectionStatus.value === 'disconnected')
const isError = computed(() => connectionStatus.value === 'error')
const lastMessage = computed(() => messages.value[messages.value.length - 1])
// 日志方法
function addLog(type, connect) {
const now = new Date()
const time =
`${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}:${now.getSeconds().toString().padStart(2,'0')}`
logs.value.push({
type,
connect,
time
})
if (logs.value.length > maxLogCount.value) {
logs.value = logs.value.slice(-maxLogCount.value)
}
console.log(`[${type.toUpperCase()}] ${connect}`);
}
function clearLogs() {
logs.value = []
}
// ==================== 连接相关方法 ====================
function connect(options = {}) {
messages.value = []
messageString.value = ''
config.value = {
...config.value,
...options
}
addLog('info',
`准备连接FriendsWebSocket。Token:${config.value.token || '未设置'}。UserId: ${config.value.UserId || '未设置'}`
)
if (!config.value.token || !config.value.UserId) {
addLog('error', 'Token和UserId都不能为空')
return
}
connectionStatus.value = 'connecting'
friendSocketManager.connect({
token: config.value.token,
UserId: config.value.UserId,
onMessage: handleMessage,
onError: handleError,
onOpen: handleOpen,
onClose: handleClose,
onReconnect: handleReconnecting
})
setConnectionTimeout()
}
function disconnect() {
friendSocketManager.close()
connectionStatus.value = 'disconnected'
addLog('warn', '已主动断开连接')
}
async function send(message) {
if (!isConnected.value) {
addLog('error', '发送失败: 连接未建立')
throw new Error('连接未建立')
}
try {
await friendSocketManager.send(message)
addLog('send', typeof message === 'string' ? message : JSON.stringify(message))
return true
} catch (error) {
addLog('error', `发送失败: ${error.message || error}`)
throw error
}
}
// =====================连接成功发送验证标识指令为7===============
async function sendAuthData() {
const userId = getUserId()
const authData = {
"version": "1.1",
"body": {
"command": 7,
"sender": userId,
"avatar": "",
"sessionId": "",
"message": "",
"callBackMessage": false,
}
}
try {
await friendSocketManager.send(authData)
addLog('send', typeof authData === 'string' ? authData : JSON.stringify(authData))
return true
} catch (error) {
addLog('error', `发送验证失败: ${error.message || error}`)
throw error
}
}
// ==================== 事件回调 ====================
function handleOpen() {
connectionStatus.value = 'connected'
addLog('success', '连接成功!')
sendAuthData()
}
function handleClose() {
if (connectionStatus.value !== 'disconnected') {
// disconnect()
connectionStatus.value = 'disconnected'
addLog('warn', '连接已断开')
}
}
function handleError(error) {
addLog('error', `Socket错误: ${JSON.stringify(error)}`)
connectionStatus.value = 'error'
}
function handleReconnecting(attempts) {
connectionStatus.value = 'connecting'
addLog('warn', `重连中... (${attempts}/5)`)
}
function setConnectionTimeout() {
const timer = setTimeout(() => {
if (connectionStatus.value === 'connecting') {
connectionStatus.value = 'error'
addLog('error', '连接超时(10s)')
}
}, 10000)
// 返回 timer 以便必要时清除,但目前用不到
return timer
}
function handleMessage(messageData) {
addLog('receive', `收到: ${JSON.stringify(messageData)}`)
const msgBody = messageData.body || messageData;
// command 和 groupId和响应式变量重名冲突直接解构时重命名
const {
callBackMessage,
groupName,
command: msgCommand,
groupId: msgGroupId
} = msgBody || {}
switch (msgCommand) {
case 3:
command.value = msgCommand
groupId.value = msgGroupId
break
case 7:
command.value = msgCommand
break
case 1:
console.log("有好友消息");
MessageReceived.value = true
break
case 9:
console.log("群消息发送成功/有新群消息");
MessageReceived.value = true
break
default:
addLog('info', `未知事件类型`)
}
}
// ==================== 状态查询 ====================
function getStatusText() {
const statusMap = {
connecting: '连接中',
connected: '已连接',
disconnected: '未连接',
error: '连接错误'
}
return statusMap[connectionStatus.value] || '未知状态'
}
function getReadyState() {
return friendSocketManager.getReadyState()
}
// ==================== 导出 ====================
return {
// 状态
connectionStatus,
//属性变量
messageString,
logs,
config,
command,
groupId,
MessageReceived,
// 计算属性
isConnected,
isConnecting,
isDisconnected,
isError,
lastMessage,
// 方法
connect,
disconnect,
send,
addLog,
clearLogs,
getStatusText
}
})

353
stores/socket.js Normal file
View File

@@ -0,0 +1,353 @@
import {
defineStore
} from "pinia";
import {
computed,
ref
} from "vue";
import {
socketManager
} from '@/utils/socket.js'
import {
getToken
} from "../utils/user-info";
export const useSocketStore = defineStore('socket', () => {
// ==================== 状态定义 ====================
const connectionStatus = ref('disconnected') //connecting | connected | disconnected | error
const messages = ref([])
const messageString = ref('')
const isThinking = ref(false)
const config = ref({
token: '',
conversationId: ''
})
const taskCallId = ref('')
// 日志数组和最大值
const logs = ref([])
const maxLogCount = ref(20)
// ==================== 计算属性 ====================
const isConnected = computed(() => connectionStatus.value === 'connected')
const isConnecting = computed(() => connectionStatus.value === 'connecting')
const isDisconnected = computed(() => connectionStatus.value === 'disconnected')
const isError = computed(() => connectionStatus.value === 'error')
const lastMessage = computed(() => messages.value[messages.value.length - 1])
// 日志方法
function addLog(type, connect) {
const now = new Date()
const time =
`${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}:${now.getSeconds().toString().padStart(2,'0')}`
logs.value.push({
type,
connect,
time
})
if (logs.value.length > maxLogCount.value) {
logs.value = logs.value.slice(-maxLogCount.value)
}
console.log(`[${type.toUpperCase()}] ${connect}`);
}
function clearLogs() {
logs.value = []
}
// ==================== 连接相关方法 ====================
function connect(options = {}) {
messages.value = []
messageString.value = ''
config.value = {
...config.value,
...options
}
addLog('info',
`准备连接WebSocket。Token:${config.value.token || '未设置'}。ConversationId: ${config.value.conversationId || '未设置'}`
)
if (!config.value.token || !config.value.conversationId) {
addLog('error', 'Token和ConversationId都不能为空')
return
}
connectionStatus.value = 'connecting'
socketManager.connect({
token: config.value.token,
conversationId: config.value.conversationId,
onMessage: handleMessage,
onError: handleError,
onOpen: handleOpen,
onClose: handleClose,
onReconnect: handleReconnecting
})
setConnectionTimeout()
}
function disconnect() {
socketManager.close()
connectionStatus.value = 'disconnected'
addLog('warn', '已主动断开连接')
}
async function send(message) {
console.log("检查到要发生消息为:",message);
if (!isConnected.value) {
addLog('error', '发送失败: 连接未建立')
throw new Error('连接未建立')
}
try {
await socketManager.send(message)
addLog('send', typeof message === 'string' ? message : JSON.stringify(message))
return true
} catch (error) {
addLog('error', `发送失败: ${error.message || error}`)
throw error
}
}
// ==================== 事件回调 ====================
function handleOpen() {
connectionStatus.value = 'connected'
addLog('success', '连接成功!发送auth')
console.log('连接成功!发送auth');
sendAuth()
}
function handleClose() {
if (connectionStatus.value !== 'disconnected') {
connectionStatus.value = 'disconnected'
addLog('warn', '连接已断开')
}
}
function handleError(error) {
addLog('error', `Socket错误: ${JSON.stringify(error)}`)
connectionStatus.value = 'error'
}
function handleReconnecting(attempts) {
connectionStatus.value = 'connecting'
addLog('warn', `重连中... (${attempts}/5)`)
}
function setConnectionTimeout() {
const timer = setTimeout(() => {
if (connectionStatus.value === 'connecting') {
connectionStatus.value = 'error'
addLog('error', '连接超时(10s)')
}
}, 10000)
// 返回 timer 以便必要时清除,但目前用不到
return timer
}
// function handleMessage(messageData) {
// addLog('receive', `收到: ${JSON.stringify(messageData)}`)
// const {
// ws_event,
// queue,
// data
// } = messageData || {}
// if (data?.task_call_id) {
// taskCallId.value = data.task_call_id
// uni.setStorageSync('taskCallId', data.task_call_id)
// }
// switch (ws_event) {
// case 'connect':
// addLog('success', '连接成功')
// handleBindConversation(messageData)
// break
// case 'disconnect':
// addLog('warn', '收到服务端断开指令')
// disconnect()
// break
// case 'message':
// handleBusinessMessage(messageData)
// break
// default:
// addLog('info', `未知事件类型: ${ws_event}`)
// }
// }
function handleMessage(messageData) {
addLog('receive', `收到: ${JSON.stringify(messageData)}`)
const {
type,
conversation_id,
message_id,
data
} = messageData || {}
// 调试日志:明确输出 type 和 data
console.log('[handleMessage] type =', type, ', data =', JSON.stringify(data));
switch (type) {
case 'auth_ok':
addLog('success', '连接成功')
break
case 'chat_ack':
addLog('warn', 'AI成功收到用户发送的消息')
break
case 'render':
addLog('warn', 'AI正在回复信息')
handleBusinessMessage(data)
break
default:
addLog('info', `未知事件类型: ${type}`)
}
}
// ==================== 消息处理 ====================
function sendAuth() {
config.value.token
socketManager.send({
"type": "auth",
"access_token": config.value.token
})
}
function handleBindConversation(messageData) {
// 管理绑定对话,// 发送"task_call_id","token""conversation_id"
const {
ws_event,
queue,
data
} = messageData || {}
if (data?.task_call_id) {
socketManager.send({
"ws_event": "message",
"data": {
"task_call_id": taskCallId.value,
"token": config.value.token,
"conversation_id": config.value.conversationId,
},
})
}
}
// function handleBusinessMessage(messageData) {
// const {
// ws_event,
// queue,
// data
// } = messageData
// const messageContent = data?.content || data?.chunk || ''
// // 调用工具
// if (data?.cmd === 'list_tools' || data?.cmd === 'catalog') {
// socketManager.send({
// "ws_event": "message",
// "data": {
// "task_call_id": taskCallId.value,
// "result": {
// "tools": []
// }
// },
// })
// addLog('info', `调用工具: ${data?.module}`)
// return
// }
// // 消息事件:渲染队列的业务消息
// if (ws_event === 'message' && queue === 'render') {
// messageString.value += messageContent
// // 有任务ID时自动回复消息确认包
// if (data.task_call_id) {
// socketManager.send({
// "ws_event": "message",
// "data": {
// "task_call_id": taskCallId.value
// }
// }).catch(err => console.error('发送确认失败:', err))
// }
// }
// }
function handleBusinessMessage(data) {
// 处理 data 为字符串 "exit" 的情况
if (data === "exit") {
console.log("ai结束思考");
isThinking.value = false
return
}
// 处理 data 为对象的情况
if (!data || typeof data !== 'object') return
const {
role,
chunk,
message_role,
meaasge_uuid,
message_type,
task_call_id
} = data
// ai 开始回复:首次收到 chunk 或 message_role 为 assistant 时
if (!isThinking.value && (chunk || message_role === 'assistant')) {
console.log("ai开始思考");
messageString.value = ''
isThinking.value = true
}
if (chunk) {
// 拼接 ai 回复的内容
messageString.value += chunk
}
}
// ==================== 状态查询 ====================
function getStatusText() {
const statusMap = {
connecting: '连接中',
connected: '已连接',
disconnected: '未连接',
error: '连接错误'
}
return statusMap[connectionStatus.value] || '未知状态'
}
function getReadyState() {
return socketManager.getReadyState()
}
// ==================== 导出 ====================
return {
// 状态
connectionStatus,
messageString,
isThinking,
logs,
config,
// 计算属性
isConnected,
isConnecting,
isDisconnected,
isError,
lastMessage,
// 方法
connect,
disconnect,
send,
addLog,
clearLogs,
getStatusText
}
})