feat: 前端APP智能体从后台配置加载
- 从后台API(/api/config)获取智能体列表 - 热门智能体 = tags中包含hot标签 - 其他类别 = 根据category字段分类(basic/work/study/life) - 游客限制从后台配置加载
This commit is contained in:
145
www/app.js
145
www/app.js
@@ -19,39 +19,18 @@ let isLoading = false;
|
||||
// 当前页面状态
|
||||
let currentPage = 'chats'; // chats | agents | profile
|
||||
|
||||
// 系统智能体数据(完整列表)
|
||||
let systemAgents = [
|
||||
// 热门智能体
|
||||
{ id: 'assistant', name: '通用助手', avatar: '🤖', category: 'hot', desc: '能回答各类问题,帮助写作、分析、解答疑惑', systemPrompt: '你是一个智能助手,能够回答各类问题,帮助用户解决问题。', heat: 9500 },
|
||||
{ id: 'writer', name: '写作助手', avatar: '✍️', category: 'hot', desc: '专注于文章写作、文案创作、内容润色', systemPrompt: '你是一个专业的写作助手,擅长各类文章写作、文案创作和内容润色。', heat: 8800 },
|
||||
{ id: 'coder', name: '编程助手', avatar: '👨💻', category: 'hot', desc: '精通编程语言,解答技术问题,生成代码', systemPrompt: '你是一个专业的编程助手,精通各类编程语言,能够解答技术问题并生成高质量代码。', heat: 8500 },
|
||||
{ id: 'translator', name: '翻译助手', avatar: '🌐', category: 'hot', desc: '多语言翻译,精准表达,文化适配', systemPrompt: '你是一个专业的翻译助手,精通多语言翻译,能够精准表达并适配文化差异。', heat: 7200 },
|
||||
|
||||
// 工作助手
|
||||
{ id: 'assistant-work', name: '工作助手', avatar: '💼', category: 'work', desc: '职场问题解答,工作效率提升', systemPrompt: '你是一个工作助手,帮助解决职场问题,提升工作效率。', heat: 5000 },
|
||||
{ id: 'ppt', name: 'PPT助手', avatar: '📊', category: 'work', desc: 'PPT内容生成,结构优化,设计建议', systemPrompt: '你是一个PPT助手,擅长PPT内容生成、结构优化和设计建议。', heat: 4500 },
|
||||
{ id: 'excel', name: 'Excel助手', avatar: '📈', category: 'work', desc: 'Excel公式、数据分析、表格优化', systemPrompt: '你是一个Excel助手,精通Excel公式、数据分析和表格优化。', heat: 4000 },
|
||||
|
||||
// 学习助手
|
||||
{ id: 'teacher', name: '学习助手', avatar: '📚', category: 'study', desc: '知识讲解,学习方法,考试辅导', systemPrompt: '你是一个学习助手,擅长知识讲解、学习方法指导和考试辅导。', heat: 5500 },
|
||||
{ id: 'english', name: '英语助手', avatar: '🔤', category: 'study', desc: '英语学习,语法纠正,口语练习', systemPrompt: '你是一个英语助手,帮助英语学习、语法纠正和口语练习。', heat: 5000 },
|
||||
{ id: 'math', name: '数学助手', avatar: '🔢', category: 'study', desc: '数学解题,公式推导,概念讲解', systemPrompt: '你是一个数学助手,擅长数学解题、公式推导和概念讲解。', heat: 4500 },
|
||||
|
||||
// 生活助手
|
||||
{ id: 'health', name: '健康助手', avatar: '🏥', category: 'life', desc: '健康咨询,养生建议,运动指导', systemPrompt: '你是一个健康助手,提供健康咨询、养生建议和运动指导。', heat: 3500 },
|
||||
{ id: 'travel', name: '旅行助手', avatar: '✈️', category: 'life', desc: '旅行规划,景点推荐,美食指南', systemPrompt: '你是一个旅行助手,擅长旅行规划、景点推荐和美食指南。', heat: 3200 },
|
||||
{ id: 'food', name: '美食助手', avatar: '🍳', category: 'life', desc: '菜谱推荐,烹饪技巧,营养搭配', systemPrompt: '你是一个美食助手,提供菜谱推荐、烹饪技巧和营养搭配建议。', heat: 3000 },
|
||||
];
|
||||
// 系统智能体数据(从后台API加载)
|
||||
let systemAgents = [];
|
||||
|
||||
// 用户智能体界面显示的智能体(默认显示热门智能体)
|
||||
// 用户智能体界面显示的智能体
|
||||
let agents = [];
|
||||
|
||||
// 用户添加的智能体(按类别分组)
|
||||
let myAgents = {
|
||||
hot: ['assistant', 'writer', 'coder', 'translator'],
|
||||
work: ['assistant-work', 'ppt', 'excel'],
|
||||
study: ['teacher', 'english', 'math'],
|
||||
life: ['health', 'travel', 'food']
|
||||
basic: [],
|
||||
work: [],
|
||||
study: [],
|
||||
life: []
|
||||
};
|
||||
|
||||
// 收藏的智能体列表
|
||||
@@ -59,7 +38,7 @@ let favoriteAgents = [];
|
||||
|
||||
// 置顶的智能体列表(按类别)
|
||||
let pinnedAgents = {
|
||||
hot: [],
|
||||
basic: [],
|
||||
work: [],
|
||||
study: [],
|
||||
life: []
|
||||
@@ -67,6 +46,9 @@ let pinnedAgents = {
|
||||
|
||||
let currentAgent = null; // 当前选中的智能体
|
||||
|
||||
// 后台配置
|
||||
let backendConfig = null; // 从API获取的配置
|
||||
|
||||
// 用户状态
|
||||
let currentUser = null; // 当前登录用户 { username, password, registeredAt }
|
||||
|
||||
@@ -79,12 +61,12 @@ let dailyUsage = {
|
||||
agentMessages: 0 // 智能体消息数
|
||||
};
|
||||
|
||||
// 未登录用户限制
|
||||
const GUEST_LIMITS = {
|
||||
maxChatSessionsPerDay: 1, // 每天最多1个对话会话
|
||||
maxChatMessagesPerDay: 20, // 每天最多20条对话消息
|
||||
maxAgentPerDay: 1, // 每天只能用1个智能体(通用助手)
|
||||
maxAgentMessagesPerDay: 20 // 每天最多20条智能体消息
|
||||
// 未登录用户限制(从后台配置加载)
|
||||
let GUEST_LIMITS = {
|
||||
maxChatSessionsPerDay: 1,
|
||||
maxChatMessagesPerDay: 20,
|
||||
maxAgentPerDay: 1,
|
||||
maxAgentMessagesPerDay: 20
|
||||
};
|
||||
|
||||
// 获取今日日期字符串
|
||||
@@ -93,6 +75,59 @@ function getTodayDate() {
|
||||
return `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
// 从后台API加载配置
|
||||
async function loadBackendConfig() {
|
||||
try {
|
||||
// 后台服务地址
|
||||
const API_BASE = 'http://localhost:19021';
|
||||
const res = await fetch(`${API_BASE}/api/config`);
|
||||
backendConfig = await res.json();
|
||||
|
||||
// 加载智能体列表
|
||||
if (backendConfig.agents) {
|
||||
systemAgents = backendConfig.agents.map(a => ({
|
||||
id: a.agent_id,
|
||||
name: a.name,
|
||||
avatar: a.avatar,
|
||||
category: a.category,
|
||||
desc: a.description,
|
||||
systemPrompt: a.system_prompt,
|
||||
heat: a.heat || 0,
|
||||
tags: a.tags || '',
|
||||
enable_tools: a.enable_tools || ''
|
||||
}));
|
||||
|
||||
// 初始化用户智能体列表(按类别)
|
||||
systemAgents.forEach(agent => {
|
||||
if (!myAgents[agent.category]) {
|
||||
myAgents[agent.category] = [];
|
||||
}
|
||||
myAgents[agent.category].push(agent.id);
|
||||
});
|
||||
}
|
||||
|
||||
// 加载游客限制配置
|
||||
if (backendConfig.system?.guestLimits) {
|
||||
GUEST_LIMITS = {
|
||||
maxChatSessionsPerDay: backendConfig.system.guestLimits.chatSessions || 1,
|
||||
maxChatMessagesPerDay: backendConfig.system.guestLimits.chatMessages || 20,
|
||||
maxAgentPerDay: 1, // 游客只能用通用助手
|
||||
maxAgentMessagesPerDay: backendConfig.system.guestLimits.agentMessages || 20
|
||||
};
|
||||
}
|
||||
|
||||
updateAgentsDisplay();
|
||||
console.log('后台配置已加载', backendConfig);
|
||||
} catch (e) {
|
||||
console.error('加载后台配置失败', e);
|
||||
// 使用默认配置
|
||||
systemAgents = [
|
||||
{ id: 'assistant', name: '通用助手', avatar: '🤖', category: 'basic', desc: '能回答各类问题,帮助写作、分析、解答疑惑', systemPrompt: '你是一个智能助手,能够回答各类问题,帮助用户解决问题。', heat: 9500, tags: 'hot' },
|
||||
];
|
||||
updateAgentsDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
// 检查并重置每日使用统计
|
||||
function checkDailyUsage() {
|
||||
const today = getTodayDate();
|
||||
@@ -321,7 +356,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
checkDailyUsage();
|
||||
|
||||
// 根据用户配置更新显示的智能体
|
||||
updateAgentsDisplay();
|
||||
// updateAgentsDisplay(); // 先不调用,等后台配置加载后再更新
|
||||
|
||||
// 加载当前页面状态
|
||||
const savedPage = localStorage.getItem('currentPage');
|
||||
@@ -329,8 +364,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
currentPage = savedPage;
|
||||
}
|
||||
|
||||
// 显示主页
|
||||
showMainPage();
|
||||
// 加载后台配置并显示主页
|
||||
loadBackendConfig().then(() => {
|
||||
showMainPage();
|
||||
}).catch(() => {
|
||||
// 即使加载失败也显示主页
|
||||
showMainPage();
|
||||
});
|
||||
});
|
||||
|
||||
// 根据用户配置更新显示的智能体
|
||||
@@ -644,8 +684,11 @@ function bindChatsPageEvents() {
|
||||
// ==================== 智能体页面 ====================
|
||||
|
||||
function renderAgentsPage() {
|
||||
// 根据用户配置筛选智能体
|
||||
const hotAgents = agents.filter(a => a.category === 'hot');
|
||||
// 根据后台配置筛选智能体
|
||||
// 热门智能体 = 标签中包含 "hot"
|
||||
const hotAgents = agents.filter(a => a.tags && a.tags.split(',').includes('hot'));
|
||||
// 其他类别 = 根据 category 字段分类
|
||||
const basicAgents = agents.filter(a => a.category === 'basic');
|
||||
const workAgents = agents.filter(a => a.category === 'work');
|
||||
const studyAgents = agents.filter(a => a.category === 'study');
|
||||
const lifeAgents = agents.filter(a => a.category === 'life');
|
||||
@@ -698,7 +741,7 @@ function renderAgentsPage() {
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
<!-- 热门智能体 -->
|
||||
<!-- 热门智能体(标签为hot) -->
|
||||
${hotAgents.length > 0 ? `
|
||||
<div class="agents-section">
|
||||
<div class="section-title">🔥 热门智能体</div>
|
||||
@@ -1032,7 +1075,10 @@ function showAgentDiscoverPage() {
|
||||
const sortedAgents = [...systemAgents].sort((a, b) => b.heat - a.heat);
|
||||
|
||||
// 分类显示
|
||||
const hotAgents = systemAgents.filter(a => a.category === 'hot');
|
||||
// 热门智能体 = 标签中包含 "hot"
|
||||
const hotAgents = systemAgents.filter(a => a.tags && a.tags.split(',').includes('hot'));
|
||||
// 其他类别
|
||||
const basicAgents = systemAgents.filter(a => a.category === 'basic');
|
||||
const workAgents = systemAgents.filter(a => a.category === 'work');
|
||||
const studyAgents = systemAgents.filter(a => a.category === 'study');
|
||||
const lifeAgents = systemAgents.filter(a => a.category === 'life');
|
||||
@@ -1053,15 +1099,28 @@ function showAgentDiscoverPage() {
|
||||
<input type="text" id="discoverSearchInput" placeholder="搜索智能体名称或描述...">
|
||||
</div>
|
||||
|
||||
<!-- 热门智能体 -->
|
||||
<!-- 热门智能体(标签为hot) -->
|
||||
${hotAgents.length > 0 ? `
|
||||
<div class="discover-section">
|
||||
<div class="discover-section-title">🔥 热门智能体</div>
|
||||
<div class="discover-grid" id="discoverHotGrid">
|
||||
${hotAgents.map(agent => renderDiscoverCard(agent)).join('')}
|
||||
</div>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
<!-- 基础智能体 -->
|
||||
${basicAgents.length > 0 ? `
|
||||
<div class="discover-section">
|
||||
<div class="discover-section-title">⭐ 基础智能体</div>
|
||||
<div class="discover-grid" id="discoverBasicGrid">
|
||||
${basicAgents.map(agent => renderDiscoverCard(agent)).join('')}
|
||||
</div>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
<!-- 工作助手 -->
|
||||
${workAgents.length > 0 ? `
|
||||
<div class="discover-section">
|
||||
<div class="discover-section-title">💼 工作助手</div>
|
||||
<div class="discover-grid" id="discoverWorkGrid">
|
||||
|
||||
Reference in New Issue
Block a user