Merge branch 'feature/refactor' of github.com:AUTO-MAS-Project/AUTO-MAS into feature/refactor
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { ref, type Ref } from 'vue'
|
||||
import { message, notification, Modal } from 'ant-design-vue'
|
||||
import { message, Modal, notification } from 'ant-design-vue'
|
||||
|
||||
// 基础配置
|
||||
const BASE_WS_URL = 'ws://localhost:36163/api/core/ws'
|
||||
@@ -45,22 +45,6 @@ export interface WebSocketSubscriber {
|
||||
onResult?: (data: ResultMessage) => void
|
||||
onError?: (err: ErrorMessage) => 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
|
||||
}
|
||||
|
||||
// 后端状态类型
|
||||
@@ -103,7 +87,7 @@ const initGlobalStorage = (): GlobalWSStorage => {
|
||||
heartbeatTimer: undefined,
|
||||
isConnecting: false,
|
||||
lastPingTime: 0,
|
||||
connectionId: Math.random().toString(36).substr(2, 9),
|
||||
connectionId: Math.random().toString(36).substring(2, 9),
|
||||
moduleLoadCount: 0,
|
||||
createdAt: Date.now(),
|
||||
hasEverConnected: false,
|
||||
@@ -118,7 +102,7 @@ const initGlobalStorage = (): GlobalWSStorage => {
|
||||
lastConnectAttempt: 0,
|
||||
// 连接权限控制
|
||||
allowNewConnection: true, // 初始化时允许创建连接
|
||||
connectionReason: '系统初始化'
|
||||
connectionReason: '系统初始化',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,19 +112,13 @@ const getGlobalStorage = (): GlobalWSStorage => {
|
||||
;(window as any)[WS_STORAGE_KEY] = initGlobalStorage()
|
||||
}
|
||||
|
||||
const storage = (window as any)[WS_STORAGE_KEY] as GlobalWSStorage
|
||||
return storage
|
||||
return (window as any)[WS_STORAGE_KEY] as GlobalWSStorage
|
||||
}
|
||||
|
||||
// 设置全局状态
|
||||
const setGlobalStatus = (status: WebSocketStatus) => {
|
||||
const global = getGlobalStorage()
|
||||
global.status.value = status
|
||||
|
||||
// 广播状态变化给所有订阅者(兼容 onStatusChange)
|
||||
global.subscribers.value.forEach(sub => {
|
||||
sub.onStatusChange?.(status)
|
||||
})
|
||||
}
|
||||
|
||||
// 设置后端状态
|
||||
@@ -152,12 +130,12 @@ const setBackendStatus = (status: BackendStatus) => {
|
||||
// 检查后端是否运行(通过WebSocket连接状态判断)
|
||||
const checkBackendStatus = (): boolean => {
|
||||
const global = getGlobalStorage()
|
||||
|
||||
|
||||
// 如果WebSocket存在且状态为OPEN,说明后端运行正常
|
||||
if (global.wsRef && global.wsRef.readyState === WebSocket.OPEN) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
// 如果WebSocket不存在或状态不是OPEN,说明后端可能有问题
|
||||
return false
|
||||
}
|
||||
@@ -165,7 +143,7 @@ const checkBackendStatus = (): boolean => {
|
||||
// 重启后端
|
||||
const restartBackend = async (): Promise<boolean> => {
|
||||
const global = getGlobalStorage()
|
||||
|
||||
|
||||
if (global.isRestartingBackend) {
|
||||
return false
|
||||
}
|
||||
@@ -173,7 +151,7 @@ const restartBackend = async (): Promise<boolean> => {
|
||||
try {
|
||||
global.isRestartingBackend = true
|
||||
global.backendRestartAttempts++
|
||||
|
||||
|
||||
setBackendStatus('starting')
|
||||
|
||||
// 调用 Electron API 重启后端
|
||||
@@ -202,7 +180,7 @@ const restartBackend = async (): Promise<boolean> => {
|
||||
// 后端监控和重启逻辑
|
||||
const handleBackendFailure = async () => {
|
||||
const global = getGlobalStorage()
|
||||
|
||||
|
||||
if (global.backendRestartAttempts >= MAX_RESTART_ATTEMPTS) {
|
||||
// 弹窗提示用户重启整个应用
|
||||
Modal.error({
|
||||
@@ -211,11 +189,11 @@ const handleBackendFailure = async () => {
|
||||
okText: '重启应用',
|
||||
onOk: () => {
|
||||
if ((window.electronAPI as any)?.windowClose) {
|
||||
(window.electronAPI as any).windowClose()
|
||||
;(window.electronAPI as any).windowClose()
|
||||
} else {
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -242,16 +220,16 @@ const handleBackendFailure = async () => {
|
||||
// 启动后端监控(仅基于WebSocket状态)
|
||||
const startBackendMonitoring = () => {
|
||||
const global = getGlobalStorage()
|
||||
|
||||
|
||||
if (global.backendCheckTimer) {
|
||||
clearInterval(global.backendCheckTimer)
|
||||
}
|
||||
|
||||
|
||||
global.backendCheckTimer = window.setInterval(() => {
|
||||
const isRunning = checkBackendStatus()
|
||||
const now = Date.now()
|
||||
global.lastBackendCheck = now
|
||||
|
||||
|
||||
// 基于 WebSocket 状态判断后端运行状态
|
||||
if (isRunning) {
|
||||
// WebSocket连接正常
|
||||
@@ -266,9 +244,9 @@ const startBackendMonitoring = () => {
|
||||
setBackendStatus('stopped')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 仅在必要时检查心跳超时
|
||||
if (global.lastPingTime > 0 && (now - global.lastPingTime) > HEARTBEAT_TIMEOUT * 2) {
|
||||
if (global.lastPingTime > 0 && now - global.lastPingTime > HEARTBEAT_TIMEOUT * 2) {
|
||||
if (global.wsRef && global.wsRef.readyState === WebSocket.OPEN) {
|
||||
setBackendStatus('error')
|
||||
}
|
||||
@@ -295,24 +273,17 @@ const startGlobalHeartbeat = (ws: WebSocket) => {
|
||||
try {
|
||||
const pingTime = Date.now()
|
||||
global.lastPingTime = pingTime
|
||||
const pingData = { Ping: pingTime, connectionId: global.connectionId }
|
||||
|
||||
const pingMessage = JSON.stringify({
|
||||
type: 'Signal',
|
||||
data: pingData
|
||||
})
|
||||
|
||||
ws.send(pingMessage)
|
||||
|
||||
// 心跳超时检测 - 但不主动断开连接
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: 'Signal',
|
||||
data: { Ping: pingTime, connectionId: global.connectionId },
|
||||
})
|
||||
)
|
||||
setTimeout(() => {
|
||||
if (global.lastPingTime === pingTime && ws.readyState === WebSocket.OPEN) {
|
||||
// 心跳超时但保持连接,等待网络层或服务端处理
|
||||
}
|
||||
/* 心跳超时不主动断开 */
|
||||
}, HEARTBEAT_TIMEOUT)
|
||||
|
||||
} catch (e) {
|
||||
// 心跳发送失败,静默处理
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
}, HEARTBEAT_INTERVAL)
|
||||
@@ -336,12 +307,12 @@ const handleMessage = (raw: WebSocketBaseMessage) => {
|
||||
const ws = global.wsRef
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
try {
|
||||
const pongMessage = {
|
||||
type: 'Signal',
|
||||
data: { Pong: raw.data.Ping, connectionId: global.connectionId }
|
||||
}
|
||||
const pongJson = JSON.stringify(pongMessage)
|
||||
ws.send(pongJson)
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: 'Signal',
|
||||
data: { Pong: raw.data.Ping, connectionId: global.connectionId },
|
||||
})
|
||||
)
|
||||
} catch (e) {
|
||||
// Pong发送失败,静默处理
|
||||
}
|
||||
@@ -353,9 +324,6 @@ const handleMessage = (raw: WebSocketBaseMessage) => {
|
||||
const dispatch = (sub: WebSocketSubscriber) => {
|
||||
if (msgType === 'Signal') return
|
||||
|
||||
// 兼容旧版:先调用通用 onMessage 回调
|
||||
sub.onMessage?.(raw)
|
||||
|
||||
if (msgType === 'Progress') return sub.onProgress?.(raw.data as ProgressMessage)
|
||||
if (msgType === 'Result') return sub.onResult?.(raw.data as ResultMessage)
|
||||
if (msgType === 'Error') {
|
||||
@@ -370,7 +338,7 @@ const handleMessage = (raw: WebSocketBaseMessage) => {
|
||||
if (raw.data && (raw.data as NotifyMessage).title) {
|
||||
notification.info({
|
||||
message: (raw.data as NotifyMessage).title,
|
||||
description: (raw.data as NotifyMessage).content
|
||||
description: (raw.data as NotifyMessage).content,
|
||||
})
|
||||
}
|
||||
return
|
||||
@@ -392,7 +360,7 @@ const handleMessage = (raw: WebSocketBaseMessage) => {
|
||||
// 后端启动后建立连接的公开函数
|
||||
export const connectAfterBackendStart = async (): Promise<boolean> => {
|
||||
setConnectionPermission(true, '后端启动后连接')
|
||||
|
||||
|
||||
try {
|
||||
const connected = await connectGlobalWebSocket('后端启动后连接')
|
||||
if (connected) {
|
||||
@@ -408,7 +376,7 @@ export const connectAfterBackendStart = async (): Promise<boolean> => {
|
||||
}
|
||||
}
|
||||
|
||||
// 创建 WebSocket 连接 - 移除销毁检查,确保永不放弃连接
|
||||
// 创建 WebSocket 连接
|
||||
const createGlobalWebSocket = (): WebSocket => {
|
||||
const global = getGlobalStorage()
|
||||
|
||||
@@ -428,9 +396,9 @@ const createGlobalWebSocket = (): WebSocket => {
|
||||
ws.onopen = () => {
|
||||
global.isConnecting = false
|
||||
global.hasEverConnected = true
|
||||
global.reconnectAttempts = 0 // 重置重连计数
|
||||
global.reconnectAttempts = 0
|
||||
setGlobalStatus('已连接')
|
||||
|
||||
|
||||
startGlobalHeartbeat(ws)
|
||||
|
||||
// 连接成功后禁止新连接
|
||||
@@ -438,26 +406,24 @@ const createGlobalWebSocket = (): WebSocket => {
|
||||
|
||||
// 发送连接确认和初始pong
|
||||
try {
|
||||
const connectData = { Connect: true, connectionId: global.connectionId }
|
||||
const connectMessage = JSON.stringify({
|
||||
type: 'Signal',
|
||||
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.send(
|
||||
JSON.stringify({
|
||||
type: 'Signal',
|
||||
data: { Connect: true, connectionId: global.connectionId },
|
||||
})
|
||||
)
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: 'Signal',
|
||||
data: { Pong: Date.now(), connectionId: global.connectionId },
|
||||
})
|
||||
)
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
ws.onmessage = (ev) => {
|
||||
ws.onmessage = ev => {
|
||||
try {
|
||||
const raw = JSON.parse(ev.data) as WebSocketBaseMessage
|
||||
handleMessage(raw)
|
||||
@@ -470,14 +436,17 @@ const createGlobalWebSocket = (): WebSocket => {
|
||||
setGlobalStatus('连接错误')
|
||||
}
|
||||
|
||||
ws.onclose = (event) => {
|
||||
ws.onclose = event => {
|
||||
setGlobalStatus('已断开')
|
||||
stopGlobalHeartbeat()
|
||||
global.isConnecting = false
|
||||
|
||||
// 检查是否是后端自杀导致的关闭
|
||||
if (event.code === 1000 && event.reason === 'Ping超时') {
|
||||
handleBackendFailure()
|
||||
handleBackendFailure().catch(error => {
|
||||
// 忽略错误,或者可以添加适当的错误处理
|
||||
console.warn('handleBackendFailure error:', error)
|
||||
})
|
||||
} else {
|
||||
// 连接断开,不自动重连,等待后端重启
|
||||
setGlobalStatus('已断开')
|
||||
@@ -490,7 +459,7 @@ const createGlobalWebSocket = (): WebSocket => {
|
||||
return ws
|
||||
}
|
||||
|
||||
// 连接全局 WebSocket - 确保单一连接
|
||||
// 连接全局 WebSocket
|
||||
const connectGlobalWebSocket = async (reason: string = '未指定原因'): Promise<boolean> => {
|
||||
const global = getGlobalStorage()
|
||||
|
||||
@@ -537,18 +506,18 @@ const connectGlobalWebSocket = async (reason: string = '未指定原因'): Promi
|
||||
// 额外保护:检查最近连接尝试时间,避免过于频繁的连接
|
||||
const now = Date.now()
|
||||
const MIN_CONNECT_INTERVAL = 2000 // 最小连接间隔2秒
|
||||
if (global.lastConnectAttempt && (now - global.lastConnectAttempt) < MIN_CONNECT_INTERVAL) {
|
||||
if (global.lastConnectAttempt && now - global.lastConnectAttempt < MIN_CONNECT_INTERVAL) {
|
||||
return false
|
||||
}
|
||||
|
||||
global.isConnecting = true
|
||||
global.lastConnectAttempt = now
|
||||
|
||||
|
||||
// 清理旧连接引用(如果存在且已关闭)
|
||||
if (global.wsRef && global.wsRef.readyState === WebSocket.CLOSED) {
|
||||
global.wsRef = null
|
||||
}
|
||||
|
||||
|
||||
global.wsRef = createGlobalWebSocket()
|
||||
setGlobalStatus('连接中')
|
||||
return true
|
||||
@@ -562,8 +531,6 @@ const connectGlobalWebSocket = async (reason: string = '未指定原因'): Promi
|
||||
}
|
||||
}
|
||||
|
||||
// 移除未使用的函数,已改为外部调用 connectAfterBackendStart
|
||||
|
||||
// 连接权限控制函数
|
||||
const setConnectionPermission = (allow: boolean, reason: string) => {
|
||||
const global = getGlobalStorage()
|
||||
@@ -573,21 +540,14 @@ const setConnectionPermission = (allow: boolean, reason: string) => {
|
||||
|
||||
const checkConnectionPermission = (): boolean => {
|
||||
const global = getGlobalStorage()
|
||||
if (!global.allowNewConnection) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return global.allowNewConnection
|
||||
}
|
||||
|
||||
// 只在后端启动/重启时允许创建连接
|
||||
const allowedConnectionReasons = [
|
||||
'后端启动后连接',
|
||||
'后端重启后重连'
|
||||
]
|
||||
const allowedConnectionReasons = ['后端启动后连接', '后端重启后重连']
|
||||
|
||||
const isValidConnectionReason = (reason: string): boolean => {
|
||||
return allowedConnectionReasons.includes(reason)
|
||||
}
|
||||
const isValidConnectionReason = (reason: string): boolean =>
|
||||
allowedConnectionReasons.includes(reason)
|
||||
|
||||
// 全局连接锁 - 防止多个模块实例同时连接
|
||||
let isGlobalConnectingLock = false
|
||||
@@ -636,67 +596,51 @@ export function useWebSocket() {
|
||||
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
try {
|
||||
const messageData = { id, type, data }
|
||||
ws.send(JSON.stringify(messageData))
|
||||
ws.send(JSON.stringify({ id, type, data }))
|
||||
} catch (e) {
|
||||
// 发送失败,静默处理
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 移除 forceReconnect 功能,现在只能通过后端重启建立连接
|
||||
const ensureConnection = () => {
|
||||
return Promise.resolve(false)
|
||||
}
|
||||
const getConnectionInfo = () => ({
|
||||
connectionId: global.connectionId,
|
||||
status: global.status.value,
|
||||
subscriberCount: global.subscribers.value.size,
|
||||
moduleLoadCount: global.moduleLoadCount,
|
||||
wsReadyState: global.wsRef ? global.wsRef.readyState : null,
|
||||
isConnecting: global.isConnecting,
|
||||
hasHeartbeat: !!global.heartbeatTimer,
|
||||
hasEverConnected: global.hasEverConnected,
|
||||
reconnectAttempts: global.reconnectAttempts,
|
||||
isPersistentMode: true, // 标识为永久连接模式
|
||||
})
|
||||
|
||||
const getConnectionInfo = () => {
|
||||
const info = {
|
||||
connectionId: global.connectionId,
|
||||
status: global.status.value,
|
||||
subscriberCount: global.subscribers.value.size,
|
||||
moduleLoadCount: global.moduleLoadCount,
|
||||
wsReadyState: global.wsRef ? global.wsRef.readyState : null,
|
||||
isConnecting: global.isConnecting,
|
||||
hasHeartbeat: !!global.heartbeatTimer,
|
||||
hasEverConnected: global.hasEverConnected,
|
||||
reconnectAttempts: global.reconnectAttempts,
|
||||
isPersistentMode: true // 标识为永久连接模式
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
// 手动重启后端
|
||||
const restartBackendManually = async () => {
|
||||
const global = getGlobalStorage()
|
||||
global.backendRestartAttempts = 0 // 重置重启计数
|
||||
global.backendRestartAttempts = 0
|
||||
return await restartBackend()
|
||||
}
|
||||
|
||||
// 获取后端状态
|
||||
const getBackendStatus = () => {
|
||||
const global = getGlobalStorage()
|
||||
return {
|
||||
status: global.backendStatus.value,
|
||||
restartAttempts: global.backendRestartAttempts,
|
||||
isRestarting: global.isRestartingBackend,
|
||||
lastCheck: global.lastBackendCheck
|
||||
lastCheck: global.lastBackendCheck,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
// 新的订阅 API
|
||||
subscribe,
|
||||
unsubscribe,
|
||||
sendRaw,
|
||||
// 连接管理
|
||||
ensureConnection,
|
||||
getConnectionInfo,
|
||||
// 状态
|
||||
status: global.status,
|
||||
subscribers: global.subscribers,
|
||||
// 后端管理
|
||||
backendStatus: global.backendStatus,
|
||||
restartBackend: restartBackendManually,
|
||||
getBackendStatus
|
||||
getBackendStatus,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { addUser, updateUser, getUsers, loading: userLoading } = useUserApi()
|
||||
const { getScript } = useScriptApi()
|
||||
const { connect, disconnect } = useWebSocket()
|
||||
const { subscribe, unsubscribe } = useWebSocket()
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
const loading = computed(() => userLoading.value)
|
||||
@@ -513,47 +513,28 @@ const loadUserData = async () => {
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
await formRef.value?.validate()
|
||||
|
||||
// 确保扁平化字段同步到嵌套数据
|
||||
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 = {
|
||||
Info: { ...formData.Info },
|
||||
Notify: generalNotify,
|
||||
Notify: { ...formData.Notify },
|
||||
Data: { ...formData.Data },
|
||||
}
|
||||
|
||||
if (isEdit.value) {
|
||||
// 编辑模式
|
||||
const result = await updateUser(scriptId, userId, userData)
|
||||
if (result) {
|
||||
message.success('用户更新成功')
|
||||
handleCancel()
|
||||
}
|
||||
} else {
|
||||
// 添加模式
|
||||
const result = await addUser(scriptId)
|
||||
if (result) {
|
||||
// 创建成功后立即更新用户数据
|
||||
try {
|
||||
const updateResult = await updateUser(scriptId, result.userId, userData)
|
||||
console.log('用户数据更新结果:', updateResult)
|
||||
|
||||
if (updateResult) {
|
||||
message.success('用户创建成功')
|
||||
handleCancel()
|
||||
} else {
|
||||
message.error('用户创建成功,但数据更新失败,请手动编辑用户信息')
|
||||
// 不跳转,让用户可以重新保存
|
||||
}
|
||||
} catch (updateError) {
|
||||
console.error('更新用户数据时发生错误:', updateError)
|
||||
@@ -575,35 +556,23 @@ const handleGeneralConfig = async () => {
|
||||
try {
|
||||
generalConfigLoading.value = true
|
||||
|
||||
// 如果已有连接,先断开
|
||||
if (generalWebsocketId.value) {
|
||||
disconnect(generalWebsocketId.value)
|
||||
unsubscribe(generalWebsocketId.value)
|
||||
generalWebsocketId.value = null
|
||||
}
|
||||
|
||||
// 建立WebSocket连接进行通用配置
|
||||
const websocketId = await connect({
|
||||
taskId: userId, // 使用用户ID进行配置
|
||||
mode: '设置脚本',
|
||||
showNotifications: true,
|
||||
onStatusChange: status => {
|
||||
console.log(`用户 ${formData.userName} 通用配置状态: ${status}`)
|
||||
},
|
||||
onMessage: data => {
|
||||
console.log(`用户 ${formData.userName} 通用配置消息:`, data)
|
||||
// 这里可以根据需要处理特定的消息
|
||||
},
|
||||
const subId = userId
|
||||
|
||||
subscribe(subId, {
|
||||
onError: error => {
|
||||
console.error(`用户 ${formData.userName} 通用配置错误:`, error)
|
||||
message.error(`通用配置连接失败: ${error}`)
|
||||
generalWebsocketId.value = null
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
if (websocketId) {
|
||||
generalWebsocketId.value = websocketId
|
||||
message.success(`已开始配置用户 ${formData.userName} 的通用设置`)
|
||||
}
|
||||
generalWebsocketId.value = subId
|
||||
message.success(`已开始配置用户 ${formData.userName} 的通用设置`)
|
||||
} catch (error) {
|
||||
console.error('通用配置失败:', error)
|
||||
message.error('通用配置失败')
|
||||
@@ -650,9 +619,8 @@ const selectScriptAfterTask = async () => {
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
// 清理WebSocket连接
|
||||
if (generalWebsocketId.value) {
|
||||
disconnect(generalWebsocketId.value)
|
||||
unsubscribe(generalWebsocketId.value)
|
||||
generalWebsocketId.value = null
|
||||
}
|
||||
router.push('/scripts')
|
||||
@@ -945,8 +913,8 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.path-button:disabled {
|
||||
background: var(--ant-color-bg-container-disabled);
|
||||
color: var(--ant-color-text-disabled);
|
||||
background: var(--ant-color-bg-container);
|
||||
color: var(--ant-color-text-tertiary);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
@@ -898,12 +898,14 @@ import { useUserApi } from '@/composables/useUserApi'
|
||||
import { useScriptApi } from '@/composables/useScriptApi'
|
||||
import { useWebSocket } from '@/composables/useWebSocket'
|
||||
import { Service } from '@/api'
|
||||
import { GetStageIn } from '@/api/models/GetStageIn'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { addUser, updateUser, getUsers, loading: userLoading } = useUserApi()
|
||||
const { getScript } = useScriptApi()
|
||||
const { connect, disconnect } = useWebSocket()
|
||||
const { subscribe, unsubscribe } = useWebSocket()
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
const loading = computed(() => userLoading.value)
|
||||
@@ -1129,19 +1131,17 @@ const loadUserData = async () => {
|
||||
const loadStageOptions = async () => {
|
||||
try {
|
||||
const response = await Service.getStageComboxApiInfoComboxStagePost({
|
||||
type: 'Today',
|
||||
type: GetStageIn.type.TODAY
|
||||
})
|
||||
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 (b.value === '-') return 1
|
||||
return 0
|
||||
})
|
||||
stageOptions.value = sorted
|
||||
}
|
||||
} catch (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 () => {
|
||||
try {
|
||||
const path = await window.electronAPI?.selectFile([
|
||||
const path = await (window as any).electronAPI?.selectFile([
|
||||
{ name: 'JSON 文件', extensions: ['json'] },
|
||||
{ name: '所有文件', extensions: ['*'] },
|
||||
])
|
||||
|
||||
if (path && path.length > 0) {
|
||||
infrastructureConfigPath.value = path
|
||||
formData.Info.InfrastPath = path[0]
|
||||
@@ -1182,28 +1189,22 @@ const importInfrastructureConfig = async () => {
|
||||
message.warning('请先选择配置文件')
|
||||
return
|
||||
}
|
||||
|
||||
if (!isEdit.value) {
|
||||
message.warning('请先保存用户后再导入配置')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
infrastructureImporting.value = true
|
||||
|
||||
// 调用API导入基建配置
|
||||
const result = await Service.importInfrastructureApiScriptsUserInfrastructurePost({
|
||||
scriptId: scriptId,
|
||||
userId: userId,
|
||||
jsonFile: infrastructureConfigPath.value[0],
|
||||
})
|
||||
|
||||
if (result && result.code === 200) {
|
||||
message.success('基建配置导入成功')
|
||||
// 清空文件路径
|
||||
infrastructureConfigPath.value = ''
|
||||
} else {
|
||||
message.error(result?.msg || '基建配置导入失败')
|
||||
message.error('基建配置导入失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('基建配置导入失败:', error)
|
||||
@@ -1285,33 +1286,22 @@ const handleMAAConfig = async () => {
|
||||
|
||||
// 如果已有连接,先断开
|
||||
if (maaWebsocketId.value) {
|
||||
disconnect(maaWebsocketId.value)
|
||||
unsubscribe(maaWebsocketId.value)
|
||||
maaWebsocketId.value = null
|
||||
}
|
||||
|
||||
// 建立WebSocket连接进行MAA配置
|
||||
const websocketId = await connect({
|
||||
taskId: userId, // 使用用户ID进行配置
|
||||
mode: '设置脚本',
|
||||
showNotifications: true,
|
||||
onStatusChange: status => {
|
||||
console.log(`用户 ${formData.userName} MAA配置状态: ${status}`)
|
||||
},
|
||||
onMessage: data => {
|
||||
console.log(`用户 ${formData.userName} MAA配置消息:`, data)
|
||||
// 这里可以根据需要处理特定的消息
|
||||
},
|
||||
// 直接订阅(旧 connect 参数移除)
|
||||
const subId = userId
|
||||
subscribe(subId, {
|
||||
onError: error => {
|
||||
console.error(`用户 ${formData.userName} MAA配置错误:`, error)
|
||||
message.error(`MAA配置连接失败: ${error}`)
|
||||
maaWebsocketId.value = null
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
if (websocketId) {
|
||||
maaWebsocketId.value = websocketId
|
||||
message.success(`已开始配置用户 ${formData.userName} 的MAA设置`)
|
||||
}
|
||||
maaWebsocketId.value = subId
|
||||
message.success(`已开始配置用户 ${formData.userName} 的MAA设置`)
|
||||
} catch (error) {
|
||||
console.error('MAA配置失败:', error)
|
||||
message.error('MAA配置失败')
|
||||
@@ -1335,17 +1325,12 @@ const stage3InputRef = ref()
|
||||
const stageRemainInputRef = ref()
|
||||
|
||||
// VNodes 组件,用于渲染下拉菜单内容
|
||||
const VNodes = {
|
||||
props: {
|
||||
vnodes: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return this.vnodes
|
||||
},
|
||||
}
|
||||
const VNodes = defineComponent({
|
||||
props: { vnodes: { type: Object, required: true } },
|
||||
setup(props) {
|
||||
return () => props.vnodes as any
|
||||
}
|
||||
})
|
||||
|
||||
// 验证关卡名称格式
|
||||
const validateStageName = (stageName: string): boolean => {
|
||||
@@ -1465,9 +1450,8 @@ const addCustomStageRemain = () => {
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
// 清理WebSocket连接
|
||||
if (maaWebsocketId.value) {
|
||||
disconnect(maaWebsocketId.value)
|
||||
unsubscribe(maaWebsocketId.value)
|
||||
maaWebsocketId.value = null
|
||||
}
|
||||
router.push('/scripts')
|
||||
|
||||
@@ -236,9 +236,9 @@ import MarkdownIt from 'markdown-it'
|
||||
|
||||
const router = useRouter()
|
||||
const { addScript, deleteScript, getScriptsWithUsers, loading } = useScriptApi()
|
||||
const { addUser, updateUser, deleteUser, loading: userLoading } = useUserApi()
|
||||
const { updateUser, deleteUser } = useUserApi()
|
||||
const { subscribe, unsubscribe } = useWebSocket()
|
||||
const { getWebConfigTemplates, importScriptFromWeb, loading: templateApiLoading } = useTemplateApi()
|
||||
const { getWebConfigTemplates, importScriptFromWeb } = useTemplateApi()
|
||||
|
||||
// 初始化markdown解析器
|
||||
const md = new MarkdownIt({
|
||||
@@ -503,19 +503,11 @@ const handleMAAConfig = async (script: Script) => {
|
||||
return
|
||||
}
|
||||
|
||||
// 建立WebSocket订阅进行MAA配置
|
||||
// 新订阅
|
||||
subscribe(script.id, {
|
||||
onStatusChange: status => {
|
||||
console.log(`脚本 ${script.name} 连接状态: ${status}`)
|
||||
},
|
||||
onMessage: data => {
|
||||
console.log(`脚本 ${script.name} 收到消息:`, data)
|
||||
// 这里可以根据需要处理特定的消息
|
||||
},
|
||||
onError: error => {
|
||||
console.error(`脚本 ${script.name} 连接错误:`, error)
|
||||
message.error(`MAA配置连接失败: ${error}`)
|
||||
// 清理连接记录
|
||||
activeConnections.value.delete(script.id)
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user