- 修复运行时 intent Unicode 转义显示异常(后端 extract_intent_from_partial 解码) - 修复 ask_user 弹窗问题/说明不换行 - 修复刷新页面后等待回答提示不恢复(添加 fetchPendingUserQuestions 并在初始化路径调用) - 修复回答问题弹窗长问题撑满窗口(header/context 限高滚动) - 修复角色编辑器模型选择菜单定位与滚动 - 在 AGENTS.md 中再次强调前端调试日志必须统一筛选词 测试:/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/bin/python3.9 -m unittest test.test_server_refactor_smoke; npm run build
144 lines
5.2 KiB
TypeScript
144 lines
5.2 KiB
TypeScript
// @ts-nocheck
|
|
import { useChatActionStore } from '../stores/chatActions';
|
|
import { normalizeScrollLock } from '../composables/useScrollControl';
|
|
import { setupShowImageObserver, teardownShowImageObserver } from './bootstrap';
|
|
import { debugLog } from './methods/common';
|
|
|
|
export function created() {
|
|
const actionStore = useChatActionStore();
|
|
actionStore.registerDependencies({
|
|
pushToast: (payload) => this.uiPushToast(payload),
|
|
autoResizeInput: () => this.autoResizeInput(),
|
|
focusComposer: () => {
|
|
const inputEl = this.getComposerElement('stadiumInput');
|
|
if (inputEl && typeof inputEl.focus === 'function') {
|
|
inputEl.focus();
|
|
}
|
|
},
|
|
isConnected: () => this.isConnected,
|
|
executeCommand: async (command) => this.executeSystemCommand(command, { showToast: false }),
|
|
downloadResource: (url, filename) => this.downloadResource(url, filename)
|
|
});
|
|
}
|
|
|
|
export async function mounted() {
|
|
debugLog('Vue应用已挂载');
|
|
console.log('[DEBUG_SYSTEM][boot] 前端调试版本已加载 2026-04-05');
|
|
if (window.ensureCsrfToken) {
|
|
window.ensureCsrfToken().catch((err) => {
|
|
console.warn('CSRF token 初始化失败:', err);
|
|
});
|
|
}
|
|
// 并行启动路由解析与初始化数据,网页端不再依赖 WebSocket 初始化
|
|
const routePromise = this.bootstrapRoute();
|
|
await routePromise;
|
|
this.$nextTick(() => {
|
|
this.ensureScrollListener();
|
|
// 刷新后若无输出,自动解锁滚动锁定
|
|
normalizeScrollLock(this);
|
|
});
|
|
setupShowImageObserver();
|
|
|
|
// 立即加载初始数据(并行获取状态,优先同步运行模式)
|
|
const initialDataPromise = this.loadInitialData();
|
|
this.startProjectGitSummaryIdleRefresh?.();
|
|
this.startConnectionHeartbeat();
|
|
this.fetchTerminalCount();
|
|
this.startTerminalCountIdleRefresh();
|
|
this.checkTutorialPrompt();
|
|
if (initialDataPromise && typeof initialDataPromise.then === 'function') {
|
|
initialDataPromise
|
|
.then(() => {
|
|
// 初始数据加载完成后再刷新 git 摘要,确保 workspace/project_path 已就绪
|
|
this.refreshProjectGitSummary?.();
|
|
// 避免在初始加载阶段被覆盖,加载完成后再兜底检查一次
|
|
this.checkTutorialPrompt();
|
|
})
|
|
.catch(() => {});
|
|
}
|
|
|
|
// 注册全局事件处理器(用于任务轮询)
|
|
(window as any).__taskEventHandler = (event: any) => {
|
|
if (typeof this.handleTaskEvent === 'function') {
|
|
this.handleTaskEvent(event);
|
|
}
|
|
};
|
|
|
|
// 立即尝试恢复运行中的任务(不延迟)
|
|
if (typeof this.restoreTaskState === 'function') {
|
|
this.restoreTaskState();
|
|
}
|
|
|
|
document.addEventListener('click', this.handleClickOutsideQuickMenu);
|
|
document.addEventListener('click', this.handleClickOutsidePanelMenu);
|
|
document.addEventListener('click', this.handleClickOutsideHeaderMenu);
|
|
document.addEventListener('click', this.handleClickOutsideMobileMenu);
|
|
document.addEventListener('click', this.handleCopyCodeClick);
|
|
window.addEventListener('popstate', this.handlePopState);
|
|
window.addEventListener('keydown', this.handleMobileOverlayEscape);
|
|
window.addEventListener('beforeunload', this.handleBeforeUnloadDraftPersist);
|
|
this.setupMobileViewportWatcher();
|
|
|
|
this.subAgentFetch();
|
|
this.subAgentStartPolling();
|
|
this.backgroundCommandFetch();
|
|
this.backgroundCommandStartPolling();
|
|
|
|
this.$nextTick(() => {
|
|
this.autoResizeInput();
|
|
});
|
|
this.resourceBindContainerVisibilityWatcher();
|
|
this.resourceStartContainerStatsPolling();
|
|
this.resourceStartProjectStoragePolling();
|
|
this.resourceStartUsageQuotaPolling();
|
|
|
|
// 设置拖拽上传
|
|
this.setupDragAndDrop();
|
|
}
|
|
|
|
export function beforeUnmount() {
|
|
if (this._todoRefreshTimer) {
|
|
clearTimeout(this._todoRefreshTimer);
|
|
this._todoRefreshTimer = null;
|
|
}
|
|
|
|
// 停止任务轮询
|
|
try {
|
|
const { useTaskStore } = require('../stores/task');
|
|
const taskStore = useTaskStore();
|
|
taskStore.stopPolling();
|
|
} catch (error) {
|
|
// ignore
|
|
}
|
|
|
|
document.removeEventListener('click', this.handleClickOutsideQuickMenu);
|
|
document.removeEventListener('click', this.handleClickOutsidePanelMenu);
|
|
document.removeEventListener('click', this.handleClickOutsideHeaderMenu);
|
|
document.removeEventListener('click', this.handleClickOutsideMobileMenu);
|
|
document.removeEventListener('click', this.handleCopyCodeClick);
|
|
window.removeEventListener('popstate', this.handlePopState);
|
|
window.removeEventListener('keydown', this.handleMobileOverlayEscape);
|
|
window.removeEventListener('beforeunload', this.handleBeforeUnloadDraftPersist);
|
|
this.teardownMobileViewportWatcher();
|
|
this.subAgentStopPolling();
|
|
this.backgroundCommandStopPolling();
|
|
this.stopProjectGitSummaryIdleRefresh?.();
|
|
this.stopTerminalCountIdleRefresh?.();
|
|
this.resourceStopContainerStatsPolling();
|
|
this.resourceStopProjectStoragePolling();
|
|
this.resourceStopUsageQuotaPolling();
|
|
this.stopConnectionHeartbeat();
|
|
teardownShowImageObserver();
|
|
|
|
// 移除拖拽上传监听
|
|
this.teardownDragAndDrop();
|
|
if (this.titleTypingTimer) {
|
|
clearInterval(this.titleTypingTimer);
|
|
this.titleTypingTimer = null;
|
|
}
|
|
const cleanup = this.destroyEasterEggEffect(true);
|
|
if (cleanup && typeof cleanup.catch === 'function') {
|
|
cleanup.catch(() => {});
|
|
}
|
|
}
|