🗑️ 移除ws旧版本相关代码

This commit is contained in:
MoeSnowyFox
2025-09-11 23:25:08 +08:00
parent 80eb0bc49d
commit a034f10a19
4 changed files with 71 additions and 214 deletions

View File

@@ -45,22 +45,6 @@ export interface WebSocketSubscriber {
onResult?: (data: ResultMessage) => void onResult?: (data: ResultMessage) => void
onError?: (err: ErrorMessage) => void onError?: (err: ErrorMessage) => void
onNotify?: (n: NotifyMessage) => void onNotify?: (n: NotifyMessage) => void
// 兼容旧版 API
onMessage?: (raw: WebSocketBaseMessage) => void
onStatusChange?: (status: WebSocketStatus) => void
}
// 兼容旧版 connect(config) 接口
export interface WebSocketConfig {
taskId: string
mode?: string
showNotifications?: boolean
onProgress?: (data: ProgressMessage) => void
onResult?: (data: ResultMessage) => void
onError?: (err: ErrorMessage | string) => void
onNotify?: (n: NotifyMessage) => void
onMessage?: (raw: WebSocketBaseMessage) => void
onStatusChange?: (status: WebSocketStatus) => void
} }
// 后端状态类型 // 后端状态类型
@@ -136,11 +120,6 @@ const getGlobalStorage = (): GlobalWSStorage => {
const setGlobalStatus = (status: WebSocketStatus) => { const setGlobalStatus = (status: WebSocketStatus) => {
const global = getGlobalStorage() const global = getGlobalStorage()
global.status.value = status global.status.value = status
// 广播状态变化给所有订阅者(兼容 onStatusChange
global.subscribers.value.forEach(sub => {
sub.onStatusChange?.(status)
})
} }
// 设置后端状态 // 设置后端状态
@@ -295,25 +274,9 @@ const startGlobalHeartbeat = (ws: WebSocket) => {
try { try {
const pingTime = Date.now() const pingTime = Date.now()
global.lastPingTime = pingTime global.lastPingTime = pingTime
const pingData = { Ping: pingTime, connectionId: global.connectionId } ws.send(JSON.stringify({ type: 'Signal', data: { Ping: pingTime, connectionId: global.connectionId } }))
setTimeout(() => { /* 心跳超时不主动断开 */ }, HEARTBEAT_TIMEOUT)
const pingMessage = JSON.stringify({ } catch { /* ignore */ }
type: 'Signal',
data: pingData
})
ws.send(pingMessage)
// 心跳超时检测 - 但不主动断开连接
setTimeout(() => {
if (global.lastPingTime === pingTime && ws.readyState === WebSocket.OPEN) {
// 心跳超时但保持连接,等待网络层或服务端处理
}
}, HEARTBEAT_TIMEOUT)
} catch (e) {
// 心跳发送失败,静默处理
}
} }
}, HEARTBEAT_INTERVAL) }, HEARTBEAT_INTERVAL)
} }
@@ -336,12 +299,7 @@ const handleMessage = (raw: WebSocketBaseMessage) => {
const ws = global.wsRef const ws = global.wsRef
if (ws && ws.readyState === WebSocket.OPEN) { if (ws && ws.readyState === WebSocket.OPEN) {
try { try {
const pongMessage = { ws.send(JSON.stringify({ type: 'Signal', data: { Pong: raw.data.Ping, connectionId: global.connectionId } }))
type: 'Signal',
data: { Pong: raw.data.Ping, connectionId: global.connectionId }
}
const pongJson = JSON.stringify(pongMessage)
ws.send(pongJson)
} catch (e) { } catch (e) {
// Pong发送失败静默处理 // Pong发送失败静默处理
} }
@@ -353,9 +311,6 @@ const handleMessage = (raw: WebSocketBaseMessage) => {
const dispatch = (sub: WebSocketSubscriber) => { const dispatch = (sub: WebSocketSubscriber) => {
if (msgType === 'Signal') return if (msgType === 'Signal') return
// 兼容旧版:先调用通用 onMessage 回调
sub.onMessage?.(raw)
if (msgType === 'Progress') return sub.onProgress?.(raw.data as ProgressMessage) if (msgType === 'Progress') return sub.onProgress?.(raw.data as ProgressMessage)
if (msgType === 'Result') return sub.onResult?.(raw.data as ResultMessage) if (msgType === 'Result') return sub.onResult?.(raw.data as ResultMessage)
if (msgType === 'Error') { if (msgType === 'Error') {
@@ -408,7 +363,7 @@ export const connectAfterBackendStart = async (): Promise<boolean> => {
} }
} }
// 创建 WebSocket 连接 - 移除销毁检查,确保永不放弃连接 // 创建 WebSocket 连接
const createGlobalWebSocket = (): WebSocket => { const createGlobalWebSocket = (): WebSocket => {
const global = getGlobalStorage() const global = getGlobalStorage()
@@ -428,7 +383,7 @@ const createGlobalWebSocket = (): WebSocket => {
ws.onopen = () => { ws.onopen = () => {
global.isConnecting = false global.isConnecting = false
global.hasEverConnected = true global.hasEverConnected = true
global.reconnectAttempts = 0 // 重置重连计数 global.reconnectAttempts = 0
setGlobalStatus('已连接') setGlobalStatus('已连接')
startGlobalHeartbeat(ws) startGlobalHeartbeat(ws)
@@ -438,23 +393,9 @@ const createGlobalWebSocket = (): WebSocket => {
// 发送连接确认和初始pong // 发送连接确认和初始pong
try { try {
const connectData = { Connect: true, connectionId: global.connectionId } ws.send(JSON.stringify({ type: 'Signal', data: { Connect: true, connectionId: global.connectionId } }))
const connectMessage = JSON.stringify({ ws.send(JSON.stringify({ type: 'Signal', data: { Pong: Date.now(), connectionId: global.connectionId } }))
type: 'Signal', } catch { /* ignore */ }
data: connectData
})
ws.send(connectMessage)
// 发送初始pong以重置后端last_pong时间
const initialPongMessage = JSON.stringify({
type: 'Signal',
data: { Pong: Date.now(), connectionId: global.connectionId }
})
ws.send(initialPongMessage)
} catch (e) {
// 连接确认发送失败,静默处理
}
} }
ws.onmessage = (ev) => { ws.onmessage = (ev) => {
@@ -490,7 +431,7 @@ const createGlobalWebSocket = (): WebSocket => {
return ws return ws
} }
// 连接全局 WebSocket - 确保单一连接 // 连接全局 WebSocket
const connectGlobalWebSocket = async (reason: string = '未指定原因'): Promise<boolean> => { const connectGlobalWebSocket = async (reason: string = '未指定原因'): Promise<boolean> => {
const global = getGlobalStorage() const global = getGlobalStorage()
@@ -562,8 +503,6 @@ const connectGlobalWebSocket = async (reason: string = '未指定原因'): Promi
} }
} }
// 移除未使用的函数,已改为外部调用 connectAfterBackendStart
// 连接权限控制函数 // 连接权限控制函数
const setConnectionPermission = (allow: boolean, reason: string) => { const setConnectionPermission = (allow: boolean, reason: string) => {
const global = getGlobalStorage() const global = getGlobalStorage()
@@ -573,10 +512,7 @@ const setConnectionPermission = (allow: boolean, reason: string) => {
const checkConnectionPermission = (): boolean => { const checkConnectionPermission = (): boolean => {
const global = getGlobalStorage() const global = getGlobalStorage()
if (!global.allowNewConnection) { return !!global.allowNewConnection
return false
}
return true
} }
// 只在后端启动/重启时允许创建连接 // 只在后端启动/重启时允许创建连接
@@ -585,9 +521,7 @@ const allowedConnectionReasons = [
'后端重启后重连' '后端重启后重连'
] ]
const isValidConnectionReason = (reason: string): boolean => { const isValidConnectionReason = (reason: string): boolean => allowedConnectionReasons.includes(reason)
return allowedConnectionReasons.includes(reason)
}
// 全局连接锁 - 防止多个模块实例同时连接 // 全局连接锁 - 防止多个模块实例同时连接
let isGlobalConnectingLock = false let isGlobalConnectingLock = false
@@ -636,21 +570,14 @@ export function useWebSocket() {
if (ws && ws.readyState === WebSocket.OPEN) { if (ws && ws.readyState === WebSocket.OPEN) {
try { try {
const messageData = { id, type, data } ws.send(JSON.stringify({ id, type, data }))
ws.send(JSON.stringify(messageData))
} catch (e) { } catch (e) {
// 发送失败,静默处理 // 发送失败,静默处理
} }
} }
} }
// 移除 forceReconnect 功能,现在只能通过后端重启建立连接 const getConnectionInfo = () => ({
const ensureConnection = () => {
return Promise.resolve(false)
}
const getConnectionInfo = () => {
const info = {
connectionId: global.connectionId, connectionId: global.connectionId,
status: global.status.value, status: global.status.value,
subscriberCount: global.subscribers.value.size, subscriberCount: global.subscribers.value.size,
@@ -661,40 +588,26 @@ export function useWebSocket() {
hasEverConnected: global.hasEverConnected, hasEverConnected: global.hasEverConnected,
reconnectAttempts: global.reconnectAttempts, reconnectAttempts: global.reconnectAttempts,
isPersistentMode: true // 标识为永久连接模式 isPersistentMode: true // 标识为永久连接模式
} })
return info
}
// 手动重启后端
const restartBackendManually = async () => { const restartBackendManually = async () => {
const global = getGlobalStorage() const global = getGlobalStorage()
global.backendRestartAttempts = 0 // 重置重启计数 global.backendRestartAttempts = 0
return await restartBackend() return await restartBackend()
} }
// 获取后端状态
const getBackendStatus = () => { const getBackendStatus = () => {
const global = getGlobalStorage() const global = getGlobalStorage()
return { return { status: global.backendStatus.value, restartAttempts: global.backendRestartAttempts, isRestarting: global.isRestartingBackend, lastCheck: global.lastBackendCheck }
status: global.backendStatus.value,
restartAttempts: global.backendRestartAttempts,
isRestarting: global.isRestartingBackend,
lastCheck: global.lastBackendCheck
}
} }
return { return {
// 新的订阅 API
subscribe, subscribe,
unsubscribe, unsubscribe,
sendRaw, sendRaw,
// 连接管理
ensureConnection,
getConnectionInfo, getConnectionInfo,
// 状态
status: global.status, status: global.status,
subscribers: global.subscribers, subscribers: global.subscribers,
// 后端管理
backendStatus: global.backendStatus, backendStatus: global.backendStatus,
restartBackend: restartBackendManually, restartBackend: restartBackendManually,
getBackendStatus getBackendStatus

View File

@@ -360,7 +360,7 @@ const router = useRouter()
const route = useRoute() const route = useRoute()
const { addUser, updateUser, getUsers, loading: userLoading } = useUserApi() const { addUser, updateUser, getUsers, loading: userLoading } = useUserApi()
const { getScript } = useScriptApi() const { getScript } = useScriptApi()
const { connect, disconnect } = useWebSocket() const { subscribe, unsubscribe } = useWebSocket()
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const loading = computed(() => userLoading.value) const loading = computed(() => userLoading.value)
@@ -513,47 +513,28 @@ const loadUserData = async () => {
const handleSubmit = async () => { const handleSubmit = async () => {
try { try {
await formRef.value?.validate() await formRef.value?.validate()
// 确保扁平化字段同步到嵌套数据
formData.Info.Name = formData.userName formData.Info.Name = formData.userName
console.log('提交前的表单数据:', {
userName: formData.userName,
InfoName: formData.Info.Name,
isEdit: isEdit.value,
})
// 构建提交数据移除通用脚本不需要的MAA专用字段
const { IfSendSixStar, ...generalNotify } = formData.Notify
const userData = { const userData = {
Info: { ...formData.Info }, Info: { ...formData.Info },
Notify: generalNotify, Notify: { ...formData.Notify },
Data: { ...formData.Data }, Data: { ...formData.Data },
} }
if (isEdit.value) { if (isEdit.value) {
// 编辑模式
const result = await updateUser(scriptId, userId, userData) const result = await updateUser(scriptId, userId, userData)
if (result) { if (result) {
message.success('用户更新成功') message.success('用户更新成功')
handleCancel() handleCancel()
} }
} else { } else {
// 添加模式
const result = await addUser(scriptId) const result = await addUser(scriptId)
if (result) { if (result) {
// 创建成功后立即更新用户数据
try { try {
const updateResult = await updateUser(scriptId, result.userId, userData) const updateResult = await updateUser(scriptId, result.userId, userData)
console.log('用户数据更新结果:', updateResult)
if (updateResult) { if (updateResult) {
message.success('用户创建成功') message.success('用户创建成功')
handleCancel() handleCancel()
} else { } else {
message.error('用户创建成功,但数据更新失败,请手动编辑用户信息') message.error('用户创建成功,但数据更新失败,请手动编辑用户信息')
// 不跳转,让用户可以重新保存
} }
} catch (updateError) { } catch (updateError) {
console.error('更新用户数据时发生错误:', updateError) console.error('更新用户数据时发生错误:', updateError)
@@ -575,35 +556,23 @@ const handleGeneralConfig = async () => {
try { try {
generalConfigLoading.value = true generalConfigLoading.value = true
// 如果已有连接,先断开
if (generalWebsocketId.value) { if (generalWebsocketId.value) {
disconnect(generalWebsocketId.value) unsubscribe(generalWebsocketId.value)
generalWebsocketId.value = null generalWebsocketId.value = null
} }
// 建立WebSocket连接进行通用配置 const subId = userId
const websocketId = await connect({
taskId: userId, // 使用用户ID进行配置 subscribe(subId, {
mode: '设置脚本',
showNotifications: true,
onStatusChange: status => {
console.log(`用户 ${formData.userName} 通用配置状态: ${status}`)
},
onMessage: data => {
console.log(`用户 ${formData.userName} 通用配置消息:`, data)
// 这里可以根据需要处理特定的消息
},
onError: error => { onError: error => {
console.error(`用户 ${formData.userName} 通用配置错误:`, error) console.error(`用户 ${formData.userName} 通用配置错误:`, error)
message.error(`通用配置连接失败: ${error}`) message.error(`通用配置连接失败: ${error}`)
generalWebsocketId.value = null generalWebsocketId.value = null
}, }
}) })
if (websocketId) { generalWebsocketId.value = subId
generalWebsocketId.value = websocketId
message.success(`已开始配置用户 ${formData.userName} 的通用设置`) message.success(`已开始配置用户 ${formData.userName} 的通用设置`)
}
} catch (error) { } catch (error) {
console.error('通用配置失败:', error) console.error('通用配置失败:', error)
message.error('通用配置失败') message.error('通用配置失败')
@@ -650,9 +619,8 @@ const selectScriptAfterTask = async () => {
} }
const handleCancel = () => { const handleCancel = () => {
// 清理WebSocket连接
if (generalWebsocketId.value) { if (generalWebsocketId.value) {
disconnect(generalWebsocketId.value) unsubscribe(generalWebsocketId.value)
generalWebsocketId.value = null generalWebsocketId.value = null
} }
router.push('/scripts') router.push('/scripts')
@@ -945,8 +913,8 @@ onMounted(() => {
} }
.path-button:disabled { .path-button:disabled {
background: var(--ant-color-bg-container-disabled); background: var(--ant-color-bg-container);
color: var(--ant-color-text-disabled); color: var(--ant-color-text-tertiary);
cursor: not-allowed; cursor: not-allowed;
} }
</style> </style>

View File

@@ -898,12 +898,14 @@ import { useUserApi } from '@/composables/useUserApi'
import { useScriptApi } from '@/composables/useScriptApi' import { useScriptApi } from '@/composables/useScriptApi'
import { useWebSocket } from '@/composables/useWebSocket' import { useWebSocket } from '@/composables/useWebSocket'
import { Service } from '@/api' import { Service } from '@/api'
import { GetStageIn } from '@/api/models/GetStageIn'
import { defineComponent } from 'vue'
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const { addUser, updateUser, getUsers, loading: userLoading } = useUserApi() const { addUser, updateUser, getUsers, loading: userLoading } = useUserApi()
const { getScript } = useScriptApi() const { getScript } = useScriptApi()
const { connect, disconnect } = useWebSocket() const { subscribe, unsubscribe } = useWebSocket()
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const loading = computed(() => userLoading.value) const loading = computed(() => userLoading.value)
@@ -1129,19 +1131,17 @@ const loadUserData = async () => {
const loadStageOptions = async () => { const loadStageOptions = async () => {
try { try {
const response = await Service.getStageComboxApiInfoComboxStagePost({ const response = await Service.getStageComboxApiInfoComboxStagePost({
type: 'Today', type: GetStageIn.type.TODAY
}) })
if (response && response.code === 200 && response.data) { if (response && response.code === 200 && response.data) {
const sorted = [...response.data].sort((a, b) => { stageOptions.value = [...response.data].sort((a, b) => {
if (a.value === '-') return -1 if (a.value === '-') return -1
if (b.value === '-') return 1 if (b.value === '-') return 1
return 0 return 0
}) })
stageOptions.value = sorted
} }
} catch (error) { } catch (error) {
console.error('加载关卡选项失败:', error) console.error('加载关卡选项失败:', error)
// 保持默认选项
} }
} }
@@ -1157,14 +1157,21 @@ const loadStageModeOptions = async () => {
} }
} }
// 替换 VNodes 组件定义
const VNodes = defineComponent({
props: { vnodes: { type: Object, required: true } },
setup(props) {
return () => props.vnodes as any
}
})
// 选择基建配置文件 // 选择基建配置文件
const selectInfrastructureConfig = async () => { const selectInfrastructureConfig = async () => {
try { try {
const path = await window.electronAPI?.selectFile([ const path = await (window as any).electronAPI?.selectFile([
{ name: 'JSON 文件', extensions: ['json'] }, { name: 'JSON 文件', extensions: ['json'] },
{ name: '所有文件', extensions: ['*'] }, { name: '所有文件', extensions: ['*'] },
]) ])
if (path && path.length > 0) { if (path && path.length > 0) {
infrastructureConfigPath.value = path infrastructureConfigPath.value = path
formData.Info.InfrastPath = path[0] formData.Info.InfrastPath = path[0]
@@ -1182,28 +1189,22 @@ const importInfrastructureConfig = async () => {
message.warning('请先选择配置文件') message.warning('请先选择配置文件')
return return
} }
if (!isEdit.value) { if (!isEdit.value) {
message.warning('请先保存用户后再导入配置') message.warning('请先保存用户后再导入配置')
return return
} }
try { try {
infrastructureImporting.value = true infrastructureImporting.value = true
// 调用API导入基建配置
const result = await Service.importInfrastructureApiScriptsUserInfrastructurePost({ const result = await Service.importInfrastructureApiScriptsUserInfrastructurePost({
scriptId: scriptId, scriptId: scriptId,
userId: userId, userId: userId,
jsonFile: infrastructureConfigPath.value[0], jsonFile: infrastructureConfigPath.value[0],
}) })
if (result && result.code === 200) { if (result && result.code === 200) {
message.success('基建配置导入成功') message.success('基建配置导入成功')
// 清空文件路径
infrastructureConfigPath.value = '' infrastructureConfigPath.value = ''
} else { } else {
message.error(result?.msg || '基建配置导入失败') message.error('基建配置导入失败')
} }
} catch (error) { } catch (error) {
console.error('基建配置导入失败:', error) console.error('基建配置导入失败:', error)
@@ -1285,33 +1286,22 @@ const handleMAAConfig = async () => {
// 如果已有连接,先断开 // 如果已有连接,先断开
if (maaWebsocketId.value) { if (maaWebsocketId.value) {
disconnect(maaWebsocketId.value) unsubscribe(maaWebsocketId.value)
maaWebsocketId.value = null maaWebsocketId.value = null
} }
// 建立WebSocket连接进行MAA配置 // 直接订阅(旧 connect 参数移除)
const websocketId = await connect({ const subId = userId
taskId: userId, // 使用用户ID进行配置 subscribe(subId, {
mode: '设置脚本',
showNotifications: true,
onStatusChange: status => {
console.log(`用户 ${formData.userName} MAA配置状态: ${status}`)
},
onMessage: data => {
console.log(`用户 ${formData.userName} MAA配置消息:`, data)
// 这里可以根据需要处理特定的消息
},
onError: error => { onError: error => {
console.error(`用户 ${formData.userName} MAA配置错误:`, error) console.error(`用户 ${formData.userName} MAA配置错误:`, error)
message.error(`MAA配置连接失败: ${error}`) message.error(`MAA配置连接失败: ${error}`)
maaWebsocketId.value = null maaWebsocketId.value = null
}, }
}) })
if (websocketId) { maaWebsocketId.value = subId
maaWebsocketId.value = websocketId
message.success(`已开始配置用户 ${formData.userName} 的MAA设置`) message.success(`已开始配置用户 ${formData.userName} 的MAA设置`)
}
} catch (error) { } catch (error) {
console.error('MAA配置失败:', error) console.error('MAA配置失败:', error)
message.error('MAA配置失败') message.error('MAA配置失败')
@@ -1335,17 +1325,12 @@ const stage3InputRef = ref()
const stageRemainInputRef = ref() const stageRemainInputRef = ref()
// VNodes 组件,用于渲染下拉菜单内容 // VNodes 组件,用于渲染下拉菜单内容
const VNodes = { const VNodes = defineComponent({
props: { props: { vnodes: { type: Object, required: true } },
vnodes: { setup(props) {
type: Object, return () => props.vnodes as any
required: true,
},
},
render() {
return this.vnodes
},
} }
})
// 验证关卡名称格式 // 验证关卡名称格式
const validateStageName = (stageName: string): boolean => { const validateStageName = (stageName: string): boolean => {
@@ -1465,9 +1450,8 @@ const addCustomStageRemain = () => {
} }
const handleCancel = () => { const handleCancel = () => {
// 清理WebSocket连接
if (maaWebsocketId.value) { if (maaWebsocketId.value) {
disconnect(maaWebsocketId.value) unsubscribe(maaWebsocketId.value)
maaWebsocketId.value = null maaWebsocketId.value = null
} }
router.push('/scripts') router.push('/scripts')

View File

@@ -236,9 +236,9 @@ import MarkdownIt from 'markdown-it'
const router = useRouter() const router = useRouter()
const { addScript, deleteScript, getScriptsWithUsers, loading } = useScriptApi() const { addScript, deleteScript, getScriptsWithUsers, loading } = useScriptApi()
const { addUser, updateUser, deleteUser, loading: userLoading } = useUserApi() const { updateUser, deleteUser } = useUserApi()
const { subscribe, unsubscribe } = useWebSocket() const { subscribe, unsubscribe } = useWebSocket()
const { getWebConfigTemplates, importScriptFromWeb, loading: templateApiLoading } = useTemplateApi() const { getWebConfigTemplates, importScriptFromWeb } = useTemplateApi()
// 初始化markdown解析器 // 初始化markdown解析器
const md = new MarkdownIt({ const md = new MarkdownIt({
@@ -503,19 +503,11 @@ const handleMAAConfig = async (script: Script) => {
return return
} }
// 建立WebSocket订阅进行MAA配置 // 新订阅
subscribe(script.id, { subscribe(script.id, {
onStatusChange: status => {
console.log(`脚本 ${script.name} 连接状态: ${status}`)
},
onMessage: data => {
console.log(`脚本 ${script.name} 收到消息:`, data)
// 这里可以根据需要处理特定的消息
},
onError: error => { onError: error => {
console.error(`脚本 ${script.name} 连接错误:`, error) console.error(`脚本 ${script.name} 连接错误:`, error)
message.error(`MAA配置连接失败: ${error}`) message.error(`MAA配置连接失败: ${error}`)
// 清理连接记录
activeConnections.value.delete(script.id) activeConnections.value.delete(script.id)
}, },
}) })