fix: 优化浮动菜单位置计算与 token 处理
This commit is contained in:
parent
089291f77e
commit
11ffdc2bb5
@ -2301,32 +2301,52 @@ const updateFloatingMenuPosition = async () => {
|
|||||||
|
|
||||||
const padding = 16;
|
const padding = 16;
|
||||||
const gap = 10;
|
const gap = 10;
|
||||||
const menuHeight = menu?.getBoundingClientRect().height || 0;
|
|
||||||
let top: number;
|
// 测量单个选项高度,计算 4 选项固定 max-height
|
||||||
if (menuHeight > 0) {
|
const optionEl = menu?.querySelector<HTMLElement>('.settings-menu-option');
|
||||||
const spaceBelow = window.innerHeight - rect.bottom - padding;
|
const optionHeight = optionEl ? optionEl.getBoundingClientRect().height : 44;
|
||||||
const spaceAbove = rect.top - padding;
|
const menuPadding = 12; // menu padding 6px top + 6px bottom
|
||||||
if (spaceBelow >= menuHeight) {
|
const fixedMaxHeight = Math.round(optionHeight * 4) + menuPadding;
|
||||||
top = rect.bottom + gap;
|
|
||||||
} else if (spaceAbove >= menuHeight) {
|
// 先限制菜单高度为固定值,再次获取实际高度
|
||||||
top = rect.top - menuHeight - gap;
|
if (menu) {
|
||||||
} else if (spaceBelow >= spaceAbove) {
|
menu.style.maxHeight = `${fixedMaxHeight}px`;
|
||||||
// 下方空间相对更大:菜单贴底部,内容通过 max-height 滚动
|
|
||||||
top = Math.max(rect.bottom + gap, window.innerHeight - menuHeight - padding);
|
|
||||||
} else {
|
|
||||||
// 上方空间相对更大:菜单贴顶部
|
|
||||||
top = padding;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
top = Math.max(padding, Math.min(rect.bottom + gap, window.innerHeight - 80));
|
|
||||||
}
|
}
|
||||||
|
// 重新读取受限后的菜单高度
|
||||||
|
const menuHeight = menu?.getBoundingClientRect().height || fixedMaxHeight;
|
||||||
|
|
||||||
|
const spaceBelow = window.innerHeight - rect.bottom - padding;
|
||||||
|
const spaceAbove = rect.top - padding;
|
||||||
|
|
||||||
|
let top: number;
|
||||||
|
let maxHeight: number | undefined;
|
||||||
|
|
||||||
|
if (spaceBelow >= menuHeight) {
|
||||||
|
// 下方空间足够完整显示
|
||||||
|
top = rect.bottom + gap;
|
||||||
|
} else if (spaceAbove >= menuHeight) {
|
||||||
|
// 上方空间足够完整显示,翻转到上方
|
||||||
|
top = rect.top - menuHeight - gap;
|
||||||
|
} else if (spaceBelow >= spaceAbove) {
|
||||||
|
// 上下都不够,下方空间相对更大:限制高度到可用空间,贴按钮向下
|
||||||
|
const availableHeight = Math.max(80, spaceBelow - gap);
|
||||||
|
maxHeight = availableHeight;
|
||||||
|
top = rect.bottom + gap;
|
||||||
|
} else {
|
||||||
|
// 上方空间相对更大:限制高度到可用空间,翻转到上方
|
||||||
|
const availableHeight = Math.max(80, spaceAbove - gap);
|
||||||
|
maxHeight = availableHeight;
|
||||||
|
top = Math.max(padding, rect.top - availableHeight - gap);
|
||||||
|
}
|
||||||
|
|
||||||
floatingMenuStyle.value = {
|
floatingMenuStyle.value = {
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
top: `${Math.round(top)}px`,
|
top: `${Math.round(top)}px`,
|
||||||
left: `${Math.round(left)}px`,
|
left: `${Math.round(left)}px`,
|
||||||
right: 'auto',
|
right: 'auto',
|
||||||
width: `${Math.round(menuWidth)}px`,
|
width: `${Math.round(menuWidth)}px`,
|
||||||
zIndex: '2147483647'
|
zIndex: '2147483647',
|
||||||
|
...(maxHeight !== undefined ? { maxHeight: `${Math.round(maxHeight)}px` } : {})
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3713,8 +3733,9 @@ const applyDefaultHideWorkspaceOption = async (hidden: boolean) => {
|
|||||||
right: auto;
|
right: auto;
|
||||||
top: auto;
|
top: auto;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
max-height: min(420px, 60vh);
|
max-height: calc(44px * 4 + 12px);
|
||||||
overflow: auto;
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
background: var(--settings-floating-menu-bg);
|
background: var(--settings-floating-menu-bg);
|
||||||
|
|||||||
@ -144,17 +144,23 @@ class TokenMixin:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
success = self.conversation_manager.update_token_statistics(
|
# 路由到正确的 conversation_manager(与 get_conversation_token_statistics 一致)
|
||||||
|
# 多智能体对话 ID 存储在 multi_agent_conversation_manager 中,
|
||||||
|
# 直接使用 self.conversation_manager 会找不到对话导致统计写入失败
|
||||||
|
target_manager = getattr(
|
||||||
|
self, "_get_conversation_manager_for_id", lambda _: self.conversation_manager
|
||||||
|
)(self.current_conversation_id)
|
||||||
|
success = target_manager.update_token_statistics(
|
||||||
self.current_conversation_id,
|
self.current_conversation_id,
|
||||||
prompt_tokens,
|
prompt_tokens,
|
||||||
completion_tokens,
|
completion_tokens,
|
||||||
total_tokens,
|
total_tokens,
|
||||||
current_context_tokens=current_context_tokens,
|
current_context_tokens=current_context_tokens,
|
||||||
)
|
)
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
self.safe_broadcast_token_update()
|
self.safe_broadcast_token_update()
|
||||||
|
|
||||||
return success
|
return success
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"更新usage统计失败: {e}")
|
print(f"更新usage统计失败: {e}")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user