refactor(web): 统一使用新的颜色系统变量替换旧变量
重构整个前端项目中的颜色变量,使用新的标准化颜色系统(--color-*-500)替换旧的--chart-*和--color-*变量。主要变更包括: 1. 替换所有组件中的颜色变量为新的标准命名格式 2. 更新图表颜色工具函数,移除旧的getChartColor方法 3. 调整暗色模式下的颜色变量值 4. 优化仪表盘统计卡片样式 5. 修复错误消息显示逻辑 6. 简化知识库类型选择卡片样式 同时更新了后端API错误处理逻辑,提供更详细的错误信息。移除不再使用的代码和样式。
This commit is contained in:
parent
fb3b864565
commit
33ef9f0e15
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.8 MiB |
@ -224,15 +224,18 @@ async def save_partial_message(conv_mgr, thread_id, full_msg=None, error_message
|
||||
error_type: 错误类型标识
|
||||
"""
|
||||
try:
|
||||
extra_metadata = {
|
||||
"error_type": error_type,
|
||||
"is_error": True,
|
||||
"error_message": error_message or f"发生错误: {error_type}"
|
||||
}
|
||||
if full_msg:
|
||||
# 保存部分生成的AI消息
|
||||
msg_dict = full_msg.model_dump() if hasattr(full_msg, "model_dump") else {}
|
||||
content = full_msg.content if hasattr(full_msg, "content") else str(full_msg)
|
||||
extra_metadata = msg_dict | {"error_type": error_type}
|
||||
else:
|
||||
# 保存纯错误消息
|
||||
content = error_message or f"发生错误: {error_type}"
|
||||
extra_metadata = {"error_type": error_type, "is_error": True}
|
||||
content = ""
|
||||
|
||||
saved_msg = conv_mgr.add_message_by_thread_id(
|
||||
thread_id=thread_id,
|
||||
@ -517,14 +520,24 @@ async def chat_agent(
|
||||
|
||||
# Input guard
|
||||
if conf.enable_content_guard and await content_guard.check(query):
|
||||
yield make_chunk(status="error", message="输入内容包含敏感词", meta=meta)
|
||||
yield make_chunk(
|
||||
status="error",
|
||||
error_type="content_guard_blocked",
|
||||
error_message="输入内容包含敏感词",
|
||||
meta=meta
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
agent = agent_manager.get_agent(agent_id)
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting agent {agent_id}: {e}, {traceback.format_exc()}")
|
||||
yield make_chunk(message=f"Error getting agent {agent_id}: {e}", status="error")
|
||||
yield make_chunk(
|
||||
status="error",
|
||||
error_type="agent_error",
|
||||
error_message=f"智能体 {agent_id} 获取失败: {str(e)}",
|
||||
meta=meta
|
||||
)
|
||||
return
|
||||
|
||||
messages = [human_message]
|
||||
@ -671,7 +684,12 @@ async def chat_agent(
|
||||
finally:
|
||||
new_db.close()
|
||||
|
||||
yield make_chunk(message=error_msg, status="error")
|
||||
yield make_chunk(
|
||||
status="error",
|
||||
error_type=error_type,
|
||||
error_message=error_msg,
|
||||
meta=meta
|
||||
)
|
||||
|
||||
return StreamingResponse(stream_messages(), media_type="application/json")
|
||||
|
||||
@ -880,6 +898,8 @@ async def get_agent_history(
|
||||
"content": msg.content,
|
||||
"created_at": msg.created_at.isoformat() if msg.created_at else None,
|
||||
"error_type": msg.extra_metadata.get("error_type") if msg.extra_metadata else None,
|
||||
"error_message": msg.extra_metadata.get("error_message") if msg.extra_metadata else None,
|
||||
"extra_metadata": msg.extra_metadata, # 保留完整的metadata以备前端需要
|
||||
"message_type": msg.message_type, # 添加消息类型字段
|
||||
"image_content": msg.image_content, # 添加图片内容字段
|
||||
}
|
||||
|
||||
@ -560,27 +560,24 @@ async def get_agent_analytics(
|
||||
|
||||
agent_tool_usage.append({"agent_id": agent_id, "tool_usage_count": tool_usage_count})
|
||||
|
||||
# 表现最佳的智能体(综合评分)
|
||||
# 表现最佳的智能体(按对话数排序)
|
||||
top_performing_agents = []
|
||||
for i, (agent_id, conv_count) in enumerate(agents):
|
||||
# 综合评分 = 对话数权重 + 满意度权重
|
||||
# 获取满意度数据
|
||||
satisfaction_data = next(
|
||||
(s for s in agent_satisfaction if s["agent_id"] == agent_id), {"satisfaction_rate": 0}
|
||||
)
|
||||
|
||||
score = conv_count * 0.3 + satisfaction_data["satisfaction_rate"] * 0.7
|
||||
|
||||
top_performing_agents.append(
|
||||
{
|
||||
"agent_id": agent_id,
|
||||
"score": round(score, 2),
|
||||
"conversation_count": conv_count,
|
||||
"satisfaction_rate": satisfaction_data["satisfaction_rate"],
|
||||
}
|
||||
)
|
||||
|
||||
# 按评分排序,取前5名
|
||||
top_performing_agents.sort(key=lambda x: x["score"], reverse=True)
|
||||
# 按对话数排序,取前5名
|
||||
top_performing_agents.sort(key=lambda x: x["conversation_count"], reverse=True)
|
||||
top_performing_agents = top_performing_agents[:5]
|
||||
|
||||
return AgentAnalytics(
|
||||
|
||||
@ -40,76 +40,64 @@
|
||||
--gray-10: #fbfcfc;
|
||||
--gray-0: #ffffff;
|
||||
|
||||
/* Standard Color System - 标准5档色阶系统 */
|
||||
--color-primary-50: #e1f6fb; /* 主色调-最浅 */
|
||||
--color-primary-100: #a3d8e8; /* 主色调-浅 */
|
||||
--color-primary-500: #3996ae; /* 主色调-标准 */
|
||||
--color-primary-700: #046a82; /* 主色调-深 */
|
||||
--color-primary-900: #023944; /* 主色调-最深 */
|
||||
|
||||
/* 保留原有的 main 变量 */
|
||||
--main-color: #016179;
|
||||
/* 鲜艳一点的 */
|
||||
--main-bright: #0188a6;
|
||||
--secondry-color: #4e616d;
|
||||
--error-color: #ba1a1a;
|
||||
--color-primary: #1c7796;
|
||||
--color-primary-bg: #d6eef1;
|
||||
--color-success: #45b30e;
|
||||
--color-success-light: #f6ffed;
|
||||
--color-error: #c73234;
|
||||
--color-error-light: #fff2f0;
|
||||
--color-info: #0058d4;
|
||||
--color-info-light: #e6f7ff;
|
||||
--color-warning: #faad14;
|
||||
--color-warning-light: #fffbe6;
|
||||
|
||||
/* Chart Colors - 图表颜色系统 */
|
||||
--chart-primary: var(--main-500); /* 主色调 - 用于主要数据 */
|
||||
--chart-primary-light: var(--main-400); /* 主色调浅色 - 用于渐变 */
|
||||
--chart-primary-dark: var(--main-600); /* 主色调深色 - 用于强调 */
|
||||
--color-secondary-50: #f5f7f7; /* 次要色-最浅 */
|
||||
--color-secondary-100: #eff2f2; /* 次要色-浅 */
|
||||
--color-secondary-500: #4e616d; /* 次要色-标准 */
|
||||
--color-secondary-700: #3a4a56; /* 次要色-深 */
|
||||
--color-secondary-900: #2c3843; /* 次要色-最深 */
|
||||
|
||||
--chart-success: #52c41a; /* 成功色 - 绿色 */
|
||||
--chart-success-light: #95de64; /* 成功色浅色 */
|
||||
--chart-success-dark: #389e0d; /* 成功色深色 */
|
||||
--color-success-50: #f6ffed; /* 成功色-最浅 */
|
||||
--color-success-100: #b7eb8f; /* 成功色-浅 */
|
||||
--color-success-500: #52c41a; /* 成功色-标准 */
|
||||
--color-success-700: #389e0d; /* 成功色-深 */
|
||||
--color-success-900: #135200; /* 成功色-最深 */
|
||||
|
||||
--chart-warning: #faad14; /* 警告色 - 橙色 */
|
||||
--chart-warning-light: #ffd666; /* 警告色浅色 */
|
||||
--chart-warning-dark: #d48806; /* 警告色深色 */
|
||||
--color-error-50: #fff2f0; /* 错误色-最浅 */
|
||||
--color-error-100: #ffccc7; /* 错误色-浅 */
|
||||
--color-error-500: #ff4d4f; /* 错误色-标准 */
|
||||
--color-error-700: #cf1322; /* 错误色-深 */
|
||||
--color-error-900: #820014; /* 错误色-最深 */
|
||||
|
||||
--chart-error: #f5222d; /* 错误色 - 红色 */
|
||||
--chart-error-light: #ff7875; /* 错误色浅色 */
|
||||
--chart-error-dark: #cf1322; /* 错误色深色 */
|
||||
--color-warning-50: #fffbe6; /* 警告色-最浅 */
|
||||
--color-warning-100: #ffe58f; /* 警告色-浅 */
|
||||
--color-warning-500: #faad14; /* 警告色-标准 */
|
||||
--color-warning-700: #d48806; /* 警告色-深 */
|
||||
--color-warning-900: #ad6800; /* 警告色-最深 */
|
||||
|
||||
--chart-info: #1890ff; /* 信息色 - 蓝色 */
|
||||
--chart-info-light: #69c0ff; /* 信息色浅色 */
|
||||
--chart-info-dark: #096dd9; /* 信息色深色 */
|
||||
--color-info-50: #e6f7ff; /* 信息色-最浅 */
|
||||
--color-info-100: #bae7ff; /* 信息色-浅 */
|
||||
--color-info-500: #1890ff; /* 信息色-标准 */
|
||||
--color-info-700: #096dd9; /* 信息色-深 */
|
||||
--color-info-900: #0050b3; /* 信息色-最深 */
|
||||
|
||||
--chart-secondary: #722ed1; /* 次要色 - 紫色 */
|
||||
--chart-secondary-light: #b37feb; /* 次要色浅色 */
|
||||
--chart-secondary-dark: #531dab; /* 次要色深色 */
|
||||
|
||||
--chart-accent: #13c2c2; /* 强调色 - 青色 */
|
||||
--chart-accent-light: #5cdbd3; /* 强调色浅色 */
|
||||
--chart-accent-dark: #08979c; /* 强调色深色 */
|
||||
--color-accent-50: #e6fffb; /* 强调色-最浅 */
|
||||
--color-accent-100: #87e8de; /* 强调色-浅 */
|
||||
--color-accent-500: #13c2c2; /* 强调色-标准 */
|
||||
--color-accent-700: #08979c; /* 强调色-深 */
|
||||
--color-accent-900: #006d75; /* 强调色-最深 */
|
||||
|
||||
/* Chart Palette - 图表调色板 */
|
||||
--chart-palette-1: var(--chart-primary);
|
||||
--chart-palette-2: #11cbe3; /* 浅一点的青蓝 */
|
||||
--chart-palette-3: #00b8a9; /* 明亮青绿(邻近色) */
|
||||
--chart-palette-4: #f2c94c; /* 柔和金黄(对比色) */
|
||||
--chart-palette-5: #eb5757; /* 温暖红橙(强调) */
|
||||
--chart-palette-6: #2f80ed; /* 明亮蓝色(辅助) */
|
||||
--chart-palette-7: #9b51e0; /* 紫色(分类区分) */
|
||||
--chart-palette-8: #56ccf2; /* 天蓝色(柔和点缀) */
|
||||
--chart-palette-9: #6fcf97; /* 淡绿色(平衡) */
|
||||
--chart-palette-10: #333333; /* 深灰(中性补充) */
|
||||
|
||||
/* Stats Card Colors - 统计卡片颜色系统 */
|
||||
--stats-primary-bg: #eff6ff; /* 主色调背景 */
|
||||
--stats-primary-color: #2563eb; /* 主色调文字 */
|
||||
--stats-success-bg: #f0fdf4; /* 成功色背景 */
|
||||
--stats-success-color: #16a34a; /* 成功色文字 */
|
||||
--stats-info-bg: #f0f9ff; /* 信息色背景 */
|
||||
--stats-info-color: #0284c7; /* 信息色文字 */
|
||||
--stats-warning-bg: #fffbeb; /* 警告色背景 */
|
||||
--stats-warning-color: #d97706; /* 警告色文字 */
|
||||
--stats-secondary-bg: #faf5ff; /* 次要色背景 */
|
||||
--stats-secondary-color: #9333ea; /* 次要色文字 */
|
||||
--stats-error-bg: #fef2f2; /* 错误色背景 */
|
||||
--stats-error-color: #dc2626; /* 错误色文字 */
|
||||
--chart-palette-1: var(--main-500);
|
||||
--chart-palette-2: #5AD8A6;
|
||||
--chart-palette-3: #F6BD16;
|
||||
--chart-palette-4: #F27C7C;
|
||||
--chart-palette-5: #9581CC;
|
||||
--chart-palette-6: #6DC8EC;
|
||||
--chart-palette-7: #FF9D4D;
|
||||
--chart-palette-8: #92D050;
|
||||
--chart-palette-9: #E885BA;
|
||||
--chart-palette-10: #8C8C8C;
|
||||
|
||||
--bg-sider: var(--main-5);
|
||||
--color-text: var(--c-black);
|
||||
@ -122,11 +110,6 @@
|
||||
--shadow-4: rgba(0, 0, 0, 0.16);
|
||||
--shadow-5: rgba(0, 0, 0, 0.20);
|
||||
|
||||
/* Extended Chart Variables - 扩展图表变量 */
|
||||
--chart-primary-lighter: var(--chart-primary-light);
|
||||
--chart-info-lighter: var(--chart-info-light);
|
||||
--chart-primary-shadow: rgba(28, 119, 150, 0.3);
|
||||
--chart-info-shadow: rgba(24, 144, 255, 0.3);
|
||||
|
||||
--min-width: 400px;
|
||||
|
||||
|
||||
@ -38,63 +38,64 @@
|
||||
--gray-10: #080808;
|
||||
--gray-0: #030303;
|
||||
|
||||
/* Standard Color System - 深色模式5档色阶系统 */
|
||||
--color-primary-50: #023944; /* 主色调-最深 */
|
||||
--color-primary-100: #035065; /* 主色调-深 */
|
||||
--color-primary-500: #4a9fb8; /* 主色调-标准 */
|
||||
--color-primary-700: #5faec2; /* 主色调-浅 */
|
||||
--color-primary-900: #82c3d6; /* 主色调-最浅 */
|
||||
|
||||
/* 保留原有的 main 变量 */
|
||||
--main-color: #4a9fb8;
|
||||
--main-bright: #5faec2;
|
||||
--secondry-color: #8fa5b0;
|
||||
--error-color: #ff6b6b;
|
||||
--color-primary: #4a9fb8;
|
||||
--color-primary-bg: #1a3a42;
|
||||
--color-success: #52c41a;
|
||||
--color-success-light: #162312;
|
||||
--color-error: #ff4d4f;
|
||||
--color-error-light: #2a1215;
|
||||
--color-info: #3d8fff;
|
||||
--color-info-light: #111b26;
|
||||
--color-warning: #faad14;
|
||||
--color-warning-light: #2b2111;
|
||||
|
||||
/* Chart Colors - 深色模式图表颜色 */
|
||||
--chart-primary: var(--main-500);
|
||||
--chart-primary-light: var(--main-600);
|
||||
--chart-primary-dark: var(--main-400);
|
||||
--color-secondary-50: #151616; /* 次要色-最深 */
|
||||
--color-secondary-100: #1e1f1f; /* 次要色-深 */
|
||||
--color-secondary-500: #8fa5b0; /* 次要色-标准 */
|
||||
--color-secondary-700: #9fb5c0; /* 次要色-浅 */
|
||||
--color-secondary-900: #b8c8d0; /* 次要色-最浅 */
|
||||
|
||||
--chart-success: #52c41a;
|
||||
--chart-success-light: #73d13d;
|
||||
--chart-success-dark: #389e0d;
|
||||
--color-success-50: #162312; /* 成功色-最深 */
|
||||
--color-success-100: #273921; /* 成功色-深 */
|
||||
--color-success-500: #52c41a; /* 成功色-标准 */
|
||||
--color-success-700: #73d13d; /* 成功色-浅 */
|
||||
--color-success-900: #95de64; /* 成功色-最浅 */
|
||||
|
||||
--chart-warning: #faad14;
|
||||
--chart-warning-light: #ffc53d;
|
||||
--chart-warning-dark: #d48806;
|
||||
--color-error-50: #2a1215; /* 错误色-最深 */
|
||||
--color-error-100: #58181c; /* 错误色-深 */
|
||||
--color-error-500: #ff4d4f; /* 错误色-标准 */
|
||||
--color-error-700: #ff7875; /* 错误色-浅 */
|
||||
--color-error-900: #ffa39e; /* 错误色-最浅 */
|
||||
|
||||
--chart-error: #ff4d4f;
|
||||
--chart-error-light: #ff7875;
|
||||
--chart-error-dark: #cf1322;
|
||||
--color-warning-50: #2b2111; /* 警告色-最深 */
|
||||
--color-warning-100: #614700; /* 警告色-深 */
|
||||
--color-warning-500: #faad14; /* 警告色-标准 */
|
||||
--color-warning-700: #ffc53d; /* 警告色-浅 */
|
||||
--color-warning-900: #ffd666; /* 警告色-最浅 */
|
||||
|
||||
--chart-info: #1890ff;
|
||||
--chart-info-light: #40a9ff;
|
||||
--chart-info-dark: #096dd9;
|
||||
--color-info-50: #111b26; /* 信息色-最深 */
|
||||
--color-info-100: #111d2c; /* 信息色-深 */
|
||||
--color-info-500: #3d8fff; /* 信息色-标准 */
|
||||
--color-info-700: #40a9ff; /* 信息色-浅 */
|
||||
--color-info-900: #69c0ff; /* 信息色-最浅 */
|
||||
|
||||
--chart-secondary: #722ed1;
|
||||
--chart-secondary-light: #9254de;
|
||||
--chart-secondary-dark: #531dab;
|
||||
--color-accent-50: #0f2e2e; /* 强调色-最深 */
|
||||
--color-accent-100: #164e63; /* 强调色-深 */
|
||||
--color-accent-500: #13c2c2; /* 强调色-标准 */
|
||||
--color-accent-700: #36cfc9; /* 强调色-浅 */
|
||||
--color-accent-900: #5cdbd3; /* 强调色-最浅 */
|
||||
|
||||
--chart-accent: #13c2c2;
|
||||
--chart-accent-light: #36cfc9;
|
||||
--chart-accent-dark: #08979c;
|
||||
--chart-palette-1: var(--main-300);
|
||||
--chart-palette-2: #3EA896;
|
||||
--chart-palette-3: #D6AD37;
|
||||
--chart-palette-4: #CF6666;
|
||||
--chart-palette-5: #8672B4;
|
||||
--chart-palette-6: #529AB8;
|
||||
--chart-palette-7: #D48242;
|
||||
--chart-palette-8: #82B354;
|
||||
--chart-palette-9: #C46E9E;
|
||||
--chart-palette-10: #7A7A7A;
|
||||
|
||||
/* Stats Card Colors - 深色模式统计卡片 */
|
||||
--stats-primary-bg: #1e3a8a;
|
||||
--stats-primary-color: #93c5fd;
|
||||
--stats-success-bg: #14532d;
|
||||
--stats-success-color: #86efac;
|
||||
--stats-info-bg: #0c4a6e;
|
||||
--stats-info-color: #7dd3fc;
|
||||
--stats-warning-bg: #78350f;
|
||||
--stats-warning-color: #fcd34d;
|
||||
--stats-secondary-bg: #581c87;
|
||||
--stats-secondary-color: #d8b4fe;
|
||||
--stats-error-bg: #7f1d1d;
|
||||
--stats-error-color: #fca5a5;
|
||||
|
||||
--bg-sider: #141414;
|
||||
--color-text: #ffffff;
|
||||
@ -113,11 +114,6 @@
|
||||
--shadow-4: rgba(0, 0, 0, 0.5);
|
||||
--shadow-5: rgba(0, 0, 0, 0.6);
|
||||
|
||||
/* Extended Chart Variables - 扩展图表变量 */
|
||||
--chart-primary-lighter: var(--chart-primary-light);
|
||||
--chart-info-lighter: var(--chart-info-light);
|
||||
--chart-primary-shadow: rgba(74, 159, 184, 0.4);
|
||||
--chart-info-shadow: rgba(24, 144, 255, 0.4);
|
||||
|
||||
--color-trans-light: rgba(0, 0, 0, 0.85);
|
||||
--color-trans-dark: rgba(255, 255, 255, 0.85);
|
||||
@ -129,14 +125,14 @@
|
||||
--markmap-a-hover-color: var(--main-600);
|
||||
--markmap-code-bg: var(--gray-50);
|
||||
--markmap-code-color: var(--gray-700);
|
||||
--markmap-highlight-bg: var(--color-warning-light);
|
||||
--markmap-highlight-bg: var(--color-warning-50);
|
||||
--markmap-table-border: 1px solid currentColor;
|
||||
--markmap-font: 300 16px / 20px sans-serif;
|
||||
--markmap-circle-open-bg: var(--main-0);
|
||||
--markmap-text-color: var(--gray-700);
|
||||
--markmap-highlight-node-bg: var(--color-error-light);
|
||||
--markmap-highlight-node-bg: var(--color-error-50);
|
||||
}
|
||||
|
||||
:root.dark .md-editor {
|
||||
--md-bk-color: var(--gray-0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
type: 'linear',
|
||||
x: 0, y: 0, x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'var(--chart-primary)' },
|
||||
{ offset: 1, color: 'var(--chart-primary-light)' }
|
||||
{ offset: 0, color: 'var(--chart-primary-500)' },
|
||||
{ offset: 1, color: 'var(--chart-primary-100)' }
|
||||
]
|
||||
};
|
||||
|
||||
@ -16,8 +16,8 @@
|
||||
type: 'linear',
|
||||
x: 0, y: 0, x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'var(--chart-success)' },
|
||||
{ offset: 1, color: 'var(--chart-success-light)' }
|
||||
{ offset: 0, color: 'var(--color-success-500)' },
|
||||
{ offset: 1, color: 'var(--color-success-100)' }
|
||||
]
|
||||
};
|
||||
|
||||
@ -25,8 +25,8 @@
|
||||
type: 'linear',
|
||||
x: 0, y: 0, x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'var(--chart-warning)' },
|
||||
{ offset: 1, color: 'var(--chart-warning-light)' }
|
||||
{ offset: 0, color: 'var(--color-warning-500)' },
|
||||
{ offset: 1, color: 'var(--color-warning-100)' }
|
||||
]
|
||||
};
|
||||
|
||||
@ -34,8 +34,8 @@
|
||||
type: 'linear',
|
||||
x: 0, y: 0, x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'var(--chart-error)' },
|
||||
{ offset: 1, color: 'var(--chart-error-light)' }
|
||||
{ offset: 0, color: 'var(--color-error-500)' },
|
||||
{ offset: 1, color: 'var(--color-error-100)' }
|
||||
]
|
||||
};
|
||||
|
||||
@ -43,8 +43,8 @@
|
||||
type: 'linear',
|
||||
x: 0, y: 0, x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'var(--chart-info)' },
|
||||
{ offset: 1, color: 'var(--chart-info-light)' }
|
||||
{ offset: 0, color: 'var(--color-info-500)' },
|
||||
{ offset: 1, color: 'var(--color-info-100)' }
|
||||
]
|
||||
};
|
||||
|
||||
@ -52,8 +52,8 @@
|
||||
type: 'linear',
|
||||
x: 0, y: 0, x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'var(--chart-secondary)' },
|
||||
{ offset: 1, color: 'var(--chart-secondary-light)' }
|
||||
{ offset: 0, color: 'var(--color-accent-500)' },
|
||||
{ offset: 1, color: 'var(--color-accent-100)' }
|
||||
]
|
||||
};
|
||||
|
||||
@ -61,8 +61,8 @@
|
||||
type: 'linear',
|
||||
x: 0, y: 0, x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'var(--chart-accent)' },
|
||||
{ offset: 1, color: 'var(--chart-accent-light)' }
|
||||
{ offset: 0, color: 'var(--color-accent-500)' },
|
||||
{ offset: 1, color: 'var(--color-accent-100)' }
|
||||
]
|
||||
};
|
||||
}
|
||||
@ -245,6 +245,11 @@
|
||||
color: var(--gray-1000);
|
||||
}
|
||||
|
||||
/* 强制设置所有统计卡片数字为粗体 */
|
||||
.dashboard-card .ant-statistic-content-value {
|
||||
font-weight: 700 !important;
|
||||
}
|
||||
|
||||
.dashboard-card .ant-table {
|
||||
background-color: var(--gray-0);
|
||||
border-radius: 8px;
|
||||
|
||||
@ -21,35 +21,35 @@
|
||||
|
||||
/* 高亮样式 */
|
||||
.node-highlighted {
|
||||
stroke: var(--color-error) !important;
|
||||
stroke-width: 3px !important;
|
||||
stroke: var(--color-error-500);
|
||||
stroke-width: 3px;
|
||||
}
|
||||
|
||||
.edge-highlighted {
|
||||
stroke: var(--color-error) !important;
|
||||
stroke-width: 3px !important;
|
||||
stroke: var(--color-error-500);
|
||||
stroke-width: 3px;
|
||||
}
|
||||
|
||||
/* 选中样式 */
|
||||
.node-selected {
|
||||
stroke: var(--color-info) !important;
|
||||
stroke-width: 4px !important;
|
||||
stroke: var(--color-info-500);
|
||||
stroke-width: 4px;
|
||||
}
|
||||
|
||||
.edge-selected {
|
||||
stroke: var(--color-info) !important;
|
||||
stroke-width: 4px !important;
|
||||
stroke: var(--color-info-500);
|
||||
stroke-width: 4px;
|
||||
}
|
||||
|
||||
/* 悬停样式 */
|
||||
.node-focused {
|
||||
stroke: var(--color-success) !important;
|
||||
stroke-width: 2px !important;
|
||||
stroke: var(--color-success-500);
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
.edge-focused {
|
||||
stroke: var(--color-success) !important;
|
||||
stroke-width: 2px !important;
|
||||
stroke: var(--color-success-500);
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
/* 加载动画 */
|
||||
|
||||
@ -734,9 +734,9 @@ watch(() => props.isOpen, (newVal) => {
|
||||
.system-prompt-display {
|
||||
min-height: 60px;
|
||||
background: var(--gray-50);
|
||||
border: 1px solid var(--gray-200);
|
||||
border: 1px dashed var(--gray-200);
|
||||
border-radius: 6px;
|
||||
padding: 8px 12px;
|
||||
padding: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
transition: all 0.2s ease;
|
||||
@ -774,10 +774,10 @@ watch(() => props.isOpen, (newVal) => {
|
||||
top: 8px;
|
||||
right: 12px;
|
||||
font-size: 12px;
|
||||
color: var(--gray-400);
|
||||
color: var(--gray-800);
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
background: var(--gray-0);
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
@ -890,8 +890,8 @@ watch(() => props.isOpen, (newVal) => {
|
||||
|
||||
.option-card {
|
||||
border: 1px solid var(--gray-300);
|
||||
border-radius: 6px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 8px;
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
background: var(--gray-0);
|
||||
@ -946,30 +946,6 @@ watch(() => props.isOpen, (newVal) => {
|
||||
|
||||
// 工具选择弹窗样式
|
||||
.tools-modal {
|
||||
:deep(.ant-modal-content) {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
border: 1px solid var(--gray-200);
|
||||
}
|
||||
|
||||
:deep(.ant-modal-header) {
|
||||
background: var(--gray-0);
|
||||
border-bottom: 1px solid var(--gray-200);
|
||||
padding: 16px 20px;
|
||||
|
||||
.ant-modal-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--gray-900);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-modal-body) {
|
||||
padding: 20px;
|
||||
background: var(--gray-0);
|
||||
}
|
||||
|
||||
.tools-modal-content {
|
||||
.tools-search {
|
||||
margin-bottom: 16px;
|
||||
@ -1010,7 +986,6 @@ watch(() => props.isOpen, (newVal) => {
|
||||
overflow-y: auto;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
background: var(--gray-0);
|
||||
|
||||
// 在小屏幕下调整为单列布局
|
||||
@media (max-width: 480px) {
|
||||
@ -1085,19 +1060,19 @@ watch(() => props.isOpen, (newVal) => {
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background: var(--main-30);
|
||||
// border-color: var(--main-color);
|
||||
background: var(--main-50);
|
||||
border-color: var(--main-200);
|
||||
|
||||
.tool-content {
|
||||
.tool-name {
|
||||
color: var(--main-color);
|
||||
color: var(--main-800);
|
||||
}
|
||||
.tool-indicator {
|
||||
color: var(--main-color);
|
||||
color: var(--main-800);
|
||||
}
|
||||
}
|
||||
.tool-description {
|
||||
color: var(--gray-700);
|
||||
color: var(--gray-900);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -34,10 +34,12 @@
|
||||
<div v-else-if="parsedData.reasoning_content" class="empty-block"></div>
|
||||
|
||||
<!-- 错误提示块 -->
|
||||
<div v-if="message.error_type" class="error-hint">
|
||||
<span v-if="message.error_type === 'interrupted'">回答生成已中断</span>
|
||||
<div v-if="displayError" class="error-hint">
|
||||
<span v-if="getErrorMessage">{{ getErrorMessage }}</span>
|
||||
<span v-else-if="message.error_type === 'interrupted'">回答生成已中断</span>
|
||||
<span v-else-if="message.error_type === 'unexpect'">生成过程中出现异常</span>
|
||||
<span v-else-if="message.error_type === 'content_guard_blocked'">检测到敏感内容,已中断输出</span>
|
||||
<span v-else>{{ message.error_type || '未知错误' }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="validToolCalls && validToolCalls.length > 0" class="tool-calls-container">
|
||||
@ -153,6 +155,38 @@ const emit = defineEmits(['retry', 'retryStoppedMessage', 'openRefs']);
|
||||
const reasoningActiveKey = ref(['hide']);
|
||||
const expandedToolCalls = ref(new Set()); // 展开的工具调用集合
|
||||
|
||||
// 错误消息处理
|
||||
const displayError = computed(() => {
|
||||
// 简化错误判断:只检查明确的错误类型标识
|
||||
return !!(props.message.error_type || props.message.extra_metadata?.error_type);
|
||||
});
|
||||
|
||||
const getErrorMessage = computed(() => {
|
||||
// 优先使用直接的 error_message 字段
|
||||
if (props.message.error_message) {
|
||||
return props.message.error_message;
|
||||
}
|
||||
|
||||
// 其次从 extra_metadata 中获取具体的错误信息
|
||||
if (props.message.extra_metadata?.error_message) {
|
||||
return props.message.extra_metadata.error_message;
|
||||
}
|
||||
|
||||
// 对于已知的错误类型,返回默认提示
|
||||
switch (props.message.error_type) {
|
||||
case 'interrupted':
|
||||
return '回答生成已中断';
|
||||
case 'content_guard_blocked':
|
||||
return '检测到敏感内容,已中断输出';
|
||||
case 'unexpect':
|
||||
return '生成过程中出现异常';
|
||||
case 'agent_error':
|
||||
return '智能体获取失败';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// 引入智能体 store
|
||||
const agentStore = useAgentStore();
|
||||
const infoStore = useInfoStore();
|
||||
@ -297,12 +331,12 @@ const toggleToolCall = (toolCallId) => {
|
||||
}
|
||||
|
||||
.err-msg {
|
||||
color: var(--color-error);
|
||||
color: var(--color-error-500);
|
||||
border: 1px solid currentColor;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 8px;
|
||||
text-align: left;
|
||||
background: var(--color-error-light);
|
||||
background: var(--color-error-50);
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -374,9 +408,9 @@ const toggleToolCall = (toolCallId) => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background-color: var(--color-error-light);
|
||||
background-color: var(--color-error-50);
|
||||
// border: 1px solid #f87171;
|
||||
color: var(--color-error);
|
||||
color: var(--color-error-500);
|
||||
span {
|
||||
line-height: 1.5;
|
||||
}
|
||||
@ -457,15 +491,15 @@ const toggleToolCall = (toolCallId) => {
|
||||
}
|
||||
|
||||
.tool-loader.tool-success {
|
||||
color: var(--color-success);
|
||||
color: var(--color-success-500);
|
||||
}
|
||||
|
||||
.tool-loader.tool-error {
|
||||
color: var(--color-error);
|
||||
color: var(--color-error-500);
|
||||
}
|
||||
|
||||
.tool-loader.tool-loading {
|
||||
color: var(--color-info);
|
||||
color: var(--color-info-500);
|
||||
}
|
||||
}
|
||||
|
||||
@ -528,7 +562,7 @@ const toggleToolCall = (toolCallId) => {
|
||||
}
|
||||
|
||||
.retry-link {
|
||||
color: var(--color-info);
|
||||
color: var(--color-info-500);
|
||||
cursor: pointer;
|
||||
margin-left: 4px;
|
||||
|
||||
@ -539,10 +573,10 @@ const toggleToolCall = (toolCallId) => {
|
||||
|
||||
.ant-btn-icon-only {
|
||||
&:has(.anticon-stop) {
|
||||
background-color: var(--color-error) !important;
|
||||
background-color: var(--color-error-500) !important;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--chart-error-light) !important;
|
||||
background-color: var(--color-error-100) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -760,4 +794,4 @@ const toggleToolCall = (toolCallId) => {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -341,13 +341,13 @@ const emitRefresh = () => {
|
||||
transition: all 0.15s ease;
|
||||
|
||||
&.completed {
|
||||
background: var(--stats-success-bg);
|
||||
color: var(--stats-success-color);
|
||||
background: var(--color-success-50);
|
||||
color: var(--color-success-700);
|
||||
}
|
||||
|
||||
&.in_progress {
|
||||
background: var(--stats-warning-bg);
|
||||
color: var(--stats-warning-color);
|
||||
background: var(--color-warning-50);
|
||||
color: var(--color-warning-700);
|
||||
}
|
||||
|
||||
&.pending {
|
||||
|
||||
@ -286,7 +286,7 @@ const handleRemoveAttachment = (fileId) => {
|
||||
transition: all 0.15s ease;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
color: var(--color-error);
|
||||
color: var(--color-error-500);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
|
||||
@ -549,7 +549,7 @@ const printAgentConfig = async () => {
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--error-color);
|
||||
color: var(--color-error-500);
|
||||
}
|
||||
|
||||
.log-container {
|
||||
|
||||
@ -121,10 +121,10 @@
|
||||
</a-button>
|
||||
<span v-else-if="column.key === 'type'" :class="['span-type', text]">{{ text?.toUpperCase() }}</span>
|
||||
<div v-else-if="column.key === 'status'" style="display: flex; align-items: center; justify-content: flex-end;">
|
||||
<CheckCircleFilled v-if="text === 'done'" style="color: var(--color-success);"/>
|
||||
<CloseCircleFilled v-else-if="text === 'failed'" style="color: var(--color-error);"/>
|
||||
<HourglassFilled v-else-if="text === 'processing'" style="color: var(--color-info);"/>
|
||||
<ClockCircleFilled v-else-if="text === 'waiting'" style="color: var(--color-warning);"/>
|
||||
<CheckCircleFilled v-if="text === 'done'" style="color: var(--color-success-500);"/>
|
||||
<CloseCircleFilled v-else-if="text === 'failed'" style="color: var(--color-error-500);"/>
|
||||
<HourglassFilled v-else-if="text === 'processing'" style="color: var(--color-info-500);"/>
|
||||
<ClockCircleFilled v-else-if="text === 'waiting'" style="color: var(--color-warning-500);"/>
|
||||
</div>
|
||||
|
||||
<a-tooltip v-else-if="column.key === 'created_at'" :title="formatRelativeTime(text)" placement="left">
|
||||
@ -670,11 +670,11 @@ import ChunkParamsConfig from '@/components/ChunkParamsConfig.vue';
|
||||
}
|
||||
|
||||
.my-table .rechunk-btn:hover {
|
||||
color: var(--color-warning);
|
||||
color: var(--color-warning-500);
|
||||
}
|
||||
|
||||
.my-table .del-btn:hover {
|
||||
color: var(--error-color);
|
||||
color: var(--color-error-500);
|
||||
}
|
||||
|
||||
.my-table .del-btn:disabled {
|
||||
|
||||
@ -733,6 +733,6 @@ const chunkData = async () => {
|
||||
|
||||
.zip-support-tip {
|
||||
font-size: 12px;
|
||||
color: var(--color-warning);
|
||||
color: var(--color-warning-500);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -97,7 +97,7 @@ defineEmits(['index-nodes', 'export-data'])
|
||||
font-size: 14px;
|
||||
|
||||
&.warning {
|
||||
color: var(--color-warning);
|
||||
color: var(--color-warning-500);
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ defineEmits(['index-nodes', 'export-data'])
|
||||
font-weight: 600;
|
||||
|
||||
&.warning {
|
||||
color: var(--color-warning);
|
||||
color: var(--color-warning-500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -594,7 +594,7 @@ const registerEvents = () => {
|
||||
const graph = sigmaInstance.getGraph()
|
||||
if (graph.hasEdge(edge)) {
|
||||
// 高亮悬停的边
|
||||
graph.setEdgeAttribute(edge, 'color', getCSSVariable('--color-error'))
|
||||
graph.setEdgeAttribute(edge, 'color', getCSSVariable('--color-error-500'))
|
||||
graph.setEdgeAttribute(edge, 'size', (graph.getEdgeAttribute(edge, 'size') || 1) * 1.5)
|
||||
sigmaInstance.refresh()
|
||||
console.log('悬停在边上:', edge)
|
||||
@ -1271,11 +1271,11 @@ defineExpose({
|
||||
}
|
||||
|
||||
&.node-panel {
|
||||
border-left: 4px solid var(--color-success); // 绿色边框标识节点面板
|
||||
border-left: 4px solid var(--color-success-500); // 绿色边框标识节点面板
|
||||
}
|
||||
|
||||
&.edge-panel {
|
||||
border-left: 4px solid var(--color-info); // 蓝色边框标识边面板
|
||||
border-left: 4px solid var(--color-info-500); // 蓝色边框标识边面板
|
||||
}
|
||||
}
|
||||
|
||||
@ -1304,11 +1304,11 @@ defineExpose({
|
||||
flex-shrink: 0;
|
||||
|
||||
&.node-indicator {
|
||||
background: var(--color-success);
|
||||
background: var(--color-success-500);
|
||||
}
|
||||
|
||||
&.edge-indicator {
|
||||
background: var(--color-info);
|
||||
background: var(--color-info-500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -309,7 +309,7 @@ onUnmounted(() => {
|
||||
} */
|
||||
/*
|
||||
.chunk-item.highlighted {
|
||||
border-color: var(--color-success);
|
||||
border-color: var(--color-success-500);
|
||||
background: var(--main-50);
|
||||
} */
|
||||
|
||||
|
||||
@ -180,9 +180,9 @@ const handleSelectModel = async (provider, name) => {
|
||||
|
||||
<style lang="less" scoped>
|
||||
// 变量定义
|
||||
@status-success: var(--color-success);
|
||||
@status-error: var(--color-error);
|
||||
@status-warning: var(--chart-warning);
|
||||
@status-success: var(--color-success-500);
|
||||
@status-error: var(--color-error-500);
|
||||
@status-warning: var(--color-warning-500);
|
||||
@status-default: var(--gray-500);
|
||||
@border-radius: 8px;
|
||||
@scrollbar-width: 6px;
|
||||
|
||||
@ -527,8 +527,8 @@ defineExpose({
|
||||
}
|
||||
|
||||
.result-rerank-score {
|
||||
background-color: var(--stats-warning-bg);
|
||||
color: var(--stats-warning-color);
|
||||
background-color: var(--color-warning-50);
|
||||
color: var(--color-warning-700);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -491,8 +491,8 @@ function canCancel(task) {
|
||||
}
|
||||
|
||||
.task-card-error {
|
||||
background: var(--color-error-light);
|
||||
color: var(--color-error);
|
||||
background: var(--color-error-50);
|
||||
color: var(--color-error-500);
|
||||
}
|
||||
|
||||
.task-card-footer {
|
||||
@ -535,7 +535,7 @@ function canCancel(task) {
|
||||
}
|
||||
|
||||
.completion-badge--success {
|
||||
color: var(--color-success);
|
||||
color: var(--color-success-500);
|
||||
}
|
||||
|
||||
.completion-badge--success .completion-icon {
|
||||
@ -545,12 +545,12 @@ function canCancel(task) {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
background: var(--stats-success-bg);
|
||||
background: var(--color-success-50);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.completion-badge--failed {
|
||||
color: var(--color-error);
|
||||
color: var(--color-error-500);
|
||||
}
|
||||
|
||||
.completion-badge--failed .completion-icon {
|
||||
@ -560,7 +560,7 @@ function canCancel(task) {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
background: var(--stats-error-bg);
|
||||
background: var(--color-error-50);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="user-info-component">
|
||||
<a-dropdown :trigger="['click']" v-if="userStore.isLoggedIn">
|
||||
<a-dropdown :trigger="['hover']" v-if="userStore.isLoggedIn">
|
||||
<div class="user-info-dropdown" :data-align="showRole ? 'left' : 'center'">
|
||||
<div class="user-avatar">
|
||||
<img v-if="userStore.avatar" :src="userStore.avatar" :alt="userStore.username" class="avatar-image" />
|
||||
@ -30,6 +30,10 @@
|
||||
<span class="menu-text">{{ themeStore.isDark ? '切换到浅色模式' : '切换到深色模式 (Beta)' }}</span>
|
||||
</a-menu-item>
|
||||
<a-menu-divider />
|
||||
<a-menu-item key="setting" @click="goToSetting">
|
||||
<Settings size="16"/>
|
||||
<span class="menu-text">系统设置</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="logout" @click="logout">
|
||||
<LogOut size="16"/>
|
||||
<span class="menu-text">退出登录</span>
|
||||
@ -162,7 +166,7 @@ import { useUserStore } from '@/stores/user';
|
||||
//
|
||||
//
|
||||
import { message } from 'ant-design-vue';
|
||||
import { CircleUser, UserRoundCheck, BookOpen, Sun, Moon, User, LogOut, Upload } from 'lucide-vue-next';
|
||||
import { CircleUser, UserRoundCheck, BookOpen, Sun, Moon, User, LogOut, Upload, Settings } from 'lucide-vue-next';
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
|
||||
const router = useRouter();
|
||||
@ -239,6 +243,11 @@ const toggleTheme = () => {
|
||||
themeStore.toggleTheme()
|
||||
}
|
||||
|
||||
// 前往设置页
|
||||
const goToSetting = () => {
|
||||
router.push('/setting');
|
||||
}
|
||||
|
||||
// 打开个人资料页面
|
||||
const openProfile = async () => {
|
||||
profileModalVisible.value = true;
|
||||
@ -421,15 +430,15 @@ const handleAvatarChange = async (info) => {
|
||||
border: 2px solid var(--gray-0);
|
||||
|
||||
&.superadmin {
|
||||
background-color: var(--color-warning);
|
||||
background-color: var(--color-warning-500);
|
||||
}
|
||||
|
||||
&.admin {
|
||||
background-color: var(--color-info); /* 蓝色,管理员 */
|
||||
background-color: var(--color-info-500); /* 蓝色,管理员 */
|
||||
}
|
||||
|
||||
&.user {
|
||||
background-color: var(--color-success); /* 绿色,普通用户 */
|
||||
background-color: var(--color-success-500); /* 绿色,普通用户 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -645,8 +645,8 @@ onMounted(() => {
|
||||
|
||||
&.ant-btn-dangerous:hover {
|
||||
background: var(--gray-25);
|
||||
border-color: var(--color-error);
|
||||
color: var(--color-error);
|
||||
border-color: var(--color-error-500);
|
||||
color: var(--color-error-500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -698,7 +698,7 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.error-text {
|
||||
color: var(--color-error);
|
||||
color: var(--color-error-500);
|
||||
font-size: 12px;
|
||||
margin-top: 4px;
|
||||
line-height: 1.3;
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<a-statistic
|
||||
title="智能体总数"
|
||||
:value="agentStats?.total_agents || 0"
|
||||
:value-style="{ color: 'var(--chart-info)' }"
|
||||
:value-style="{ color: 'var(--color-info-500)' }"
|
||||
suffix="个"
|
||||
/>
|
||||
</a-col>
|
||||
@ -15,7 +15,7 @@
|
||||
<a-statistic
|
||||
title="总对话数"
|
||||
:value="totalConversations"
|
||||
:value-style="{ color: 'var(--chart-secondary)' }"
|
||||
:value-style="{ color: 'var(--color-accent-500)' }"
|
||||
suffix="次"
|
||||
/>
|
||||
</a-col>
|
||||
@ -23,7 +23,7 @@
|
||||
<a-statistic
|
||||
title="工具调用总数"
|
||||
:value="totalToolUsage"
|
||||
:value-style="{ color: 'var(--chart-warning)' }"
|
||||
:value-style="{ color: 'var(--color-warning-500)' }"
|
||||
suffix="次"
|
||||
/>
|
||||
</a-col>
|
||||
@ -65,22 +65,13 @@
|
||||
<template v-if="column.key === 'agent_id'">
|
||||
<a-tag color="blue">{{ record.agent_id }}</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'score'">
|
||||
<a-progress
|
||||
:percent="record.score"
|
||||
size="small"
|
||||
:stroke-color="getScoreColor(record.score)"
|
||||
:show-info="true"
|
||||
:format="(percent) => `${percent}分`"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'satisfaction_rate'">
|
||||
<a-statistic
|
||||
:value="record.satisfaction_rate"
|
||||
suffix="%"
|
||||
:value-style="{
|
||||
color: record.satisfaction_rate >= 80 ? 'var(--chart-success)' :
|
||||
record.satisfaction_rate >= 60 ? 'var(--chart-warning)' : 'var(--chart-error)',
|
||||
color: record.satisfaction_rate >= 80 ? 'var(--color-success-500)' :
|
||||
record.satisfaction_rate >= 60 ? 'var(--color-warning-500)' : 'var(--color-error-500)',
|
||||
fontSize: '14px'
|
||||
}"
|
||||
/>
|
||||
@ -98,7 +89,7 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, watch, nextTick, computed } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { getColorByIndex, getChartColor } from '@/utils/chartColors'
|
||||
import { getColorByIndex } from '@/utils/chartColors'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
|
||||
// CSS 变量解析工具函数
|
||||
@ -136,23 +127,18 @@ const performerColumns = [
|
||||
{
|
||||
title: '智能体ID',
|
||||
key: 'agent_id',
|
||||
width: '25%'
|
||||
},
|
||||
{
|
||||
title: '综合评分',
|
||||
key: 'score',
|
||||
width: '20%'
|
||||
width: '30%'
|
||||
},
|
||||
{
|
||||
title: '满意度',
|
||||
key: 'satisfaction_rate',
|
||||
width: '20%',
|
||||
width: '25%',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '对话数',
|
||||
key: 'conversation_count',
|
||||
width: '15%',
|
||||
width: '20%',
|
||||
align: 'center'
|
||||
}
|
||||
]
|
||||
@ -172,12 +158,6 @@ const topPerformers = computed(() => {
|
||||
return props.agentStats?.top_performing_agents || []
|
||||
})
|
||||
|
||||
// 颜色辅助函数
|
||||
const getScoreColor = (score) => {
|
||||
if (score >= 80) return getChartColor('primary')
|
||||
if (score >= 60) return getChartColor('warning')
|
||||
return getChartColor('accent')
|
||||
}
|
||||
|
||||
|
||||
// 初始化对话数和工具调用数合并图表
|
||||
@ -288,14 +268,14 @@ const initConversationToolChart = () => {
|
||||
return item ? item.conversation_count : 0
|
||||
}),
|
||||
itemStyle: {
|
||||
color: getChartColor('primary'),
|
||||
color: getColorByIndex(0),
|
||||
borderRadius: [4, 4, 0, 0]
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
color: getChartColor('primary'),
|
||||
color: getColorByIndex(0),
|
||||
shadowBlur: 10,
|
||||
shadowColor: getCSSVariable('--chart-info-shadow')
|
||||
shadowColor: getCSSVariable('--color-info-50')
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -307,14 +287,14 @@ const initConversationToolChart = () => {
|
||||
return item ? item.tool_usage_count : 0
|
||||
}),
|
||||
itemStyle: {
|
||||
color: getChartColor('accent'),
|
||||
color: getColorByIndex(1),
|
||||
borderRadius: [4, 4, 0, 0]
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
color: getChartColor('primary'),
|
||||
color: getColorByIndex(1),
|
||||
shadowBlur: 10,
|
||||
shadowColor: getCSSVariable('--chart-info-shadow')
|
||||
shadowColor: getCSSVariable('--color-info-50')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -431,4 +411,8 @@ defineExpose({
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
:deep(.ant-statistic-content-value) {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -304,10 +304,10 @@ watch(() => props.agentId, () => {
|
||||
}
|
||||
|
||||
.reason-content {
|
||||
background: var(--color-warning-light);
|
||||
background: var(--color-warning-50);
|
||||
padding: 10px;
|
||||
border-radius: 6px;
|
||||
border-left: 3px solid var(--color-warning);
|
||||
border-left: 3px solid var(--color-warning-500);
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
color: var(--gray-800);
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<a-statistic
|
||||
title="知识库总数"
|
||||
:value="knowledgeStats?.total_databases || 0"
|
||||
:value-style="{ color: 'var(--chart-info)' }"
|
||||
:value-style="{ color: 'var(--color-info-500)' }"
|
||||
suffix="个"
|
||||
/>
|
||||
</a-col>
|
||||
@ -15,7 +15,7 @@
|
||||
<a-statistic
|
||||
title="文件总数"
|
||||
:value="knowledgeStats?.total_files || 0"
|
||||
:value-style="{ color: 'var(--chart-success)' }"
|
||||
:value-style="{ color: 'var(--color-success-500)' }"
|
||||
suffix="个"
|
||||
/>
|
||||
</a-col>
|
||||
@ -23,7 +23,7 @@
|
||||
<a-statistic
|
||||
title="存储容量"
|
||||
:value="formattedStorageSize"
|
||||
:value-style="{ color: 'var(--chart-warning)' }"
|
||||
:value-style="{ color: 'var(--color-warning-500)' }"
|
||||
/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
@ -103,7 +103,7 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, watch, nextTick, computed } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { getColorByIndex, getChartColor, getColorPalette } from '@/utils/chartColors'
|
||||
import { getColorByIndex, getColorPalette } from '@/utils/chartColors'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
|
||||
// CSS 变量解析工具函数
|
||||
@ -356,7 +356,7 @@ const initFileTypeChart = () => {
|
||||
data: [
|
||||
{ name: '暂无数据', value: 1 }
|
||||
],
|
||||
color: [getCSSVariable('--chart-info-lighter')]
|
||||
color: [getCSSVariable('--color-info-500')]
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
@ -124,57 +124,57 @@ const getSatisfactionClass = () => {
|
||||
|
||||
&.primary {
|
||||
.stat-icon {
|
||||
background-color: var(--stats-primary-bg);
|
||||
color: var(--stats-primary-color);
|
||||
background-color: var(--color-primary-50);
|
||||
color: var(--main-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.success {
|
||||
.stat-icon {
|
||||
background-color: var(--stats-success-bg);
|
||||
color: var(--stats-success-color);
|
||||
background-color: var(--color-success-50);
|
||||
color: var(--color-success-700);
|
||||
}
|
||||
}
|
||||
|
||||
&.info {
|
||||
.stat-icon {
|
||||
background-color: var(--stats-info-bg);
|
||||
color: var(--stats-info-color);
|
||||
background-color: var(--color-info-50);
|
||||
color: var(--color-info-700);
|
||||
}
|
||||
}
|
||||
|
||||
&.warning {
|
||||
.stat-icon {
|
||||
background-color: var(--stats-warning-bg);
|
||||
color: var(--stats-warning-color);
|
||||
background-color: var(--color-warning-50);
|
||||
color: var(--color-warning-700);
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
.stat-icon {
|
||||
background-color: var(--stats-secondary-bg);
|
||||
color: var(--stats-secondary-color);
|
||||
background-color: var(--color-accent-50);
|
||||
color: var(--color-accent-700);
|
||||
}
|
||||
}
|
||||
|
||||
&.satisfaction-high {
|
||||
.stat-icon {
|
||||
background-color: var(--stats-success-bg);
|
||||
color: var(--stats-success-color);
|
||||
background-color: var(--color-success-50);
|
||||
color: var(--color-success-700);
|
||||
}
|
||||
}
|
||||
|
||||
&.satisfaction-medium {
|
||||
.stat-icon {
|
||||
background-color: var(--stats-warning-bg);
|
||||
color: var(--stats-warning-color);
|
||||
background-color: var(--color-warning-50);
|
||||
color: var(--color-warning-700);
|
||||
}
|
||||
}
|
||||
|
||||
&.satisfaction-low {
|
||||
.stat-icon {
|
||||
background-color: var(--stats-error-bg);
|
||||
color: var(--stats-error-color);
|
||||
background-color: var(--color-error-50);
|
||||
color: var(--color-error-700);
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,11 +226,11 @@ const getSatisfactionClass = () => {
|
||||
height: 14px;
|
||||
|
||||
&.up {
|
||||
color: var(--stats-success-color);
|
||||
color: var(--color-success-700);
|
||||
}
|
||||
|
||||
&.down {
|
||||
color: var(--stats-error-color);
|
||||
color: var(--color-error-700);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,14 +7,14 @@
|
||||
<a-statistic
|
||||
title="总调用次数"
|
||||
:value="toolStats?.total_calls || 0"
|
||||
:value-style="{ color: 'var(--chart-info)' }"
|
||||
:value-style="{ color: 'var(--color-info-500)' }"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-statistic
|
||||
title="失败调用"
|
||||
:value="toolStats?.failed_calls || 0"
|
||||
:value-style="{ color: 'var(--chart-error)' }"
|
||||
:value-style="{ color: 'var(--color-error-500)' }"
|
||||
suffix="次"
|
||||
/>
|
||||
</a-col>
|
||||
@ -24,8 +24,8 @@
|
||||
:value="toolStats?.success_rate || 0"
|
||||
suffix="%"
|
||||
:value-style="{
|
||||
color: (toolStats?.success_rate || 0) >= 90 ? 'var(--chart-success)' :
|
||||
(toolStats?.success_rate || 0) >= 70 ? 'var(--chart-warning)' : 'var(--chart-error)'
|
||||
color: (toolStats?.success_rate || 0) >= 90 ? 'var(--color-success-500)' :
|
||||
(toolStats?.success_rate || 0) >= 70 ? 'var(--color-warning-500)' : 'var(--color-error-500)'
|
||||
}"
|
||||
/>
|
||||
</a-col>
|
||||
@ -78,7 +78,7 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, watch, nextTick, computed } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { getColorByIndex, getChartColor, getColorPalette } from '@/utils/chartColors'
|
||||
import { getColorByIndex, getColorPalette } from '@/utils/chartColors'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
|
||||
// CSS 变量解析工具函数
|
||||
@ -205,14 +205,14 @@ const initToolsChart = () => {
|
||||
type: 'bar',
|
||||
data: data.map(item => item.count),
|
||||
itemStyle: {
|
||||
color: getChartColor('primary'),
|
||||
color: getColorByIndex(0),
|
||||
borderRadius: [0, 4, 4, 0]
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
color: getChartColor('primary'),
|
||||
color: getColorByIndex(0),
|
||||
shadowBlur: 10,
|
||||
shadowColor: getCSSVariable('--chart-info-shadow')
|
||||
shadowColor: getCSSVariable('--color-info-50')
|
||||
}
|
||||
}
|
||||
}]
|
||||
@ -331,15 +331,3 @@ defineExpose({
|
||||
cleanup
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
// ToolStatsComponent 特有的样式
|
||||
.error-analysis {
|
||||
h4 {
|
||||
margin-bottom: 16px;
|
||||
color: var(--gray-1000);
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -30,8 +30,6 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, watch, nextTick } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { getChartColor } from '@/utils/chartColors'
|
||||
import { dashboardApi } from '@/apis/dashboard_api'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
|
||||
// CSS 变量解析工具函数
|
||||
@ -121,7 +119,7 @@ const initActivityChart = () => {
|
||||
data: props.userStats.daily_active_users.map(item => item.active_users),
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
color: getChartColor('primary'),
|
||||
color: getCSSVariable('--main-color'),
|
||||
width: 3
|
||||
},
|
||||
areaStyle: {
|
||||
@ -132,24 +130,24 @@ const initActivityChart = () => {
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: getCSSVariable('--chart-primary-light')
|
||||
offset: 0, color: getCSSVariable('--main-500')
|
||||
}, {
|
||||
offset: 1, color: getCSSVariable('--chart-primary-lighter')
|
||||
offset: 1, color: getCSSVariable('--main-0')
|
||||
}]
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: getChartColor('primary'),
|
||||
color: getCSSVariable('--main-color'),
|
||||
borderWidth: 2,
|
||||
borderColor: getCSSVariable('--gray-0')
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
color: getChartColor('primary'),
|
||||
color: getCSSVariable('--main-color'),
|
||||
borderWidth: 3,
|
||||
borderColor: getCSSVariable('--gray-0'),
|
||||
shadowBlur: 10,
|
||||
shadowColor: getCSSVariable('--chart-primary-shadow')
|
||||
shadowColor: getCSSVariable('--shadow-1')
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
@ -4,7 +4,7 @@ import { RouterLink, RouterView, useRoute } from 'vue-router'
|
||||
import {
|
||||
GithubOutlined,
|
||||
} from '@ant-design/icons-vue'
|
||||
import { Bot, Waypoints, LibraryBig, Settings, BarChart3, CircleCheck } from 'lucide-vue-next';
|
||||
import { Bot, Waypoints, LibraryBig, BarChart3, CircleCheck } from 'lucide-vue-next';
|
||||
import { onLongPress } from '@vueuse/core'
|
||||
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
@ -188,19 +188,10 @@ const mainList = [{
|
||||
|
||||
<!-- 用户信息组件 -->
|
||||
<div class="nav-item user-info">
|
||||
<a-tooltip placement="right">
|
||||
<template #title>用户信息</template>
|
||||
<UserInfoComponent />
|
||||
</a-tooltip>
|
||||
<UserInfoComponent />
|
||||
</div>
|
||||
|
||||
<RouterLink class="nav-item setting" to="/setting" active-class="active">
|
||||
<a-tooltip placement="right">
|
||||
<template #title>设置</template>
|
||||
<Settings />
|
||||
</a-tooltip>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-mobile">
|
||||
<RouterLink to="/agent" class="nav-item" active-class="active">对话</RouterLink>
|
||||
<RouterLink to="/database" class="nav-item" active-class="active">知识</RouterLink>
|
||||
@ -347,7 +338,7 @@ div.header, #app-router-view {
|
||||
}
|
||||
|
||||
&.warning {
|
||||
color: var(--color-error);
|
||||
color: var(--color-error-500);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@ -376,7 +367,7 @@ div.header, #app-router-view {
|
||||
margin-top: 4px;
|
||||
|
||||
.star-icon {
|
||||
color: var(--color-warning);
|
||||
color: var(--color-warning-500);
|
||||
font-size: 12px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
@ -415,13 +406,8 @@ div.header, #app-router-view {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.setting {
|
||||
margin: 8px 0;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
&.user-info {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -537,7 +523,7 @@ div.header, #app-router-view {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
&.github, &.setting {
|
||||
&.github {
|
||||
padding: 8px 12px;
|
||||
|
||||
.icon {
|
||||
@ -548,9 +534,7 @@ div.header, #app-router-view {
|
||||
&.active {
|
||||
color: var(--main-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.github {
|
||||
a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -562,7 +546,7 @@ div.header, #app-router-view {
|
||||
margin-left: 6px;
|
||||
|
||||
.star-icon {
|
||||
color: var(--color-warning);
|
||||
color: var(--color-warning-500);
|
||||
font-size: 14px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
@ -21,28 +21,27 @@ const buildColorPalette = () => {
|
||||
return v && v.trim() ? v.trim() : fallback
|
||||
}
|
||||
|
||||
// Base chart colors
|
||||
// Base chart colors - using new color system
|
||||
const baseVars = [
|
||||
['--chart-primary', '#3996ae'],
|
||||
['--chart-success', '#52c41a'],
|
||||
['--chart-warning', '#faad14'],
|
||||
['--chart-error', '#f5222d'],
|
||||
['--chart-secondary', '#722ed1'],
|
||||
['--chart-accent', '#13c2c2'],
|
||||
['--main-500', '#3996ae'],
|
||||
['--color-success-500', '#52c41a'],
|
||||
['--color-warning-500', '#faad14'],
|
||||
['--color-error-500', '#ff4d4f'],
|
||||
['--color-accent-500', '#13c2c2'],
|
||||
]
|
||||
|
||||
// Extended palette colors
|
||||
const paletteVars = [
|
||||
['--chart-palette-1', '#3996ae'],
|
||||
['--chart-palette-2', '#028ea0'],
|
||||
['--chart-palette-3', '#00b8a9'],
|
||||
['--chart-palette-4', '#f2c94c'],
|
||||
['--chart-palette-5', '#eb5757'],
|
||||
['--chart-palette-6', '#2f80ed'],
|
||||
['--chart-palette-7', '#9b51e0'],
|
||||
['--chart-palette-8', '#56ccf2'],
|
||||
['--chart-palette-9', '#6fcf97'],
|
||||
['--chart-palette-10', '#333333'],
|
||||
['--chart-palette-1', '#265C96'],
|
||||
['--chart-palette-2', '#009485'],
|
||||
['--chart-palette-3', '#E8A035'],
|
||||
['--chart-palette-4', '#D64B55'],
|
||||
['--chart-palette-5', '#7D54C4'],
|
||||
['--chart-palette-6', '#2D9CDB'],
|
||||
['--chart-palette-7', '#F28B30'],
|
||||
['--chart-palette-8', '#65C466'],
|
||||
['--chart-palette-9', '#C2589E'],
|
||||
['--chart-palette-10', '#4F4F4F'],
|
||||
]
|
||||
|
||||
const baseColors = baseVars.map(([n, f]) => pick(n, f))
|
||||
@ -59,8 +58,8 @@ const buildColorPalette = () => {
|
||||
console.warn('Failed to build color palette from CSS variables, using fallback:', e)
|
||||
// Fallback palette
|
||||
colorPalette = [
|
||||
'#3996ae', '#52c41a', '#faad14', '#f5222d', '#722ed1', '#13c2c2',
|
||||
'#fa8c16', '#1890ff', '#95de64', '#69c0ff'
|
||||
'#3996ae', '#52c41a', '#faad14', '#ff4d4f', '#13c2c2',
|
||||
'#265C96', '#009485', '#E8A035', '#D64B55', '#7D54C4'
|
||||
]
|
||||
isInitialized = true
|
||||
}
|
||||
@ -91,33 +90,6 @@ export const getColorPalette = () => {
|
||||
return [...colorPalette] // Return a copy
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specific chart colors by name
|
||||
* 根据名称获取特定的图表颜色
|
||||
* @param {string} colorName - Color name (primary, success, warning, error, secondary, accent)
|
||||
* @returns {string} Color value
|
||||
*/
|
||||
export const getChartColor = (colorName) => {
|
||||
const colorMap = {
|
||||
primary: '#3996ae',
|
||||
success: '#52c41a',
|
||||
warning: '#faad14',
|
||||
error: '#f5222d',
|
||||
secondary: '#722ed1',
|
||||
accent: '#13c2c2'
|
||||
}
|
||||
|
||||
try {
|
||||
const root = document.documentElement
|
||||
const styles = getComputedStyle(root)
|
||||
const cssVarName = `--chart-${colorName}`
|
||||
const value = styles.getPropertyValue(cssVarName)
|
||||
return value && value.trim() ? value.trim() : colorMap[colorName] || colorMap.primary
|
||||
} catch (e) {
|
||||
return colorMap[colorName] || colorMap.primary
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate legend text for better display
|
||||
* 截断图例文本以便更好地显示
|
||||
|
||||
@ -437,7 +437,7 @@ const handlePreview = () => {
|
||||
}
|
||||
|
||||
.default-icon {
|
||||
color: var(--color-warning);
|
||||
color: var(--color-warning-500);
|
||||
font-size: 14px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
@ -763,7 +763,7 @@ const handlePreview = () => {
|
||||
}
|
||||
|
||||
.default-icon {
|
||||
color: var(--color-warning);
|
||||
color: var(--color-warning-500);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
@ -834,7 +834,7 @@ const handlePreview = () => {
|
||||
}
|
||||
|
||||
.default-icon {
|
||||
color: var(--color-warning);
|
||||
color: var(--color-warning-500);
|
||||
font-size: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@ -696,4 +696,5 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
</style>
|
||||
@ -11,7 +11,7 @@
|
||||
<a-modal :open="state.openNewDatabaseModel" title="新建知识库" @ok="createDatabase" @cancel="cancelCreateDatabase" class="new-database-modal" width="800px">
|
||||
|
||||
<!-- 知识库类型选择 -->
|
||||
<h3>知识库类型<span style="color: var(--error-color)">*</span></h3>
|
||||
<h3>知识库类型<span style="color: var(--color-error-500)">*</span></h3>
|
||||
<div class="kb-type-cards">
|
||||
<div
|
||||
v-for="(typeInfo, typeKey) in supportedKbTypes"
|
||||
@ -25,9 +25,6 @@
|
||||
<span class="type-title">{{ getKbTypeLabel(typeKey) }}</span>
|
||||
</div>
|
||||
<div class="card-description">{{ typeInfo.description }}</div>
|
||||
<div class="card-features">
|
||||
<span class="feature-tag">{{ getKbTypeFeature(typeKey) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -41,7 +38,7 @@
|
||||
/>
|
||||
</div> -->
|
||||
|
||||
<h3>知识库名称<span style="color: var(--error-color)">*</span></h3>
|
||||
<h3>知识库名称<span style="color: var(--color-error-500)">*</span></h3>
|
||||
<a-input v-model:value="newDatabase.name" placeholder="新建知识库名称" size="large" />
|
||||
|
||||
<h3>嵌入模型</h3>
|
||||
@ -398,14 +395,6 @@ const getKbTypeColor = (type) => {
|
||||
return colors[type] || 'blue'
|
||||
}
|
||||
|
||||
const getKbTypeFeature = (type) => {
|
||||
const features = {
|
||||
lightrag: '图结构索引',
|
||||
chroma: '轻量向量',
|
||||
milvus: '生产级部署'
|
||||
}
|
||||
return features[type] || ''
|
||||
}
|
||||
|
||||
// 格式化创建时间
|
||||
const formatCreatedTime = (createdAt) => {
|
||||
@ -612,6 +601,10 @@ onMounted(() => {
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.reranker-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -653,6 +646,10 @@ onMounted(() => {
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
color: var(--gray-500);
|
||||
|
||||
&:last-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -685,15 +682,15 @@ onMounted(() => {
|
||||
|
||||
// 为不同知识库类型设置不同的悬停颜色
|
||||
&:nth-child(1):hover {
|
||||
border-color: var(--chart-secondary-light);
|
||||
border-color: var(--color-accent-100);
|
||||
}
|
||||
|
||||
&:nth-child(2):hover {
|
||||
border-color: var(--chart-warning-light);
|
||||
border-color: var(--color-warning-100);
|
||||
}
|
||||
|
||||
&:nth-child(3):hover {
|
||||
border-color: var(--chart-error-light);
|
||||
border-color: var(--color-error-100);
|
||||
}
|
||||
|
||||
&.active {
|
||||
@ -703,58 +700,38 @@ onMounted(() => {
|
||||
.type-icon {
|
||||
color: var(--main-color);
|
||||
}
|
||||
|
||||
.feature-tag {
|
||||
background: rgba(24, 144, 255, 0.1);
|
||||
color: var(--main-color);
|
||||
}
|
||||
}
|
||||
|
||||
// 为不同知识库类型设置不同的主题色
|
||||
&:nth-child(1) {
|
||||
&.active {
|
||||
border-color: var(--chart-secondary-light);
|
||||
border-color: var(--color-accent-100);
|
||||
background: rgba(114, 46, 209, 0.05);
|
||||
|
||||
.type-icon {
|
||||
color: var(--chart-secondary);
|
||||
}
|
||||
|
||||
.feature-tag {
|
||||
background: rgba(114, 46, 209, 0.1);
|
||||
color: var(--chart-secondary);
|
||||
color: var(--color-accent-500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
&.active {
|
||||
border-color: var(--chart-warning-light);
|
||||
border-color: var(--color-warning-100);
|
||||
background: rgba(250, 140, 22, 0.05);
|
||||
|
||||
.type-icon {
|
||||
color: var(--chart-warning);
|
||||
}
|
||||
|
||||
.feature-tag {
|
||||
background: rgba(250, 140, 22, 0.1);
|
||||
color: var(--chart-warning);
|
||||
color: var(--color-warning-500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
&.active {
|
||||
border-color: var(--chart-error-light);
|
||||
border-color: var(--color-error-100);
|
||||
background: rgba(245, 34, 45, 0.05);
|
||||
|
||||
.type-icon {
|
||||
color: var(--chart-error);
|
||||
}
|
||||
|
||||
.feature-tag {
|
||||
background: rgba(245, 34, 45, 0.1);
|
||||
color: var(--chart-error);
|
||||
color: var(--color-error-500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -786,18 +763,6 @@ onMounted(() => {
|
||||
margin-bottom: 12px;
|
||||
// min-height: 40px;
|
||||
}
|
||||
|
||||
.card-features {
|
||||
.feature-tag {
|
||||
display: inline-block;
|
||||
padding: 4px 8px;
|
||||
background: rgba(24, 144, 255, 0.08);
|
||||
color: var(--main-color);
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -920,7 +885,7 @@ onMounted(() => {
|
||||
align-items: center;
|
||||
background: var(--main-30);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--gray-200);
|
||||
border: 1px solid var(--gray-150);
|
||||
color: var(--main-color);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@ -393,16 +393,16 @@ const openLink = (url) => {
|
||||
display: inline-block;
|
||||
|
||||
&.loading {
|
||||
background-color: var(--color-warning);
|
||||
background-color: var(--color-warning-500);
|
||||
animation: pulse 1.5s infinite ease-in-out;
|
||||
}
|
||||
|
||||
&.open {
|
||||
background-color: var(--color-success);
|
||||
background-color: var(--color-success-500);
|
||||
}
|
||||
|
||||
&.closed {
|
||||
background-color: var(--color-error);
|
||||
background-color: var(--color-error-500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -92,6 +92,7 @@ import { useRouter } from 'vue-router'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { useInfoStore } from '@/stores/info'
|
||||
import { useAgentStore } from '@/stores/agent'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
import UserInfoComponent from '@/components/UserInfoComponent.vue'
|
||||
import {
|
||||
BookText,
|
||||
@ -109,6 +110,7 @@ const router = useRouter()
|
||||
const userStore = useUserStore()
|
||||
const infoStore = useInfoStore()
|
||||
const agentStore = useAgentStore()
|
||||
const themeStore = useThemeStore()
|
||||
|
||||
const goToChat = async () => {
|
||||
// 检查用户是否登录
|
||||
@ -332,11 +334,21 @@ const actionLinks = computed(() => {
|
||||
svg {
|
||||
margin-right: 6px;
|
||||
transition: transform 0.3s ease;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.stars-count {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
// 暗色模式样式
|
||||
:global(.dark) & {
|
||||
color: var(--gray-400);
|
||||
|
||||
&:hover {
|
||||
color: var(--gray-300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hero-section {
|
||||
|
||||
@ -716,10 +716,10 @@ onUnmounted(() => {
|
||||
.error-message {
|
||||
margin-top: 16px;
|
||||
padding: 10px 12px;
|
||||
background-color: var(--stats-error-bg);
|
||||
border: 1px solid color-mix(in srgb, var(--color-error) 25%, transparent);
|
||||
background-color: var(--color-error-50);
|
||||
border: 1px solid color-mix(in srgb, var(--color-error-500) 25%, transparent);
|
||||
border-radius: 8px;
|
||||
color: var(--stats-error-color);
|
||||
color: var(--color-error-700);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@ -808,10 +808,10 @@ onUnmounted(() => {
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 12px 20px;
|
||||
background: linear-gradient(135deg, var(--color-error), var(--chart-error-light));
|
||||
background: linear-gradient(135deg, var(--color-error-500), var(--color-error-100));
|
||||
color: var(--gray-0);
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px color-mix(in srgb, var(--color-error) 30%, transparent);
|
||||
box-shadow: 0 2px 8px color-mix(in srgb, var(--color-error-500) 30%, transparent);
|
||||
|
||||
.alert-content {
|
||||
display: flex;
|
||||
|
||||
@ -293,9 +293,9 @@ const getModelStatusIcon = (modelId) => {
|
||||
const getModelStatusColor = (modelId) => {
|
||||
const status = state.modelStatuses[modelId]
|
||||
if (!status) return 'var(--gray-500)'
|
||||
if (status.status === 'available') return 'var(--color-success)'
|
||||
if (status.status === 'unavailable') return 'var(--color-error)'
|
||||
if (status.status === 'error') return 'var(--color-warning)'
|
||||
if (status.status === 'available') return 'var(--color-success-500)'
|
||||
if (status.status === 'unavailable') return 'var(--color-error-500)'
|
||||
if (status.status === 'error') return 'var(--color-warning-500)'
|
||||
return 'var(--gray-500)'
|
||||
}
|
||||
// 获取模型状态提示文本
|
||||
|
||||
Loading…
Reference in New Issue
Block a user