fix: 修复极简模式多个问题并恢复偏好设置自动应用

- 修复极简模式下步骤竖线距离SVG不均匀的问题
  - 使用flex布局让竖线自动填充空间
  - 添加负margin让竖线延伸到下一个步骤
  - 确保竖线上下距离SVG图标相等

- 修复SVG图标颜色问题
  - 统一使用灰色(--claude-text-tertiary)
  - 不再受颜色模式影响

- 修复思考内容自动滚动问题
  - 添加registerThinkingRef和handleThinkingScroll支持
  - 移除导致滚动异常的伪元素负margin
  - 实现与堆叠模式一致的自动滚动行为

- 修复轮询改造后偏好设置不自动应用的问题
  - 在loadInitialData中应用默认模型和运行模式
  - 在createNewConversation前应用偏好设置
  - 在loadConversation前应用偏好设置
  - 确保新建或切换对话时使用用户设置的默认值

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
JOJO 2026-04-04 16:18:15 +08:00
parent a030ff954b
commit c26cd3d3fd
4 changed files with 111 additions and 16 deletions

View File

@ -179,6 +179,36 @@ export const conversationMethods = {
return; return;
} }
// 应用个性化设置中的默认模型和思考模式
try {
const { usePersonalizationStore } = await import('../../stores/personalization');
const personalizationStore = usePersonalizationStore();
if (personalizationStore.loaded) {
const defaultRunMode = personalizationStore.form.default_run_mode;
const defaultModel = personalizationStore.form.default_model;
if (defaultRunMode) {
this.runMode = defaultRunMode;
debugLog('应用默认运行模式:', defaultRunMode);
}
if (defaultModel) {
this.currentModelKey = defaultModel;
debugLog('应用默认模型:', defaultModel);
}
// 根据默认运行模式设置思考模式
if (defaultRunMode === 'thinking') {
this.thinkingMode = true;
} else if (defaultRunMode === 'fast') {
this.thinkingMode = false;
}
}
} catch (error) {
console.warn('应用个性化默认设置失败:', error);
}
// 有任务或后台子智能体运行时,提示用户确认切换 // 有任务或后台子智能体运行时,提示用户确认切换
try { try {
const { useTaskStore } = await import('../../stores/task'); const { useTaskStore } = await import('../../stores/task');
@ -294,6 +324,36 @@ export const conversationMethods = {
}); });
this.logMessageState('createNewConversation:start'); this.logMessageState('createNewConversation:start');
// 应用个性化设置中的默认模型和思考模式
try {
const { usePersonalizationStore } = await import('../../stores/personalization');
const personalizationStore = usePersonalizationStore();
if (personalizationStore.loaded) {
const defaultRunMode = personalizationStore.form.default_run_mode;
const defaultModel = personalizationStore.form.default_model;
if (defaultRunMode) {
this.runMode = defaultRunMode;
debugLog('应用默认运行模式:', defaultRunMode);
}
if (defaultModel) {
this.currentModelKey = defaultModel;
debugLog('应用默认模型:', defaultModel);
}
// 根据默认运行模式设置思考模式
if (defaultRunMode === 'thinking') {
this.thinkingMode = true;
} else if (defaultRunMode === 'fast') {
this.thinkingMode = false;
}
}
} catch (error) {
console.warn('应用个性化默认设置失败:', error);
}
// 检查是否有运行中的任务,如果有则提示用户 // 检查是否有运行中的任务,如果有则提示用户
let hasActiveTask = false; let hasActiveTask = false;
try { try {

View File

@ -1118,11 +1118,34 @@ export const uiMethods = {
// 加载个性化设置 // 加载个性化设置
const personalizationStore = usePersonalizationStore(); const personalizationStore = usePersonalizationStore();
if (!personalizationStore.loaded && !personalizationStore.loading) { if (!personalizationStore.loaded && !personalizationStore.loading) {
personalizationStore.fetchPersonalization().catch(err => { await personalizationStore.fetchPersonalization().catch(err => {
console.warn('加载个性化设置失败:', err); console.warn('加载个性化设置失败:', err);
}); });
} }
// 应用个性化设置中的默认模型和思考模式
if (personalizationStore.loaded) {
const defaultRunMode = personalizationStore.form.default_run_mode;
const defaultModel = personalizationStore.form.default_model;
if (defaultRunMode) {
this.runMode = defaultRunMode;
debugLog('应用默认运行模式:', defaultRunMode);
}
if (defaultModel) {
this.currentModelKey = defaultModel;
debugLog('应用默认模型:', defaultModel);
}
// 根据默认运行模式设置思考模式
if (defaultRunMode === 'thinking') {
this.thinkingMode = true;
} else if (defaultRunMode === 'fast') {
this.thinkingMode = false;
}
}
const focusPromise = this.focusFetchFiles(); const focusPromise = this.focusFetchFiles();
const todoPromise = this.fileFetchTodoList(); const todoPromise = this.fileFetchTodoList();
let treePromise: Promise<any> | null = null; let treePromise: Promise<any> | null = null;

View File

@ -60,6 +60,8 @@
:format-search-time="formatSearchTime" :format-search-time="formatSearchTime"
:format-search-domains="formatSearchDomains" :format-search-domains="formatSearchDomains"
:render-markdown="renderMarkdown" :render-markdown="renderMarkdown"
:register-thinking-ref="registerThinkingRef"
:handle-thinking-scroll="props.handleThinkingScroll"
/> />
</template> </template>
<template v-else-if="stackedBlocksEnabled"> <template v-else-if="stackedBlocksEnabled">

View File

@ -43,7 +43,12 @@
</div> </div>
<div class="step-content"> <div class="step-content">
<div v-if="step.type === 'thinking'" class="step-body"> <div v-if="step.type === 'thinking'" class="step-body">
<div class="thinking-content" v-html="renderContent(step.content)"></div> <div
class="thinking-content"
:ref="el => registerThinking(step.id, el)"
@scroll="handleScroll(step.id, $event)"
v-html="renderContent(step.content)"
></div>
</div> </div>
<div v-else-if="step.type === 'tool'" class="step-body"> <div v-else-if="step.type === 'tool'" class="step-body">
<div class="step-header">{{ getToolName(step.action) }}</div> <div class="step-header">{{ getToolName(step.action) }}</div>
@ -117,6 +122,8 @@ const props = defineProps<{
formatSearchTime?: (filters: Record<string, any>) => string; formatSearchTime?: (filters: Record<string, any>) => string;
formatSearchDomains?: (filters: Record<string, any>) => string; formatSearchDomains?: (filters: Record<string, any>) => string;
renderMarkdown?: (content: string, isStreaming: boolean) => string; renderMarkdown?: (content: string, isStreaming: boolean) => string;
registerThinkingRef?: (key: string, el: Element | null) => void;
handleThinkingScroll?: (blockId: string, event: Event) => void;
}>(); }>();
const personalizationStore = usePersonalizationStore(); const personalizationStore = usePersonalizationStore();
@ -330,6 +337,18 @@ const escapeHtml = (text: string) => {
return div.innerHTML; return div.innerHTML;
}; };
const registerThinking = (key: string, el: Element | null) => {
if (typeof props.registerThinkingRef === 'function') {
props.registerThinkingRef(key, el);
}
};
const handleScroll = (blockId: string, event: Event) => {
if (typeof props.handleThinkingScroll === 'function') {
props.handleThinkingScroll(blockId, event);
}
};
watch(() => props.actions, () => { watch(() => props.actions, () => {
// //
}, { deep: true }); }, { deep: true });
@ -461,17 +480,21 @@ watch(() => props.actions, () => {
align-items: center; align-items: center;
flex-shrink: 0; flex-shrink: 0;
padding-top: 2px; padding-top: 2px;
align-self: stretch; /* 填充整个 step-item 的高度 */
} }
.step-icon { .step-icon {
flex-shrink: 0; flex-shrink: 0;
color: var(--claude-text-tertiary); /* 和竖线、字体一样的灰色 */
} }
.step-line { .step-line {
width: 2px; width: 2px;
flex: 1; flex: 1; /* 自动填充剩余空间 */
background: var(--claude-border); background: var(--claude-border);
margin-top: 4px; margin-top: 4px;
margin-bottom: -14px; /* 延伸到下一个 step-item保持上下距离 SVG 相等 */
flex-shrink: 0;
} }
/* 最后一个步骤隐藏竖线 */ /* 最后一个步骤隐藏竖线 */
@ -511,22 +534,9 @@ watch(() => props.actions, () => {
overflow-y: auto; overflow-y: auto;
margin: 0; margin: 0;
padding: 0; padding: 0;
/* 让第一行文字紧贴顶部 */
display: block; display: block;
} }
.thinking-content::before {
content: '';
display: block;
margin-top: calc((1.7em - 1em) / -2);
}
.thinking-content::after {
content: '';
display: block;
margin-bottom: calc((1.7em - 1em) / -2);
}
/* 工具内容 */ /* 工具内容 */
.step-header { .step-header {
font-size: 12px; font-size: 12px;