This commit is contained in:
Baobhan Sith
2025-04-16 11:04:29 +08:00
parent 269473c526
commit a83b346956
20 changed files with 922 additions and 350 deletions
+21 -1
View File
@@ -4,7 +4,8 @@ import { useI18n } from 'vue-i18n';
import { useConnectionsStore, type ConnectionInfo } from './connections.store';
// 导入管理器工厂函数 (用于创建实例)
import { createWebSocketConnectionManager } from '../composables/useWebSocketConnection';
// 导入 WsConnectionStatus 类型
import { createWebSocketConnectionManager, type WsConnectionStatus } from '../composables/useWebSocketConnection';
import { createSftpActionsManager, type WebSocketDependencies } from '../composables/useSftpActions';
import { createSshTerminalManager, type SshTerminalDependencies } from '../composables/useSshTerminal';
import { createStatusMonitorManager, type StatusMonitorDependencies } from '../composables/useStatusMonitor';
@@ -31,6 +32,14 @@ export interface SessionState {
currentSftpPath: Ref<string>; // SFTP 当前路径 (可能需要保留在此处或移至 SftpManager 内部)
}
// 为标签栏定义包含状态的类型
export interface SessionTabInfoWithStatus {
sessionId: string;
connectionName: string;
status: WsConnectionStatus; // 添加状态字段
}
export const useSessionStore = defineStore('session', () => {
// --- 依赖 ---
const { t } = useI18n();
@@ -49,6 +58,16 @@ export const useSessionStore = defineStore('session', () => {
}));
});
// 新增:包含状态的标签页信息
const sessionTabsWithStatus = computed((): SessionTabInfoWithStatus[] => {
return Array.from(sessions.value.values()).map(session => ({
sessionId: session.sessionId,
connectionName: session.connectionName,
status: session.wsManager.connectionStatus.value, // 从 wsManager 获取状态
}));
});
const activeSession = computed((): SessionState | null => {
if (!activeSessionId.value) return null;
return sessions.value.get(activeSessionId.value) || null;
@@ -240,6 +259,7 @@ export const useSessionStore = defineStore('session', () => {
activeSessionId,
// Getters
sessionTabs,
sessionTabsWithStatus, // 导出新的 getter
activeSession,
// Actions
openNewSession,
@@ -0,0 +1,68 @@
import { defineStore } from 'pinia';
import { ref } from 'vue';
// 定义通知对象的接口
export interface UINotification {
id: number;
type: 'success' | 'error' | 'info' | 'warning';
message: string;
timeout?: number; // 可选的自动关闭超时时间 (毫秒)
}
export const useUiNotificationsStore = defineStore('uiNotifications', () => {
const notifications = ref<UINotification[]>([]);
let nextId = 0;
/**
* 添加一个新通知
* @param notification - 通知对象 (至少包含 type 和 message)
*/
const addNotification = (notification: Omit<UINotification, 'id'>) => {
const id = nextId++;
const newNotification: UINotification = { ...notification, id };
notifications.value.push(newNotification);
// 如果设置了超时,则在超时后自动移除通知
if (notification.timeout) {
setTimeout(() => {
removeNotification(id);
}, notification.timeout);
}
};
/**
* 移除一个通知
* @param id - 要移除的通知的 ID
*/
const removeNotification = (id: number) => {
notifications.value = notifications.value.filter(n => n.id !== id);
};
// 便捷方法
const showError = (message: string, options: { timeout?: number } = {}) => {
addNotification({ type: 'error', message, timeout: options.timeout ?? 5000 }); // 默认 5 秒超时
};
const showSuccess = (message: string, options: { timeout?: number } = {}) => {
addNotification({ type: 'success', message, timeout: options.timeout ?? 3000 }); // 默认 3 秒超时
};
const showInfo = (message: string, options: { timeout?: number } = {}) => {
addNotification({ type: 'info', message, timeout: options.timeout ?? 3000 });
};
const showWarning = (message: string, options: { timeout?: number } = {}) => {
addNotification({ type: 'warning', message, timeout: options.timeout ?? 5000 });
};
return {
notifications,
addNotification,
removeNotification,
showError,
showSuccess,
showInfo,
showWarning,
};
});