Compare commits

...

5 Commits

2 changed files with 74 additions and 17 deletions

View File

@@ -19,6 +19,7 @@ let isLoading = false;
// 功能开关 // 功能开关
let enableThinking = false; // 深度思考 let enableThinking = false; // 深度思考
let enableSearch = false; // 联网搜索 let enableSearch = false; // 联网搜索
let autoScrollEnabled = true; // 自动滚动(用户滚动后可关闭)
// DOM 元素(初始为 null在 openConversation 时重新获取) // DOM 元素(初始为 null在 openConversation 时重新获取)
let appContainer = null; let appContainer = null;
@@ -575,6 +576,12 @@ function openConversation(id) {
thinkingBtn = document.getElementById('thinkingBtn'); thinkingBtn = document.getElementById('thinkingBtn');
searchBtn = document.getElementById('searchBtn'); searchBtn = document.getElementById('searchBtn');
// 重置自动滚动状态
autoScrollEnabled = true;
// 设置滚动监听
setupScrollListener();
// 绑定按钮事件 // 绑定按钮事件
const backBtn = document.getElementById('backBtn'); const backBtn = document.getElementById('backBtn');
if (backBtn) backBtn.addEventListener('click', showConversationList); if (backBtn) backBtn.addEventListener('click', showConversationList);
@@ -739,6 +746,9 @@ async function sendMessage() {
currentConversation.updatedAt = Date.now(); currentConversation.updatedAt = Date.now();
saveConversations(); saveConversations();
// 发送新消息时启用自动滚动
autoScrollEnabled = true;
renderMessages(); renderMessages();
userInput.value = ''; userInput.value = '';
autoResize(userInput); autoResize(userInput);
@@ -927,7 +937,8 @@ async function streamGenerate(userMsgIndex) {
// 自动总结标题第一次对话和每隔5次对话 // 自动总结标题第一次对话和每隔5次对话
const totalMessages = currentConversation.messages.length; const totalMessages = currentConversation.messages.length;
if (totalMessages === 1 || totalMessages % 5 === 0) { // 第一次对话(用户+AI=2条或每5次对话10条
if (totalMessages === 2 || totalMessages % 10 === 0) {
await generateConversationTitle(); await generateConversationTitle();
} }
} }
@@ -1002,12 +1013,14 @@ function hideStopGenerateBtn() {
async function generateConversationTitle() { async function generateConversationTitle() {
if (!currentConversation) return; if (!currentConversation) return;
console.log('开始生成标题,当前消息数:', currentConversation.messages.length);
// 构建对话摘要 // 构建对话摘要
const conversationText = currentConversation.messages.map(m => const conversationText = currentConversation.messages.map(m =>
`${m.role === 'user' ? '用户' : 'AI'}: ${m.content.slice(0, 200)}` `${m.role === 'user' ? '用户' : 'AI'}: ${m.content.slice(0, 200)}`
).join('\n'); ).join('\n');
const titlePrompt = `请用不超过10个字总结以下对话的主题只输出标题不要其他内容 const titlePrompt = `请用不超过20个字总结以下对话的主题只输出标题不要其他内容
${conversationText}`; ${conversationText}`;
try { try {
@@ -1020,24 +1033,46 @@ ${conversationText}`;
body: JSON.stringify({ body: JSON.stringify({
model: CONFIG.model, model: CONFIG.model,
messages: [{ role: 'user', content: titlePrompt }], messages: [{ role: 'user', content: titlePrompt }],
max_tokens: 50 max_tokens: 100,
thinking: { type: 'disabled' } // 禁用思考模式,直接输出标题
}) })
}); });
console.log('标题API响应状态:', response.status);
if (response.ok) { if (response.ok) {
const data = await response.json(); const data = await response.json();
console.log('标题API响应数据:', data);
const newTitle = data.choices?.[0]?.message?.content?.trim(); const newTitle = data.choices?.[0]?.message?.content?.trim();
if (newTitle && newTitle.length > 0 && newTitle.length <= 15) { console.log('生成的标题:', newTitle);
currentConversation.title = newTitle;
if (newTitle && newTitle.length > 0) {
// 去掉可能的引号和多余符号
const cleanTitle = newTitle.replace(/^["'"']+|["'"']+$/g, '').trim();
if (cleanTitle.length > 0 && cleanTitle.length <= 30) {
currentConversation.title = cleanTitle;
currentConversation.updatedAt = Date.now(); currentConversation.updatedAt = Date.now();
saveConversations(); saveConversations();
console.log('标题已保存:', cleanTitle);
// 更新页面标题显示 // 更新页面标题显示
const titleEl = document.querySelector('.header h1'); const titleEl = document.querySelector('.header h1');
if (titleEl) { if (titleEl) {
titleEl.textContent = newTitle; titleEl.textContent = cleanTitle;
}
// 更新侧边栏标题(如果在对话列表页面)
const convItem = document.querySelector(`.conversation-item[data-id="${currentConversation.id}"] .conv-title`);
if (convItem) {
convItem.textContent = cleanTitle;
}
showToast('标题已更新');
} }
} }
} else {
const errorText = await response.text();
console.error('标题API错误:', errorText);
} }
} catch (error) { } catch (error) {
console.error('生成标题失败:', error); console.error('生成标题失败:', error);
@@ -1273,12 +1308,34 @@ function renderMarkdown(text) {
return marked.parse(text); return marked.parse(text);
} }
// 滚动到底部 // 滚动到底部(智能滚动:只在用户已在底部时自动滚动)
function scrollToBottom() { function scrollToBottom() {
if (messagesContainer) { if (messagesContainer) {
// 判断用户是否在底部附近距离底部100px以内
const isNearBottom = messagesContainer.scrollHeight - messagesContainer.scrollTop - messagesContainer.clientHeight < 100;
if (isNearBottom || autoScrollEnabled) {
messagesContainer.scrollTop = messagesContainer.scrollHeight; messagesContainer.scrollTop = messagesContainer.scrollHeight;
} }
} }
}
// 监听用户滚动行为
function setupScrollListener() {
if (messagesContainer) {
messagesContainer.addEventListener('scroll', () => {
// 判断用户是否在底部附近
const isNearBottom = messagesContainer.scrollHeight - messagesContainer.scrollTop - messagesContainer.clientHeight < 100;
if (isNearBottom) {
autoScrollEnabled = true;
} else {
// 用户往上滚动,停止自动滚动
autoScrollEnabled = false;
}
});
}
}
// 保存对话列表 // 保存对话列表
function saveConversations() { function saveConversations() {

View File

@@ -8,12 +8,12 @@
<meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0"> <meta http-equiv="Expires" content="0">
<title>AI助手</title> <title>AI助手</title>
<link rel="stylesheet" href="style.css?v=2.7.3"> <link rel="stylesheet" href="style.css?v=2.8.0">
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
<script src="marked.min.js?v=2.7.3"></script> <script src="marked.min.js?v=2.8.0"></script>
<script src="app.js?v=2.7.3"></script> <script src="app.js?v=2.8.0"></script>
</body> </body>
</html> </html>