mirror of
https://github.com/Minidoracat/mcp-feedback-enhanced.git
synced 2025-07-27 02:22:26 +08:00
测试
This commit is contained in:
parent
9c412a1321
commit
2cd8d91bb9
@ -156,6 +156,10 @@
|
||||
"submitted": {
|
||||
"title": "Submitted",
|
||||
"message": "Waiting for next MCP call"
|
||||
},
|
||||
"completed": {
|
||||
"title": "Completed",
|
||||
"message": "Session completed"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
|
@ -156,6 +156,10 @@
|
||||
"submitted": {
|
||||
"title": "反馈已提交",
|
||||
"message": "等待下次 MCP 调用"
|
||||
},
|
||||
"completed": {
|
||||
"title": "已完成",
|
||||
"message": "会话已完成"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
|
@ -161,6 +161,10 @@
|
||||
"submitted": {
|
||||
"title": "回饋已提交",
|
||||
"message": "等待下次 MCP 調用"
|
||||
},
|
||||
"completed": {
|
||||
"title": "已完成",
|
||||
"message": "會話已完成"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
|
@ -318,25 +318,46 @@ class WebUIManager:
|
||||
|
||||
def create_session(self, project_directory: str, summary: str) -> str:
|
||||
"""創建新的回饋會話 - 重構為單一活躍會話模式,保留標籤頁狀態"""
|
||||
# 保存舊會話的 WebSocket 連接以便發送更新通知
|
||||
# 保存舊會話的引用和 WebSocket 連接
|
||||
old_session = self.current_session
|
||||
old_websocket = None
|
||||
if self.current_session and self.current_session.websocket:
|
||||
old_websocket = self.current_session.websocket
|
||||
if old_session and old_session.websocket:
|
||||
old_websocket = old_session.websocket
|
||||
debug_log("保存舊會話的 WebSocket 連接以發送更新通知")
|
||||
|
||||
# 如果已有活躍會話,先保存其標籤頁狀態到全局狀態
|
||||
if self.current_session:
|
||||
debug_log("保存現有會話的標籤頁狀態並清理會話")
|
||||
# 保存標籤頁狀態到全局
|
||||
if hasattr(self.current_session, "active_tabs"):
|
||||
self._merge_tabs_to_global(self.current_session.active_tabs)
|
||||
|
||||
# 同步清理會話資源(但保留 WebSocket 連接)
|
||||
self.current_session._cleanup_sync()
|
||||
|
||||
# 創建新會話
|
||||
session_id = str(uuid.uuid4())
|
||||
session = WebFeedbackSession(session_id, project_directory, summary)
|
||||
|
||||
# 如果有舊會話,處理狀態轉換和清理
|
||||
if old_session:
|
||||
debug_log(f"處理舊會話 {old_session.session_id} 的狀態轉換,當前狀態: {old_session.status.value}")
|
||||
|
||||
# 保存標籤頁狀態到全局
|
||||
if hasattr(old_session, "active_tabs"):
|
||||
self._merge_tabs_to_global(old_session.active_tabs)
|
||||
|
||||
# 如果舊會話是已提交狀態,進入下一步(已完成)
|
||||
if old_session.status == SessionStatus.FEEDBACK_SUBMITTED:
|
||||
debug_log(f"舊會話 {old_session.session_id} 進入下一步:已提交 → 已完成")
|
||||
success = old_session.next_step("反饋已處理,會話完成")
|
||||
if success:
|
||||
debug_log(f"✅ 舊會話 {old_session.session_id} 成功進入已完成狀態")
|
||||
else:
|
||||
debug_log(f"❌ 舊會話 {old_session.session_id} 無法進入下一步")
|
||||
else:
|
||||
debug_log(f"舊會話 {old_session.session_id} 狀態為 {old_session.status.value},無需轉換")
|
||||
|
||||
# 確保舊會話仍在字典中(用於API獲取)
|
||||
if old_session.session_id in self.sessions:
|
||||
debug_log(f"舊會話 {old_session.session_id} 仍在會話字典中")
|
||||
else:
|
||||
debug_log(f"⚠️ 舊會話 {old_session.session_id} 不在會話字典中,重新添加")
|
||||
self.sessions[old_session.session_id] = old_session
|
||||
|
||||
# 同步清理會話資源(但保留 WebSocket 連接)
|
||||
old_session._cleanup_sync()
|
||||
|
||||
# 將全局標籤頁狀態繼承到新會話
|
||||
session.active_tabs = self.global_active_tabs.copy()
|
||||
|
||||
@ -348,25 +369,11 @@ class WebUIManager:
|
||||
debug_log(f"創建新的活躍會話: {session_id}")
|
||||
debug_log(f"繼承 {len(session.active_tabs)} 個活躍標籤頁")
|
||||
|
||||
# 處理會話更新通知
|
||||
# 處理WebSocket連接轉移
|
||||
if old_websocket:
|
||||
# 有舊連接,立即發送會話更新通知並轉移連接
|
||||
self._old_websocket_for_update = old_websocket
|
||||
self._new_session_for_update = session
|
||||
debug_log("已保存舊 WebSocket 連接,準備發送會話更新通知")
|
||||
|
||||
# 立即發送會話更新通知
|
||||
import asyncio
|
||||
|
||||
try:
|
||||
# 在後台任務中發送通知並轉移連接
|
||||
asyncio.create_task(self._send_immediate_session_update())
|
||||
except Exception as e:
|
||||
debug_log(f"創建會話更新任務失敗: {e}")
|
||||
# 即使任務創建失敗,也要嘗試直接轉移連接
|
||||
session.websocket = old_websocket
|
||||
debug_log("任務創建失敗,直接轉移 WebSocket 連接到新會話")
|
||||
self._pending_session_update = True
|
||||
# 直接轉移連接到新會話,消息發送由 smart_open_browser 統一處理
|
||||
session.websocket = old_websocket
|
||||
debug_log("已將舊 WebSocket 連接轉移到新會話")
|
||||
else:
|
||||
# 沒有舊連接,標記需要發送會話更新通知(當新 WebSocket 連接建立時)
|
||||
self._pending_session_update = True
|
||||
@ -682,107 +689,9 @@ class WebUIManager:
|
||||
else:
|
||||
debug_log("沒有活躍的桌面應用程式實例")
|
||||
|
||||
async def notify_session_update(self, session):
|
||||
"""向活躍標籤頁發送會話更新通知"""
|
||||
try:
|
||||
# 檢查是否有活躍的 WebSocket 連接
|
||||
if session.websocket:
|
||||
# 直接通過當前會話的 WebSocket 發送
|
||||
await session.websocket.send_json(
|
||||
{
|
||||
"type": "session_updated",
|
||||
"action": "new_session_created",
|
||||
"message": "新會話已創建,正在更新頁面內容",
|
||||
"session_info": {
|
||||
"project_directory": session.project_directory,
|
||||
"summary": session.summary,
|
||||
"session_id": session.session_id,
|
||||
},
|
||||
}
|
||||
)
|
||||
debug_log("會話更新通知已通過 WebSocket 發送")
|
||||
else:
|
||||
# 沒有活躍連接,設置待更新標記
|
||||
self._pending_session_update = True
|
||||
debug_log("沒有活躍 WebSocket 連接,設置待更新標記")
|
||||
except Exception as e:
|
||||
debug_log(f"發送會話更新通知失敗: {e}")
|
||||
# 設置待更新標記作為備用方案
|
||||
self._pending_session_update = True
|
||||
|
||||
async def _send_immediate_session_update(self):
|
||||
"""立即發送會話更新通知(使用舊的 WebSocket 連接)"""
|
||||
try:
|
||||
# 檢查是否有保存的舊 WebSocket 連接
|
||||
if hasattr(self, "_old_websocket_for_update") and hasattr(
|
||||
self, "_new_session_for_update"
|
||||
):
|
||||
old_websocket = self._old_websocket_for_update
|
||||
new_session = self._new_session_for_update
|
||||
|
||||
# 改進的連接有效性檢查
|
||||
websocket_valid = False
|
||||
if old_websocket:
|
||||
try:
|
||||
# 檢查 WebSocket 連接狀態
|
||||
if hasattr(old_websocket, "client_state"):
|
||||
websocket_valid = (
|
||||
old_websocket.client_state
|
||||
!= old_websocket.client_state.DISCONNECTED
|
||||
)
|
||||
else:
|
||||
# 如果沒有 client_state 屬性,嘗試發送測試消息來檢查連接
|
||||
websocket_valid = True
|
||||
except Exception as check_error:
|
||||
debug_log(f"檢查 WebSocket 連接狀態失敗: {check_error}")
|
||||
websocket_valid = False
|
||||
|
||||
if websocket_valid:
|
||||
try:
|
||||
# 發送會話更新通知
|
||||
await old_websocket.send_json(
|
||||
{
|
||||
"type": "session_updated",
|
||||
"action": "new_session_created",
|
||||
"message": "新會話已創建,正在更新頁面內容",
|
||||
"session_info": {
|
||||
"project_directory": new_session.project_directory,
|
||||
"summary": new_session.summary,
|
||||
"session_id": new_session.session_id,
|
||||
},
|
||||
}
|
||||
)
|
||||
debug_log("已通過舊 WebSocket 連接發送會話更新通知")
|
||||
|
||||
# 延遲一小段時間讓前端處理消息
|
||||
await asyncio.sleep(0.2)
|
||||
|
||||
# 將 WebSocket 連接轉移到新會話
|
||||
new_session.websocket = old_websocket
|
||||
debug_log("已將 WebSocket 連接轉移到新會話")
|
||||
|
||||
except Exception as send_error:
|
||||
debug_log(f"發送會話更新通知失敗: {send_error}")
|
||||
# 如果發送失敗,仍然嘗試轉移連接
|
||||
new_session.websocket = old_websocket
|
||||
debug_log("發送失敗但仍轉移 WebSocket 連接到新會話")
|
||||
else:
|
||||
debug_log("舊 WebSocket 連接無效,設置待更新標記")
|
||||
self._pending_session_update = True
|
||||
|
||||
# 清理臨時變數
|
||||
delattr(self, "_old_websocket_for_update")
|
||||
delattr(self, "_new_session_for_update")
|
||||
|
||||
else:
|
||||
# 沒有舊連接,設置待更新標記
|
||||
self._pending_session_update = True
|
||||
debug_log("沒有舊 WebSocket 連接,設置待更新標記")
|
||||
|
||||
except Exception as e:
|
||||
debug_log(f"立即發送會話更新通知失敗: {e}")
|
||||
# 回退到待更新標記
|
||||
self._pending_session_update = True
|
||||
|
||||
async def _safe_close_websocket(self, websocket):
|
||||
"""安全關閉 WebSocket 連接,避免事件循環衝突 - 僅在連接已轉移後調用"""
|
||||
@ -1127,7 +1036,7 @@ async def launch_web_feedback_ui(
|
||||
"""
|
||||
manager = get_web_ui_manager()
|
||||
|
||||
# 創建或更新當前活躍會話
|
||||
# 創建新會話(每次AI調用都應該創建新會話)
|
||||
manager.create_session(project_directory, summary)
|
||||
session = manager.get_current_session()
|
||||
|
||||
@ -1154,9 +1063,9 @@ async def launch_web_feedback_ui(
|
||||
|
||||
debug_log(f"[DEBUG] 服務器地址: {feedback_url}")
|
||||
|
||||
# 如果檢測到活躍標籤頁但沒有開啟新視窗,立即發送會話更新通知
|
||||
# 如果檢測到活躍標籤頁,消息已在 smart_open_browser 中發送,無需額外處理
|
||||
if has_active_tabs:
|
||||
debug_log("檢測到活躍標籤頁,跳過額外的會話更新通知(已在 smart_open_browser 中發送)")
|
||||
debug_log("檢測到活躍標籤頁,會話更新通知已發送")
|
||||
|
||||
try:
|
||||
# 等待用戶回饋,傳遞 timeout 參數
|
||||
|
@ -29,15 +29,13 @@ from ...utils.resource_manager import get_resource_manager, register_process
|
||||
|
||||
|
||||
class SessionStatus(Enum):
|
||||
"""會話狀態枚舉"""
|
||||
"""會話狀態枚舉 - 單向流轉設計"""
|
||||
|
||||
WAITING = "waiting" # 等待中
|
||||
ACTIVE = "active" # 活躍中
|
||||
FEEDBACK_SUBMITTED = "feedback_submitted" # 已提交反饋
|
||||
COMPLETED = "completed" # 已完成
|
||||
TIMEOUT = "timeout" # 超時
|
||||
ERROR = "error" # 錯誤
|
||||
EXPIRED = "expired" # 已過期
|
||||
ERROR = "error" # 錯誤(終態)
|
||||
EXPIRED = "expired" # 已過期(終態)
|
||||
|
||||
|
||||
class CleanupReason(Enum):
|
||||
@ -174,21 +172,79 @@ class WebFeedbackSession:
|
||||
f"會話 {self.session_id} 初始化完成,自動清理延遲: {auto_cleanup_delay}秒,最大空閒: {max_idle_time}秒"
|
||||
)
|
||||
|
||||
def update_status(self, status: SessionStatus, message: str | None = None):
|
||||
"""更新會話狀態"""
|
||||
self.status = status
|
||||
def next_step(self, message: str | None = None) -> bool:
|
||||
"""進入下一個狀態 - 單向流轉,不可倒退"""
|
||||
old_status = self.status
|
||||
|
||||
# 定義狀態流轉路徑
|
||||
next_status_map = {
|
||||
SessionStatus.WAITING: SessionStatus.FEEDBACK_SUBMITTED,
|
||||
SessionStatus.FEEDBACK_SUBMITTED: SessionStatus.COMPLETED,
|
||||
SessionStatus.COMPLETED: None, # 終態
|
||||
SessionStatus.ERROR: None, # 終態
|
||||
SessionStatus.EXPIRED: None # 終態
|
||||
}
|
||||
|
||||
next_status = next_status_map.get(self.status)
|
||||
|
||||
if next_status is None:
|
||||
debug_log(f"⚠️ 會話 {self.session_id} 已處於終態 {self.status.value},無法進入下一步")
|
||||
return False
|
||||
|
||||
# 執行狀態轉換
|
||||
self.status = next_status
|
||||
if message:
|
||||
self.status_message = message
|
||||
# 統一使用 time.time()
|
||||
else:
|
||||
# 默認消息
|
||||
default_messages = {
|
||||
SessionStatus.FEEDBACK_SUBMITTED: "用戶已提交反饋",
|
||||
SessionStatus.COMPLETED: "會話已完成"
|
||||
}
|
||||
self.status_message = default_messages.get(next_status, "狀態已更新")
|
||||
|
||||
self.last_activity = time.time()
|
||||
|
||||
# 如果會話變為活躍狀態,重置清理定時器
|
||||
if status in [SessionStatus.ACTIVE, SessionStatus.FEEDBACK_SUBMITTED]:
|
||||
# 如果會話變為已提交狀態,重置清理定時器
|
||||
if next_status == SessionStatus.FEEDBACK_SUBMITTED:
|
||||
self._schedule_auto_cleanup()
|
||||
|
||||
debug_log(
|
||||
f"會話 {self.session_id} 狀態更新: {status.value} - {self.status_message}"
|
||||
f"✅ 會話 {self.session_id} 狀態流轉: {old_status.value} → {next_status.value} - {self.status_message}"
|
||||
)
|
||||
return True
|
||||
|
||||
def set_error(self, message: str = "會話發生錯誤") -> bool:
|
||||
"""設置錯誤狀態(特殊方法,可從任何狀態進入)"""
|
||||
old_status = self.status
|
||||
self.status = SessionStatus.ERROR
|
||||
self.status_message = message
|
||||
self.last_activity = time.time()
|
||||
|
||||
debug_log(
|
||||
f"❌ 會話 {self.session_id} 設置為錯誤狀態: {old_status.value} → {self.status.value} - {message}"
|
||||
)
|
||||
return True
|
||||
|
||||
def set_expired(self, message: str = "會話已過期") -> bool:
|
||||
"""設置過期狀態(特殊方法,可從任何狀態進入)"""
|
||||
old_status = self.status
|
||||
self.status = SessionStatus.EXPIRED
|
||||
self.status_message = message
|
||||
self.last_activity = time.time()
|
||||
|
||||
debug_log(
|
||||
f"⏰ 會話 {self.session_id} 設置為過期狀態: {old_status.value} → {self.status.value} - {message}"
|
||||
)
|
||||
return True
|
||||
|
||||
def can_proceed(self) -> bool:
|
||||
"""檢查是否可以進入下一步"""
|
||||
return self.status in [SessionStatus.WAITING, SessionStatus.FEEDBACK_SUBMITTED]
|
||||
|
||||
def is_terminal(self) -> bool:
|
||||
"""檢查是否處於終態"""
|
||||
return self.status in [SessionStatus.COMPLETED, SessionStatus.ERROR, SessionStatus.EXPIRED]
|
||||
|
||||
def get_status_info(self) -> dict[str, Any]:
|
||||
"""獲取會話狀態信息"""
|
||||
@ -404,10 +460,8 @@ class WebFeedbackSession:
|
||||
self.settings = settings or {}
|
||||
self.images = self._process_images(images)
|
||||
|
||||
# 更新狀態為已提交反饋
|
||||
self.update_status(
|
||||
SessionStatus.FEEDBACK_SUBMITTED, "已送出反饋,等待下次 MCP 調用"
|
||||
)
|
||||
# 進入下一步:等待中 → 已提交反饋
|
||||
self.next_step("已送出反饋,等待下次 MCP 調用")
|
||||
|
||||
self.feedback_completed.set()
|
||||
|
||||
|
@ -157,6 +157,41 @@ def setup_routes(manager: "WebUIManager"):
|
||||
}
|
||||
)
|
||||
|
||||
@manager.app.get("/api/all-sessions")
|
||||
async def get_all_sessions():
|
||||
"""獲取所有會話的實時狀態"""
|
||||
try:
|
||||
sessions_data = []
|
||||
|
||||
# 獲取所有會話的實時狀態
|
||||
for session_id, session in manager.sessions.items():
|
||||
session_info = {
|
||||
"session_id": session.session_id,
|
||||
"project_directory": session.project_directory,
|
||||
"summary": session.summary,
|
||||
"status": session.status.value,
|
||||
"status_message": session.status_message,
|
||||
"created_at": int(session.created_at * 1000), # 轉換為毫秒
|
||||
"last_activity": int(session.last_activity * 1000),
|
||||
"feedback_completed": session.feedback_completed.is_set(),
|
||||
"has_websocket": session.websocket is not None,
|
||||
"is_current": session == manager.current_session
|
||||
}
|
||||
sessions_data.append(session_info)
|
||||
|
||||
# 按創建時間排序(最新的在前)
|
||||
sessions_data.sort(key=lambda x: x["created_at"], reverse=True)
|
||||
|
||||
debug_log(f"返回 {len(sessions_data)} 個會話的實時狀態")
|
||||
return JSONResponse(content={"sessions": sessions_data})
|
||||
|
||||
except Exception as e:
|
||||
debug_log(f"獲取所有會話狀態失敗: {e}")
|
||||
return JSONResponse(
|
||||
status_code=500,
|
||||
content={"error": f"獲取會話狀態失敗: {e!s}"}
|
||||
)
|
||||
|
||||
@manager.app.websocket("/ws")
|
||||
async def websocket_endpoint(websocket: WebSocket):
|
||||
"""WebSocket 端點 - 重構後移除 session_id 依賴"""
|
||||
|
@ -686,7 +686,7 @@
|
||||
|
||||
// 檢查是否是新會話創建的通知
|
||||
if (data.action === 'new_session_created') {
|
||||
console.log('🆕 檢測到新會話創建,準備刷新頁面顯示新內容');
|
||||
console.log('🆕 檢測到新會話創建,完全刷新頁面以確保狀態同步');
|
||||
|
||||
// 播放音效通知
|
||||
if (this.audioManager) {
|
||||
@ -699,9 +699,9 @@
|
||||
window.MCPFeedback.Utils.CONSTANTS.MESSAGE_SUCCESS
|
||||
);
|
||||
|
||||
// 延遲一小段時間讓用戶看到通知,然後刷新頁面
|
||||
// 延遲一小段時間讓用戶看到通知,然後完全刷新頁面
|
||||
setTimeout(function() {
|
||||
console.log('🔄 刷新頁面以顯示新會話內容');
|
||||
console.log('🔄 完全刷新頁面以顯示新會話內容');
|
||||
window.location.reload();
|
||||
}, 1500);
|
||||
|
||||
@ -831,7 +831,16 @@
|
||||
* 處理狀態更新(原始版本,供防抖使用)
|
||||
*/
|
||||
FeedbackApp.prototype._originalHandleStatusUpdate = function(statusInfo) {
|
||||
console.log('處理狀態更新:', statusInfo);
|
||||
console.log('📊 處理狀態更新:', statusInfo);
|
||||
|
||||
const sessionId = statusInfo.session_id;
|
||||
console.log('🔍 狀態更新詳情:', {
|
||||
currentSessionId: this.currentSessionId,
|
||||
newSessionId: sessionId,
|
||||
status: statusInfo.status,
|
||||
message: statusInfo.message,
|
||||
isNewSession: sessionId !== this.currentSessionId
|
||||
});
|
||||
|
||||
// 更新 SessionManager 的狀態資訊
|
||||
if (this.sessionManager && this.sessionManager.updateStatusInfo) {
|
||||
@ -844,43 +853,36 @@
|
||||
document.title = 'MCP Feedback - ' + projectName;
|
||||
}
|
||||
|
||||
// 提取會話 ID
|
||||
const sessionId = statusInfo.session_id || this.currentSessionId;
|
||||
// 使用之前已聲明的 sessionId
|
||||
|
||||
// 根據狀態更新 UI
|
||||
// 前端只管理會話ID,所有狀態都從服務器獲取
|
||||
console.log('📊 收到服務器狀態更新:', statusInfo.status, '會話ID:', sessionId);
|
||||
|
||||
// 更新當前會話ID
|
||||
if (sessionId) {
|
||||
this.currentSessionId = sessionId;
|
||||
console.log('🔄 更新當前會話ID:', sessionId.substring(0, 8) + '...');
|
||||
}
|
||||
|
||||
// 根據服務器狀態更新消息顯示(不修改前端狀態)
|
||||
switch (statusInfo.status) {
|
||||
case 'feedback_submitted':
|
||||
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_SUBMITTED, sessionId);
|
||||
const submittedMessage = window.i18nManager ? window.i18nManager.t('feedback.submittedWaiting') : '已送出反饋,等待下次 MCP 調用...';
|
||||
this.updateSummaryStatus(submittedMessage);
|
||||
break;
|
||||
|
||||
case 'active':
|
||||
case 'waiting':
|
||||
// 檢查是否是新會話
|
||||
if (sessionId && sessionId !== this.currentSessionId) {
|
||||
// 新會話:重置為等待狀態
|
||||
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, sessionId);
|
||||
} else {
|
||||
// 同一會話:保護已提交狀態,避免被覆蓋
|
||||
const currentState = this.uiManager.getFeedbackState();
|
||||
if (currentState !== window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_SUBMITTED) {
|
||||
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, sessionId);
|
||||
} else {
|
||||
console.log('🔒 保護已提交狀態,不重置為等待狀態');
|
||||
}
|
||||
}
|
||||
const waitingMessage = window.i18nManager ? window.i18nManager.t('feedback.waitingForUser') : '等待用戶回饋...';
|
||||
this.updateSummaryStatus(waitingMessage);
|
||||
|
||||
if (statusInfo.status === 'waiting') {
|
||||
const waitingMessage = window.i18nManager ? window.i18nManager.t('feedback.waitingForUser') : '等待用戶回饋...';
|
||||
this.updateSummaryStatus(waitingMessage);
|
||||
|
||||
// 檢查並啟動自動提交(如果條件滿足)
|
||||
const self = this;
|
||||
setTimeout(function() {
|
||||
self.checkAndStartAutoSubmit();
|
||||
}, 100); // 短暫延遲確保狀態更新完成
|
||||
}
|
||||
// 檢查並啟動自動提交(如果條件滿足)
|
||||
const self = this;
|
||||
setTimeout(function() {
|
||||
self.checkAndStartAutoSubmit();
|
||||
}, 100);
|
||||
break;
|
||||
case 'completed':
|
||||
const completedMessage = window.i18nManager ? window.i18nManager.t('feedback.completed') : '會話已完成';
|
||||
this.updateSummaryStatus(completedMessage);
|
||||
break;
|
||||
}
|
||||
};
|
||||
@ -923,10 +925,15 @@
|
||||
* 檢查是否可以提交回饋
|
||||
*/
|
||||
FeedbackApp.prototype.canSubmitFeedback = function() {
|
||||
return this.webSocketManager &&
|
||||
this.webSocketManager.isReady() &&
|
||||
this.uiManager &&
|
||||
this.uiManager.getFeedbackState() === window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING;
|
||||
// 簡化檢查:只檢查WebSocket連接,狀態由服務器端驗證
|
||||
const wsReady = this.webSocketManager && this.webSocketManager.isReady();
|
||||
|
||||
console.log('🔍 提交檢查:', {
|
||||
wsReady: wsReady,
|
||||
sessionId: this.currentSessionId
|
||||
});
|
||||
|
||||
return wsReady;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1203,14 +1210,9 @@
|
||||
FeedbackApp.prototype.handleSessionUpdate = function(sessionData) {
|
||||
console.log('🔄 處理自動檢測到的會話更新:', sessionData);
|
||||
|
||||
// 更新當前會話 ID
|
||||
// 只更新當前會話 ID,不管理狀態
|
||||
this.currentSessionId = sessionData.session_id;
|
||||
|
||||
// 重置回饋狀態
|
||||
if (this.uiManager) {
|
||||
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, sessionData.session_id);
|
||||
}
|
||||
|
||||
// 局部更新頁面內容
|
||||
this.refreshPageContent();
|
||||
};
|
||||
@ -1233,9 +1235,17 @@
|
||||
.then(function(sessionData) {
|
||||
console.log('📥 獲取到最新會話資料:', sessionData);
|
||||
|
||||
// 重置回饋狀態
|
||||
// 檢查並保護已提交狀態
|
||||
if (sessionData.session_id && self.uiManager) {
|
||||
self.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, sessionData.session_id);
|
||||
const currentState = self.uiManager.getFeedbackState();
|
||||
if (currentState !== window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_SUBMITTED) {
|
||||
self.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, sessionData.session_id);
|
||||
console.log('🔄 局部更新:重置回饋狀態為等待中');
|
||||
} else {
|
||||
console.log('🔒 局部更新:保護已提交狀態,不重置');
|
||||
// 只更新會話ID,保持已提交狀態
|
||||
self.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_SUBMITTED, sessionData.session_id);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新 AI 摘要內容
|
||||
|
@ -62,9 +62,13 @@
|
||||
if (this.currentSession && this.currentSession.session_id) {
|
||||
console.log('📊 檢測到會話 ID 變更,處理舊會話:', this.currentSession.session_id, '->', sessionData.session_id);
|
||||
|
||||
// 將舊會話標記為完成並加入歷史記錄
|
||||
// 將舊會話加入歷史記錄,保持其原有狀態
|
||||
const oldSession = Object.assign({}, this.currentSession);
|
||||
oldSession.status = 'completed';
|
||||
|
||||
// 完全保持舊會話的原有狀態,不做任何修改
|
||||
// 讓服務器端負責狀態轉換,前端只負責顯示
|
||||
console.log('📊 保持舊會話的原有狀態:', oldSession.status);
|
||||
|
||||
oldSession.completed_at = TimeUtils.getCurrentTimestamp();
|
||||
|
||||
// 計算持續時間
|
||||
@ -589,23 +593,25 @@
|
||||
};
|
||||
|
||||
/**
|
||||
* 從伺服器載入會話歷史
|
||||
* 從伺服器載入會話歷史(包含實時狀態)
|
||||
*/
|
||||
SessionDataManager.prototype.loadFromServer = function() {
|
||||
const self = this;
|
||||
|
||||
fetch('/api/load-session-history')
|
||||
// 首先嘗試獲取實時會話狀態
|
||||
fetch('/api/all-sessions')
|
||||
.then(function(response) {
|
||||
if (response.ok) {
|
||||
return response.json();
|
||||
} else {
|
||||
throw new Error('伺服器回應錯誤: ' + response.status);
|
||||
throw new Error('獲取實時會話狀態失敗: ' + response.status);
|
||||
}
|
||||
})
|
||||
.then(function(data) {
|
||||
if (data && Array.isArray(data.sessions)) {
|
||||
// 使用實時會話狀態
|
||||
self.sessionHistory = data.sessions;
|
||||
console.log('📊 從伺服器載入', self.sessionHistory.length, '個會話');
|
||||
console.log('📊 從伺服器載入', self.sessionHistory.length, '個實時會話狀態');
|
||||
|
||||
// 載入完成後進行清理和統計更新
|
||||
self.cleanupExpiredSessions();
|
||||
@ -621,13 +627,53 @@
|
||||
self.onDataChanged();
|
||||
}
|
||||
} else {
|
||||
console.warn('📊 伺服器回應格式錯誤:', data);
|
||||
self.sessionHistory = [];
|
||||
console.warn('📊 實時會話狀態回應格式錯誤,回退到歷史文件');
|
||||
self.loadFromHistoryFile();
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.warn('📊 獲取實時會話狀態失敗,回退到歷史文件:', error);
|
||||
self.loadFromHistoryFile();
|
||||
});
|
||||
};
|
||||
|
||||
// 即使沒有資料也要更新統計
|
||||
/**
|
||||
* 從歷史文件載入會話數據(備用方案)
|
||||
*/
|
||||
SessionDataManager.prototype.loadFromHistoryFile = function() {
|
||||
const self = this;
|
||||
|
||||
fetch('/api/load-session-history')
|
||||
.then(function(response) {
|
||||
if (response.ok) {
|
||||
return response.json();
|
||||
} else {
|
||||
throw new Error('伺服器回應錯誤: ' + response.status);
|
||||
}
|
||||
})
|
||||
.then(function(data) {
|
||||
if (data && Array.isArray(data.sessions)) {
|
||||
self.sessionHistory = data.sessions;
|
||||
console.log('📊 從歷史文件載入', self.sessionHistory.length, '個會話');
|
||||
|
||||
// 載入完成後進行清理和統計更新
|
||||
self.cleanupExpiredSessions();
|
||||
self.updateStats();
|
||||
|
||||
// 觸發歷史記錄變更回調
|
||||
if (self.onHistoryChange) {
|
||||
self.onHistoryChange(self.sessionHistory);
|
||||
}
|
||||
|
||||
// 觸發資料變更回調
|
||||
if (self.onDataChanged) {
|
||||
self.onDataChanged();
|
||||
}
|
||||
} else {
|
||||
console.warn('📊 歷史文件回應格式錯誤:', data);
|
||||
self.sessionHistory = [];
|
||||
self.updateStats();
|
||||
|
||||
// 觸發歷史記錄變更回調(空列表)
|
||||
if (self.onHistoryChange) {
|
||||
self.onHistoryChange(self.sessionHistory);
|
||||
}
|
||||
@ -638,13 +684,10 @@
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.warn('📊 從伺服器載入會話歷史失敗:', error);
|
||||
console.warn('📊 從歷史文件載入失敗:', error);
|
||||
self.sessionHistory = [];
|
||||
|
||||
// 載入失敗時也要更新統計
|
||||
self.updateStats();
|
||||
|
||||
// 觸發歷史記錄變更回調(空列表)
|
||||
if (self.onHistoryChange) {
|
||||
self.onHistoryChange(self.sessionHistory);
|
||||
}
|
||||
|
@ -486,9 +486,18 @@
|
||||
|
||||
// 狀態徽章
|
||||
const statusContainer = DOMUtils.createElement('div', { className: 'session-status' });
|
||||
const statusText = StatusUtils.getStatusText(sessionData.status);
|
||||
|
||||
// 添加調試信息
|
||||
console.log('🎨 會話狀態調試:', {
|
||||
sessionId: sessionData.session_id ? sessionData.session_id.substring(0, 8) + '...' : 'unknown',
|
||||
rawStatus: sessionData.status,
|
||||
displayText: statusText
|
||||
});
|
||||
|
||||
const statusBadge = DOMUtils.createElement('span', {
|
||||
className: 'status-badge ' + (sessionData.status || 'waiting'),
|
||||
textContent: StatusUtils.getStatusText(sessionData.status)
|
||||
textContent: statusText
|
||||
});
|
||||
|
||||
statusContainer.appendChild(statusBadge);
|
||||
|
@ -47,7 +47,7 @@
|
||||
'waiting_for_feedback': 'connectionMonitor.waiting',
|
||||
'active': 'status.processing.title',
|
||||
'feedback_submitted': 'status.submitted.title',
|
||||
'completed': 'status.submitted.title',
|
||||
'completed': 'status.completed.title',
|
||||
'timeout': 'session.timeout',
|
||||
'error': 'status.error',
|
||||
'expired': 'session.timeout',
|
||||
|
Loading…
x
Reference in New Issue
Block a user