@@ -118,12 +118,23 @@ async function loadBackendConfig() {
// 加载工具列表
if ( backendConfig . allTools ) {
allTools = backendConfig . allTools ;
// 过滤掉联网搜索(已有单独按钮)
allTools = backendConfig . allTools . filter ( t => t . type !== 'search' ) ;
}
// 加载默认启用的工具
if ( backendConfig . tools ) {
enabledTools = backendConfig . tools . map ( t => t . tool _id ) ;
// 不 加载默认启用的工具,所有工具默认未启用
// 将后台系统配置赋值到 CONFIG
if ( backendConfig . system ) {
CONFIG . system = backendConfig . system ;
}
// 将后台 LLM 配置赋值到 CONFIG
if ( backendConfig . llm ) {
CONFIG . apiUrl = backendConfig . llm . api _url ;
CONFIG . apiKey = backendConfig . llm . api _key ;
CONFIG . model = backendConfig . llm . model ;
CONFIG . maxTokens = backendConfig . llm . max _tokens || 2048 ;
}
updateAgentsDisplay ( ) ;
@@ -310,15 +321,41 @@ document.addEventListener('DOMContentLoaded', async () => {
// 初始化 appContainer
appContainer = document . getElementById ( 'app' ) ;
// 加载后台配置(包含 LLM、智能体等)
await loadBackendConfig ( ) ;
// 加载用户登录状态(优先检查)
const savedUser = localStorage . getItem ( 'currentUser' ) ;
if ( savedUser ) {
currentUser = JSON . parse ( savedUser ) ;
}
// 如果用户已登录且有ID, 从 backend 加载对话数据
// 如果用户已登录且有ID, 从 backend 加载最新用户信息和 对话数据
if ( currentUser && currentUser . id ) {
try {
// 从后台获取最新用户信息(包括头像)
const userRes = await fetch ( ` /api/user/ ${ currentUser . id } ` ) ;
if ( userRes . ok ) {
const userData = await userRes . json ( ) ;
if ( userData && userData . id ) {
// 更新 currentUser 为后台最新数据
currentUser = {
id : userData . id ,
username : userData . username ,
phone : userData . phone || '' ,
email : userData . email || '' ,
avatar : userData . avatar || '👤' ,
signature : userData . signature || '' ,
gender : userData . gender || '' ,
age : userData . age || '' ,
region : userData . region || '' ,
registeredAt : Date . now ( )
} ;
saveCurrentUser ( ) ;
}
}
// 从 backend 加载对话数据
const res = await fetch ( ` /api/user/ ${ currentUser . id } /conversations ` ) ;
const data = await res . json ( ) ;
if ( Array . isArray ( data ) && data . length > 0 ) {
@@ -426,13 +463,8 @@ document.addEventListener('DOMContentLoaded', async () => {
currentPage = savedPage ;
}
// 加载后台配置并 显示主页
loadBackendConfig ( ) . then ( ( ) => {
showMainPage ( ) ;
} ) . catch ( ( ) => {
// 即使加载失败也显示主页
showMainPage ( ) ;
} ) ;
// 显示主页
showMainPage ( ) ;
} ) ;
// 根据用户配置更新显示的智能体
@@ -791,7 +823,7 @@ function renderAgentsPage() {
<div class="recent-agent-item" data-conv-id=" ${ conv . id } ">
<div class="recent-agent-left">
<span class="recent-agent-avatar"> ${ conv . agent ? conv . agent . avatar : '🤖' } </span>
<span class="recent-agent-nam e"> ${ conv . title } </span>
<span class="recent-agent-titl e"> ${ conv . title } </span>
</div>
<div class="recent-agent-right">
<span class="recent-agent-agent-name"> ${ conv . agent ? conv . agent . name : '未知智能体' } </span>
@@ -1326,6 +1358,7 @@ function filterDiscoverAgents(keyword) {
if ( ! keyword ) {
// 显示所有
showDiscoverSection ( 'hot' , systemAgents . filter ( a => a . category === 'hot' ) ) ;
showDiscoverSection ( 'basic' , systemAgents . filter ( a => a . category === 'basic' ) ) ;
showDiscoverSection ( 'work' , systemAgents . filter ( a => a . category === 'work' ) ) ;
showDiscoverSection ( 'study' , systemAgents . filter ( a => a . category === 'study' ) ) ;
showDiscoverSection ( 'life' , systemAgents . filter ( a => a . category === 'life' ) ) ;
@@ -1340,6 +1373,7 @@ function filterDiscoverAgents(keyword) {
// 显示搜索结果
showDiscoverSection ( 'hot' , filtered . filter ( a => a . category === 'hot' ) ) ;
showDiscoverSection ( 'basic' , filtered . filter ( a => a . category === 'basic' ) ) ;
showDiscoverSection ( 'work' , filtered . filter ( a => a . category === 'work' ) ) ;
showDiscoverSection ( 'study' , filtered . filter ( a => a . category === 'study' ) ) ;
showDiscoverSection ( 'life' , filtered . filter ( a => a . category === 'life' ) ) ;
@@ -2613,7 +2647,12 @@ function showAboutPage() {
const privacyPolicyBtn = document . getElementById ( 'privacyPolicyBtn' ) ;
if ( privacyPolicyBtn ) {
privacyPolicyBtn . addEventListener ( 'click' , ( ) => {
showToast ( '隐私政策页面待完善' ) ;
const privacyUrl = CONFIG ? . system ? . privacyPolicyUrl ;
if ( privacyUrl ) {
window . open ( privacyUrl , '_blank' ) ;
} else {
showToast ( '隐私政策链接未配置' ) ;
}
} ) ;
}
@@ -2621,7 +2660,12 @@ function showAboutPage() {
const userAgreementBtn = document . getElementById ( 'userAgreementBtn' ) ;
if ( userAgreementBtn ) {
userAgreementBtn . addEventListener ( 'click' , ( ) => {
showToast ( '用户协议页面待完善' ) ;
const agreementUrl = CONFIG ? . system ? . userAgreementUrl ;
if ( agreementUrl ) {
window . open ( agreementUrl , '_blank' ) ;
} else {
showToast ( '用户协议链接未配置' ) ;
}
} ) ;
}
}
@@ -3005,10 +3049,10 @@ function showAgentHistoryPage() {
<div class="agent-history-item" data-conv-id=" ${ conv . id } ">
<div class="agent-history-left">
<span class="agent-history-avatar"> ${ conv . agent ? conv . agent . avatar : '🤖' } </span>
<span class="agent-history-nam e"> ${ conv . title } </span>
<span class="agent-history-titl e"> ${ conv . title } </span>
</div>
<div class="agent-history-right">
<span class="agent-history-agent"> ${ conv . agent ? conv . agent . name : '未知智能体' } </span>
<span class="agent-history-agent-name "> ${ conv . agent ? conv . agent . name : '未知智能体' } </span>
<span class="agent-history-time"> ${ formatTime ( conv . updatedAt ) } </span>
</div>
</div>
@@ -3044,6 +3088,9 @@ async function openAgent(agentId) {
currentAgent = systemAgents . find ( a => a . id === agentId ) ;
if ( ! currentAgent ) return ;
// 加载该智能体的工具选择状态
loadToolsState ( ) ;
// 检查未登录用户的智能体限制
if ( ! currentUser ) {
const check = canUseAgent ( agentId ) ;
@@ -3086,7 +3133,7 @@ async function openAgent(agentId) {
// 创建新对话并设置智能体
const newConv = {
id : backendId || Date . now ( ) . toString ( ) ,
title : currentAgent . name ,
title : '新对话' , // 和普通对话一样,初始标题为"新对话",后续自动生成
messages : [ ] ,
agentId : agentId ,
createdAt : Date . now ( ) ,
@@ -3130,22 +3177,10 @@ function showAgentChatPage() {
<div class="messages" id="messages"></div>
</div>
<!-- 功能开关 栏 -->
<!-- 功能栏(智能体对话不需要工具选择,工具由后台配置) -->
<div class="feature-bar" id="featureBar">
<div class="feature-left">
<button class="feature-btn thinking-btn" id="thinkingBtn" >
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>
<span>深度思考</span>
</button>
<button class="feature-btn search-btn" id="searchBtn">
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 7 9.5 7 14 9.01 14 9.5 11.99 14 9.5 14z"/></svg>
<span>联网搜索</span>
</button>
<button class="feature-btn tools-btn" id="moreToolsBtn">
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z"/></svg>
<span>更多工具</span>
${ enabledTools . length > 0 ? ` <span class="tools-count"> ${ enabledTools . length } </span> ` : '' }
</button>
<!-- 智能体工具由后台配置,不显示选择按钮 -- >
</div>
<div class="feature-right">
<button class="feature-btn nav-btn" id="scrollTopBtn">
@@ -3599,6 +3634,10 @@ function openConversation(id) {
return ;
}
// 普通对话,加载普通对话的工具状态
currentAgent = null ;
loadToolsState ( ) ;
// 渲染对话页面
const chatHtml = `
<div id="chatPage">
@@ -4232,6 +4271,9 @@ function confirmToolsSelection() {
enabledTools = selectedTools ;
// 保存工具选择状态
saveToolsState ( ) ;
// 更新按钮显示
const moreToolsBtn = document . getElementById ( 'moreToolsBtn' ) ;
if ( moreToolsBtn ) {
@@ -4254,6 +4296,38 @@ function confirmToolsSelection() {
showToast ( ` 已启用 ${ enabledTools . length } 个工具 ` ) ;
}
// 保存工具选择状态
function saveToolsState ( ) {
if ( currentAgent ) {
// 智能体对话:保存到 localStorage( 按智能体ID)
localStorage . setItem ( ` agentEnabledTools_ ${ currentAgent . id } ` , JSON . stringify ( enabledTools ) ) ;
} else {
// 普通对话:保存到 localStorage
localStorage . setItem ( 'chatEnabledTools' , JSON . stringify ( enabledTools ) ) ;
}
}
// 加载工具选择状态
function loadToolsState ( ) {
if ( currentAgent ) {
// 智能体对话:加载该智能体的工具状态
const saved = localStorage . getItem ( ` agentEnabledTools_ ${ currentAgent . id } ` ) ;
if ( saved ) {
enabledTools = JSON . parse ( saved ) ;
} else {
enabledTools = [ ] ;
}
} else {
// 普通对话:加载普通对话的工具状态
const saved = localStorage . getItem ( 'chatEnabledTools' ) ;
if ( saved ) {
enabledTools = JSON . parse ( saved ) ;
} else {
enabledTools = [ ] ;
}
}
}
// 渲染头像(支持 emoji 和上传的图片)
function renderAvatar ( avatar ) {
if ( ! avatar ) return '👤' ;
@@ -4513,7 +4587,11 @@ function renderMessages() {
messagesDiv . innerHTML = currentConversation . messages . map ( ( msg , index ) => {
const isUser = msg . role === 'user' ;
const avatar = isUser ? '👤' : '🤖' ;
// 用户头像使用实际头像, AI头像使用智能体头像或默认
const avatar = isUser
? ( currentUser ? . avatar || '👤' )
: ( currentAgent ? . avatar || '🤖' ) ;
const avatarHtml = isUser ? renderAvatar ( avatar ) : avatar ;
// 处理消息内容(支持图片)
let contentHtml = '' ;
@@ -4588,7 +4666,7 @@ function renderMessages() {
return `
<div class="message ${ msg . role } " data-index=" ${ index } ">
<div class="message-avatar"> ${ avatar } </div>
<div class="message-avatar"> ${ avatarHtml } </div>
<div class="message-body">
${ searchHtml }
${ thinkingHtml }