Update: Basic Functions of chat.html 75% maybe

This commit is contained in:
XOF
2025-11-28 00:08:25 +08:00
parent 166437c0ac
commit 0839ec35a2
17 changed files with 3962 additions and 785 deletions

View File

@@ -8,47 +8,118 @@
<!-- =================================================================== -->
<!-- 1. 左侧栏: 会话列表 -->
<!-- =================================================================== -->
<!-- =================================================================== -->
<!-- 1. 左侧栏: 会话列表 (包含新的设置面板) -->
<!-- =================================================================== -->
<aside class="w-[280px] h-full flex flex-col border-r border-border bg-muted/50 shrink-0">
<!-- 侧边栏头部 -->
<div class="p-4 border-b border-border shrink-0">
<div class="flex items-center justify-between">
<h2 class="text-xl font-bold tracking-tight">会话</h2>
<button class="btn btn-ghost btn-icon btn-sm" aria-label="新建会话">
<button id="new-session-btn" class="btn btn-ghost btn-icon btn-sm" aria-label="新建会话">
<i class="fas fa-plus"></i>
</button>
</div>
<div class="relative mt-4">
<i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground"></i>
<input class="input h-9 pl-10" placeholder="搜索会话...">
<input id="session-search-input" class="input h-9 pl-10" placeholder="搜索会话...">
</div>
</div>
<!-- 会话列表 (可滚动) -->
<div class="flex-grow overflow-y-auto main-content-scroll p-2">
<!-- 示例会话 1: 激活状态 -->
<a href="#" class="flex flex-col items-start gap-2 rounded-lg p-3 text-left text-sm transition-all hover:bg-accent bg-accent">
<div class="flex w-full items-center justify-between">
<div class="font-semibold">关于Python异步编程</div>
<div class="ml-auto text-xs text-muted-foreground">3:15 PM</div>
<div id="session-list-container" class="flex-grow overflow-y-auto main-content-scroll p-2">
<!-- Session items will be dynamically inserted here by JavaScript -->
</div>
<!-- 设置面板区域: 相对定位上下文 -->
<div class="shrink-0 p-2 border-t border-border relative">
<!-- 快速设置面板: 绝对定位 -->
<div id="quick-settings-panel"
class="absolute bottom-full left-2 right-2 mb-2 p-3 bg-background border border-border rounded-lg shadow-lg grid grid-rows-[0] transition-all duration-300 ease-in-out overflow-hidden invisible data-[expanded=true]:visible data-[expanded=true]:grid-rows-[1]">
<div class="min-h-0 space-y-4">
<div class="space-y-2"><label class="text-sm font-medium">路由模式</label><div class="btn-group grid grid-cols-2 gap-px rounded-md border border-border overflow-hidden"><button data-group="routing-mode" data-value="smart" class="btn-group-item px-3 py-1.5 text-sm bg-background hover:bg-muted focus:relative data-[active=true]:bg-primary data-[active=true]:text-primary-foreground" data-active="true">智能聚合</button><button data-group="routing-mode" data-value="direct" class="btn-group-item px-3 py-1.5 text-sm bg-background hover:bg-muted focus:relative data-[active=true]:bg-primary data-[active=true]:text-primary-foreground">精准路由</button></div></div>
<div id="direct-routing-options" class="hidden space-y-2">
<label class="text-sm font-medium">选择群组</label>
<div id="group-select-container" class="custom-select-v2">
<!-- 1. The trigger button -->
<button class="custom-select-trigger btn btn-secondary btn-sm w-full justify-between">
<span></span> <!-- Text will be populated by JS -->
<i class="fas fa-chevron-down text-xs"></i>
</button>
<!-- 2. The hidden native select for state management -->
<select id="group-select" class="hidden">
<option value="group-a">默认群组</option>
<option value="group-b">测试群组</option>
</select>
<!-- 3. The template for the dropdown panel -->
<template class="custom-select-panel-template">
<div class="custom-select-panel z-50 w-[var(--radix-popper-anchor-width)] bg-background border border-border rounded-md shadow-lg p-1">
<!-- Options will be populated by JS -->
</div>
</template>
</div>
</div>
<div class="text-xs text-muted-foreground line-clamp-2">好的,我明白了。所以 aiohttp 客户端的 session 应该在...</div>
</a>
<!-- 示例会话 2: 非激活状态 -->
<a href="#" class="flex flex-col items-start gap-2 rounded-lg p-3 text-left text-sm transition-all hover:bg-accent">
<div class="flex w-full items-center justify-between">
<div class="font-semibold">Tailwind v4 迁移指南</div>
<div class="ml-auto text-xs text-muted-foreground">1:45 PM</div>
<div class="space-y-2"><label class="text-sm font-medium">接口方式</label><div class="btn-group grid grid-cols-2 gap-px rounded-md border border-border overflow-hidden"><button data-group="api-interface" data-value="gemini" class="btn-group-item px-3 py-1.5 text-sm bg-background hover:bg-muted focus:relative data-[active=true]:bg-primary data-[active=true]:text-primary-foreground" data-active="true">Gemini</button><button data-group-api-interface="api-interface" data-value="openai" class="btn-group-item px-3 py-1.5 text-sm bg-background hover:bg-muted focus:relative data-[active=true]:bg-primary data-[active=true]:text-primary-foreground">OpenAI</button></div></div>
<div class="space-y-2">
<label class="text-sm font-medium">模型选择</label>
<div id="model-select-container" class="custom-select-v2">
<button id="model-select-btn" class="custom-select-trigger btn btn-secondary btn-sm w-full justify-between">
<span>gemini-1.5-flash</span>
<i class="fas fa-chevron-down text-xs"></i>
</button>
<select id="model-select" class="hidden">
<!-- Options to be added later -->
</select>
<template class="custom-select-panel-template">
<div class="custom-select-panel z-50 w-[var(--radix-popper-anchor-width)] bg-background border border-border rounded-md shadow-lg p-1"></div>
</template>
</div>
</div>
</div>
<div class="text-xs text-muted-foreground line-clamp-2">我们已经成功解决了 JIT 编译器的缓存和 HSL 函数的问题...</div>
</a>
<!-- 示例会话 3: 非激活状态 -->
<a href="#" class="flex flex-col items-start gap-2 rounded-lg p-3 text-left text-sm transition-all hover:bg-accent">
<div class="flex w-full items-center justify-between">
<div class="font-semibold">数据库性能优化</div>
<div class="ml-auto text-xs text-muted-foreground">昨天</div>
</div>
<!-- 会话参数面板: 绝对定位 -->
<div id="session-params-panel"
class="absolute bottom-full left-2 right-2 mb-2 p-3 bg-background border border-border rounded-lg shadow-lg grid grid-rows-[0] transition-all duration-300 ease-in-out overflow-hidden invisible data-[expanded=true]:visible data-[expanded=true]:grid-rows-[1]">
<div class="min-h-0 space-y-4">
<!-- [MODIFIED] Replaced switches with a pure Tailwind CSS component -->
<div class="flex items-center justify-between">
<label for="streaming-toggle" class="text-sm font-medium">流式输出</label>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" id="streaming-toggle" class="sr-only peer" checked>
<div class="w-11 h-6 bg-muted rounded-full peer peer-focus:ring-2 peer-focus:ring-primary/50 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-border after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
</label>
</div>
<div class="flex items-center justify-between">
<label for="thinking-toggle" class="text-sm font-medium">模型思考</label>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" id="thinking-toggle" class="sr-only peer" checked>
<div class="w-11 h-6 bg-muted rounded-full peer peer-focus:ring-2 peer-focus:ring-primary/50 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-border after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
</label>
</div>
<div class="space-y-2">
<div class="flex justify-between items-center">
<label for="temperature-slider" class="text-sm font-medium">温度</label>
<span id="temperature-value" class="text-sm font-mono text-muted-foreground">0.7</span>
</div>
<input id="temperature-slider" type="range" min="0" max="2" value="0.7" step="0.1" class="slider w-full">
</div>
<div class="space-y-2">
<div class="flex justify-between items-center">
<label for="context-slider" class="text-sm font-medium">上下文</label>
<span id="context-value" class="text-sm font-mono text-muted-foreground">5k</span>
</div>
<input id="context-slider" type="range" min="0" max="25" value="5" step="1" class="slider w-full">
</div>
</div>
<div class="text-xs text-muted-foreground line-clamp-2">索引的创建确实是关键,特别是在有大量 JOIN 操作的查询中。</div>
</a>
</div>
<!-- 底部触发按钮 -->
<div class="flex items-center justify-center gap-2 mt-2">
<button id="toggle-quick-settings" class="btn btn-ghost btn-icon data-[active=true]:bg-muted data-[active=true]:text-accent-foreground" title="快速设置"><i class="fas fa-cog"></i></button>
<button id="toggle-session-params" class="btn btn-ghost btn-icon data-[active=true]:bg-muted data-[active=true]:text-accent-foreground" title="会话参数"><i class="fas fa-sliders-h"></i></button>
</div>
</div>
</aside>
@@ -58,9 +129,9 @@
<main class="flex-1 flex flex-col h-full">
<!-- 聊天窗口头部 -->
<div class="flex items-center p-4 border-b border-border shrink-0">
<h3 class="text-lg font-semibold">关于Python异步编程</h3>
<h3 class="text-lg font-semibold chat-header-title">新会话</h3>
<div class="ml-auto flex items-center gap-2">
<button class="btn btn-ghost btn-icon btn-sm" aria-label="清除会话">
<button id="clear-session-btn" class="btn btn-ghost btn-icon btn-sm" aria-label="清除会话">
<i class="fas fa-eraser"></i>
</button>
<button class="btn btn-ghost btn-icon btn-sm" aria-label="更多选项">
@@ -70,48 +141,31 @@
</div>
<!-- 消息区域 (可滚动) -->
<div class="flex-grow p-6 overflow-y-auto main-content-scroll">
<div class="space-y-6">
<!-- 示例消息 1: 用户 -->
<div class="flex items-start gap-4">
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-secondary text-secondary-foreground">
<i class="fas fa-user"></i>
</span>
<div class="flex-1 space-y-2">
<div class="rounded-lg bg-muted p-3">
<p class="text-sm text-foreground">你能给我解释一下 aiohttp 客户端的 session 和 connector 管理吗?我总是搞不清楚什么时候应该创建,什么时候应该关闭。</p>
</div>
</div>
</div>
<!-- 示例消息 2: 助手 (Gemini) -->
<div class="flex items-start gap-4">
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground">
<i class="fas fa-robot"></i>
</span>
<div class="flex-1 space-y-2">
<div class="rounded-lg bg-primary/10 border border-primary/20 p-3">
<p class="text-sm text-foreground">当然可以。这是一个非常经典的问题。简单来说,`ClientSession` 应该在你的应用程序的生命周期内尽可能地保持单例存在...</p>
</div>
</div>
</div>
<div class="flex-grow p-6 overflow-y-auto main-content-scroll" id="chat-scroll-container">
<div class="space-y-6" id="chat-messages-container">
<!--fill with js -->
</div>
</div>
<!-- 输入区域 -->
<div class="p-4 border-t border-border shrink-0 bg-background">
<div class="relative">
<textarea placeholder="输入消息..." class="input pr-20 resize-none" rows="1"></textarea>
<div class="absolute top-1/2 right-3 -translate-y-1/2 flex items-center gap-2">
<button class="btn btn-ghost btn-icon btn-sm" aria-label="附加文件">
<i class="fas fa-paperclip"></i>
<form id="message-form" class="relative">
<textarea id="message-input" placeholder="输入消息..." class="input w-full min-h-14 pr-24 resize-none overflow-y-hidden" rows="1"></textarea>
<div class="absolute bottom-2 right-2 flex items-center gap-2">
<button type="button" class="btn btn-ghost btn-icon btn-sm" aria-label="附加文件" title="此功能将在未来版本中提供">
<i class="fas fa-paperclip text-muted-foreground/60"></i>
</button>
<button type="submit" id="send-btn" class="btn btn-primary btn-icon w-9 h-9 shrink-0 rounded-full bg-green-500 hover:bg-green-600 dark:bg-green-600 dark:hover:bg-green-700 disabled:bg-green-500/50">
<i class="fas fa-arrow-up text-white dark:text-black"></i>
</button>
<button class="btn btn-primary btn-sm">发送</button>
</div>
</div>
</form>
</div>
</main>
</div>
{% endblock %}
{% block page_scripts %}
{% endblock page_scripts %}