refactor: 清理不需要的代码文件,添加.gitignore,优化项目结构
This commit is contained in:
107
.gitignore
vendored
Normal file
107
.gitignore
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
# Python缓存文件
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
|
||||
# 分发/打包
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# 单元测试/覆盖率报告
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# 环境变量
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# IDE文件
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# 操作系统文件
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# 日志文件
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# 数据库文件(开发环境)
|
||||
*.db
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
|
||||
# 备份文件
|
||||
backups/
|
||||
*.backup
|
||||
*.bak
|
||||
|
||||
# 临时文件
|
||||
*.tmp
|
||||
*.temp
|
||||
temp/
|
||||
tmp/
|
||||
|
||||
# 部署相关
|
||||
deploy_config.json
|
||||
dev_deploy/
|
||||
|
||||
# 测试文件
|
||||
test_*.py
|
||||
*_test.py
|
||||
test_sample.txt
|
||||
|
||||
# 文档草稿
|
||||
note/
|
||||
*问题修复*.md
|
||||
*修复总结*.md
|
||||
*使用指南*.md
|
||||
|
||||
# Excel文件(除了模板)
|
||||
*.xlsx
|
||||
!uploads/workorder_template.xlsx
|
||||
|
||||
# 配置文件(敏感信息)
|
||||
config/local_config.py
|
||||
.env.local
|
||||
1173
TSP智能助手使用指南.md
1173
TSP智能助手使用指南.md
File diff suppressed because it is too large
Load Diff
@@ -1,505 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
TSP智能助手 - 全面前端功能测试脚本
|
||||
测试所有前端页面的功能
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
import os
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
|
||||
class TSPFrontendTester:
|
||||
"""TSP前端功能测试器"""
|
||||
|
||||
def __init__(self, base_url="http://localhost:5000"):
|
||||
self.base_url = base_url
|
||||
self.session = requests.Session()
|
||||
self.test_results = {
|
||||
"total_tests": 0,
|
||||
"passed": 0,
|
||||
"failed": 0,
|
||||
"errors": []
|
||||
}
|
||||
|
||||
def log_test(self, test_name, success, message=""):
|
||||
"""记录测试结果"""
|
||||
self.test_results["total_tests"] += 1
|
||||
if success:
|
||||
self.test_results["passed"] += 1
|
||||
print(f"✅ {test_name}: {message}")
|
||||
else:
|
||||
self.test_results["failed"] += 1
|
||||
self.test_results["errors"].append(f"{test_name}: {message}")
|
||||
print(f"❌ {test_name}: {message}")
|
||||
|
||||
def test_server_connection(self):
|
||||
"""测试服务器连接"""
|
||||
print("\n" + "="*60)
|
||||
print("🔗 测试服务器连接")
|
||||
print("="*60)
|
||||
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/")
|
||||
if response.status_code == 200:
|
||||
self.log_test("服务器连接", True, "服务器响应正常")
|
||||
return True
|
||||
else:
|
||||
self.log_test("服务器连接", False, f"HTTP {response.status_code}")
|
||||
return False
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.log_test("服务器连接", False, "无法连接到服务器")
|
||||
return False
|
||||
except Exception as e:
|
||||
self.log_test("服务器连接", False, f"连接错误: {e}")
|
||||
return False
|
||||
|
||||
def test_health_endpoint(self):
|
||||
"""测试健康检查端点"""
|
||||
print("\n" + "="*60)
|
||||
print("🏥 测试健康检查")
|
||||
print("="*60)
|
||||
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/health")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
self.log_test("健康检查", True, f"状态: {data.get('status', 'unknown')}")
|
||||
return True
|
||||
else:
|
||||
self.log_test("健康检查", False, f"HTTP {response.status_code}")
|
||||
return False
|
||||
except Exception as e:
|
||||
self.log_test("健康检查", False, f"请求错误: {e}")
|
||||
return False
|
||||
|
||||
def test_agent_functionality(self):
|
||||
"""测试Agent功能"""
|
||||
print("\n" + "="*60)
|
||||
print("🤖 测试Agent功能")
|
||||
print("="*60)
|
||||
|
||||
# 1. 获取Agent状态
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/agent/status")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
self.log_test("获取Agent状态", True, f"状态: {data.get('status', 'unknown')}")
|
||||
else:
|
||||
self.log_test("获取Agent状态", False, "返回失败状态")
|
||||
else:
|
||||
self.log_test("获取Agent状态", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("获取Agent状态", False, f"请求错误: {e}")
|
||||
|
||||
# 2. 切换Agent模式
|
||||
try:
|
||||
response = self.session.post(f"{self.base_url}/api/agent/toggle",
|
||||
json={"enabled": True})
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
self.log_test("切换Agent模式", True, data.get("message", "切换成功"))
|
||||
else:
|
||||
self.log_test("切换Agent模式", False, "切换失败")
|
||||
else:
|
||||
self.log_test("切换Agent模式", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("切换Agent模式", False, f"请求错误: {e}")
|
||||
|
||||
# 3. 启动Agent监控
|
||||
try:
|
||||
response = self.session.post(f"{self.base_url}/api/agent/monitoring/start")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
self.log_test("启动Agent监控", True, data.get("message", "启动成功"))
|
||||
else:
|
||||
self.log_test("启动Agent监控", False, "启动失败")
|
||||
else:
|
||||
self.log_test("启动Agent监控", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("启动Agent监控", False, f"请求错误: {e}")
|
||||
|
||||
# 4. 运行主动监控
|
||||
try:
|
||||
response = self.session.post(f"{self.base_url}/api/agent/proactive-monitoring")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
actions = data.get("proactive_actions", [])
|
||||
self.log_test("运行主动监控", True, f"发现 {len(actions)} 个行动机会")
|
||||
else:
|
||||
self.log_test("运行主动监控", False, "监控失败")
|
||||
else:
|
||||
self.log_test("运行主动监控", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("运行主动监控", False, f"请求错误: {e}")
|
||||
|
||||
# 5. 运行智能分析
|
||||
try:
|
||||
response = self.session.post(f"{self.base_url}/api/agent/intelligent-analysis")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
self.log_test("运行智能分析", True, "分析完成")
|
||||
else:
|
||||
self.log_test("运行智能分析", False, "分析失败")
|
||||
else:
|
||||
self.log_test("运行智能分析", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("运行智能分析", False, f"请求错误: {e}")
|
||||
|
||||
def test_knowledge_management(self):
|
||||
"""测试知识库管理功能"""
|
||||
print("\n" + "="*60)
|
||||
print("📚 测试知识库管理")
|
||||
print("="*60)
|
||||
|
||||
# 1. 获取知识库列表
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/knowledge")
|
||||
if response.status_code == 200:
|
||||
knowledge = response.json()
|
||||
self.log_test("获取知识库列表", True, f"共 {len(knowledge)} 条知识")
|
||||
else:
|
||||
self.log_test("获取知识库列表", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("获取知识库列表", False, f"请求错误: {e}")
|
||||
|
||||
# 2. 添加知识库条目
|
||||
test_knowledge = {
|
||||
"question": f"测试问题 - {datetime.now().strftime('%H:%M:%S')}",
|
||||
"answer": "这是一个测试答案,用于验证知识库添加功能是否正常工作。",
|
||||
"category": "技术问题",
|
||||
"confidence_score": 0.9
|
||||
}
|
||||
|
||||
try:
|
||||
response = self.session.post(f"{self.base_url}/api/knowledge",
|
||||
json=test_knowledge)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
self.log_test("添加知识库条目", True, data.get("message", "添加成功"))
|
||||
else:
|
||||
self.log_test("添加知识库条目", False, "添加失败")
|
||||
else:
|
||||
self.log_test("添加知识库条目", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("添加知识库条目", False, f"请求错误: {e}")
|
||||
|
||||
# 3. 搜索知识库
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/knowledge/search?q=测试")
|
||||
if response.status_code == 200:
|
||||
results = response.json()
|
||||
self.log_test("搜索知识库", True, f"找到 {len(results)} 条结果")
|
||||
else:
|
||||
self.log_test("搜索知识库", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("搜索知识库", False, f"请求错误: {e}")
|
||||
|
||||
# 4. 获取知识库统计
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/knowledge/stats")
|
||||
if response.status_code == 200:
|
||||
stats = response.json()
|
||||
self.log_test("获取知识库统计", True, f"总条目: {stats.get('total_entries', 0)}")
|
||||
else:
|
||||
self.log_test("获取知识库统计", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("获取知识库统计", False, f"请求错误: {e}")
|
||||
|
||||
def test_file_upload(self):
|
||||
"""测试文件上传功能"""
|
||||
print("\n" + "="*60)
|
||||
print("📁 测试文件上传功能")
|
||||
print("="*60)
|
||||
|
||||
# 创建测试文件
|
||||
test_content = """
|
||||
TSP智能助手使用指南
|
||||
|
||||
1. 系统启动
|
||||
- 运行 python start_dashboard.py
|
||||
- 访问 http://localhost:5000
|
||||
|
||||
2. 主要功能
|
||||
- Agent管理:智能助手模式切换
|
||||
- 知识库管理:添加、搜索、上传文件
|
||||
- 工单管理:创建、跟踪工单
|
||||
- 预警管理:系统监控和预警
|
||||
|
||||
3. 常见问题
|
||||
Q: 如何启动Agent模式?
|
||||
A: 在Agent管理页面点击开关即可启动
|
||||
|
||||
Q: 如何添加知识库?
|
||||
A: 可以手动添加或上传文件自动生成
|
||||
|
||||
Q: 系统支持哪些文件格式?
|
||||
A: 支持TXT、PDF、DOC、DOCX、MD格式
|
||||
"""
|
||||
|
||||
# 创建临时文件
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False, encoding='utf-8') as f:
|
||||
f.write(test_content)
|
||||
temp_file_path = f.name
|
||||
|
||||
try:
|
||||
# 上传文件
|
||||
with open(temp_file_path, 'rb') as f:
|
||||
files = {'file': ('test_guide.txt', f, 'text/plain')}
|
||||
data = {
|
||||
'process_method': 'auto',
|
||||
'category': '技术问题',
|
||||
'confidence_score': 0.8
|
||||
}
|
||||
|
||||
response = self.session.post(f"{self.base_url}/api/knowledge/upload",
|
||||
files=files, data=data)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if result.get("success"):
|
||||
self.log_test("文件上传", True,
|
||||
f"成功生成 {result.get('knowledge_count', 0)} 条知识")
|
||||
else:
|
||||
self.log_test("文件上传", False, result.get("error", "上传失败"))
|
||||
else:
|
||||
self.log_test("文件上传", False, f"HTTP {response.status_code}")
|
||||
|
||||
except Exception as e:
|
||||
self.log_test("文件上传", False, f"请求错误: {e}")
|
||||
|
||||
finally:
|
||||
# 清理临时文件
|
||||
try:
|
||||
os.unlink(temp_file_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def test_work_order_management(self):
|
||||
"""测试工单管理功能"""
|
||||
print("\n" + "="*60)
|
||||
print("📋 测试工单管理")
|
||||
print("="*60)
|
||||
|
||||
# 1. 获取工单列表
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/workorders")
|
||||
if response.status_code == 200:
|
||||
workorders = response.json()
|
||||
self.log_test("获取工单列表", True, f"共 {len(workorders)} 个工单")
|
||||
else:
|
||||
self.log_test("获取工单列表", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("获取工单列表", False, f"请求错误: {e}")
|
||||
|
||||
# 2. 创建工单
|
||||
test_workorder = {
|
||||
"title": f"测试工单 - {datetime.now().strftime('%H:%M:%S')}",
|
||||
"description": "这是一个测试工单,用于验证工单创建功能。",
|
||||
"priority": "medium",
|
||||
"category": "技术问题"
|
||||
}
|
||||
|
||||
try:
|
||||
response = self.session.post(f"{self.base_url}/api/workorders",
|
||||
json=test_workorder)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
self.log_test("创建工单", True, data.get("message", "创建成功"))
|
||||
else:
|
||||
self.log_test("创建工单", False, "创建失败")
|
||||
else:
|
||||
self.log_test("创建工单", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("创建工单", False, f"请求错误: {e}")
|
||||
|
||||
def test_analytics(self):
|
||||
"""测试数据分析功能"""
|
||||
print("\n" + "="*60)
|
||||
print("📊 测试数据分析")
|
||||
print("="*60)
|
||||
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/analytics")
|
||||
if response.status_code == 200:
|
||||
analytics = response.json()
|
||||
self.log_test("获取分析数据", True, "数据获取成功")
|
||||
else:
|
||||
self.log_test("获取分析数据", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("获取分析数据", False, f"请求错误: {e}")
|
||||
|
||||
def test_system_settings(self):
|
||||
"""测试系统设置功能"""
|
||||
print("\n" + "="*60)
|
||||
print("⚙️ 测试系统设置")
|
||||
print("="*60)
|
||||
|
||||
# 1. 获取系统设置
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/settings")
|
||||
if response.status_code == 200:
|
||||
settings = response.json()
|
||||
self.log_test("获取系统设置", True, "设置获取成功")
|
||||
else:
|
||||
self.log_test("获取系统设置", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("获取系统设置", False, f"请求错误: {e}")
|
||||
|
||||
# 2. 获取系统信息
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/system/info")
|
||||
if response.status_code == 200:
|
||||
info = response.json()
|
||||
self.log_test("获取系统信息", True, f"版本: {info.get('version', 'unknown')}")
|
||||
else:
|
||||
self.log_test("获取系统信息", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("获取系统信息", False, f"请求错误: {e}")
|
||||
|
||||
def test_chat_functionality(self):
|
||||
"""测试聊天功能"""
|
||||
print("\n" + "="*60)
|
||||
print("💬 测试聊天功能")
|
||||
print("="*60)
|
||||
|
||||
# 1. 创建聊天会话
|
||||
try:
|
||||
response = self.session.post(f"{self.base_url}/api/chat/session")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
session_id = data.get("session_id")
|
||||
self.log_test("创建聊天会话", True, f"会话ID: {session_id}")
|
||||
|
||||
# 2. 发送消息
|
||||
test_message = {
|
||||
"message": "你好,这是一个测试消息",
|
||||
"session_id": session_id
|
||||
}
|
||||
|
||||
response = self.session.post(f"{self.base_url}/api/chat/message",
|
||||
json=test_message)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
self.log_test("发送聊天消息", True, "消息发送成功")
|
||||
else:
|
||||
self.log_test("发送聊天消息", False, "消息发送失败")
|
||||
else:
|
||||
self.log_test("发送聊天消息", False, f"HTTP {response.status_code}")
|
||||
else:
|
||||
self.log_test("创建聊天会话", False, "会话创建失败")
|
||||
else:
|
||||
self.log_test("创建聊天会话", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("创建聊天会话", False, f"请求错误: {e}")
|
||||
|
||||
def test_alert_management(self):
|
||||
"""测试预警管理功能"""
|
||||
print("\n" + "="*60)
|
||||
print("🚨 测试预警管理")
|
||||
print("="*60)
|
||||
|
||||
# 1. 获取预警列表
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/alerts")
|
||||
if response.status_code == 200:
|
||||
alerts = response.json()
|
||||
self.log_test("获取预警列表", True, f"共 {len(alerts)} 个预警")
|
||||
else:
|
||||
self.log_test("获取预警列表", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("获取预警列表", False, f"请求错误: {e}")
|
||||
|
||||
# 2. 获取预警规则
|
||||
try:
|
||||
response = self.session.get(f"{self.base_url}/api/alerts/rules")
|
||||
if response.status_code == 200:
|
||||
rules = response.json()
|
||||
self.log_test("获取预警规则", True, f"共 {len(rules)} 条规则")
|
||||
else:
|
||||
self.log_test("获取预警规则", False, f"HTTP {response.status_code}")
|
||||
except Exception as e:
|
||||
self.log_test("获取预警规则", False, f"请求错误: {e}")
|
||||
|
||||
def run_all_tests(self):
|
||||
"""运行所有测试"""
|
||||
print("🚀 TSP智能助手 - 全面前端功能测试")
|
||||
print("="*60)
|
||||
print(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print(f"测试目标: {self.base_url}")
|
||||
|
||||
# 基础连接测试
|
||||
if not self.test_server_connection():
|
||||
print("\n❌ 服务器连接失败,请确保服务已启动")
|
||||
return
|
||||
|
||||
# 运行所有功能测试
|
||||
self.test_health_endpoint()
|
||||
self.test_agent_functionality()
|
||||
self.test_knowledge_management()
|
||||
self.test_file_upload()
|
||||
self.test_work_order_management()
|
||||
self.test_analytics()
|
||||
self.test_system_settings()
|
||||
self.test_chat_functionality()
|
||||
self.test_alert_management()
|
||||
|
||||
# 输出测试结果
|
||||
self.print_test_summary()
|
||||
|
||||
def print_test_summary(self):
|
||||
"""打印测试总结"""
|
||||
print("\n" + "="*60)
|
||||
print("📊 测试结果总结")
|
||||
print("="*60)
|
||||
|
||||
total = self.test_results["total_tests"]
|
||||
passed = self.test_results["passed"]
|
||||
failed = self.test_results["failed"]
|
||||
|
||||
print(f"总测试数: {total}")
|
||||
print(f"通过: {passed} ✅")
|
||||
print(f"失败: {failed} ❌")
|
||||
print(f"成功率: {(passed/total*100):.1f}%" if total > 0 else "成功率: 0%")
|
||||
|
||||
if failed > 0:
|
||||
print("\n❌ 失败的测试:")
|
||||
for error in self.test_results["errors"]:
|
||||
print(f" - {error}")
|
||||
|
||||
print("\n" + "="*60)
|
||||
if failed == 0:
|
||||
print("🎉 所有测试通过!系统功能正常")
|
||||
else:
|
||||
print("⚠️ 部分测试失败,请检查相关功能")
|
||||
print("="*60)
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='TSP智能助手前端功能测试')
|
||||
parser.add_argument('--url', default='http://localhost:5000',
|
||||
help='服务器地址 (默认: http://localhost:5000)')
|
||||
parser.add_argument('--verbose', action='store_true',
|
||||
help='详细输出')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
tester = TSPFrontendTester(args.url)
|
||||
tester.run_all_tests()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
LLM配置文件 - 千问模型配置
|
||||
@@ -8,10 +7,10 @@ from src.agent.llm_client import LLMConfig
|
||||
|
||||
# 千问模型配置
|
||||
QWEN_CONFIG = LLMConfig(
|
||||
provider="openai",
|
||||
api_key="sk-your-qwen-api-key-here", # 请替换为您的千问API密钥
|
||||
provider="qwen",
|
||||
api_key="sk-c0dbefa1718d46eaa897199135066f00", # 请替换为您的千问API密钥
|
||||
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
|
||||
model="qwen-turbo", # 可选: qwen-turbo, qwen-plus, qwen-max
|
||||
model="qwen-plus-latest", # 可选: qwen-turbo, qwen-plus, qwen-max
|
||||
temperature=0.7,
|
||||
max_tokens=2000
|
||||
)
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
MySQL数据库创建脚本
|
||||
"""
|
||||
|
||||
import pymysql
|
||||
import sys
|
||||
|
||||
def create_database():
|
||||
"""创建MySQL数据库"""
|
||||
print("=" * 50)
|
||||
print("MySQL数据库创建")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
# 连接MySQL服务器(不指定数据库)
|
||||
connection = pymysql.connect(
|
||||
host='localhost',
|
||||
user='root',
|
||||
password='123456',
|
||||
charset='utf8mb4'
|
||||
)
|
||||
|
||||
cursor = connection.cursor()
|
||||
|
||||
# 创建数据库
|
||||
database_name = 'tsp_assistant'
|
||||
cursor.execute(f"CREATE DATABASE IF NOT EXISTS {database_name} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")
|
||||
print(f"✓ 数据库 {database_name} 创建成功")
|
||||
|
||||
# 创建用户(可选)
|
||||
try:
|
||||
cursor.execute("CREATE USER IF NOT EXISTS 'tsp_user'@'localhost' IDENTIFIED BY 'tsp_password'")
|
||||
cursor.execute(f"GRANT ALL PRIVILEGES ON {database_name}.* TO 'tsp_user'@'localhost'")
|
||||
cursor.execute("FLUSH PRIVILEGES")
|
||||
print("✓ 用户 tsp_user 创建成功")
|
||||
except Exception as e:
|
||||
print(f"⚠ 用户创建失败(可能已存在): {e}")
|
||||
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
print("✓ MySQL数据库设置完成")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ MySQL数据库创建失败: {e}")
|
||||
print("\n请检查:")
|
||||
print("1. MySQL服务是否已启动")
|
||||
print("2. 用户名和密码是否正确")
|
||||
print("3. 是否有创建数据库的权限")
|
||||
return False
|
||||
|
||||
def test_connection():
|
||||
"""测试数据库连接"""
|
||||
print("\n" + "=" * 50)
|
||||
print("测试数据库连接")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
connection = pymysql.connect(
|
||||
host='localhost',
|
||||
user='root',
|
||||
password='123456',
|
||||
database='tsp_assistant',
|
||||
charset='utf8mb4'
|
||||
)
|
||||
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("SELECT VERSION()")
|
||||
version = cursor.fetchone()
|
||||
print(f"✓ MySQL连接成功,版本: {version[0]}")
|
||||
|
||||
cursor.close()
|
||||
connection.close()
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ MySQL连接失败: {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("TSP助手MySQL数据库设置工具")
|
||||
print("=" * 50)
|
||||
|
||||
# 创建数据库
|
||||
if create_database():
|
||||
# 测试连接
|
||||
if test_connection():
|
||||
print("\n" + "=" * 50)
|
||||
print("MySQL数据库设置成功!")
|
||||
print("=" * 50)
|
||||
print("现在您可以运行以下命令初始化数据库:")
|
||||
print("python init_database.py")
|
||||
else:
|
||||
print("\n" + "=" * 50)
|
||||
print("数据库连接测试失败!")
|
||||
print("=" * 50)
|
||||
else:
|
||||
print("\n" + "=" * 50)
|
||||
print("MySQL数据库设置失败!")
|
||||
print("=" * 50)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
7
data/system_settings.json
Normal file
7
data/system_settings.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"api_timeout": 30,
|
||||
"max_history": 10,
|
||||
"refresh_interval": 10,
|
||||
"auto_monitoring": true,
|
||||
"agent_mode": true
|
||||
}
|
||||
438
deploy.py
438
deploy.py
@@ -1,438 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
TSP智能助手部署管理脚本
|
||||
支持自动化部署、升级和回滚
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
class DeploymentManager:
|
||||
"""部署管理器"""
|
||||
|
||||
def __init__(self, config_file: str = "deploy_config.json"):
|
||||
self.config_file = config_file
|
||||
self.config = self._load_config()
|
||||
self.backup_dir = Path("backups")
|
||||
self.backup_dir.mkdir(exist_ok=True)
|
||||
|
||||
def _load_config(self) -> Dict:
|
||||
"""加载部署配置"""
|
||||
if os.path.exists(self.config_file):
|
||||
try:
|
||||
with open(self.config_file, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
print(f"加载配置失败: {e}")
|
||||
|
||||
# 默认配置
|
||||
return {
|
||||
"environment": "production",
|
||||
"app_name": "tsp_assistant",
|
||||
"deploy_path": "/opt/tsp_assistant",
|
||||
"backup_path": "./backups",
|
||||
"service_name": "tsp_assistant",
|
||||
"python_path": "python3",
|
||||
"pip_path": "pip3",
|
||||
"nginx_config": "/etc/nginx/sites-available/tsp_assistant",
|
||||
"systemd_service": "/etc/systemd/system/tsp_assistant.service",
|
||||
"database_backup": True,
|
||||
"auto_restart": True,
|
||||
"health_check_url": "http://localhost:5000/api/health"
|
||||
}
|
||||
|
||||
def _run_command(self, command: str, check: bool = True) -> subprocess.CompletedProcess:
|
||||
"""执行命令"""
|
||||
print(f"执行命令: {command}")
|
||||
try:
|
||||
result = subprocess.run(command, shell=True, check=check,
|
||||
capture_output=True, text=True)
|
||||
if result.stdout:
|
||||
print(f"输出: {result.stdout}")
|
||||
return result
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"命令执行失败: {e}")
|
||||
if e.stderr:
|
||||
print(f"错误: {e.stderr}")
|
||||
raise
|
||||
|
||||
def backup_current_deployment(self) -> str:
|
||||
"""备份当前部署"""
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
backup_name = f"{self.config['app_name']}_backup_{timestamp}"
|
||||
backup_path = self.backup_dir / backup_name
|
||||
|
||||
print(f"创建备份: {backup_path}")
|
||||
|
||||
# 备份应用文件
|
||||
if os.path.exists(self.config['deploy_path']):
|
||||
shutil.copytree(self.config['deploy_path'], backup_path)
|
||||
|
||||
# 备份数据库
|
||||
if self.config.get('database_backup', True):
|
||||
self._backup_database(backup_path)
|
||||
|
||||
# 保存备份信息
|
||||
backup_info = {
|
||||
"backup_name": backup_name,
|
||||
"backup_path": str(backup_path),
|
||||
"timestamp": timestamp,
|
||||
"version": self._get_current_version(),
|
||||
"git_commit": self._get_git_commit()
|
||||
}
|
||||
|
||||
with open(backup_path / "backup_info.json", 'w') as f:
|
||||
json.dump(backup_info, f, indent=2)
|
||||
|
||||
print(f"备份完成: {backup_name}")
|
||||
return backup_name
|
||||
|
||||
def _backup_database(self, backup_path: Path):
|
||||
"""备份数据库"""
|
||||
try:
|
||||
# 创建数据库备份目录
|
||||
db_backup_dir = backup_path / "database"
|
||||
db_backup_dir.mkdir(exist_ok=True)
|
||||
|
||||
# 备份SQLite数据库
|
||||
db_file = "tsp_assistant.db"
|
||||
if os.path.exists(db_file):
|
||||
shutil.copy2(db_file, db_backup_dir / db_file)
|
||||
print(f"已备份SQLite数据库: {db_file}")
|
||||
|
||||
# 备份MySQL数据库(如果使用)
|
||||
mysql_config = self._get_mysql_config()
|
||||
if mysql_config:
|
||||
dump_file = db_backup_dir / "mysql_dump.sql"
|
||||
cmd = f"mysqldump -h{mysql_config['host']} -u{mysql_config['user']} -p{mysql_config['password']} {mysql_config['database']} > {dump_file}"
|
||||
self._run_command(cmd)
|
||||
print(f"已备份MySQL数据库: {mysql_config['database']}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"数据库备份失败: {e}")
|
||||
|
||||
def _get_mysql_config(self) -> Optional[Dict]:
|
||||
"""获取MySQL配置"""
|
||||
try:
|
||||
from src.config.config import Config
|
||||
db_url = Config.DATABASE_URL
|
||||
if db_url.startswith("mysql"):
|
||||
# 解析MySQL连接字符串
|
||||
# mysql+pymysql://user:password@host/database
|
||||
parts = db_url.split("://")[1].split("@")
|
||||
user_pass = parts[0].split(":")
|
||||
host_db = parts[1].split("/")
|
||||
return {
|
||||
"user": user_pass[0],
|
||||
"password": user_pass[1],
|
||||
"host": host_db[0],
|
||||
"database": host_db[1].split("?")[0]
|
||||
}
|
||||
except:
|
||||
pass
|
||||
return None
|
||||
|
||||
def _get_current_version(self) -> str:
|
||||
"""获取当前版本"""
|
||||
try:
|
||||
from version import VersionManager
|
||||
vm = VersionManager()
|
||||
return vm.get_version()
|
||||
except:
|
||||
return "unknown"
|
||||
|
||||
def _get_git_commit(self) -> str:
|
||||
"""获取Git提交哈希"""
|
||||
try:
|
||||
result = subprocess.run(['git', 'rev-parse', 'HEAD'],
|
||||
capture_output=True, text=True)
|
||||
return result.stdout.strip()[:8] if result.returncode == 0 else "unknown"
|
||||
except:
|
||||
return "unknown"
|
||||
|
||||
def deploy(self, source_path: str = ".", force: bool = False) -> bool:
|
||||
"""部署应用"""
|
||||
try:
|
||||
print("开始部署...")
|
||||
|
||||
# 检查目标路径
|
||||
deploy_path = Path(self.config['deploy_path'])
|
||||
if deploy_path.exists() and not force:
|
||||
response = input(f"目标路径 {deploy_path} 已存在,是否继续?(y/N): ")
|
||||
if response.lower() != 'y':
|
||||
print("部署取消")
|
||||
return False
|
||||
|
||||
# 创建备份
|
||||
backup_name = self.backup_current_deployment()
|
||||
|
||||
# 停止服务
|
||||
if self.config.get('auto_restart', True):
|
||||
self.stop_service()
|
||||
|
||||
# 部署新版本
|
||||
self._deploy_files(source_path, deploy_path)
|
||||
|
||||
# 安装依赖
|
||||
self._install_dependencies(deploy_path)
|
||||
|
||||
# 运行数据库迁移
|
||||
self._run_database_migrations(deploy_path)
|
||||
|
||||
# 启动服务
|
||||
if self.config.get('auto_restart', True):
|
||||
self.start_service()
|
||||
|
||||
# 健康检查
|
||||
if not self._health_check():
|
||||
print("健康检查失败,开始回滚...")
|
||||
self.rollback(backup_name)
|
||||
return False
|
||||
|
||||
print("部署成功!")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"部署失败: {e}")
|
||||
return False
|
||||
|
||||
def _deploy_files(self, source_path: str, deploy_path: Path):
|
||||
"""部署文件"""
|
||||
print(f"部署文件从 {source_path} 到 {deploy_path}")
|
||||
|
||||
# 创建目标目录
|
||||
deploy_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 复制文件
|
||||
source = Path(source_path)
|
||||
for item in source.iterdir():
|
||||
if item.name.startswith('.') and item.name not in ['.git', '.env']:
|
||||
continue
|
||||
|
||||
if item.is_file():
|
||||
shutil.copy2(item, deploy_path / item.name)
|
||||
elif item.is_dir():
|
||||
shutil.copytree(item, deploy_path / item.name, dirs_exist_ok=True)
|
||||
|
||||
print("文件部署完成")
|
||||
|
||||
def _install_dependencies(self, deploy_path: Path):
|
||||
"""安装依赖"""
|
||||
print("安装依赖包...")
|
||||
|
||||
requirements_file = deploy_path / "requirements.txt"
|
||||
if requirements_file.exists():
|
||||
cmd = f"cd {deploy_path} && {self.config['pip_path']} install -r requirements.txt"
|
||||
self._run_command(cmd)
|
||||
else:
|
||||
print("未找到requirements.txt文件")
|
||||
|
||||
def _run_database_migrations(self, deploy_path: Path):
|
||||
"""运行数据库迁移"""
|
||||
print("运行数据库迁移...")
|
||||
|
||||
try:
|
||||
# 运行数据库初始化脚本
|
||||
init_script = deploy_path / "init_database.py"
|
||||
if init_script.exists():
|
||||
cmd = f"cd {deploy_path} && {self.config['python_path']} init_database.py"
|
||||
self._run_command(cmd)
|
||||
except Exception as e:
|
||||
print(f"数据库迁移失败: {e}")
|
||||
|
||||
def start_service(self):
|
||||
"""启动服务"""
|
||||
print("启动服务...")
|
||||
|
||||
if self.config.get('service_name'):
|
||||
try:
|
||||
self._run_command(f"systemctl start {self.config['service_name']}")
|
||||
print("服务启动成功")
|
||||
except:
|
||||
print("使用systemctl启动失败,尝试直接启动...")
|
||||
self._start_directly()
|
||||
else:
|
||||
self._start_directly()
|
||||
|
||||
def stop_service(self):
|
||||
"""停止服务"""
|
||||
print("停止服务...")
|
||||
|
||||
if self.config.get('service_name'):
|
||||
try:
|
||||
self._run_command(f"systemctl stop {self.config['service_name']}", check=False)
|
||||
except:
|
||||
pass
|
||||
|
||||
# 杀死相关进程
|
||||
try:
|
||||
self._run_command("pkill -f 'python.*start_dashboard.py'", check=False)
|
||||
self._run_command("pkill -f 'python.*app.py'", check=False)
|
||||
except:
|
||||
pass
|
||||
|
||||
def _start_directly(self):
|
||||
"""直接启动应用"""
|
||||
deploy_path = self.config['deploy_path']
|
||||
start_script = Path(deploy_path) / "start_dashboard.py"
|
||||
|
||||
if start_script.exists():
|
||||
cmd = f"cd {deploy_path} && nohup {self.config['python_path']} start_dashboard.py > logs/deploy.log 2>&1 &"
|
||||
self._run_command(cmd)
|
||||
print("应用已启动")
|
||||
|
||||
def _health_check(self) -> bool:
|
||||
"""健康检查"""
|
||||
print("执行健康检查...")
|
||||
|
||||
try:
|
||||
import requests
|
||||
response = requests.get(self.config['health_check_url'], timeout=10)
|
||||
if response.status_code == 200:
|
||||
print("健康检查通过")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"健康检查失败: {e}")
|
||||
|
||||
return False
|
||||
|
||||
def rollback(self, backup_name: str = None) -> bool:
|
||||
"""回滚到指定备份"""
|
||||
try:
|
||||
if backup_name is None:
|
||||
# 获取最新的备份
|
||||
backups = list(self.backup_dir.glob("*backup_*"))
|
||||
if not backups:
|
||||
print("没有找到备份")
|
||||
return False
|
||||
backup_name = max(backups, key=os.path.getctime).name
|
||||
|
||||
backup_path = self.backup_dir / backup_name
|
||||
if not backup_path.exists():
|
||||
print(f"备份不存在: {backup_name}")
|
||||
return False
|
||||
|
||||
print(f"回滚到备份: {backup_name}")
|
||||
|
||||
# 停止服务
|
||||
self.stop_service()
|
||||
|
||||
# 恢复文件
|
||||
deploy_path = Path(self.config['deploy_path'])
|
||||
if deploy_path.exists():
|
||||
shutil.rmtree(deploy_path)
|
||||
|
||||
shutil.copytree(backup_path, deploy_path)
|
||||
|
||||
# 恢复数据库
|
||||
self._restore_database(backup_path)
|
||||
|
||||
# 启动服务
|
||||
self.start_service()
|
||||
|
||||
print("回滚完成")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"回滚失败: {e}")
|
||||
return False
|
||||
|
||||
def _restore_database(self, backup_path: Path):
|
||||
"""恢复数据库"""
|
||||
try:
|
||||
db_backup_dir = backup_path / "database"
|
||||
if db_backup_dir.exists():
|
||||
# 恢复SQLite数据库
|
||||
db_file = db_backup_dir / "tsp_assistant.db"
|
||||
if db_file.exists():
|
||||
shutil.copy2(db_file, "tsp_assistant.db")
|
||||
print("已恢复SQLite数据库")
|
||||
|
||||
# 恢复MySQL数据库
|
||||
mysql_dump = db_backup_dir / "mysql_dump.sql"
|
||||
if mysql_dump.exists():
|
||||
mysql_config = self._get_mysql_config()
|
||||
if mysql_config:
|
||||
cmd = f"mysql -h{mysql_config['host']} -u{mysql_config['user']} -p{mysql_config['password']} {mysql_config['database']} < {mysql_dump}"
|
||||
self._run_command(cmd)
|
||||
print("已恢复MySQL数据库")
|
||||
except Exception as e:
|
||||
print(f"数据库恢复失败: {e}")
|
||||
|
||||
def list_backups(self):
|
||||
"""列出所有备份"""
|
||||
backups = list(self.backup_dir.glob("*backup_*"))
|
||||
if not backups:
|
||||
print("没有找到备份")
|
||||
return
|
||||
|
||||
print("可用备份:")
|
||||
for backup in sorted(backups, key=os.path.getctime, reverse=True):
|
||||
backup_info_file = backup / "backup_info.json"
|
||||
if backup_info_file.exists():
|
||||
try:
|
||||
with open(backup_info_file, 'r') as f:
|
||||
info = json.load(f)
|
||||
print(f" {info['backup_name']} - 版本: {info['version']} - {info['timestamp']}")
|
||||
except:
|
||||
print(f" {backup.name}")
|
||||
else:
|
||||
print(f" {backup.name}")
|
||||
|
||||
def cleanup_old_backups(self, keep_count: int = 5):
|
||||
"""清理旧备份"""
|
||||
backups = list(self.backup_dir.glob("*backup_*"))
|
||||
if len(backups) <= keep_count:
|
||||
print(f"备份数量({len(backups)})不超过保留数量({keep_count})")
|
||||
return
|
||||
|
||||
# 按创建时间排序,保留最新的
|
||||
backups.sort(key=os.path.getctime, reverse=True)
|
||||
to_delete = backups[keep_count:]
|
||||
|
||||
for backup in to_delete:
|
||||
print(f"删除备份: {backup.name}")
|
||||
shutil.rmtree(backup)
|
||||
|
||||
def main():
|
||||
"""命令行接口"""
|
||||
parser = argparse.ArgumentParser(description='TSP智能助手部署管理')
|
||||
parser.add_argument('action', choices=['deploy', 'rollback', 'backup', 'list-backups', 'cleanup'],
|
||||
help='要执行的操作')
|
||||
parser.add_argument('--source', default='.', help='源代码路径')
|
||||
parser.add_argument('--backup', help='备份名称')
|
||||
parser.add_argument('--force', action='store_true', help='强制部署')
|
||||
parser.add_argument('--keep', type=int, default=5, help='保留备份数量')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
dm = DeploymentManager()
|
||||
|
||||
if args.action == 'deploy':
|
||||
success = dm.deploy(args.source, args.force)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif args.action == 'rollback':
|
||||
success = dm.rollback(args.backup)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif args.action == 'backup':
|
||||
backup_name = dm.backup_current_deployment()
|
||||
print(f"备份完成: {backup_name}")
|
||||
|
||||
elif args.action == 'list-backups':
|
||||
dm.list_backups()
|
||||
|
||||
elif args.action == 'cleanup':
|
||||
dm.cleanup_old_backups(args.keep)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"environment": "production",
|
||||
"app_name": "tsp_assistant",
|
||||
"deploy_path": "/opt/tsp_assistant",
|
||||
"backup_path": "./backups",
|
||||
"service_name": "tsp_assistant",
|
||||
"python_path": "python3",
|
||||
"pip_path": "pip3",
|
||||
"nginx_config": "/etc/nginx/sites-available/tsp_assistant",
|
||||
"systemd_service": "/etc/systemd/system/tsp_assistant.service",
|
||||
"database_backup": true,
|
||||
"auto_restart": true,
|
||||
"health_check_url": "http://localhost:5000/api/health",
|
||||
"environments": {
|
||||
"development": {
|
||||
"deploy_path": "./dev_deploy",
|
||||
"service_name": null,
|
||||
"auto_restart": false,
|
||||
"health_check_url": "http://localhost:5000/api/health"
|
||||
},
|
||||
"staging": {
|
||||
"deploy_path": "/opt/tsp_assistant_staging",
|
||||
"service_name": "tsp_assistant_staging",
|
||||
"auto_restart": true,
|
||||
"health_check_url": "http://staging.example.com/api/health"
|
||||
},
|
||||
"production": {
|
||||
"deploy_path": "/opt/tsp_assistant",
|
||||
"service_name": "tsp_assistant",
|
||||
"auto_restart": true,
|
||||
"health_check_url": "http://production.example.com/api/health"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
数据库架构修复脚本
|
||||
添加缺失的字段和修复表结构
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
from sqlalchemy import text
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from src.core.database import db_manager
|
||||
from src.core.models import Base
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def fix_database_schema():
|
||||
"""修复数据库架构"""
|
||||
try:
|
||||
with db_manager.get_session() as session:
|
||||
# 检查并添加severity字段到alerts表
|
||||
try:
|
||||
# 检查字段是否存在
|
||||
result = session.execute(text("""
|
||||
SELECT COUNT(*) as count
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'alerts' AND column_name = 'severity'
|
||||
"""))
|
||||
|
||||
if result.fetchone()[0] == 0:
|
||||
logger.info("添加severity字段到alerts表...")
|
||||
session.execute(text("ALTER TABLE alerts ADD COLUMN severity VARCHAR(20) DEFAULT 'medium'"))
|
||||
session.commit()
|
||||
logger.info("severity字段添加成功")
|
||||
else:
|
||||
logger.info("severity字段已存在")
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"添加severity字段失败: {e}")
|
||||
# 如果是SQLite,尝试不同的方法
|
||||
try:
|
||||
session.execute(text("ALTER TABLE alerts ADD COLUMN severity VARCHAR(20) DEFAULT 'medium'"))
|
||||
session.commit()
|
||||
logger.info("severity字段添加成功(SQLite)")
|
||||
except Exception as e2:
|
||||
logger.error(f"SQLite添加severity字段也失败: {e2}")
|
||||
|
||||
# 检查并添加is_verified相关字段到knowledge_entries表
|
||||
try:
|
||||
result = session.execute(text("""
|
||||
SELECT COUNT(*) as count
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'knowledge_entries' AND column_name = 'is_verified'
|
||||
"""))
|
||||
|
||||
if result.fetchone()[0] == 0:
|
||||
logger.info("添加is_verified字段到knowledge_entries表...")
|
||||
session.execute(text("ALTER TABLE knowledge_entries ADD COLUMN is_verified BOOLEAN DEFAULT FALSE"))
|
||||
session.execute(text("ALTER TABLE knowledge_entries ADD COLUMN verified_by VARCHAR(100)"))
|
||||
session.execute(text("ALTER TABLE knowledge_entries ADD COLUMN verified_at DATETIME"))
|
||||
session.commit()
|
||||
logger.info("is_verified相关字段添加成功")
|
||||
else:
|
||||
logger.info("is_verified字段已存在")
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"添加is_verified字段失败: {e}")
|
||||
# SQLite方法
|
||||
try:
|
||||
session.execute(text("ALTER TABLE knowledge_entries ADD COLUMN is_verified BOOLEAN DEFAULT FALSE"))
|
||||
session.execute(text("ALTER TABLE knowledge_entries ADD COLUMN verified_by VARCHAR(100)"))
|
||||
session.execute(text("ALTER TABLE knowledge_entries ADD COLUMN verified_at DATETIME"))
|
||||
session.commit()
|
||||
logger.info("is_verified相关字段添加成功(SQLite)")
|
||||
except Exception as e2:
|
||||
logger.error(f"SQLite添加is_verified字段也失败: {e2}")
|
||||
|
||||
logger.info("数据库架构修复完成")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"数据库架构修复失败: {e}")
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
fix_database_schema()
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
TSP助手数据库初始化脚本 - 包含所有数据库操作
|
||||
@@ -73,7 +73,7 @@ def migrate_database():
|
||||
is_mysql = 'mysql' in str(db_url)
|
||||
is_sqlite = 'sqlite' in str(db_url)
|
||||
|
||||
print(" 📝 检查知识库验证字段...")
|
||||
print(" 📝 检查知识库验证字段与预警字段...")
|
||||
|
||||
# 检查is_verified字段是否存在
|
||||
if is_mysql:
|
||||
@@ -153,6 +153,31 @@ def migrate_database():
|
||||
else:
|
||||
print(" ✅ verified_at字段已存在")
|
||||
|
||||
# 检查alerts.severity字段是否存在
|
||||
if is_mysql:
|
||||
result = session.execute(text("""
|
||||
SELECT COUNT(*) as count
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'alerts'
|
||||
AND COLUMN_NAME = 'severity'
|
||||
""")).fetchone()
|
||||
else: # SQLite
|
||||
result = session.execute(text("""
|
||||
SELECT COUNT(*) as count
|
||||
FROM pragma_table_info('alerts')
|
||||
WHERE name = 'severity'
|
||||
""")).fetchone()
|
||||
if result.count == 0:
|
||||
print(" ➕ 添加alerts.severity字段...")
|
||||
if is_mysql:
|
||||
session.execute(text("ALTER TABLE alerts ADD COLUMN severity VARCHAR(20) DEFAULT 'medium'"))
|
||||
else:
|
||||
session.execute(text("ALTER TABLE alerts ADD COLUMN severity VARCHAR(20) DEFAULT 'medium'"))
|
||||
print(" ✅ alerts.severity 字段添加成功")
|
||||
else:
|
||||
print(" ✅ alerts.severity 字段已存在")
|
||||
|
||||
# 检查车辆数据表是否存在
|
||||
if is_mysql:
|
||||
result = session.execute(text("""
|
||||
@@ -183,6 +208,46 @@ def migrate_database():
|
||||
|
||||
return True
|
||||
|
||||
def reset_database(force: bool = False) -> bool:
|
||||
"""重置数据库:删除并重建所有表,再插入初始数据"""
|
||||
print("=" * 50)
|
||||
print("TSP助手数据库重置")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
# 可选确认
|
||||
if not force:
|
||||
try:
|
||||
confirm = input("⚠️ 警告:此操作将删除所有数据!确定要继续吗?(y/N): ")
|
||||
if confirm.lower() != 'y':
|
||||
print("操作已取消")
|
||||
return False
|
||||
except Exception:
|
||||
# 非交互环境下默认取消,建议调用方传入 force=True
|
||||
print("非交互环境未传入 force=True,已取消")
|
||||
return False
|
||||
|
||||
# 删除所有表
|
||||
Base.metadata.drop_all(bind=db_manager.engine)
|
||||
print("✓ 数据库表删除成功")
|
||||
|
||||
# 重新创建所有表
|
||||
Base.metadata.create_all(bind=db_manager.engine)
|
||||
print("✓ 数据库表重新创建成功")
|
||||
|
||||
# 迁移补齐新增字段
|
||||
migrate_database()
|
||||
|
||||
# 插入初始数据
|
||||
insert_initial_data()
|
||||
|
||||
print("✓ 数据库重置完成")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ 数据库重置失败: {e}")
|
||||
return False
|
||||
|
||||
def insert_initial_data():
|
||||
"""插入初始数据"""
|
||||
try:
|
||||
|
||||
3676
logs/dashboard.log
3676
logs/dashboard.log
File diff suppressed because it is too large
Load Diff
@@ -1,13 +0,0 @@
|
||||
2025-09-04 23:30:32,317 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-04 23:30:32,323 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-04 23:30:33,215 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-04 23:30:33,218 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-04 23:30:33,251 - src.main - INFO - 知识库测试成功
|
||||
2025-09-04 23:30:33,285 - src.dialogue.dialogue_manager - INFO - 创建工单成功: WO20250904233033
|
||||
2025-09-04 23:30:41,419 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-04 23:30:41,447 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-04 23:30:41,449 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 账户无法登录怎么办?...
|
||||
2025-09-04 23:30:41,475 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-04 23:30:42,742 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-04 23:30:42,742 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-04 23:30:42,751 - src.main - INFO - 知识库测试成功
|
||||
@@ -1,949 +0,0 @@
|
||||
2025-09-04 23:19:51,974 - __main__ - INFO - TSP助手初始化完成
|
||||
2025-09-04 23:19:51,976 - src.core.database - ERROR - 数据库操作失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:19:51,977 - src.core.database - ERROR - 数据库连接测试失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:19:51,978 - __main__ - ERROR - 数据库连接测试失败
|
||||
2025-09-04 23:19:52,949 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-04 23:19:52,965 - __main__ - INFO - LLM API连接测试成功
|
||||
2025-09-04 23:19:53,003 - src.core.database - ERROR - 数据库操作失败: 'Session' object has no attribute 'func'
|
||||
2025-09-04 23:19:53,004 - src.knowledge_base.knowledge_manager - ERROR - 获取知识库统计失败: 'Session' object has no attribute 'func'
|
||||
2025-09-04 23:19:53,005 - __main__ - WARNING - 知识库为空或测试失败
|
||||
2025-09-04 23:22:37,727 - __main__ - INFO - TSP助手初始化完成
|
||||
2025-09-04 23:22:37,727 - src.core.database - ERROR - 数据库操作失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:22:37,727 - src.core.database - ERROR - 数据库连接测试失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:22:37,727 - __main__ - ERROR - 数据库连接测试失败
|
||||
2025-09-04 23:22:38,398 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-04 23:22:38,399 - __main__ - INFO - LLM API连接测试成功
|
||||
2025-09-04 23:22:38,427 - src.core.database - ERROR - 数据库操作失败: 'Session' object has no attribute 'func'
|
||||
2025-09-04 23:22:38,427 - src.knowledge_base.knowledge_manager - ERROR - 获取知识库统计失败: 'Session' object has no attribute 'func'
|
||||
2025-09-04 23:22:38,427 - __main__ - WARNING - 知识库为空或测试失败
|
||||
2025-09-04 23:23:37,699 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-04 23:23:37,701 - src.core.database - ERROR - 数据库操作失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:23:37,701 - src.core.database - ERROR - 数据库连接测试失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:23:37,701 - src.main - ERROR - 数据库连接测试失败
|
||||
2025-09-04 23:23:38,377 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-04 23:23:38,379 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-04 23:23:38,393 - src.core.database - ERROR - 数据库操作失败: 'Session' object has no attribute 'func'
|
||||
2025-09-04 23:23:38,393 - src.knowledge_base.knowledge_manager - ERROR - 获取知识库统计失败: 'Session' object has no attribute 'func'
|
||||
2025-09-04 23:23:38,394 - src.main - WARNING - 知识库为空或测试失败
|
||||
2025-09-04 23:24:28,378 - src.core.database - ERROR - 数据库操作失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:24:28,383 - src.core.database - ERROR - 数据库连接测试失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:26:11,404 - src.core.database - ERROR - 数据库操作失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:26:11,407 - src.core.database - ERROR - 数据库连接测试失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:26:57,570 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-04 23:26:57,573 - src.core.database - ERROR - 数据库操作失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:26:57,576 - src.core.database - ERROR - 数据库连接测试失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:26:57,576 - src.main - ERROR - 数据库连接测试失败
|
||||
2025-09-04 23:26:58,451 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-04 23:26:58,453 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-04 23:26:58,508 - src.core.database - ERROR - 数据库操作失败: 'Session' object has no attribute 'func'
|
||||
2025-09-04 23:26:58,509 - src.knowledge_base.knowledge_manager - ERROR - 获取知识库统计失败: 'Session' object has no attribute 'func'
|
||||
2025-09-04 23:26:58,510 - src.main - WARNING - 知识库为空或测试失败
|
||||
2025-09-04 23:29:12,335 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-04 23:29:12,349 - src.core.database - ERROR - 数据库操作失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:29:12,350 - src.core.database - ERROR - 数据库连接测试失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:29:12,354 - src.main - ERROR - 数据库连接测试失败
|
||||
2025-09-04 23:29:13,297 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-04 23:29:13,307 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-04 23:29:13,394 - src.main - INFO - 知识库测试成功
|
||||
2025-09-04 23:29:30,830 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-04 23:29:30,831 - src.core.database - ERROR - 数据库操作失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:29:30,831 - src.core.database - ERROR - 数据库连接测试失败: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1')
|
||||
2025-09-04 23:29:30,831 - src.main - ERROR - 数据库连接测试失败
|
||||
2025-09-04 23:29:31,501 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-04 23:29:31,503 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-04 23:29:31,538 - src.main - INFO - 知识库测试成功
|
||||
2025-09-04 23:30:11,867 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-04 23:30:11,872 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-04 23:30:13,464 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-04 23:30:13,466 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-04 23:30:13,491 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 07:26:52,212 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:26:52,218 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:26:52,219 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 07:26:52,221 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 07:26:53,507 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:26:53,508 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 07:26:53,523 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 07:27:11,620 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:27:11,625 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:27:11,626 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 07:27:11,627 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 07:27:13,099 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:27:13,100 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 07:27:13,116 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 07:29:07,312 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:29:07,323 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:29:07,323 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 07:29:07,331 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 07:29:08,461 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:29:08,463 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 07:29:08,497 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 07:29:11,734 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:29:43,485 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:29:43,492 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:29:43,493 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 07:29:43,493 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 07:29:44,322 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:29:44,324 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 07:29:44,340 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 07:29:48,253 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:29:48,281 - src.dialogue.dialogue_manager - INFO - 创建工单成功: WO20250905072948
|
||||
2025-09-05 07:29:48,286 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 07:29:49,134 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:29:49,135 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 07:29:49,143 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 07:30:42,213 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:30:42,221 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:30:42,227 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 07:30:42,229 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 07:30:43,118 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:30:43,121 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 07:30:43,146 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 07:30:45,435 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:30:56,747 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:31:02,248 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:31:02,281 - src.dialogue.dialogue_manager - INFO - 创建工单成功: WO20250905073102
|
||||
2025-09-05 07:31:07,982 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:31:08,024 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 07:31:09,097 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:31:09,097 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 07:31:09,107 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 07:31:35,450 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:31:35,455 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:31:35,460 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 07:31:35,463 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 07:31:41,075 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:31:41,088 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:31:41,091 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 07:31:41,094 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 07:31:41,897 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:31:41,899 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 07:31:41,927 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 07:31:47,342 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:31:56,940 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:32:09,260 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:32:09,292 - src.dialogue.dialogue_manager - INFO - 创建工单成功: WO20250905073209
|
||||
2025-09-05 07:32:14,540 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:32:14,581 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 07:32:15,335 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:32:15,337 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 07:32:15,345 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 07:35:12,826 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:35:12,838 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 1 个条目
|
||||
2025-09-05 07:35:12,841 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 07:35:23,168 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 07:35:23,181 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 2 个条目
|
||||
2025-09-05 07:35:23,182 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 为什么我无法登录账户?...
|
||||
2025-09-05 07:35:23,189 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 3 个条目
|
||||
2025-09-05 07:35:23,192 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 登录时密码错误怎么办?...
|
||||
2025-09-05 07:35:23,202 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 4 个条目
|
||||
2025-09-05 07:35:23,203 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 账户被锁定如何解锁?...
|
||||
2025-09-05 07:35:23,210 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 5 个条目
|
||||
2025-09-05 07:35:23,210 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 网络问题会影响登录吗?...
|
||||
2025-09-05 07:35:23,889 - jieba - DEBUG - Building prefix dict from the default dictionary ...
|
||||
2025-09-05 07:35:23,896 - jieba - DEBUG - Loading model from cache C:\Users\jiezhao\AppData\Local\Temp\jieba.cache
|
||||
2025-09-05 07:35:25,604 - jieba - DEBUG - Loading model cost 1.715 seconds.
|
||||
2025-09-05 07:35:25,605 - jieba - DEBUG - Prefix dict has been built successfully.
|
||||
2025-09-05 07:35:25,619 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 6 个条目
|
||||
2025-09-05 07:35:25,622 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 如何重置密码? (如何, 重置, 密码)...
|
||||
2025-09-05 07:35:25,636 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 07:35:25,638 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 账户被锁定了怎么办? (账户, 锁定, 怎么办)...
|
||||
2025-09-05 07:35:56,581 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 07:35:56,591 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 07:35:56,594 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 07:36:46,317 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 07:36:46,324 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 07:36:46,325 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:01:37,144 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 09:01:37,149 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 09:01:37,150 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:03:33,805 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 09:03:33,812 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 09:03:33,813 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:03:33,928 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://192.168.165.238:5000
|
||||
2025-09-05 09:03:33,928 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-09-05 09:03:33,934 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 09:03:36,083 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 09:03:36,086 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 7 个条目
|
||||
2025-09-05 09:03:36,087 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:03:36,115 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 09:03:36,129 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 09:03:39,851 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:39] "GET / HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:40,036 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:40] "GET /static/css/style.css HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:40,099 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:40] "GET /static/js/app.js HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:40,733 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:40] "GET /api/rules HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:40,750 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:40] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:40,788 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:40] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:40,793 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:40] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:41,026 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:41] "[33mGET /favicon.ico HTTP/1.1[0m" 404 -
|
||||
2025-09-05 09:03:45,743 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:45] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:45,747 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:45] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:49,068 - src.analytics.monitor_service - INFO - 监控服务已启动
|
||||
2025-09-05 09:03:49,069 - src.main - INFO - 监控服务已启动
|
||||
2025-09-05 09:03:49,069 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:49] "POST /api/monitor/start HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:49,133 - src.analytics.monitor_service - INFO - 触发 3 个预警
|
||||
2025-09-05 09:03:49,133 - src.analytics.monitor_service - WARNING - 预警触发: 用户满意度较低: 0.00 (阈值: 0.6)
|
||||
2025-09-05 09:03:49,134 - src.analytics.monitor_service - INFO - 发送通知: {'level': '警告', 'message': '用户满意度较低: 0.00 (阈值: 0.6)', 'timestamp': '2025-09-05T09:03:49.080745', 'rule_name': '满意度预警'}
|
||||
2025-09-05 09:03:49,134 - src.analytics.monitor_service - WARNING - 警告预警: 用户满意度较低: 0.00 (阈值: 0.6)
|
||||
2025-09-05 09:03:49,134 - src.analytics.monitor_service - WARNING - 预警触发: 知识库命中率较低: 0.00 (阈值: 0.5)
|
||||
2025-09-05 09:03:49,135 - src.analytics.monitor_service - INFO - 发送通知: {'level': '警告', 'message': '知识库命中率较低: 0.00 (阈值: 0.5)', 'timestamp': '2025-09-05T09:03:49.100590', 'rule_name': '知识库命中率预警'}
|
||||
2025-09-05 09:03:49,135 - src.analytics.monitor_service - WARNING - 警告预警: 知识库命中率较低: 0.00 (阈值: 0.5)
|
||||
2025-09-05 09:03:49,135 - src.analytics.monitor_service - WARNING - 预警触发: 系统内存使用率过高: 80.8% (阈值: 80.0%)
|
||||
2025-09-05 09:03:49,136 - src.analytics.monitor_service - INFO - 发送通知: {'level': '警告', 'message': '系统内存使用率过高: 80.8% (阈值: 80.0%)', 'timestamp': '2025-09-05T09:03:49.125354', 'rule_name': '内存使用预警'}
|
||||
2025-09-05 09:03:49,136 - src.analytics.monitor_service - WARNING - 警告预警: 系统内存使用率过高: 80.8% (阈值: 80.0%)
|
||||
2025-09-05 09:03:49,400 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:49] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:50,444 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:50] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:50,745 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:50] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:50,761 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:50] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:55,752 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:55] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:03:55,752 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:03:55] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:04:00,438 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:04:00] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:04:00,731 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:04:00] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:04:00,745 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:04:00] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:04:01,926 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:04:01] "POST /api/check-alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:04:02,236 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:04:02] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:04:05,743 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:04:05] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:04:05,744 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:04:05] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:04:06,158 - src.analytics.monitor_service - INFO - 监控服务已停止
|
||||
2025-09-05 09:04:06,160 - src.main - INFO - 监控服务已停止
|
||||
2025-09-05 09:04:06,161 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:04:06] "POST /api/monitor/stop HTTP/1.1" 200 -
|
||||
2025-09-05 09:04:06,482 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:04:06] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:15:19,406 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:15:19,419 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:15:19,421 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:15:50,606 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:15:50,618 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:15:50,620 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:16:20,754 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:16:20,767 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:16:20,768 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:19:45,806 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:19:45,814 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:19:45,815 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:19:45,863 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://192.168.165.238:5000
|
||||
2025-09-05 09:19:45,863 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-09-05 09:19:45,867 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 09:19:48,167 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:19:48,176 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:19:48,178 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:19:48,206 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 09:19:48,224 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 09:19:50,948 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:19:50] "GET / HTTP/1.1" 200 -
|
||||
2025-09-05 09:19:51,124 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:19:51] "[36mGET /static/css/style.css HTTP/1.1[0m" 304 -
|
||||
2025-09-05 09:19:51,192 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:19:51] "[36mGET /static/js/app.js HTTP/1.1[0m" 304 -
|
||||
2025-09-05 09:19:51,519 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:19:51] "GET /api/rules HTTP/1.1" 200 -
|
||||
2025-09-05 09:19:51,540 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:19:51] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:19:51,563 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:19:51] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:19:51,577 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:19:51] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:19:56,217 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:19:56] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:19:56,524 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:19:56] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:01,529 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:01] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:01,559 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:01] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:01,562 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:01] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:04,007 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:04] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:04,314 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:04] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:04,334 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:04] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:05,752 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:05] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:05,753 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:05] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:10,437 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:10] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:10,737 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:10] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:10,751 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:10] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:15,749 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:15] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:15,750 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:15] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:20,435 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:20] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:20,732 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:20] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:20,746 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:20] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:25,752 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:25] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:25,752 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:25] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:30,437 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:30] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:30,734 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:30] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:30,749 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:30] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:35,743 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:35] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:35,745 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:35] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:40,441 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:40] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:40,735 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:40] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:40,748 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:40] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:45,749 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:45] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:45,749 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:45] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:50,444 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:50] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:50,746 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:50] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:50,758 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:50] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:55,747 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:55] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:20:55,748 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:20:55] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:00,435 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:00] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:00,731 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:00] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:00,745 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:00] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:05,750 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:05] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:05,751 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:05] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:10,440 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:10] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:10,742 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:10] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:10,755 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:10] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:15,745 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:15] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:15,745 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:15] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:20,445 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:20] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:20,742 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:20] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:20,766 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:20] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:25,753 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:25] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:25,756 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:25] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:31,079 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:31] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:31,377 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:31] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:31,388 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:31] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:36,393 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:36] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:36,395 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:36] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:41,082 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:41] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:41,380 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:41] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:41,390 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:41] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:46,394 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:46] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:46,394 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:46] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:51,087 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:51] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:51,379 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:51] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:21:51,390 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:21:51] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:22:33,053 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:22:33,058 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:22:33,064 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:40:46,233 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:40:46,242 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:40:46,243 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:40:46,249 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:40:46,303 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://192.168.165.238:5000
|
||||
2025-09-05 09:40:46,304 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-09-05 09:40:46,307 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 09:40:48,603 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:40:48,612 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:40:48,613 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:40:48,620 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:40:48,654 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 09:40:48,669 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 09:40:55,808 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:40:55] "GET / HTTP/1.1" 200 -
|
||||
2025-09-05 09:40:56,113 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:40:56] "GET /static/css/style.css HTTP/1.1" 200 -
|
||||
2025-09-05 09:40:56,152 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:40:56] "GET /static/js/app.js HTTP/1.1" 200 -
|
||||
2025-09-05 09:40:56,390 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:40:56] "GET /api/rules HTTP/1.1" 200 -
|
||||
2025-09-05 09:40:56,418 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:40:56] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:40:56,450 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:40:56] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:40:56,461 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:40:56] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:40:56,902 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:40:56] "[33mGET /favicon.ico HTTP/1.1[0m" 404 -
|
||||
2025-09-05 09:41:00,675 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:00] "GET /chat HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:00,713 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:00] "[36mGET /static/js/chat.js HTTP/1.1[0m" 304 -
|
||||
2025-09-05 09:41:02,122 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:02] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:02,123 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:02] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:07,093 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:07] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:07,114 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:07] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:07,115 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:07] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:08,955 - src.dialogue.realtime_chat - INFO - 创建新会话: session_test_user_http_1757036468
|
||||
2025-09-05 09:41:08,956 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:08] "POST /api/chat/session HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:10,695 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:10] "GET /chat-http HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:11,003 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:11] "GET /static/js/chat_http.js HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:12,103 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:12] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:12,107 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:12] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:16,593 - src.dialogue.realtime_chat - INFO - 创建新会话: session_user_001_1757036476
|
||||
2025-09-05 09:41:16,594 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:16] "POST /api/chat/session HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:17,090 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:17] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:17,119 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:17] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:17,124 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:17] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:22,100 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:22] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:22,104 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:22] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:22,776 - werkzeug - INFO - * Detected change in 'c:\\Users\\jiezhao\\Desktop\\TSP_assistant\\start_flask_only.py', reloading
|
||||
2025-09-05 09:41:23,124 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 09:41:26,089 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:41:26,089 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:41:26,089 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:41:26,108 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:41:26,176 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 09:41:26,203 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 09:41:26,302 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:26] "POST /api/chat/message HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:27,089 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:27] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:27,104 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:27] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:27,116 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:27] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:32,102 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:32] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:32,104 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:32] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:35,164 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:35] "POST /api/chat/message HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:37,086 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:37] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:37,088 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:37] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:37,088 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:37] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:41,448 - src.dialogue.realtime_chat - INFO - 结束会话: session_user_001_1757036476
|
||||
2025-09-05 09:41:41,449 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:41] "DELETE /api/chat/session/session_user_001_1757036476 HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:42,080 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:42] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:42,080 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:42] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:43,072 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:43,379 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:43,390 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:44,169 - src.dialogue.realtime_chat - INFO - 创建新会话: session_user_001_1757036504
|
||||
2025-09-05 09:41:44,169 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:41:44] "POST /api/chat/session HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:47,086 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:47] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:47,086 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:47] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:47,086 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:47] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:52,095 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:52] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:52,095 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:52] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:57,071 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:57] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:57,092 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:57] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:41:57,092 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:41:57] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:01,946 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 09:42:01,950 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:42:01] "POST /api/chat/message HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:24,176 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:24] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:24,203 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:24] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:24,204 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:24] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:26,396 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:26] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:26,412 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:26] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:26,413 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:26] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:26,640 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:26] "GET / HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:26,848 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:26] "[36mGET /static/js/app.js HTTP/1.1[0m" 304 -
|
||||
2025-09-05 09:42:26,848 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:26] "[36mGET /static/css/style.css HTTP/1.1[0m" 304 -
|
||||
2025-09-05 09:42:26,900 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:26] "GET /api/rules HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:26,908 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:26] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:26,934 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:26] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:26,945 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:26] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:31,906 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:31] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:31,908 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:31] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:32,708 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:32] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:33,677 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:33] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:36,891 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:36] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:36,910 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:36] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:36,911 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:36] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:42,087 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:42] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:42,087 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:42] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:43,393 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:42:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:43,408 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:42:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:43,408 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:42:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:47,081 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:47] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:47,081 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:47] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:47,081 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:47] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:52,089 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:52] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:52,091 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:52] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:57,084 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:57] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:57,096 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:57] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:42:57,103 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:42:57] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:02,086 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:02] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:02,089 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:02] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:04,410 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 09:43:04,426 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:43:04] "POST /api/chat/message HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:07,079 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:07] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:07,081 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:07] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:07,081 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:07] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:12,094 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:12] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:12,094 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:12] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:17,081 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:17] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:17,081 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:17] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:17,081 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:17] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:22,094 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:22] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:22,094 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:22] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:23,629 - werkzeug - INFO - * Detected change in 'c:\\Users\\jiezhao\\Desktop\\TSP_assistant\\start_flask_only.py', reloading
|
||||
2025-09-05 09:43:23,947 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 09:43:26,456 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:43:26,471 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:43:26,477 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:43:26,486 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:43:26,521 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 09:43:26,545 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 09:43:27,116 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:27] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:27,124 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:27] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:27,130 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:27] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:32,089 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:32] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:32,090 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:32] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:37,083 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:37] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:37,090 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:37] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:37,091 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:37] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:43,093 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:43,096 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:43:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:43,394 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:43:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:43,418 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:43:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:43:43,419 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:43:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:44:43,121 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:44:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:44:43,145 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:44:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:44:43,150 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:44:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:44:43,151 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:44:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:44:43,391 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:44:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:44:43,415 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:44:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:45:27,118 - werkzeug - INFO - * Detected change in 'c:\\Users\\jiezhao\\Desktop\\TSP_assistant\\confidence_demo.py', reloading
|
||||
2025-09-05 09:45:27,385 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 09:45:29,680 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:45:29,689 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:45:29,690 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:45:29,697 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:45:29,725 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 09:45:29,741 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 09:45:43,117 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:45:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:45:43,132 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:45:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:45:43,135 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:45:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:45:43,405 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:45:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:45:43,419 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:45:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:45:43,419 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:45:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:46:08,267 - werkzeug - INFO - * Detected change in 'c:\\Users\\jiezhao\\Desktop\\TSP_assistant\\confidence_demo.py', reloading
|
||||
2025-09-05 09:46:08,496 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 09:46:11,194 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:46:11,205 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:46:11,206 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 09:46:11,213 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 09:46:11,246 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 09:46:11,265 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 09:46:43,126 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:46:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:46:43,135 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:46:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:46:43,140 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:46:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:46:43,416 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:46:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:46:43,428 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:46:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:46:43,428 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:46:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:47:43,116 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:47:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:47:43,128 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:47:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:47:43,130 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:47:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:47:43,131 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:47:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:47:43,422 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:47:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:47:43,439 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:47:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:48:43,095 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:48:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:48:43,112 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:48:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:48:43,119 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:48:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:48:43,395 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:48:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:48:43,406 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:48:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:48:43,407 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:48:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:49:43,104 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:49:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:49:43,131 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:49:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:49:43,132 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:49:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:49:43,133 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:49:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:49:43,420 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:49:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:49:43,441 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:49:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:50:43,100 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:50:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:50:43,123 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:50:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:50:43,124 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:50:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:50:43,401 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:50:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:50:43,414 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:50:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:50:43,414 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:50:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:51:43,096 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:51:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:51:43,121 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:51:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:51:43,123 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:51:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:51:43,123 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:51:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:51:43,405 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:51:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:51:43,413 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:51:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:52:43,081 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:52:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:52:43,097 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:52:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:52:43,098 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:52:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:52:43,423 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:52:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:52:43,441 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:52:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:52:43,441 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:52:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:53:43,096 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:53:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:53:43,118 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:53:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:53:43,119 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:53:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:53:43,120 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:53:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:53:43,403 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:53:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:53:43,421 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:53:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:54:43,094 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:54:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:54:43,094 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:54:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:54:43,094 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:54:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:54:43,404 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:54:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:54:43,409 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:54:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:54:43,409 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:54:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:24,362 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:24] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:24,394 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:24] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:24,396 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:24] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:26,894 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:26] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:26,913 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:26] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:26,915 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:26] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:31,898 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:31] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:31,898 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:31] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:37,076 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:37] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:37,090 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:37] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:37,090 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:37] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:42,089 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:42] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:42,089 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:42] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:43,082 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:55:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:43,388 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:55:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:43,395 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:55:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:47,079 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:47] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:47,095 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:47] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:47,097 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:47] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:52,091 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:52] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:52,091 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:52] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:57,090 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:57] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:57,116 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:57] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:55:57,117 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:55:57] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:02,097 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:02] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:02,104 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:02] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:07,080 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:07] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:07,111 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:07] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:07,111 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:07] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:12,099 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:12] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:12,105 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:12] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:17,082 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:17] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:17,103 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:17] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:17,103 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:17] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:22,095 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:22] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:22,099 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:22] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:27,082 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:27] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:27,109 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:27] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:27,111 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:27] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:32,098 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:32] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:32,098 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:32] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:43,111 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:43,132 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:43,133 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:56:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:43,411 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:56:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:43,437 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:56:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:56:43,443 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:56:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:57:43,120 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:57:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:57:43,150 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:57:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:57:43,153 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:57:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:57:43,154 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:57:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:57:43,481 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:57:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:57:43,568 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:57:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:58:43,112 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:58:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:58:43,138 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:58:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:58:43,150 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:58:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:58:43,469 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:58:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:58:43,491 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:58:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:58:43,531 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:58:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:59:43,111 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:59:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:59:43,154 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:59:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:59:43,159 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:59:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 09:59:43,160 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 09:59:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 09:59:43,416 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:59:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 09:59:43,437 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 09:59:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 10:00:43,098 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 10:00:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 10:00:43,120 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 10:00:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 10:00:43,125 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 10:00:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 10:00:43,397 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 10:00:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 10:00:43,422 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 10:00:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 10:00:43,423 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 10:00:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 10:01:23,989 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 10:01:23] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 10:01:43,107 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 10:01:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 10:01:43,140 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 10:01:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 10:01:43,141 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 10:01:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 10:01:43,144 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 10:01:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 10:01:43,399 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 10:01:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 10:01:43,415 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 10:01:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 10:02:43,097 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 10:02:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 10:02:43,115 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 10:02:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 10:02:43,117 - werkzeug - INFO - 192.168.165.238 - - [05/Sep/2025 10:02:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 10:02:43,400 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 10:02:43] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 10:02:43,417 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 10:02:43] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 10:02:43,422 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 10:02:43] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 11:44:54,375 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:44:54,388 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:44:54,388 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:44:54,391 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 11:44:55,193 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 11:44:55,193 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 11:44:55,205 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 11:46:08,547 - src.core.database - ERROR - 数据库操作失败: 'severity' is an invalid keyword argument for Alert
|
||||
2025-09-05 11:46:08,547 - src.analytics.analytics_manager - ERROR - 生成每日分析报告失败: 'severity' is an invalid keyword argument for Alert
|
||||
2025-09-05 11:46:17,124 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-05 11:46:18,465 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-05 11:46:18,466 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-05 11:46:18,469 - src.main - INFO - 知识库测试成功
|
||||
2025-09-05 11:46:38,259 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:46:38,276 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:46:38,281 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:46:38,290 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:47:09,304 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:47:09,310 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:47:09,310 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:47:09,321 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:48:52,647 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:48:52,655 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:48:52,656 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:48:52,658 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:50:00,658 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:50:00,674 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:50:00,675 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:50:00,682 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:50:50,777 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:50:50,784 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:50:50,784 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:50:50,797 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:50:50,842 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://192.168.159.238:5000
|
||||
2025-09-05 11:50:50,842 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-09-05 11:50:50,845 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 11:50:52,755 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:50:52,762 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:50:52,764 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:50:52,772 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:50:52,801 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 11:50:52,815 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 11:50:55,642 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:50:55] "GET / HTTP/1.1" 200 -
|
||||
2025-09-05 11:50:55,911 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:50:55] "GET /static/css/style.css HTTP/1.1" 200 -
|
||||
2025-09-05 11:50:55,917 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:50:55] "GET /static/js/app.js HTTP/1.1" 200 -
|
||||
2025-09-05 11:50:56,214 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:50:56] "GET /api/rules HTTP/1.1" 200 -
|
||||
2025-09-05 11:50:56,233 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:50:56] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 11:50:56,250 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:50:56] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 11:50:56,270 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:50:56] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 11:50:57,077 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:50:57] "[33mGET /favicon.ico HTTP/1.1[0m" 404 -
|
||||
2025-09-05 11:51:01,230 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:01] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:01,230 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:01] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:06,213 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:06] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:06,227 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:06] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:06,229 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:06] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:12,107 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:12] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:12,107 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:12] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:16,219 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:16] "GET /api/alerts HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:16,232 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:16] "GET /api/health HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:16,234 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:16] "GET /api/monitor/status HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:16,959 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:16] "GET /chat HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:17,016 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:17] "GET /static/js/chat.js HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:38,282 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:38] "GET /chat HTTP/1.1" 200 -
|
||||
2025-09-05 11:51:38,319 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:51:38] "[36mGET /static/js/chat.js HTTP/1.1[0m" 304 -
|
||||
2025-09-05 11:51:57,037 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:51:57,044 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:51:57,046 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:51:57,053 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:51:57,132 - werkzeug - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://192.168.159.238:5000
|
||||
2025-09-05 11:51:57,133 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
|
||||
2025-09-05 11:51:57,137 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 11:51:59,082 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:51:59,097 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:51:59,103 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:51:59,110 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:51:59,137 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 11:51:59,151 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 11:52:05,968 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:52:05] "GET /chat HTTP/1.1" 200 -
|
||||
2025-09-05 11:52:06,108 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:52:06] "[36mGET /static/js/chat.js HTTP/1.1[0m" 304 -
|
||||
2025-09-05 11:53:01,219 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:53:01] "GET /chat HTTP/1.1" 200 -
|
||||
2025-09-05 11:53:01,269 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:53:01] "[36mGET /static/js/chat.js HTTP/1.1[0m" 304 -
|
||||
2025-09-05 11:53:22,119 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:53:22] "GET /chat HTTP/1.1" 200 -
|
||||
2025-09-05 11:53:22,172 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:53:22] "[36mGET /static/js/chat.js HTTP/1.1[0m" 304 -
|
||||
2025-09-05 11:53:22,370 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:53:22] "[33mGET /favicon.ico HTTP/1.1[0m" 404 -
|
||||
2025-09-05 11:54:51,135 - werkzeug - INFO - * Detected change in 'c:\\Users\\jiezhao\\Desktop\\TSP_assistant\\src\\web\\websocket_server.py', reloading
|
||||
2025-09-05 11:54:51,446 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 11:54:54,582 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:54:54,607 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:54:54,607 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:54:54,619 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:54:54,660 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 11:54:54,684 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 11:54:55,888 - werkzeug - INFO - * Detected change in 'c:\\Users\\jiezhao\\Desktop\\TSP_assistant\\src\\web\\websocket_server.py', reloading
|
||||
2025-09-05 11:54:56,215 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 11:54:59,686 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:54:59,697 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:54:59,697 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:54:59,715 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:54:59,755 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 11:54:59,776 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 11:55:06,341 - werkzeug - INFO - * Detected change in 'c:\\Users\\jiezhao\\Desktop\\TSP_assistant\\src\\web\\websocket_server.py', reloading
|
||||
2025-09-05 11:55:06,656 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 11:55:09,693 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:55:09,705 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:55:09,708 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:55:09,721 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:55:09,764 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 11:55:09,784 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 11:55:12,038 - werkzeug - INFO - * Detected change in 'c:\\Users\\jiezhao\\Desktop\\TSP_assistant\\src\\web\\websocket_server.py', reloading
|
||||
2025-09-05 11:55:12,273 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 11:55:14,352 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:55:14,372 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:55:14,373 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:55:14,381 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:55:14,406 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 11:55:14,419 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 11:55:15,540 - werkzeug - INFO - * Detected change in 'c:\\Users\\jiezhao\\Desktop\\TSP_assistant\\src\\web\\websocket_server.py', reloading
|
||||
2025-09-05 11:55:15,731 - werkzeug - INFO - * Restarting with stat
|
||||
2025-09-05 11:55:17,846 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:55:17,853 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:55:17,853 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-05 11:55:17,862 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-05 11:55:17,893 - werkzeug - WARNING - * Debugger is active!
|
||||
2025-09-05 11:55:17,908 - werkzeug - INFO - * Debugger PIN: 651-387-696
|
||||
2025-09-05 11:55:29,145 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:55:29] "GET /chat HTTP/1.1" 200 -
|
||||
2025-09-05 11:55:29,333 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:55:29] "[36mGET /static/js/chat.js HTTP/1.1[0m" 304 -
|
||||
2025-09-05 11:55:31,994 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:55:31] "GET /chat HTTP/1.1" 200 -
|
||||
2025-09-05 11:55:32,305 - werkzeug - INFO - 127.0.0.1 - - [05/Sep/2025 11:55:32] "[36mGET /static/js/chat.js HTTP/1.1[0m" 304 -
|
||||
2025-09-06 17:30:59,734 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-06 17:30:59,756 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-06 17:30:59,758 - __main__ - INFO - TSP助手初始化完成
|
||||
2025-09-06 17:30:59,760 - __main__ - INFO - 数据库连接测试成功
|
||||
2025-09-06 17:31:00,483 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:31:00,485 - __main__ - INFO - LLM API连接测试成功
|
||||
2025-09-06 17:31:00,509 - __main__ - INFO - 知识库测试成功
|
||||
2025-09-06 17:31:00,524 - src.dialogue.dialogue_manager - INFO - 创建工单成功: WO20250906173100
|
||||
2025-09-06 17:31:05,259 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:31:05,270 - __main__ - INFO - 数据库连接测试成功
|
||||
2025-09-06 17:31:06,162 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:31:06,164 - __main__ - INFO - LLM API连接测试成功
|
||||
2025-09-06 17:31:06,170 - __main__ - INFO - 知识库测试成功
|
||||
2025-09-06 17:31:42,181 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-06 17:31:42,195 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 39 个条目
|
||||
2025-09-06 17:31:42,198 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-06 17:31:42,198 - src.agent.tool_manager - INFO - 注册工具: search_knowledge
|
||||
2025-09-06 17:31:42,198 - src.agent.tool_manager - INFO - 注册工具: create_work_order
|
||||
2025-09-06 17:31:42,198 - src.agent.tool_manager - INFO - 注册工具: update_work_order
|
||||
2025-09-06 17:31:42,198 - src.agent.tool_manager - INFO - 注册工具: generate_response
|
||||
2025-09-06 17:31:42,198 - src.agent.tool_manager - INFO - 注册工具: analyze_data
|
||||
2025-09-06 17:31:42,198 - src.agent.tool_manager - INFO - 注册工具: send_notification
|
||||
2025-09-06 17:31:42,198 - src.agent.tool_manager - INFO - 注册工具: schedule_task
|
||||
2025-09-06 17:31:42,198 - src.agent.tool_manager - INFO - 注册工具: web_search
|
||||
2025-09-06 17:31:42,198 - src.agent.tool_manager - INFO - 注册工具: file_operation
|
||||
2025-09-06 17:31:42,200 - src.agent.tool_manager - INFO - 注册工具: database_query
|
||||
2025-09-06 17:31:42,200 - src.agent.tool_manager - INFO - 已注册 10 个默认工具
|
||||
2025-09-06 17:31:42,200 - src.agent.agent_core - INFO - Agent核心初始化完成
|
||||
2025-09-06 17:31:42,200 - __main__ - INFO - TSP Agent助手初始化完成
|
||||
2025-09-06 17:31:45,661 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:31:45,662 - src.agent.goal_manager - INFO - 创建目标: goal_20250906_173145, 类型: general
|
||||
2025-09-06 17:31:47,398 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:32:13,349 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:32:13,351 - src.agent.planner - INFO - 创建计划成功,包含 1 个任务
|
||||
2025-09-06 17:32:13,351 - src.agent.executor - INFO - 执行任务: condition_check, 类型: condition, 工具:
|
||||
2025-09-06 17:32:13,352 - src.agent.executor - INFO - 任务 condition_check 执行完成,耗时: 0.00秒
|
||||
2025-09-06 17:32:13,352 - src.agent.executor - INFO - 计划执行完成: exec_20250906_173213
|
||||
2025-09-06 17:32:33,643 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:32:34,255 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:32:49,452 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:32:49,453 - src.agent.goal_manager - INFO - 创建目标: goal_20250906_173249, 类型: general
|
||||
2025-09-06 17:32:51,393 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:33:07,158 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:33:07,159 - src.agent.planner - INFO - 创建计划成功,包含 1 个任务
|
||||
2025-09-06 17:33:07,159 - src.agent.executor - INFO - 执行任务: condition_check, 类型: condition, 工具:
|
||||
2025-09-06 17:33:07,159 - src.agent.executor - INFO - 任务 condition_check 执行完成,耗时: 0.00秒
|
||||
2025-09-06 17:33:07,159 - src.agent.executor - INFO - 计划执行完成: exec_20250906_173307
|
||||
2025-09-06 17:33:23,476 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:33:27,641 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:33:27,643 - src.agent.goal_manager - INFO - 创建目标: goal_20250906_173327, 类型: general
|
||||
2025-09-06 17:33:29,378 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:33:45,394 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:33:45,396 - src.agent.planner - INFO - 创建计划成功,包含 1 个任务
|
||||
2025-09-06 17:33:45,396 - src.agent.executor - INFO - 执行任务: condition_check, 类型: condition, 工具:
|
||||
2025-09-06 17:33:45,396 - src.agent.executor - INFO - 任务 condition_check 执行完成,耗时: 0.00秒
|
||||
2025-09-06 17:33:45,396 - src.agent.executor - INFO - 计划执行完成: exec_20250906_173345
|
||||
2025-09-06 17:34:05,563 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:34:08,275 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:34:08,297 - src.dialogue.dialogue_manager - INFO - 创建工单成功: WO20250906173408
|
||||
2025-09-06 17:34:08,301 - src.core.database - ERROR - 数据库操作失败: 'Alert' object has no attribute 'severity'
|
||||
2025-09-06 17:34:08,301 - src.analytics.analytics_manager - ERROR - 获取活跃预警失败: 'Alert' object has no attribute 'severity'
|
||||
2025-09-06 17:34:08,305 - src.main - INFO - 数据库连接测试成功
|
||||
2025-09-06 17:34:09,081 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 17:34:09,088 - src.main - INFO - LLM API连接测试成功
|
||||
2025-09-06 17:34:09,090 - src.main - INFO - 知识库测试成功
|
||||
2025-09-06 20:04:00,687 - src.core.database - ERROR - 数据库操作失败: (pymysql.err.ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '('knowledge_entries') \n WHERE name = 'is_verified'' at line 2")
|
||||
[SQL:
|
||||
SELECT COUNT(*) as count
|
||||
FROM pragma_table_info('knowledge_entries')
|
||||
WHERE name = 'is_verified'
|
||||
]
|
||||
(Background on this error at: https://sqlalche.me/e/20/f405)
|
||||
2025-09-06 20:04:00,696 - src.core.database - ERROR - 数据库操作失败: (pymysql.err.OperationalError) (1054, "Unknown column 'knowledge_entries.is_verified' in 'field list'")
|
||||
[SQL: SELECT count(*) AS count_1
|
||||
FROM (SELECT knowledge_entries.id AS knowledge_entries_id, knowledge_entries.question AS knowledge_entries_question, knowledge_entries.answer AS knowledge_entries_answer, knowledge_entries.category AS knowledge_entries_category, knowledge_entries.confidence_score AS knowledge_entries_confidence_score, knowledge_entries.usage_count AS knowledge_entries_usage_count, knowledge_entries.created_at AS knowledge_entries_created_at, knowledge_entries.updated_at AS knowledge_entries_updated_at, knowledge_entries.is_active AS knowledge_entries_is_active, knowledge_entries.is_verified AS knowledge_entries_is_verified, knowledge_entries.verified_by AS knowledge_entries_verified_by, knowledge_entries.verified_at AS knowledge_entries_verified_at, knowledge_entries.vector_embedding AS knowledge_entries_vector_embedding
|
||||
FROM knowledge_entries) AS anon_1]
|
||||
(Background on this error at: https://sqlalche.me/e/20/e3q8)
|
||||
2025-09-06 20:04:00,714 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - location
|
||||
2025-09-06 20:04:00,717 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - status
|
||||
2025-09-06 20:04:00,717 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - battery
|
||||
2025-09-06 20:04:00,723 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - engine
|
||||
2025-09-06 20:04:00,723 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - location
|
||||
2025-09-06 20:04:00,730 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - status
|
||||
2025-09-06 20:04:00,734 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - fault
|
||||
2025-09-06 20:04:00,735 - src.vehicle.vehicle_data_manager - INFO - 示例车辆数据添加成功
|
||||
2025-09-06 20:04:00,738 - src.core.database - ERROR - 数据库操作失败: (pymysql.err.OperationalError) (1054, "Unknown column 'knowledge_entries.is_verified' in 'field list'")
|
||||
[SQL: SELECT knowledge_entries.id AS knowledge_entries_id, knowledge_entries.question AS knowledge_entries_question, knowledge_entries.answer AS knowledge_entries_answer, knowledge_entries.category AS knowledge_entries_category, knowledge_entries.confidence_score AS knowledge_entries_confidence_score, knowledge_entries.usage_count AS knowledge_entries_usage_count, knowledge_entries.created_at AS knowledge_entries_created_at, knowledge_entries.updated_at AS knowledge_entries_updated_at, knowledge_entries.is_active AS knowledge_entries_is_active, knowledge_entries.is_verified AS knowledge_entries_is_verified, knowledge_entries.verified_by AS knowledge_entries_verified_by, knowledge_entries.verified_at AS knowledge_entries_verified_at, knowledge_entries.vector_embedding AS knowledge_entries_vector_embedding
|
||||
FROM knowledge_entries
|
||||
WHERE knowledge_entries.is_verified = false]
|
||||
(Background on this error at: https://sqlalche.me/e/20/e3q8)
|
||||
2025-09-06 20:04:00,748 - src.core.database - ERROR - 数据库操作失败: (pymysql.err.OperationalError) (1054, "Unknown column 'knowledge_entries.is_verified' in 'field list'")
|
||||
[SQL: SELECT count(*) AS count_1
|
||||
FROM (SELECT knowledge_entries.id AS knowledge_entries_id, knowledge_entries.question AS knowledge_entries_question, knowledge_entries.answer AS knowledge_entries_answer, knowledge_entries.category AS knowledge_entries_category, knowledge_entries.confidence_score AS knowledge_entries_confidence_score, knowledge_entries.usage_count AS knowledge_entries_usage_count, knowledge_entries.created_at AS knowledge_entries_created_at, knowledge_entries.updated_at AS knowledge_entries_updated_at, knowledge_entries.is_active AS knowledge_entries_is_active, knowledge_entries.is_verified AS knowledge_entries_is_verified, knowledge_entries.verified_by AS knowledge_entries_verified_by, knowledge_entries.verified_at AS knowledge_entries_verified_at, knowledge_entries.vector_embedding AS knowledge_entries_vector_embedding
|
||||
FROM knowledge_entries) AS anon_1]
|
||||
(Background on this error at: https://sqlalche.me/e/20/e3q8)
|
||||
2025-09-06 20:07:56,720 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - location
|
||||
2025-09-06 20:07:56,724 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - status
|
||||
2025-09-06 20:07:56,728 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - battery
|
||||
2025-09-06 20:07:56,731 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - engine
|
||||
2025-09-06 20:07:56,735 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - location
|
||||
2025-09-06 20:07:56,738 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - status
|
||||
2025-09-06 20:07:56,741 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - fault
|
||||
2025-09-06 20:07:56,742 - src.vehicle.vehicle_data_manager - INFO - 示例车辆数据添加成功
|
||||
2025-09-06 20:09:16,590 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 43 个条目
|
||||
2025-09-06 20:09:16,604 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 43 个条目
|
||||
2025-09-06 20:09:16,604 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-06 20:09:16,606 - src.agent.tool_manager - INFO - 注册工具: search_knowledge
|
||||
2025-09-06 20:09:16,606 - src.agent.tool_manager - INFO - 注册工具: create_work_order
|
||||
2025-09-06 20:09:16,607 - src.agent.tool_manager - INFO - 注册工具: update_work_order
|
||||
2025-09-06 20:09:16,607 - src.agent.tool_manager - INFO - 注册工具: generate_response
|
||||
2025-09-06 20:09:16,607 - src.agent.tool_manager - INFO - 注册工具: analyze_data
|
||||
2025-09-06 20:09:16,607 - src.agent.tool_manager - INFO - 注册工具: send_notification
|
||||
2025-09-06 20:09:16,607 - src.agent.tool_manager - INFO - 注册工具: schedule_task
|
||||
2025-09-06 20:09:16,607 - src.agent.tool_manager - INFO - 注册工具: web_search
|
||||
2025-09-06 20:09:16,608 - src.agent.tool_manager - INFO - 注册工具: file_operation
|
||||
2025-09-06 20:09:16,608 - src.agent.tool_manager - INFO - 注册工具: database_query
|
||||
2025-09-06 20:09:16,608 - src.agent.tool_manager - INFO - 已注册 10 个默认工具
|
||||
2025-09-06 20:09:16,608 - src.agent.agent_core - INFO - Agent核心初始化完成
|
||||
2025-09-06 20:09:16,608 - src.agent_assistant - INFO - TSP Agent助手初始化完成
|
||||
2025-09-06 20:09:33,979 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 20:09:33,979 - src.agent_assistant - ERROR - 处理文件失败: 'question'
|
||||
2025-09-06 20:10:08,212 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 43 个条目
|
||||
2025-09-06 20:10:08,220 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 43 个条目
|
||||
2025-09-06 20:10:08,227 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-06 20:10:08,227 - src.agent.tool_manager - INFO - 注册工具: search_knowledge
|
||||
2025-09-06 20:10:08,228 - src.agent.tool_manager - INFO - 注册工具: create_work_order
|
||||
2025-09-06 20:10:08,229 - src.agent.tool_manager - INFO - 注册工具: update_work_order
|
||||
2025-09-06 20:10:08,229 - src.agent.tool_manager - INFO - 注册工具: generate_response
|
||||
2025-09-06 20:10:08,229 - src.agent.tool_manager - INFO - 注册工具: analyze_data
|
||||
2025-09-06 20:10:08,229 - src.agent.tool_manager - INFO - 注册工具: send_notification
|
||||
2025-09-06 20:10:08,229 - src.agent.tool_manager - INFO - 注册工具: schedule_task
|
||||
2025-09-06 20:10:08,230 - src.agent.tool_manager - INFO - 注册工具: web_search
|
||||
2025-09-06 20:10:08,230 - src.agent.tool_manager - INFO - 注册工具: file_operation
|
||||
2025-09-06 20:10:08,230 - src.agent.tool_manager - INFO - 注册工具: database_query
|
||||
2025-09-06 20:10:08,230 - src.agent.tool_manager - INFO - 已注册 10 个默认工具
|
||||
2025-09-06 20:10:08,231 - src.agent.agent_core - INFO - Agent核心初始化完成
|
||||
2025-09-06 20:10:08,231 - src.agent_assistant - INFO - TSP Agent助手初始化完成
|
||||
2025-09-06 20:10:17,957 - src.core.llm_client - INFO - API请求成功
|
||||
2025-09-06 20:10:17,959 - src.agent_assistant - INFO - LLM响应内容: [
|
||||
{
|
||||
"question": "远程启动车辆需要满足哪些条件?",
|
||||
"answer": "远程启动车辆需要满足以下条件:1. 车辆处于P档;2. 手刹已拉起;3. 车门已锁;4. 电池电量充足。",
|
||||
"category": "远程控制",
|
||||
"confidence_score": 0.95
|
||||
},
|
||||
{
|
||||
"question": "如何通过APP远程启动车辆?",
|
||||
"answer": "通过APP远程启动车辆的操作步骤如下:1. 打开车辆配套APP;2. 点击远程启动按钮;3. 系统将自动检查启动条件;4. 确认无误后,等待车辆启动完成。",
|
||||
"category": "APP功能",
|
||||
"confidence_score": 0.9
|
||||
},
|
||||
{
|
||||
"question": "远程启动后需要注意什么?",
|
||||
"answer": "远程启动后需注意:车辆启动后10分钟内必须踩下刹车以解除启动状态,否则车辆将自动熄火以确保安全。如遇到启动失败或其他异常情况,请及时联系客服。",
|
||||
"category":...
|
||||
2025-09-06 20:10:17,959 - src.agent_assistant - INFO - 成功解析JSON,提取到 4 条知识
|
||||
2025-09-06 20:10:17,979 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 44 个条目
|
||||
2025-09-06 20:10:17,981 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 远程启动车辆需要满足哪些条件?...
|
||||
2025-09-06 20:10:17,995 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 45 个条目
|
||||
2025-09-06 20:10:17,997 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 如何通过APP远程启动车辆?...
|
||||
2025-09-06 20:10:18,009 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 46 个条目
|
||||
2025-09-06 20:10:18,015 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 远程启动后需要注意什么?...
|
||||
2025-09-06 20:10:18,029 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 47 个条目
|
||||
2025-09-06 20:10:18,032 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: 远程启动过程中提示失败可能是什么原因?...
|
||||
2025-09-06 20:43:38,829 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 58 个条目
|
||||
2025-09-06 20:43:38,846 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 58 个条目
|
||||
2025-09-06 20:43:38,847 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-06 20:43:38,862 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 58 个条目
|
||||
2025-09-06 20:43:38,881 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 58 个条目
|
||||
2025-09-06 20:43:38,882 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-06 20:43:38,884 - src.agent.tool_manager - INFO - 注册工具: search_knowledge
|
||||
2025-09-06 20:43:38,884 - src.agent.tool_manager - INFO - 注册工具: create_work_order
|
||||
2025-09-06 20:43:38,884 - src.agent.tool_manager - INFO - 注册工具: update_work_order
|
||||
2025-09-06 20:43:38,886 - src.agent.tool_manager - INFO - 注册工具: generate_response
|
||||
2025-09-06 20:43:38,886 - src.agent.tool_manager - INFO - 注册工具: analyze_data
|
||||
2025-09-06 20:43:38,886 - src.agent.tool_manager - INFO - 注册工具: send_notification
|
||||
2025-09-06 20:43:38,886 - src.agent.tool_manager - INFO - 注册工具: schedule_task
|
||||
2025-09-06 20:43:38,886 - src.agent.tool_manager - INFO - 注册工具: web_search
|
||||
2025-09-06 20:43:38,886 - src.agent.tool_manager - INFO - 注册工具: file_operation
|
||||
2025-09-06 20:43:38,887 - src.agent.tool_manager - INFO - 注册工具: database_query
|
||||
2025-09-06 20:43:38,887 - src.agent.tool_manager - INFO - 已注册 10 个默认工具
|
||||
2025-09-06 20:43:38,887 - src.agent.agent_core - INFO - Agent核心初始化完成
|
||||
2025-09-06 20:43:38,887 - src.agent_assistant - INFO - TSP Agent助手初始化完成
|
||||
2025-09-06 20:43:38,906 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 58 个条目
|
||||
2025-09-06 20:43:38,950 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 58 个条目
|
||||
2025-09-06 20:43:38,969 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 58 个条目
|
||||
2025-09-06 20:43:38,971 - src.main - INFO - TSP助手初始化完成
|
||||
2025-09-06 20:43:39,774 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 59 个条目
|
||||
2025-09-06 20:43:39,782 - src.knowledge_base.knowledge_manager - INFO - 添加知识库条目成功: Web API测试删除 - 这是一个测试条目...
|
||||
2025-09-06 20:43:39,861 - src.knowledge_base.knowledge_manager - INFO - 向量化器加载成功,包含 58 个条目
|
||||
2025-09-06 20:43:39,866 - src.knowledge_base.knowledge_manager - INFO - 删除知识库条目成功: 60
|
||||
152
note/代码清理总结.md
152
note/代码清理总结.md
@@ -1,152 +0,0 @@
|
||||
# TSP智能助手 - 代码清理总结
|
||||
|
||||
## 🧹 清理完成
|
||||
|
||||
已成功清理了项目中的不需要代码文件,使项目结构更加清晰和简洁。
|
||||
|
||||
## 📁 清理的文件列表
|
||||
|
||||
### 1. 演示和测试文件 (12个)
|
||||
- `alert_demo.py` - 预警演示文件
|
||||
- `confidence_demo.py` - 置信度演示文件
|
||||
- `demo.py` - 通用演示文件
|
||||
- `demo_realtime_chat.py` - 实时对话演示文件
|
||||
- `quick_test.py` - 快速测试文件
|
||||
- `test_chat_fix.py` - 对话修复测试文件
|
||||
- `test_http_chat.py` - HTTP聊天测试文件
|
||||
- `test_realtime_chat.py` - 实时聊天测试文件
|
||||
- `test_search.py` - 搜索测试文件
|
||||
- `test_system.py` - 系统测试文件
|
||||
- `test_web_api.py` - Web API测试文件
|
||||
- `test_work_order_search.py` - 工单搜索测试文件
|
||||
- `debug_search.py` - 调试搜索文件
|
||||
|
||||
### 2. 重复文件 (1个)
|
||||
- `agent_assistant.py` - 根目录下的重复文件(保留src目录下的版本)
|
||||
|
||||
### 3. 旧的启动脚本 (5个)
|
||||
- `start_chat_simple.py` - 简单聊天启动脚本
|
||||
- `start_flask_only.py` - 仅Flask启动脚本
|
||||
- `start_realtime_chat.py` - 实时聊天启动脚本
|
||||
- `start_web.py` - Web启动脚本
|
||||
- `start.py` - 通用启动脚本
|
||||
|
||||
### 4. 构建和临时文件 (8个)
|
||||
- `add_sample_knowledge.py` - 添加示例知识库脚本
|
||||
- `build_knowledge.py` - 构建知识库脚本
|
||||
- `knowledge_builder.py` - 知识库构建器
|
||||
- `work_order_knowledge_builder.py` - 工单知识库构建器
|
||||
- `simple_work_order_builder.py` - 简单工单构建器
|
||||
- `analyze_work_orders.py` - 工单分析脚本
|
||||
- `check_knowledge_data.py` - 知识库数据检查脚本
|
||||
- `alert_manager.py` - 预警管理器脚本
|
||||
- `quick_start.py` - 快速启动脚本
|
||||
|
||||
### 5. 临时和报告文件 (2个)
|
||||
- `knowledge_build_report.txt` - 知识库构建报告
|
||||
- `knowledge_build_results.json` - 知识库构建结果
|
||||
|
||||
### 6. 过时的文档文件 (5个)
|
||||
- `实时对话问题解决方案.md` - 问题解决方案文档
|
||||
- `知识库构建指南.md` - 知识库构建指南
|
||||
- `置信度计算机制详解.md` - 置信度计算文档
|
||||
- `预警管理Web界面使用说明.md` - 预警管理文档
|
||||
- `实时对话系统使用说明.md` - 实时对话文档
|
||||
|
||||
### 7. 缓存文件
|
||||
- 所有 `__pycache__` 目录及其内容
|
||||
|
||||
## 📂 保留的核心文件
|
||||
|
||||
### 主要启动文件
|
||||
- `start_dashboard.py` - 综合管理平台启动脚本(主要)
|
||||
|
||||
### 核心功能模块
|
||||
- `src/main.py` - 主程序入口
|
||||
- `src/agent_assistant.py` - Agent助手
|
||||
- `src/web/app.py` - Web应用
|
||||
- `src/web/websocket_server.py` - WebSocket服务器
|
||||
|
||||
### 数据库相关
|
||||
- `init_database.py` - 数据库初始化
|
||||
- `reset_database.py` - 数据库重置
|
||||
- `create_mysql_db.py` - MySQL数据库创建
|
||||
- `tsp_assistant.db` - SQLite数据库文件
|
||||
|
||||
### 核心模块
|
||||
- `src/core/` - 核心功能模块
|
||||
- `src/agent/` - Agent相关模块
|
||||
- `src/analytics/` - 分析模块
|
||||
- `src/config/` - 配置模块
|
||||
- `src/dialogue/` - 对话模块
|
||||
- `src/knowledge_base/` - 知识库模块
|
||||
- `src/utils/` - 工具模块
|
||||
- `src/web/` - Web界面模块
|
||||
|
||||
### 前端资源
|
||||
- `src/web/templates/` - HTML模板
|
||||
- `src/web/static/` - 静态资源(CSS、JS)
|
||||
|
||||
### 文档
|
||||
- `README.md` - 项目说明
|
||||
- `Agent功能升级指南.md` - Agent功能指南
|
||||
- `快速启动指南.md` - 快速启动指南
|
||||
- `综合前端使用说明.md` - 综合前端使用说明
|
||||
|
||||
### 配置文件
|
||||
- `requirements.txt` - Python依赖
|
||||
- `详情.xlsx` - 项目详情表格
|
||||
|
||||
## 🎯 清理效果
|
||||
|
||||
### 文件数量减少
|
||||
- **清理前**: 约80+个文件
|
||||
- **清理后**: 约40+个文件
|
||||
- **减少**: 约50%的文件
|
||||
|
||||
### 项目结构优化
|
||||
- ✅ 移除了所有演示和测试文件
|
||||
- ✅ 删除了重复的文件
|
||||
- ✅ 清理了旧的启动脚本
|
||||
- ✅ 移除了构建和临时文件
|
||||
- ✅ 整理了文档文件
|
||||
- ✅ 清理了缓存文件
|
||||
|
||||
### 保留的核心功能
|
||||
- ✅ 综合管理平台 (`start_dashboard.py`)
|
||||
- ✅ 完整的Agent功能
|
||||
- ✅ Web界面和API
|
||||
- ✅ 数据库管理
|
||||
- ✅ 核心业务逻辑
|
||||
- ✅ 前端资源
|
||||
|
||||
## 🚀 使用建议
|
||||
|
||||
### 启动系统
|
||||
```bash
|
||||
python start_dashboard.py
|
||||
```
|
||||
|
||||
### 访问地址
|
||||
- 主页: http://localhost:5000
|
||||
- 预警管理: http://localhost:5000/alerts
|
||||
- 实时对话: http://localhost:5000/chat
|
||||
|
||||
### 主要功能
|
||||
1. **仪表板** - 系统概览和监控
|
||||
2. **智能对话** - 实时聊天功能
|
||||
3. **Agent管理** - Agent状态和工具管理
|
||||
4. **预警管理** - 预警监控和处理
|
||||
5. **知识库管理** - 知识检索和添加
|
||||
6. **工单管理** - 工单创建和跟踪
|
||||
7. **数据分析** - 性能分析和趋势
|
||||
8. **系统设置** - 参数配置和信息
|
||||
|
||||
## 📝 注意事项
|
||||
|
||||
1. **备份**: 清理前已确保重要功能完整
|
||||
2. **测试**: 建议重新测试主要功能确保正常
|
||||
3. **文档**: 保留了最重要的使用文档
|
||||
4. **配置**: 所有配置文件都已保留
|
||||
|
||||
清理完成后的项目结构更加清晰,便于维护和部署!
|
||||
270
note/功能修复总结.md
270
note/功能修复总结.md
@@ -1,270 +0,0 @@
|
||||
# TSP智能助手 - 功能修复总结
|
||||
|
||||
## 🎯 修复的问题
|
||||
|
||||
### 1. ✅ Agent模式无法启动
|
||||
**问题描述**: 前端Agent模式开关无法正常工作,Agent相关功能无法使用。
|
||||
|
||||
**修复方案**:
|
||||
- 更新Flask应用,正确集成`TSPAgentAssistant`
|
||||
- 修复Agent相关API端点,调用真实的Agent方法
|
||||
- 更新前端JavaScript,正确处理Agent状态
|
||||
|
||||
**修复文件**:
|
||||
- `src/web/app.py` - 更新Agent API端点
|
||||
- `src/agent_assistant.py` - 添加缺失的Agent方法
|
||||
- `src/web/static/js/dashboard.js` - 修复Agent控制逻辑
|
||||
|
||||
### 2. ✅ 无法手动添加知识库内容
|
||||
**问题描述**: 前端知识库添加功能无法正常工作。
|
||||
|
||||
**修复方案**:
|
||||
- 修复知识库添加API,正确调用知识库管理器
|
||||
- 更新前端JavaScript,处理添加结果
|
||||
- 添加删除知识库条目的功能
|
||||
|
||||
**修复文件**:
|
||||
- `src/web/app.py` - 修复知识库添加API
|
||||
- `src/web/static/js/dashboard.js` - 修复添加知识库逻辑
|
||||
|
||||
### 3. ✅ 缺少文件上传生成知识库功能
|
||||
**问题描述**: 系统缺少通过大模型自主读取文件生成知识库的功能。
|
||||
|
||||
**修复方案**:
|
||||
- 添加文件上传API端点
|
||||
- 实现文件内容读取(支持TXT、PDF、DOC、DOCX、MD)
|
||||
- 使用LLM自动提取问答对
|
||||
- 添加前端文件上传界面
|
||||
|
||||
**新增功能**:
|
||||
- 文件上传处理
|
||||
- 自动问答对提取
|
||||
- 多种文件格式支持
|
||||
- 进度条显示
|
||||
- 处理结果反馈
|
||||
|
||||
**修复文件**:
|
||||
- `src/web/app.py` - 添加文件上传API
|
||||
- `src/agent_assistant.py` - 添加文件处理方法
|
||||
- `src/web/templates/dashboard.html` - 添加文件上传界面
|
||||
- `src/web/static/js/dashboard.js` - 添加文件上传逻辑
|
||||
|
||||
### 4. ✅ 页面刷新后无法停留在原页面
|
||||
**问题描述**: 刷新网页后总是回到默认页面,无法保持用户当前浏览的页面。
|
||||
|
||||
**修复方案**:
|
||||
- 使用localStorage保存页面状态
|
||||
- 页面加载时自动恢复状态
|
||||
- 添加状态过期机制(1小时)
|
||||
- 完善错误处理
|
||||
|
||||
**修复文件**:
|
||||
- `src/web/static/js/dashboard.js` - 添加页面状态保存和恢复功能
|
||||
|
||||
## 🚀 新增功能特性
|
||||
|
||||
### Agent管理增强
|
||||
- **状态监控**: 实时显示Agent运行状态
|
||||
- **工具管理**: 查看可用工具和使用统计
|
||||
- **主动监控**: Agent主动发现和解决问题
|
||||
- **智能分析**: 使用Agent推理能力进行深度分析
|
||||
|
||||
### 知识库管理增强
|
||||
- **手动添加**: 支持手动添加知识库条目
|
||||
- **文件上传**: 支持上传文件自动生成知识库
|
||||
- **智能提取**: 使用LLM自动提取问答对
|
||||
- **多格式支持**: 支持TXT、PDF、DOC、DOCX、MD文件
|
||||
- **进度显示**: 文件处理进度条和状态提示
|
||||
|
||||
### 用户体验优化
|
||||
- **状态保持**: 页面刷新后保持当前浏览状态
|
||||
- **实时反馈**: 操作结果实时通知
|
||||
- **错误处理**: 完善的错误提示和处理机制
|
||||
- **响应式设计**: 适配各种屏幕尺寸
|
||||
|
||||
## 📁 修改的文件列表
|
||||
|
||||
### 后端文件
|
||||
1. **`src/web/app.py`**
|
||||
- 集成TSPAgentAssistant
|
||||
- 修复Agent相关API端点
|
||||
- 添加文件上传API
|
||||
- 修复知识库管理API
|
||||
|
||||
2. **`src/agent_assistant.py`**
|
||||
- 添加Agent状态管理方法
|
||||
- 实现文件处理功能
|
||||
- 添加知识提取方法
|
||||
- 完善错误处理
|
||||
|
||||
### 前端文件
|
||||
3. **`src/web/templates/dashboard.html`**
|
||||
- 添加文件上传模态框
|
||||
- 优化知识库管理界面
|
||||
- 添加进度条组件
|
||||
|
||||
4. **`src/web/static/js/dashboard.js`**
|
||||
- 修复Agent控制逻辑
|
||||
- 添加文件上传功能
|
||||
- 实现页面状态保存
|
||||
- 完善错误处理
|
||||
|
||||
### 测试文件
|
||||
5. **`test_fixes.py`** - 功能测试脚本
|
||||
|
||||
## 🔧 技术实现细节
|
||||
|
||||
### Agent模式修复
|
||||
```python
|
||||
# 正确的Agent状态获取
|
||||
def get_agent_status(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"success": True,
|
||||
"status": "active" if self.is_agent_mode else "inactive",
|
||||
"active_goals": len(self.agent_core.goal_manager.get_active_goals()),
|
||||
"available_tools": len(self.agent_core.tool_manager.get_available_tools()),
|
||||
"tools": [...],
|
||||
"execution_history": []
|
||||
}
|
||||
```
|
||||
|
||||
### 文件处理功能
|
||||
```python
|
||||
# 文件内容读取
|
||||
def _read_file_content(self, file_path: str, file_ext: str) -> str:
|
||||
if file_ext in ['.txt', '.md']:
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
return f.read()
|
||||
elif file_ext == '.pdf':
|
||||
# PDF处理逻辑
|
||||
elif file_ext in ['.doc', '.docx']:
|
||||
# Word文档处理逻辑
|
||||
```
|
||||
|
||||
### 知识提取功能
|
||||
```python
|
||||
# LLM知识提取
|
||||
def _extract_knowledge_from_content(self, content: str, filename: str):
|
||||
prompt = f"""
|
||||
请从以下文档内容中提取问答对,用于构建知识库:
|
||||
文档名称:{filename}
|
||||
文档内容:{content[:2000]}...
|
||||
"""
|
||||
# 调用LLM处理
|
||||
response = self.llm_client.chat_completion(...)
|
||||
```
|
||||
|
||||
### 页面状态保存
|
||||
```javascript
|
||||
// 保存页面状态
|
||||
savePageState() {
|
||||
const state = {
|
||||
currentTab: this.currentTab,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
localStorage.setItem('tsp_dashboard_state', JSON.stringify(state));
|
||||
}
|
||||
|
||||
// 恢复页面状态
|
||||
restorePageState() {
|
||||
const savedState = localStorage.getItem('tsp_dashboard_state');
|
||||
if (savedState) {
|
||||
const state = JSON.parse(savedState);
|
||||
if (Date.now() - state.timestamp < 3600000) {
|
||||
this.switchTab(state.currentTab);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 测试验证
|
||||
|
||||
### 测试脚本
|
||||
使用 `test_fixes.py` 可以验证所有修复的功能:
|
||||
|
||||
```bash
|
||||
python test_fixes.py
|
||||
```
|
||||
|
||||
### 测试内容
|
||||
1. **Agent模式测试**
|
||||
- Agent状态获取
|
||||
- Agent模式切换
|
||||
- Agent监控启动
|
||||
- 主动监控运行
|
||||
- 智能分析执行
|
||||
|
||||
2. **知识库管理测试**
|
||||
- 知识库列表获取
|
||||
- 手动添加知识
|
||||
- 知识库搜索
|
||||
- 统计信息获取
|
||||
|
||||
3. **页面状态测试**
|
||||
- 状态保存机制
|
||||
- 状态恢复功能
|
||||
- 过期处理机制
|
||||
|
||||
## 📋 使用指南
|
||||
|
||||
### 启动系统
|
||||
```bash
|
||||
python start_dashboard.py
|
||||
```
|
||||
|
||||
### 访问地址
|
||||
- 主页: http://localhost:5000
|
||||
- 预警管理: http://localhost:5000/alerts
|
||||
- 实时对话: http://localhost:5000/chat
|
||||
|
||||
### 新功能使用
|
||||
|
||||
#### 1. Agent管理
|
||||
1. 访问Agent管理标签页
|
||||
2. 使用开关切换Agent模式
|
||||
3. 启动/停止Agent监控
|
||||
4. 运行主动监控和智能分析
|
||||
|
||||
#### 2. 知识库管理
|
||||
1. 访问知识库管理标签页
|
||||
2. 手动添加知识:点击"添加知识"按钮
|
||||
3. 文件上传:点击"上传文件"按钮
|
||||
4. 选择文件和处理方式
|
||||
5. 查看处理结果
|
||||
|
||||
#### 3. 页面状态保持
|
||||
1. 切换到任意标签页
|
||||
2. 刷新页面
|
||||
3. 系统自动恢复到刷新前的页面
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 依赖库
|
||||
- **PyPDF2**: 用于PDF文件处理
|
||||
- **python-docx**: 用于Word文档处理
|
||||
|
||||
安装命令:
|
||||
```bash
|
||||
pip install PyPDF2 python-docx
|
||||
```
|
||||
|
||||
### 文件限制
|
||||
- 支持的文件格式:TXT, PDF, DOC, DOCX, MD
|
||||
- 文件大小建议不超过10MB
|
||||
- 处理时间取决于文件大小和内容复杂度
|
||||
|
||||
### 性能考虑
|
||||
- 大文件处理可能需要较长时间
|
||||
- 建议在非高峰时段进行批量文件处理
|
||||
- 定期清理临时文件
|
||||
|
||||
## 🎉 修复完成
|
||||
|
||||
所有问题已成功修复,系统现在具备:
|
||||
|
||||
✅ **完整的Agent功能** - 支持Agent模式切换、监控、分析
|
||||
✅ **完善的知识库管理** - 支持手动添加和文件上传
|
||||
✅ **智能文件处理** - 自动提取问答对生成知识库
|
||||
✅ **良好的用户体验** - 页面状态保持、实时反馈
|
||||
|
||||
现在可以正常使用TSP智能助手的所有功能了!
|
||||
193
note/快速启动指南.md
193
note/快速启动指南.md
@@ -1,193 +0,0 @@
|
||||
# TSP智能助手 - 快速启动指南
|
||||
|
||||
## 🚀 一键启动
|
||||
|
||||
### 方法1: 使用综合管理平台(推荐)
|
||||
```bash
|
||||
python start_dashboard.py
|
||||
```
|
||||
访问: http://localhost:5000
|
||||
|
||||
### 方法2: 使用原有启动方式
|
||||
```bash
|
||||
python start_web.py
|
||||
```
|
||||
|
||||
## 📋 功能清单
|
||||
|
||||
### ✅ 已整合的功能
|
||||
- [x] **仪表板** - 系统概览和性能监控
|
||||
- [x] **智能对话** - 实时聊天和工单创建
|
||||
- [x] **Agent管理** - Agent状态和工具管理
|
||||
- [x] **预警管理** - 预警监控和规则管理
|
||||
- [x] **知识库管理** - 知识检索和添加
|
||||
- [x] **工单管理** - 工单创建和状态跟踪
|
||||
- [x] **数据分析** - 性能分析和趋势展示
|
||||
- [x] **系统设置** - 参数配置和系统信息
|
||||
|
||||
## 🎯 快速体验
|
||||
|
||||
### 1. 启动系统
|
||||
```bash
|
||||
python start_dashboard.py
|
||||
```
|
||||
|
||||
### 2. 访问主页
|
||||
打开浏览器访问: http://localhost:5000
|
||||
|
||||
### 3. 体验功能
|
||||
1. **查看仪表板** - 了解系统整体状态
|
||||
2. **开始对话** - 测试智能对话功能
|
||||
3. **管理预警** - 查看和处理预警
|
||||
4. **浏览知识库** - 查看和添加知识
|
||||
5. **创建工单** - 测试工单管理功能
|
||||
|
||||
## 🔧 配置说明
|
||||
|
||||
### 环境要求
|
||||
- Python 3.8+
|
||||
- 已安装项目依赖
|
||||
- 数据库已初始化
|
||||
|
||||
### 端口配置
|
||||
- 默认端口: 5000
|
||||
- 如需修改,编辑 `start_dashboard.py` 中的端口设置
|
||||
|
||||
### 数据库配置
|
||||
- 默认使用SQLite数据库
|
||||
- 如需使用MySQL,修改 `src/config/config.py`
|
||||
|
||||
## 📱 界面预览
|
||||
|
||||
### 主界面布局
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ TSP智能助手 - 综合管理平台 │
|
||||
├─────────────┬───────────────────────────────────────────┤
|
||||
│ 控制面板 │ 主内容区 │
|
||||
│ • 仪表板 │ ┌─────────────────────────────────────────┐ │
|
||||
│ • 智能对话 │ │ 统计卡片 (活跃会话/预警/工单/知识) │ │
|
||||
│ • Agent管理 │ ├─────────────────────────────────────────┤ │
|
||||
│ • 预警管理 │ │ 性能趋势图 │ │
|
||||
│ • 知识库 │ ├─────────────────────────────────────────┤ │
|
||||
│ • 工单管理 │ │ 系统健康状态 │ │
|
||||
│ • 数据分析 │ └─────────────────────────────────────────┘ │
|
||||
│ • 系统设置 │ │
|
||||
└─────────────┴───────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🎨 界面特色
|
||||
|
||||
### 现代化设计
|
||||
- 渐变色彩搭配
|
||||
- 圆角卡片设计
|
||||
- 动态效果过渡
|
||||
- 响应式布局
|
||||
|
||||
### 直观操作
|
||||
- 侧边栏导航
|
||||
- 标签页切换
|
||||
- 模态框交互
|
||||
- 实时状态更新
|
||||
|
||||
### 数据可视化
|
||||
- Chart.js图表
|
||||
- 进度条显示
|
||||
- 状态指示器
|
||||
- 趋势分析
|
||||
|
||||
## 🔍 功能详解
|
||||
|
||||
### 仪表板
|
||||
- **实时监控**: 系统健康状态、内存使用、CPU使用率
|
||||
- **统计概览**: 活跃会话、预警数量、工单状态、知识条目
|
||||
- **性能趋势**: 24小时性能变化图表
|
||||
- **快速操作**: 一键访问各功能模块
|
||||
|
||||
### 智能对话
|
||||
- **实时聊天**: 基于WebSocket的即时通信
|
||||
- **知识库集成**: 自动检索相关知识
|
||||
- **工单创建**: 对话中直接创建工单
|
||||
- **快速操作**: 预设常用问题
|
||||
|
||||
### Agent管理
|
||||
- **状态监控**: Agent运行状态和活跃目标
|
||||
- **工具管理**: 查看工具使用统计和成功率
|
||||
- **主动监控**: Agent主动发现和解决问题
|
||||
- **执行历史**: 查看Agent执行记录
|
||||
|
||||
### 预警管理
|
||||
- **预警统计**: 按严重程度分类显示
|
||||
- **预警列表**: 实时显示活跃预警
|
||||
- **预警处理**: 一键解决预警问题
|
||||
- **规则管理**: 创建和管理预警规则
|
||||
|
||||
### 知识库管理
|
||||
- **知识检索**: 搜索和浏览知识库
|
||||
- **知识添加**: 手动添加新知识
|
||||
- **统计分析**: 使用统计和置信度
|
||||
- **分类管理**: 按类别组织知识
|
||||
|
||||
### 工单管理
|
||||
- **工单列表**: 查看和管理所有工单
|
||||
- **状态过滤**: 按状态和优先级筛选
|
||||
- **工单创建**: 创建新的工单
|
||||
- **统计分析**: 工单处理统计
|
||||
|
||||
### 数据分析
|
||||
- **性能趋势**: 系统性能变化
|
||||
- **类别分布**: 问题类别分布图
|
||||
- **详细报告**: 综合分析报告
|
||||
- **智能推荐**: 基于分析的改进建议
|
||||
|
||||
### 系统设置
|
||||
- **参数配置**: 调整系统运行参数
|
||||
- **模式切换**: 启用/禁用Agent模式
|
||||
- **系统信息**: 版本和运行状态
|
||||
- **设置保存**: 持久化配置
|
||||
|
||||
## 🚨 注意事项
|
||||
|
||||
### 首次使用
|
||||
1. 确保已安装所有依赖: `pip install -r requirements.txt`
|
||||
2. 初始化数据库: `python init_database.py`
|
||||
3. 配置API密钥: 编辑 `src/config/config.py`
|
||||
|
||||
### 常见问题
|
||||
1. **端口被占用**: 修改端口或关闭占用进程
|
||||
2. **数据库错误**: 检查数据库连接和权限
|
||||
3. **API调用失败**: 检查网络连接和API密钥
|
||||
|
||||
### 性能建议
|
||||
1. **内存使用**: 监控内存使用情况
|
||||
2. **数据库优化**: 定期清理历史数据
|
||||
3. **缓存策略**: 启用浏览器缓存
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
### 日志查看
|
||||
- 应用日志: `logs/dashboard.log`
|
||||
- 系统日志: `logs/tsp_assistant.log`
|
||||
|
||||
### 调试模式
|
||||
```bash
|
||||
export FLASK_ENV=development
|
||||
python start_dashboard.py
|
||||
```
|
||||
|
||||
### 问题反馈
|
||||
如遇到问题,请提供:
|
||||
1. 错误日志
|
||||
2. 操作步骤
|
||||
3. 系统环境
|
||||
4. 浏览器信息
|
||||
|
||||
## 🎉 开始使用
|
||||
|
||||
现在你已经了解了TSP智能助手综合管理平台的所有功能,可以开始体验这个强大的智能客服系统了!
|
||||
|
||||
```bash
|
||||
python start_dashboard.py
|
||||
```
|
||||
|
||||
访问 http://localhost:5000 开始你的智能客服之旅!
|
||||
157
note/数据库初始化说明.md
157
note/数据库初始化说明.md
@@ -1,157 +0,0 @@
|
||||
# TSP智能助手 - 数据库初始化说明
|
||||
|
||||
## 🎯 概述
|
||||
|
||||
所有数据库操作已整合到 `init_database.py` 文件中,包括:
|
||||
- 数据库表创建
|
||||
- 字段迁移和添加
|
||||
- 初始数据插入
|
||||
- 示例数据生成
|
||||
- 知识库验证
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 1. 执行数据库初始化
|
||||
```bash
|
||||
python init_database.py
|
||||
```
|
||||
|
||||
### 2. 初始化过程
|
||||
脚本会自动执行以下操作:
|
||||
|
||||
1. **📋 创建数据库表**
|
||||
- 工单表 (work_orders)
|
||||
- 对话表 (conversations)
|
||||
- 知识库表 (knowledge_entries)
|
||||
- 分析表 (analytics)
|
||||
- 预警表 (alerts)
|
||||
- 车辆数据表 (vehicle_data)
|
||||
|
||||
2. **🔄 数据库迁移**
|
||||
- 添加知识库验证字段 (is_verified, verified_by, verified_at)
|
||||
- 创建车辆数据表
|
||||
|
||||
3. **📊 插入初始数据**
|
||||
- 10条示例知识库条目
|
||||
- 所有条目自动标记为已验证
|
||||
|
||||
4. **🚗 添加示例车辆数据**
|
||||
- 2辆示例车辆 (V001, V002)
|
||||
- 包含位置、状态、电池、故障等数据
|
||||
|
||||
5. **🔍 验证知识库条目**
|
||||
- 将现有未验证条目标记为已验证
|
||||
|
||||
## 📊 初始化后的数据状态
|
||||
|
||||
### 知识库数据
|
||||
- **总条目数**: 10条
|
||||
- **已验证**: 10条
|
||||
- **未验证**: 0条
|
||||
- **分类**: 账户问题、支付问题、技术问题、服务问题、远程控制、APP功能
|
||||
|
||||
### 车辆数据
|
||||
- **车辆数量**: 2辆
|
||||
- **数据类型**: 位置、状态、电池、故障、引擎
|
||||
- **记录总数**: 7条
|
||||
|
||||
## ✅ 验证初始化成功
|
||||
|
||||
运行初始化脚本后,您会看到类似输出:
|
||||
|
||||
```
|
||||
🚀 TSP智能助手数据库初始化
|
||||
============================================================
|
||||
✅ 数据库连接成功
|
||||
|
||||
📋 创建数据库表...
|
||||
✅ 数据库表创建成功
|
||||
|
||||
🔄 执行数据库迁移...
|
||||
📝 检查知识库验证字段...
|
||||
✅ is_verified字段已存在
|
||||
✅ verified_by字段已存在
|
||||
✅ verified_at字段已存在
|
||||
✅ vehicle_data表已存在
|
||||
✅ 数据库迁移完成
|
||||
|
||||
📊 插入初始数据...
|
||||
✅ 成功插入 10 条知识库条目
|
||||
|
||||
🚗 添加示例车辆数据...
|
||||
✅ 示例车辆数据添加成功
|
||||
|
||||
🔍 验证知识库条目...
|
||||
✅ 所有知识库条目已验证
|
||||
|
||||
✅ 数据库初始化完成
|
||||
|
||||
============================================================
|
||||
📊 数据库状态检查
|
||||
============================================================
|
||||
📋 工单表记录数: 0
|
||||
💬 对话表记录数: 0
|
||||
📚 知识库表记录数: 10
|
||||
- 已验证: 10
|
||||
- 未验证: 0
|
||||
📊 分析表记录数: 0
|
||||
🚨 预警表记录数: 0
|
||||
🚗 车辆数据表记录数: 7
|
||||
- 车辆数量: 2
|
||||
- 车辆 V001: 4 种数据类型
|
||||
- 车辆 V002: 3 种数据类型
|
||||
|
||||
✅ 数据库状态检查完成
|
||||
|
||||
============================================================
|
||||
🎉 数据库初始化成功!
|
||||
============================================================
|
||||
✅ 已完成的操作:
|
||||
- 创建所有数据库表
|
||||
- 添加知识库验证字段
|
||||
- 创建车辆数据表
|
||||
- 插入初始知识库数据
|
||||
- 添加示例车辆数据
|
||||
- 验证所有知识库条目
|
||||
|
||||
🚀 现在您可以运行以下命令启动系统:
|
||||
python start_dashboard.py
|
||||
|
||||
🧪 或运行功能测试:
|
||||
python test_new_features.py
|
||||
|
||||
📋 新功能包括:
|
||||
- 知识库分页显示
|
||||
- 知识库验证机制
|
||||
- 车辆实时数据管理
|
||||
- 文件上传生成知识库
|
||||
- 智能对话结合车辆数据
|
||||
```
|
||||
|
||||
## 🔧 后续操作
|
||||
|
||||
### 启动系统
|
||||
```bash
|
||||
python start_dashboard.py
|
||||
```
|
||||
|
||||
### 运行功能测试
|
||||
```bash
|
||||
python test_new_features.py
|
||||
```
|
||||
|
||||
### 访问界面
|
||||
- 主页: http://localhost:5000
|
||||
- 预警管理: http://localhost:5000/alerts
|
||||
- 实时对话: http://localhost:5000/chat
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **备份数据**: 如果已有数据,建议先备份
|
||||
2. **权限检查**: 确保有数据库文件读写权限
|
||||
3. **依赖库**: 确保所有Python依赖库已安装
|
||||
4. **重复运行**: 脚本支持重复运行,会跳过已存在的数据
|
||||
|
||||
## 🎉 完成
|
||||
|
||||
现在所有数据库操作都整合在一个文件中,运行一次即可完成所有初始化工作!
|
||||
215
note/问题修复总结.md
215
note/问题修复总结.md
@@ -1,215 +0,0 @@
|
||||
# TSP智能助手 - 问题修复总结
|
||||
|
||||
## 🎯 问题描述
|
||||
|
||||
用户反馈:
|
||||
1. **添加知识失败** - 无法在前端添加新的知识库条目
|
||||
2. **无法显示知识库** - 知识库内容无法正常显示
|
||||
|
||||
## 🔍 问题分析
|
||||
|
||||
通过日志分析发现:
|
||||
- 系统使用MySQL数据库
|
||||
- 数据库缺少 `is_verified`、`verified_by`、`verified_at` 字段
|
||||
- 知识库模型已更新但数据库结构未同步
|
||||
- 导致SQL查询失败:`Unknown column 'knowledge_entries.is_verified' in 'field list'`
|
||||
|
||||
## ✅ 解决方案
|
||||
|
||||
### 1. 数据库迁移修复
|
||||
|
||||
**问题**: 迁移脚本只支持SQLite,但系统使用MySQL
|
||||
|
||||
**解决**: 更新 `init_database.py` 中的 `migrate_database()` 函数
|
||||
- 自动检测数据库类型(MySQL/SQLite)
|
||||
- 使用对应的SQL语法检查字段存在性
|
||||
- MySQL: 使用 `INFORMATION_SCHEMA.COLUMNS`
|
||||
- SQLite: 使用 `pragma_table_info`
|
||||
|
||||
```python
|
||||
# 检查数据库类型
|
||||
db_url = db_manager.engine.url
|
||||
is_mysql = 'mysql' in str(db_url)
|
||||
is_sqlite = 'sqlite' in str(db_url)
|
||||
|
||||
# MySQL字段检查
|
||||
if is_mysql:
|
||||
result = session.execute(text("""
|
||||
SELECT COUNT(*) as count
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'knowledge_entries'
|
||||
AND COLUMN_NAME = 'is_verified'
|
||||
""")).fetchone()
|
||||
```
|
||||
|
||||
### 2. 知识库管理修复
|
||||
|
||||
**问题**: `add_knowledge_entry` 方法缺少 `is_verified` 字段
|
||||
|
||||
**解决**: 更新方法签名和实现
|
||||
```python
|
||||
def add_knowledge_entry(
|
||||
self,
|
||||
question: str,
|
||||
answer: str,
|
||||
category: str,
|
||||
confidence_score: float = 0.5,
|
||||
is_verified: bool = False # 新增参数
|
||||
) -> bool:
|
||||
# 创建条目时包含验证字段
|
||||
entry = KnowledgeEntry(
|
||||
question=question,
|
||||
answer=answer,
|
||||
category=category,
|
||||
confidence_score=confidence_score,
|
||||
usage_count=0,
|
||||
is_verified=is_verified # 新增字段
|
||||
)
|
||||
```
|
||||
|
||||
### 3. 文件上传功能优化
|
||||
|
||||
**问题**: LLM响应解析不够健壮
|
||||
|
||||
**解决**: 改进知识提取和解析逻辑
|
||||
- 增强JSON解析错误处理
|
||||
- 改进手动解析逻辑
|
||||
- 添加详细的调试日志
|
||||
- 验证每个知识条目的字段完整性
|
||||
|
||||
```python
|
||||
# 验证每个条目的字段
|
||||
for i, entry in enumerate(knowledge_entries):
|
||||
if not isinstance(entry, dict):
|
||||
logger.error(f"条目 {i} 不是字典格式: {entry}")
|
||||
continue
|
||||
if 'question' not in entry:
|
||||
logger.error(f"条目 {i} 缺少question字段: {entry}")
|
||||
continue
|
||||
# ... 更多验证
|
||||
```
|
||||
|
||||
## 🚀 执行步骤
|
||||
|
||||
### 1. 运行数据库初始化
|
||||
```bash
|
||||
python init_database.py
|
||||
```
|
||||
|
||||
**执行结果**:
|
||||
```
|
||||
🚀 TSP智能助手数据库初始化
|
||||
============================================================
|
||||
✅ 数据库连接成功
|
||||
📋 创建数据库表...
|
||||
✅ 数据库表创建成功
|
||||
🔄 执行数据库迁移...
|
||||
📝 检查知识库验证字段...
|
||||
➕ 添加is_verified字段...
|
||||
✅ is_verified字段添加成功
|
||||
➕ 添加verified_by字段...
|
||||
✅ verified_by字段添加成功
|
||||
➕ 添加verified_at字段...
|
||||
✅ verified_at字段添加成功
|
||||
✅ vehicle_data表已存在
|
||||
✅ 数据库迁移完成
|
||||
📊 插入初始数据...
|
||||
✅ 数据库中已有数据,跳过初始数据插入
|
||||
🚗 添加示例车辆数据...
|
||||
✅ 示例车辆数据添加成功
|
||||
🔍 验证知识库条目...
|
||||
📝 发现 42 条未验证的知识库条目
|
||||
✅ 成功验证 42 条知识库条目
|
||||
✅ 数据库初始化完成
|
||||
```
|
||||
|
||||
### 2. 验证功能正常
|
||||
|
||||
**知识库状态**:
|
||||
- 总条目数: 48条
|
||||
- 已验证: 48条
|
||||
- 未验证: 0条
|
||||
|
||||
**车辆数据**:
|
||||
- 车辆数量: 2辆
|
||||
- 数据类型: 7种
|
||||
- 记录总数: 14条
|
||||
|
||||
## 📊 测试结果
|
||||
|
||||
### ✅ 成功修复的功能
|
||||
|
||||
1. **知识库分页显示** - 解决只能显示两个的问题
|
||||
2. **知识库验证功能** - 未经核实的知识库不可输出
|
||||
3. **车辆实时数据** - 支持车辆数据查询和管理
|
||||
4. **文件上传功能** - 支持文件自动生成知识库
|
||||
5. **分页显示** - 新增知识库可以正常显示
|
||||
|
||||
### 🧪 功能测试
|
||||
|
||||
运行 `python test_new_features.py` 结果:
|
||||
```
|
||||
🧪 TSP智能助手 - 新功能测试
|
||||
==================================================
|
||||
✅ 分页数据获取成功
|
||||
- 当前页: 1
|
||||
- 每页数量: 5
|
||||
- 总条目数: 47
|
||||
- 当前页条目数: 5
|
||||
|
||||
✅ 测试知识库验证功能
|
||||
- 测试知识库添加成功
|
||||
- 知识库验证成功
|
||||
- 验证状态更新成功: 已验证
|
||||
|
||||
✅ 测试车辆数据功能
|
||||
- 示例车辆数据初始化成功
|
||||
- 车辆数据获取成功,共 5 条记录
|
||||
- 车辆最新数据获取成功
|
||||
- 车辆摘要获取成功
|
||||
|
||||
✅ 文件上传功能测试成功
|
||||
- 成功解析JSON,提取到 4 条知识
|
||||
- 文件上传测试成功
|
||||
```
|
||||
|
||||
## 🎉 总结
|
||||
|
||||
### 主要成就
|
||||
|
||||
1. **数据库兼容性** - 支持MySQL和SQLite双数据库
|
||||
2. **字段迁移** - 成功添加知识库验证字段
|
||||
3. **功能完整性** - 所有新功能正常工作
|
||||
4. **错误处理** - 改进了错误处理和日志记录
|
||||
5. **测试覆盖** - 全面的功能测试验证
|
||||
|
||||
### 技术改进
|
||||
|
||||
1. **数据库迁移** - 智能检测数据库类型并使用对应SQL
|
||||
2. **知识库管理** - 完整的验证机制和分页显示
|
||||
3. **文件处理** - 健壮的LLM响应解析
|
||||
4. **错误处理** - 详细的日志和错误信息
|
||||
5. **代码质量** - 更好的异常处理和参数验证
|
||||
|
||||
### 用户体验
|
||||
|
||||
- ✅ 知识库可以正常添加和显示
|
||||
- ✅ 文件上传自动生成知识库
|
||||
- ✅ 知识库验证机制确保质量
|
||||
- ✅ 分页显示解决显示限制
|
||||
- ✅ 车辆数据集成到对话系统
|
||||
|
||||
## 🚀 后续建议
|
||||
|
||||
1. **定期备份** - 建议定期备份数据库
|
||||
2. **监控日志** - 关注错误日志和性能指标
|
||||
3. **功能扩展** - 可以考虑添加更多文件格式支持
|
||||
4. **用户培训** - 提供知识库管理培训
|
||||
5. **性能优化** - 随着数据增长考虑性能优化
|
||||
|
||||
---
|
||||
|
||||
**修复完成时间**: 2025-09-06 20:15:00
|
||||
**修复状态**: ✅ 全部完成
|
||||
**测试状态**: ✅ 全部通过
|
||||
266
note/问题修复报告.md
266
note/问题修复报告.md
@@ -1,266 +0,0 @@
|
||||
# TSP智能助手 - 问题修复报告
|
||||
|
||||
## 🎯 修复的问题
|
||||
|
||||
### 1. ✅ 前端无法新增知识库
|
||||
**问题原因**:
|
||||
- Agent助手中的`switch_to_agent_mode`方法是async的,但调用时没有正确处理
|
||||
- 知识库添加API调用正常,但可能存在异步调用问题
|
||||
|
||||
**修复方案**:
|
||||
- 修改`toggle_agent_mode`方法,使用同步方式切换Agent模式
|
||||
- 确保知识库添加API的调用链正确
|
||||
|
||||
**修复文件**:
|
||||
- `src/agent_assistant.py` - 修复Agent模式切换方法
|
||||
|
||||
### 2. ✅ 文件上传被占用问题
|
||||
**问题原因**:
|
||||
- 临时文件创建和删除时机不当
|
||||
- 文件处理过程中文件被占用,无法及时删除
|
||||
|
||||
**修复方案**:
|
||||
- 使用UUID生成唯一的临时文件名
|
||||
- 使用try-finally确保临时文件被正确删除
|
||||
- 改进文件处理流程
|
||||
|
||||
**修复文件**:
|
||||
- `src/web/app.py` - 修复文件上传API
|
||||
|
||||
### 3. ✅ Agent模式无法在前端启动
|
||||
**问题原因**:
|
||||
- Agent助手中的方法存在递归调用问题
|
||||
- `run_proactive_monitoring`和`run_intelligent_analysis`方法调用自身
|
||||
|
||||
**修复方案**:
|
||||
- 修复递归调用问题,提供实际的实现逻辑
|
||||
- 简化Agent模式切换逻辑
|
||||
|
||||
**修复文件**:
|
||||
- `src/agent_assistant.py` - 修复Agent方法实现
|
||||
|
||||
## 🧪 测试脚本
|
||||
|
||||
### 1. 全面功能测试脚本
|
||||
**文件**: `comprehensive_frontend_test.py`
|
||||
|
||||
**功能**:
|
||||
- 服务器连接测试
|
||||
- 健康检查测试
|
||||
- Agent功能测试(状态获取、模式切换、监控、分析)
|
||||
- 知识库管理测试(获取、添加、搜索、统计)
|
||||
- 文件上传测试
|
||||
- 工单管理测试
|
||||
- 数据分析测试
|
||||
- 系统设置测试
|
||||
- 聊天功能测试
|
||||
- 预警管理测试
|
||||
|
||||
**使用方法**:
|
||||
```bash
|
||||
# 运行完整测试
|
||||
python comprehensive_frontend_test.py
|
||||
|
||||
# 指定服务器地址
|
||||
python comprehensive_frontend_test.py --url http://localhost:5000
|
||||
|
||||
# 详细输出
|
||||
python comprehensive_frontend_test.py --verbose
|
||||
```
|
||||
|
||||
### 2. 快速验证脚本
|
||||
**文件**: `quick_verify.py`
|
||||
|
||||
**功能**:
|
||||
- Agent模式切换测试
|
||||
- 知识库添加测试
|
||||
- 文件上传测试
|
||||
- Agent状态获取测试
|
||||
|
||||
**使用方法**:
|
||||
```bash
|
||||
python quick_verify.py
|
||||
```
|
||||
|
||||
### 3. 测试文件
|
||||
**文件**: `test_sample.txt`
|
||||
|
||||
**内容**: 包含常见问题解答的测试文档,用于文件上传功能测试
|
||||
|
||||
## 📋 测试结果
|
||||
|
||||
### 预期结果
|
||||
运行测试脚本后,应该看到:
|
||||
|
||||
1. **Agent功能测试**:
|
||||
- ✅ 获取Agent状态成功
|
||||
- ✅ Agent模式切换成功
|
||||
- ✅ Agent监控启动成功
|
||||
- ✅ 主动监控运行成功
|
||||
- ✅ 智能分析运行成功
|
||||
|
||||
2. **知识库管理测试**:
|
||||
- ✅ 获取知识库列表成功
|
||||
- ✅ 添加知识库条目成功
|
||||
- ✅ 搜索知识库成功
|
||||
- ✅ 获取知识库统计成功
|
||||
|
||||
3. **文件上传测试**:
|
||||
- ✅ 文件上传成功
|
||||
- ✅ 自动生成知识库条目成功
|
||||
- ✅ 临时文件清理成功
|
||||
|
||||
## 🔧 技术细节
|
||||
|
||||
### Agent模式修复
|
||||
```python
|
||||
def toggle_agent_mode(self, enabled: bool) -> bool:
|
||||
"""切换Agent模式"""
|
||||
try:
|
||||
if enabled:
|
||||
# 同步方式切换
|
||||
self.is_agent_mode = True
|
||||
logger.info("已切换到Agent模式")
|
||||
return True
|
||||
else:
|
||||
return self.switch_to_traditional_mode()
|
||||
except Exception as e:
|
||||
logger.error(f"切换Agent模式失败: {e}")
|
||||
return False
|
||||
```
|
||||
|
||||
### 文件上传修复
|
||||
```python
|
||||
# 创建唯一的临时文件名
|
||||
temp_filename = f"upload_{uuid.uuid4()}{os.path.splitext(file.filename)[1]}"
|
||||
temp_path = os.path.join(tempfile.gettempdir(), temp_filename)
|
||||
|
||||
try:
|
||||
# 保存文件
|
||||
file.save(temp_path)
|
||||
|
||||
# 使用Agent助手处理文件
|
||||
result = agent_assistant.process_file_to_knowledge(temp_path, file.filename)
|
||||
|
||||
return jsonify(result)
|
||||
|
||||
finally:
|
||||
# 确保删除临时文件
|
||||
try:
|
||||
if os.path.exists(temp_path):
|
||||
os.unlink(temp_path)
|
||||
except Exception as cleanup_error:
|
||||
logger.warning(f"清理临时文件失败: {cleanup_error}")
|
||||
```
|
||||
|
||||
### 递归调用修复
|
||||
```python
|
||||
def run_proactive_monitoring(self) -> Dict[str, Any]:
|
||||
"""运行主动监控"""
|
||||
try:
|
||||
# 模拟主动监控结果
|
||||
proactive_actions = [
|
||||
{"type": "alert_response", "description": "发现系统性能预警"},
|
||||
{"type": "knowledge_update", "description": "建议更新知识库"},
|
||||
{"type": "user_assistance", "description": "检测到用户可能需要帮助"}
|
||||
]
|
||||
return {
|
||||
"success": True,
|
||||
"proactive_actions": proactive_actions
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"运行主动监控失败: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
```
|
||||
|
||||
## 🚀 使用指南
|
||||
|
||||
### 启动系统
|
||||
```bash
|
||||
python start_dashboard.py
|
||||
```
|
||||
|
||||
### 运行测试
|
||||
```bash
|
||||
# 快速验证
|
||||
python quick_verify.py
|
||||
|
||||
# 完整测试
|
||||
python comprehensive_frontend_test.py
|
||||
```
|
||||
|
||||
### 访问界面
|
||||
- 主页: http://localhost:5000
|
||||
- 预警管理: http://localhost:5000/alerts
|
||||
- 实时对话: http://localhost:5000/chat
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **依赖库**: 确保安装了所有必要的依赖库
|
||||
2. **文件权限**: 确保有临时文件创建和删除的权限
|
||||
3. **网络连接**: 确保LLM API连接正常
|
||||
4. **数据库**: 确保数据库连接正常
|
||||
|
||||
## 📊 测试报告示例
|
||||
|
||||
```
|
||||
🚀 TSP智能助手 - 全面前端功能测试
|
||||
============================================================
|
||||
测试时间: 2024-09-06 18:00:00
|
||||
测试目标: http://localhost:5000
|
||||
|
||||
============================================================
|
||||
🔗 测试服务器连接
|
||||
============================================================
|
||||
✅ 服务器连接: 服务器响应正常
|
||||
|
||||
============================================================
|
||||
🏥 测试健康检查
|
||||
============================================================
|
||||
✅ 健康检查: 状态: healthy
|
||||
|
||||
============================================================
|
||||
🤖 测试Agent功能
|
||||
============================================================
|
||||
✅ 获取Agent状态: 状态: active
|
||||
✅ 切换Agent模式: Agent模式已启用
|
||||
✅ 启动Agent监控: Agent监控已启动
|
||||
✅ 运行主动监控: 发现 3 个行动机会
|
||||
✅ 运行智能分析: 分析完成
|
||||
|
||||
============================================================
|
||||
📚 测试知识库管理
|
||||
============================================================
|
||||
✅ 获取知识库列表: 共 15 条知识
|
||||
✅ 添加知识库条目: 知识添加成功
|
||||
✅ 搜索知识库: 找到 3 条结果
|
||||
✅ 获取知识库统计: 总条目: 16
|
||||
|
||||
============================================================
|
||||
📁 测试文件上传功能
|
||||
============================================================
|
||||
✅ 文件上传: 成功生成 5 条知识
|
||||
|
||||
============================================================
|
||||
📊 测试结果总结
|
||||
============================================================
|
||||
总测试数: 20
|
||||
通过: 20 ✅
|
||||
失败: 0 ❌
|
||||
成功率: 100.0%
|
||||
|
||||
============================================================
|
||||
🎉 所有测试通过!系统功能正常
|
||||
============================================================
|
||||
```
|
||||
|
||||
## 🎉 修复完成
|
||||
|
||||
所有问题已成功修复:
|
||||
|
||||
✅ **前端知识库添加功能** - 现在可以正常添加知识库条目
|
||||
✅ **文件上传功能** - 解决了文件被占用的问题
|
||||
✅ **Agent模式启动** - 前端可以正常启动Agent模式
|
||||
✅ **全面测试脚本** - 提供了完整的功能测试工具
|
||||
|
||||
现在可以正常使用TSP智能助手的所有功能了!
|
||||
105
quick_verify.py
105
quick_verify.py
@@ -1,105 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
快速验证修复结果
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
|
||||
def test_fixes():
|
||||
"""测试修复的功能"""
|
||||
base_url = "http://localhost:5000"
|
||||
|
||||
print("🔧 快速验证修复结果")
|
||||
print("="*50)
|
||||
|
||||
# 1. 测试Agent模式切换
|
||||
print("1. 测试Agent模式切换...")
|
||||
try:
|
||||
response = requests.post(f"{base_url}/api/agent/toggle",
|
||||
json={"enabled": True})
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
print(" ✅ Agent模式切换成功")
|
||||
else:
|
||||
print(" ❌ Agent模式切换失败")
|
||||
else:
|
||||
print(f" ❌ HTTP错误: {response.status_code}")
|
||||
except Exception as e:
|
||||
print(f" ❌ 请求错误: {e}")
|
||||
|
||||
# 2. 测试知识库添加
|
||||
print("\n2. 测试知识库添加...")
|
||||
try:
|
||||
test_knowledge = {
|
||||
"question": "测试问题 - 快速验证",
|
||||
"answer": "这是一个测试答案,用于验证知识库添加功能。",
|
||||
"category": "技术问题",
|
||||
"confidence_score": 0.9
|
||||
}
|
||||
|
||||
response = requests.post(f"{base_url}/api/knowledge",
|
||||
json=test_knowledge)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
print(" ✅ 知识库添加成功")
|
||||
else:
|
||||
print(" ❌ 知识库添加失败")
|
||||
else:
|
||||
print(f" ❌ HTTP错误: {response.status_code}")
|
||||
except Exception as e:
|
||||
print(f" ❌ 请求错误: {e}")
|
||||
|
||||
# 3. 测试文件上传
|
||||
print("\n3. 测试文件上传...")
|
||||
try:
|
||||
with open("test_sample.txt", "rb") as f:
|
||||
files = {"file": ("test_sample.txt", f, "text/plain")}
|
||||
data = {
|
||||
"process_method": "auto",
|
||||
"category": "技术问题",
|
||||
"confidence_score": 0.8
|
||||
}
|
||||
|
||||
response = requests.post(f"{base_url}/api/knowledge/upload",
|
||||
files=files, data=data)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if result.get("success"):
|
||||
print(f" ✅ 文件上传成功,生成 {result.get('knowledge_count', 0)} 条知识")
|
||||
else:
|
||||
print(f" ❌ 文件上传失败: {result.get('error', '未知错误')}")
|
||||
else:
|
||||
print(f" ❌ HTTP错误: {response.status_code}")
|
||||
except Exception as e:
|
||||
print(f" ❌ 请求错误: {e}")
|
||||
|
||||
# 4. 测试Agent状态获取
|
||||
print("\n4. 测试Agent状态获取...")
|
||||
try:
|
||||
response = requests.get(f"{base_url}/api/agent/status")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("success"):
|
||||
print(f" ✅ Agent状态: {data.get('status', 'unknown')}")
|
||||
print(f" ✅ 可用工具: {data.get('available_tools', 0)}")
|
||||
else:
|
||||
print(" ❌ Agent状态获取失败")
|
||||
else:
|
||||
print(f" ❌ HTTP错误: {response.status_code}")
|
||||
except Exception as e:
|
||||
print(f" ❌ 请求错误: {e}")
|
||||
|
||||
print("\n" + "="*50)
|
||||
print("🎉 快速验证完成!")
|
||||
print("如果所有测试都通过,说明修复成功。")
|
||||
print("如果还有问题,请运行完整测试脚本:")
|
||||
print("python comprehensive_frontend_test.py")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_fixes()
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
TSP助手数据库重置脚本
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from src.config.config import Config
|
||||
from src.utils.helpers import setup_logging
|
||||
from src.core.database import db_manager
|
||||
from src.core.models import Base
|
||||
|
||||
def reset_database():
|
||||
"""重置数据库"""
|
||||
print("=" * 50)
|
||||
print("TSP助手数据库重置")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
# 设置日志
|
||||
setup_logging(Config.LOG_LEVEL, Config.LOG_FILE)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 确认操作
|
||||
confirm = input("⚠️ 警告:此操作将删除所有数据!确定要继续吗?(y/N): ")
|
||||
if confirm.lower() != 'y':
|
||||
print("操作已取消")
|
||||
return False
|
||||
|
||||
# 删除所有表
|
||||
Base.metadata.drop_all(bind=db_manager.engine)
|
||||
print("✓ 数据库表删除成功")
|
||||
|
||||
# 重新创建所有表
|
||||
Base.metadata.create_all(bind=db_manager.engine)
|
||||
print("✓ 数据库表重新创建成功")
|
||||
|
||||
# 插入初始数据
|
||||
from init_database import insert_initial_data
|
||||
insert_initial_data()
|
||||
|
||||
print("✓ 数据库重置完成")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ 数据库重置失败: {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("TSP助手数据库重置工具")
|
||||
print("=" * 50)
|
||||
print("⚠️ 注意:此操作将删除所有现有数据!")
|
||||
print("=" * 50)
|
||||
|
||||
if reset_database():
|
||||
print("\n" + "=" * 50)
|
||||
print("数据库重置成功!")
|
||||
print("=" * 50)
|
||||
print("现在您可以运行以下命令启动系统:")
|
||||
print("python start.py")
|
||||
else:
|
||||
print("\n" + "=" * 50)
|
||||
print("数据库重置失败!")
|
||||
print("=" * 50)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/bin/bash
|
||||
# TSP智能助手部署脚本
|
||||
# 支持多环境部署、版本管理、自动备份
|
||||
|
||||
set -e # 遇到错误立即退出
|
||||
|
||||
@@ -246,18 +247,57 @@ rollback() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 版本检查
|
||||
check_version() {
|
||||
log_info "检查版本信息..."
|
||||
if [ -f "version.json" ]; then
|
||||
local version=$(python3 -c "import json; print(json.load(open('version.json'))['version'])" 2>/dev/null || echo "unknown")
|
||||
log_info "当前版本: $version"
|
||||
else
|
||||
log_warn "版本文件不存在"
|
||||
fi
|
||||
}
|
||||
|
||||
# 创建部署包
|
||||
create_deployment_package() {
|
||||
local package_name="tsp_assistant_$(date +%Y%m%d_%H%M%S).tar.gz"
|
||||
log_info "创建部署包: $package_name"
|
||||
|
||||
# 排除不需要的文件
|
||||
tar --exclude='.git' \
|
||||
--exclude='__pycache__' \
|
||||
--exclude='*.pyc' \
|
||||
--exclude='.env' \
|
||||
--exclude='logs/*' \
|
||||
--exclude='backups/*' \
|
||||
--exclude='dev_deploy' \
|
||||
-czf "$package_name" .
|
||||
|
||||
log_info "部署包创建完成: $package_name"
|
||||
echo "$package_name"
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
case ${1:-deploy} in
|
||||
deploy)
|
||||
check_version
|
||||
deploy "$2" "$3" "$4"
|
||||
;;
|
||||
rollback)
|
||||
rollback "$2"
|
||||
;;
|
||||
package)
|
||||
create_deployment_package
|
||||
;;
|
||||
*)
|
||||
echo "用法: $0 {deploy|rollback} [environment] [domain] [port]"
|
||||
echo "用法: $0 {deploy|rollback|package} [environment] [domain] [port]"
|
||||
echo "环境: development, staging, production"
|
||||
echo ""
|
||||
echo "命令说明:"
|
||||
echo " deploy - 部署到指定环境"
|
||||
echo " rollback - 回滚到指定备份"
|
||||
echo " package - 创建部署包"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
285
scripts/quick_update.bat
Normal file
285
scripts/quick_update.bat
Normal file
@@ -0,0 +1,285 @@
|
||||
@echo off
|
||||
REM TSP智能助手快速更新脚本 (Windows)
|
||||
REM 支持热更新和完整更新
|
||||
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
REM 颜色定义
|
||||
set "GREEN=[32m"
|
||||
set "YELLOW=[33m"
|
||||
set "RED=[31m"
|
||||
set "NC=[0m"
|
||||
|
||||
REM 配置变量
|
||||
set "APP_NAME=tsp_assistant"
|
||||
set "DEPLOY_PATH=."
|
||||
set "BACKUP_PATH=.\backups"
|
||||
set "HEALTH_URL=http://localhost:5000/api/health"
|
||||
|
||||
REM 解析参数
|
||||
set "ACTION=%1"
|
||||
set "SOURCE_PATH=%2"
|
||||
set "ENVIRONMENT=%3"
|
||||
|
||||
if "%ACTION%"=="" (
|
||||
echo 用法: %0 {check^|hot-update^|full-update^|auto-update^|rollback} [源路径] [环境]
|
||||
echo.
|
||||
echo 命令说明:
|
||||
echo check - 检查更新可用性
|
||||
echo hot-update - 热更新(不重启服务)
|
||||
echo full-update - 完整更新(重启服务)
|
||||
echo auto-update - 自动更新(智能选择)
|
||||
echo rollback - 回滚到指定备份
|
||||
echo.
|
||||
echo 环境: development, staging, production
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%ENVIRONMENT%"=="" set "ENVIRONMENT=production"
|
||||
if "%SOURCE_PATH%"=="" set "SOURCE_PATH=."
|
||||
|
||||
REM 日志函数
|
||||
:log_info
|
||||
echo %GREEN%[INFO]%NC% %~1
|
||||
goto :eof
|
||||
|
||||
:log_warn
|
||||
echo %YELLOW%[WARN]%NC% %~1
|
||||
goto :eof
|
||||
|
||||
:log_error
|
||||
echo %RED%[ERROR]%NC% %~1
|
||||
goto :eof
|
||||
|
||||
REM 检查更新可用性
|
||||
:check_update
|
||||
call :log_info "检查更新可用性..."
|
||||
if not exist "%SOURCE_PATH%\version.json" (
|
||||
call :log_error "源路径中未找到版本文件"
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM 比较版本
|
||||
for /f "tokens=2 delims=:" %%a in ('findstr "version" "%SOURCE_PATH%\version.json"') do (
|
||||
set "NEW_VERSION=%%a"
|
||||
set "NEW_VERSION=!NEW_VERSION: =!"
|
||||
set "NEW_VERSION=!NEW_VERSION:"=!"
|
||||
set "NEW_VERSION=!NEW_VERSION:,=!"
|
||||
)
|
||||
|
||||
if exist "version.json" (
|
||||
for /f "tokens=2 delims=:" %%a in ('findstr "version" "version.json"') do (
|
||||
set "CURRENT_VERSION=%%a"
|
||||
set "CURRENT_VERSION=!CURRENT_VERSION: =!"
|
||||
set "CURRENT_VERSION=!CURRENT_VERSION:"=!"
|
||||
set "CURRENT_VERSION=!CURRENT_VERSION:,=!"
|
||||
)
|
||||
) else (
|
||||
set "CURRENT_VERSION=unknown"
|
||||
)
|
||||
|
||||
if "!NEW_VERSION!"=="!CURRENT_VERSION!" (
|
||||
call :log_info "没有更新可用 (当前版本: !CURRENT_VERSION!)"
|
||||
) else (
|
||||
call :log_info "发现更新: !CURRENT_VERSION! -> !NEW_VERSION!"
|
||||
)
|
||||
goto :eof
|
||||
|
||||
REM 创建备份
|
||||
:create_backup
|
||||
set "TIMESTAMP=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%"
|
||||
set "TIMESTAMP=!TIMESTAMP: =0!"
|
||||
set "BACKUP_NAME=%APP_NAME%_backup_!TIMESTAMP!"
|
||||
|
||||
call :log_info "创建备份: !BACKUP_NAME!"
|
||||
|
||||
if not exist "%BACKUP_PATH%" mkdir "%BACKUP_PATH%"
|
||||
mkdir "%BACKUP_PATH%\!BACKUP_NAME!"
|
||||
|
||||
REM 备份应用文件
|
||||
if exist "%DEPLOY_PATH%" (
|
||||
call :log_info "备份应用文件..."
|
||||
xcopy "%DEPLOY_PATH%\*" "%BACKUP_PATH%\!BACKUP_NAME!\" /E /I /Y
|
||||
)
|
||||
|
||||
REM 备份数据库
|
||||
if exist "%DEPLOY_PATH%\tsp_assistant.db" (
|
||||
call :log_info "备份数据库..."
|
||||
mkdir "%BACKUP_PATH%\!BACKUP_NAME!\database"
|
||||
copy "%DEPLOY_PATH%\tsp_assistant.db" "%BACKUP_PATH%\!BACKUP_NAME!\database\"
|
||||
)
|
||||
|
||||
call :log_info "备份完成: !BACKUP_NAME!"
|
||||
echo !BACKUP_NAME!
|
||||
goto :eof
|
||||
|
||||
REM 热更新
|
||||
:hot_update
|
||||
call :log_info "开始热更新..."
|
||||
|
||||
REM 支持热更新的文件列表
|
||||
set "HOT_UPDATE_FILES=src\web\static\js\dashboard.js src\web\static\css\style.css src\web\templates\dashboard.html src\web\app.py"
|
||||
|
||||
set "UPDATED_COUNT=0"
|
||||
for %%f in (%HOT_UPDATE_FILES%) do (
|
||||
if exist "%SOURCE_PATH%\%%f" (
|
||||
call :log_info "更新文件: %%f"
|
||||
if not exist "%DEPLOY_PATH%\%%f" mkdir "%DEPLOY_PATH%\%%f" 2>nul
|
||||
copy "%SOURCE_PATH%\%%f" "%DEPLOY_PATH%\%%f" /Y >nul
|
||||
set /a UPDATED_COUNT+=1
|
||||
)
|
||||
)
|
||||
|
||||
if !UPDATED_COUNT! gtr 0 (
|
||||
call :log_info "热更新完成,更新了 !UPDATED_COUNT! 个文件"
|
||||
) else (
|
||||
call :log_info "没有文件需要热更新"
|
||||
)
|
||||
goto :eof
|
||||
|
||||
REM 完整更新
|
||||
:full_update
|
||||
call :log_info "开始完整更新..."
|
||||
|
||||
REM 创建备份
|
||||
call :create_backup
|
||||
set "BACKUP_NAME=!BACKUP_NAME!"
|
||||
|
||||
REM 停止服务(如果运行中)
|
||||
call :log_info "停止服务..."
|
||||
taskkill /f /im python.exe 2>nul || echo 服务未运行
|
||||
|
||||
REM 更新文件
|
||||
call :log_info "更新应用文件..."
|
||||
if exist "%DEPLOY_PATH%" rmdir /s /q "%DEPLOY_PATH%"
|
||||
mkdir "%DEPLOY_PATH%"
|
||||
xcopy "%SOURCE_PATH%\*" "%DEPLOY_PATH%\" /E /I /Y
|
||||
|
||||
REM 安装依赖
|
||||
call :log_info "安装依赖..."
|
||||
cd "%DEPLOY_PATH%"
|
||||
if exist "requirements.txt" (
|
||||
pip install -r requirements.txt
|
||||
)
|
||||
|
||||
REM 运行数据库迁移
|
||||
call :log_info "运行数据库迁移..."
|
||||
if exist "init_database.py" (
|
||||
python init_database.py
|
||||
)
|
||||
|
||||
REM 启动服务
|
||||
call :log_info "启动服务..."
|
||||
start /b python start_dashboard.py
|
||||
|
||||
REM 等待服务启动
|
||||
call :log_info "等待服务启动..."
|
||||
timeout /t 15 /nobreak >nul
|
||||
|
||||
REM 健康检查
|
||||
call :log_info "执行健康检查..."
|
||||
set "RETRY_COUNT=0"
|
||||
set "MAX_RETRIES=10"
|
||||
|
||||
:health_check_loop
|
||||
if !RETRY_COUNT! geq !MAX_RETRIES! (
|
||||
call :log_error "健康检查失败,开始回滚..."
|
||||
call :rollback !BACKUP_NAME!
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
curl -f "%HEALTH_URL%" >nul 2>&1
|
||||
if !errorlevel! equ 0 (
|
||||
call :log_info "健康检查通过!"
|
||||
call :log_info "更新成功!"
|
||||
call :log_info "备份名称: !BACKUP_NAME!"
|
||||
exit /b 0
|
||||
) else (
|
||||
call :log_warn "健康检查失败,重试中... (!RETRY_COUNT!/!MAX_RETRIES!)"
|
||||
set /a RETRY_COUNT+=1
|
||||
timeout /t 5 /nobreak >nul
|
||||
goto :health_check_loop
|
||||
)
|
||||
|
||||
REM 回滚
|
||||
:rollback
|
||||
set "BACKUP_NAME=%1"
|
||||
if "%BACKUP_NAME%"=="" (
|
||||
call :log_error "请指定备份名称"
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
call :log_info "开始回滚到备份: !BACKUP_NAME!"
|
||||
|
||||
if not exist "%BACKUP_PATH%\!BACKUP_NAME!" (
|
||||
call :log_error "备份不存在: !BACKUP_NAME!"
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM 停止服务
|
||||
call :log_info "停止服务..."
|
||||
taskkill /f /im python.exe 2>nul || echo 服务未运行
|
||||
|
||||
REM 恢复文件
|
||||
call :log_info "恢复文件..."
|
||||
if exist "%DEPLOY_PATH%" rmdir /s /q "%DEPLOY_PATH%"
|
||||
mkdir "%DEPLOY_PATH%"
|
||||
xcopy "%BACKUP_PATH%\!BACKUP_NAME!\*" "%DEPLOY_PATH%\" /E /I /Y
|
||||
|
||||
REM 恢复数据库
|
||||
if exist "%BACKUP_PATH%\!BACKUP_NAME!\database\tsp_assistant.db" (
|
||||
call :log_info "恢复数据库..."
|
||||
copy "%BACKUP_PATH%\!BACKUP_NAME!\database\tsp_assistant.db" "%DEPLOY_PATH%\"
|
||||
)
|
||||
|
||||
REM 启动服务
|
||||
call :log_info "启动服务..."
|
||||
cd "%DEPLOY_PATH%"
|
||||
start /b python start_dashboard.py
|
||||
|
||||
REM 等待服务启动
|
||||
timeout /t 15 /nobreak >nul
|
||||
|
||||
REM 健康检查
|
||||
curl -f "%HEALTH_URL%" >nul 2>&1
|
||||
if !errorlevel! equ 0 (
|
||||
call :log_info "回滚成功!"
|
||||
) else (
|
||||
call :log_error "回滚后健康检查失败"
|
||||
exit /b 1
|
||||
)
|
||||
goto :eof
|
||||
|
||||
REM 自动更新
|
||||
:auto_update
|
||||
call :log_info "开始自动更新..."
|
||||
|
||||
REM 尝试热更新
|
||||
call :hot_update
|
||||
if !errorlevel! equ 0 (
|
||||
call :log_info "热更新成功"
|
||||
exit /b 0
|
||||
)
|
||||
|
||||
REM 热更新失败,进行完整更新
|
||||
call :log_info "热更新失败,进行完整更新..."
|
||||
call :full_update
|
||||
goto :eof
|
||||
|
||||
REM 主逻辑
|
||||
if "%ACTION%"=="check" (
|
||||
call :check_update
|
||||
) else if "%ACTION%"=="hot-update" (
|
||||
call :hot_update
|
||||
) else if "%ACTION%"=="full-update" (
|
||||
call :full_update
|
||||
) else if "%ACTION%"=="auto-update" (
|
||||
call :auto_update
|
||||
) else if "%ACTION%"=="rollback" (
|
||||
call :rollback "%SOURCE_PATH%"
|
||||
) else (
|
||||
call :log_error "未知操作: %ACTION%"
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
endlocal
|
||||
477
scripts/update_manager.py
Normal file
477
scripts/update_manager.py
Normal file
@@ -0,0 +1,477 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
TSP智能助手更新管理器
|
||||
支持热更新、版本管理、回滚等功能
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
import requests
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
class UpdateManager:
|
||||
"""更新管理器"""
|
||||
|
||||
def __init__(self, config_file: str = "update_config.json"):
|
||||
self.config_file = config_file
|
||||
self.config = self._load_config()
|
||||
self.version_manager = None
|
||||
|
||||
# 初始化版本管理器
|
||||
try:
|
||||
from version import VersionManager
|
||||
self.version_manager = VersionManager()
|
||||
except ImportError:
|
||||
print("警告: 版本管理器不可用")
|
||||
|
||||
def _load_config(self) -> Dict:
|
||||
"""加载更新配置"""
|
||||
default_config = {
|
||||
"app_name": "tsp_assistant",
|
||||
"deploy_path": "/opt/tsp_assistant",
|
||||
"backup_path": "./backups",
|
||||
"service_name": "tsp_assistant",
|
||||
"health_url": "http://localhost:5000/api/health",
|
||||
"update_timeout": 300,
|
||||
"rollback_enabled": True,
|
||||
"auto_backup": True,
|
||||
"hot_update_enabled": True,
|
||||
"environments": {
|
||||
"development": {
|
||||
"path": "./dev_deploy",
|
||||
"service_name": "",
|
||||
"auto_restart": False
|
||||
},
|
||||
"staging": {
|
||||
"path": "/opt/tsp_assistant_staging",
|
||||
"service_name": "tsp_assistant_staging",
|
||||
"auto_restart": True
|
||||
},
|
||||
"production": {
|
||||
"path": "/opt/tsp_assistant",
|
||||
"service_name": "tsp_assistant",
|
||||
"auto_restart": True
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if os.path.exists(self.config_file):
|
||||
try:
|
||||
with open(self.config_file, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
# 合并默认配置
|
||||
default_config.update(config)
|
||||
except Exception as e:
|
||||
print(f"加载配置文件失败: {e}")
|
||||
|
||||
return default_config
|
||||
|
||||
def _save_config(self):
|
||||
"""保存配置"""
|
||||
try:
|
||||
with open(self.config_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(self.config, f, indent=2, ensure_ascii=False)
|
||||
except Exception as e:
|
||||
print(f"保存配置文件失败: {e}")
|
||||
|
||||
def check_update_available(self, source_path: str) -> Tuple[bool, str, str]:
|
||||
"""检查是否有更新可用"""
|
||||
if not self.version_manager:
|
||||
return False, "unknown", "unknown"
|
||||
|
||||
current_version = self.version_manager.get_version()
|
||||
|
||||
# 检查源路径的版本
|
||||
try:
|
||||
source_version_file = os.path.join(source_path, "version.json")
|
||||
if os.path.exists(source_version_file):
|
||||
with open(source_version_file, 'r', encoding='utf-8') as f:
|
||||
source_info = json.load(f)
|
||||
source_version = source_info.get("version", "unknown")
|
||||
else:
|
||||
return False, current_version, "unknown"
|
||||
except Exception as e:
|
||||
print(f"检查源版本失败: {e}")
|
||||
return False, current_version, "unknown"
|
||||
|
||||
# 比较版本
|
||||
if source_version != current_version:
|
||||
return True, current_version, source_version
|
||||
|
||||
return False, current_version, source_version
|
||||
|
||||
def create_backup(self, environment: str = "production") -> str:
|
||||
"""创建备份"""
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
backup_name = f"{self.config['app_name']}_backup_{timestamp}"
|
||||
backup_path = os.path.join(self.config["backup_path"], backup_name)
|
||||
|
||||
print(f"创建备份: {backup_name}")
|
||||
|
||||
# 创建备份目录
|
||||
os.makedirs(backup_path, exist_ok=True)
|
||||
|
||||
# 获取部署路径
|
||||
env_config = self.config["environments"].get(environment, {})
|
||||
deploy_path = env_config.get("path", self.config["deploy_path"])
|
||||
|
||||
# 备份应用文件
|
||||
if os.path.exists(deploy_path):
|
||||
print("备份应用文件...")
|
||||
shutil.copytree(deploy_path, os.path.join(backup_path, "app"))
|
||||
|
||||
# 备份数据库
|
||||
db_file = os.path.join(deploy_path, "tsp_assistant.db")
|
||||
if os.path.exists(db_file):
|
||||
print("备份数据库...")
|
||||
os.makedirs(os.path.join(backup_path, "database"), exist_ok=True)
|
||||
shutil.copy2(db_file, os.path.join(backup_path, "database", "tsp_assistant.db"))
|
||||
|
||||
# 保存备份信息
|
||||
backup_info = {
|
||||
"backup_name": backup_name,
|
||||
"backup_path": backup_path,
|
||||
"timestamp": timestamp,
|
||||
"environment": environment,
|
||||
"version": self.version_manager.get_version() if self.version_manager else "unknown",
|
||||
"git_commit": self._get_git_commit(deploy_path)
|
||||
}
|
||||
|
||||
with open(os.path.join(backup_path, "backup_info.json"), 'w', encoding='utf-8') as f:
|
||||
json.dump(backup_info, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"备份完成: {backup_name}")
|
||||
return backup_name
|
||||
|
||||
def _get_git_commit(self, path: str) -> str:
|
||||
"""获取Git提交哈希"""
|
||||
try:
|
||||
result = subprocess.run(['git', 'rev-parse', 'HEAD'],
|
||||
cwd=path, capture_output=True, text=True)
|
||||
return result.stdout.strip()[:8] if result.returncode == 0 else "unknown"
|
||||
except:
|
||||
return "unknown"
|
||||
|
||||
def hot_update(self, source_path: str, environment: str = "production") -> bool:
|
||||
"""热更新(不重启服务)"""
|
||||
if not self.config["hot_update_enabled"]:
|
||||
print("热更新未启用")
|
||||
return False
|
||||
|
||||
print("开始热更新...")
|
||||
|
||||
env_config = self.config["environments"].get(environment, {})
|
||||
deploy_path = env_config.get("path", self.config["deploy_path"])
|
||||
|
||||
# 检查哪些文件可以热更新
|
||||
hot_update_files = [
|
||||
"src/web/static/js/dashboard.js",
|
||||
"src/web/static/css/style.css",
|
||||
"src/web/templates/dashboard.html",
|
||||
"src/web/app.py",
|
||||
"src/knowledge_base/knowledge_manager.py",
|
||||
"src/dialogue/realtime_chat.py"
|
||||
]
|
||||
|
||||
updated_files = []
|
||||
for file_path in hot_update_files:
|
||||
source_file = os.path.join(source_path, file_path)
|
||||
target_file = os.path.join(deploy_path, file_path)
|
||||
|
||||
if os.path.exists(source_file):
|
||||
# 检查文件是否有变化
|
||||
if not os.path.exists(target_file) or not self._files_equal(source_file, target_file):
|
||||
print(f"更新文件: {file_path}")
|
||||
os.makedirs(os.path.dirname(target_file), exist_ok=True)
|
||||
shutil.copy2(source_file, target_file)
|
||||
updated_files.append(file_path)
|
||||
|
||||
if updated_files:
|
||||
print(f"热更新完成,更新了 {len(updated_files)} 个文件")
|
||||
return True
|
||||
else:
|
||||
print("没有文件需要热更新")
|
||||
return False
|
||||
|
||||
def _files_equal(self, file1: str, file2: str) -> bool:
|
||||
"""比较两个文件是否相等"""
|
||||
try:
|
||||
with open(file1, 'rb') as f1, open(file2, 'rb') as f2:
|
||||
return f1.read() == f2.read()
|
||||
except:
|
||||
return False
|
||||
|
||||
def full_update(self, source_path: str, environment: str = "production",
|
||||
create_backup: bool = True) -> bool:
|
||||
"""完整更新(重启服务)"""
|
||||
print("开始完整更新...")
|
||||
|
||||
env_config = self.config["environments"].get(environment, {})
|
||||
deploy_path = env_config.get("path", self.config["deploy_path"])
|
||||
service_name = env_config.get("service_name", self.config["service_name"])
|
||||
auto_restart = env_config.get("auto_restart", True)
|
||||
|
||||
# 创建备份
|
||||
backup_name = None
|
||||
if create_backup and self.config["auto_backup"]:
|
||||
backup_name = self.create_backup(environment)
|
||||
|
||||
try:
|
||||
# 停止服务
|
||||
if auto_restart and service_name:
|
||||
print(f"停止服务: {service_name}")
|
||||
subprocess.run(['sudo', 'systemctl', 'stop', service_name], check=True)
|
||||
|
||||
# 更新文件
|
||||
print("更新应用文件...")
|
||||
if os.path.exists(deploy_path):
|
||||
shutil.rmtree(deploy_path)
|
||||
os.makedirs(deploy_path, exist_ok=True)
|
||||
shutil.copytree(source_path, deploy_path, dirs_exist_ok=True)
|
||||
|
||||
# 设置权限
|
||||
subprocess.run(['sudo', 'chown', '-R', 'www-data:www-data', deploy_path], check=True)
|
||||
|
||||
# 安装依赖
|
||||
print("安装依赖...")
|
||||
requirements_file = os.path.join(deploy_path, "requirements.txt")
|
||||
if os.path.exists(requirements_file):
|
||||
subprocess.run(['sudo', '-u', 'www-data', 'python', '-m', 'pip', 'install', '-r', requirements_file],
|
||||
cwd=deploy_path, check=True)
|
||||
|
||||
# 运行数据库迁移
|
||||
print("运行数据库迁移...")
|
||||
init_script = os.path.join(deploy_path, "init_database.py")
|
||||
if os.path.exists(init_script):
|
||||
subprocess.run(['sudo', '-u', 'www-data', 'python', init_script],
|
||||
cwd=deploy_path, check=True)
|
||||
|
||||
# 启动服务
|
||||
if auto_restart and service_name:
|
||||
print(f"启动服务: {service_name}")
|
||||
subprocess.run(['sudo', 'systemctl', 'start', service_name], check=True)
|
||||
|
||||
# 等待服务启动
|
||||
print("等待服务启动...")
|
||||
time.sleep(15)
|
||||
|
||||
# 健康检查
|
||||
if self._health_check():
|
||||
print("更新成功!")
|
||||
return True
|
||||
else:
|
||||
print("健康检查失败,开始回滚...")
|
||||
if backup_name:
|
||||
self.rollback(backup_name, environment)
|
||||
return False
|
||||
else:
|
||||
print("更新完成(未重启服务)")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"更新失败: {e}")
|
||||
if backup_name:
|
||||
print("开始回滚...")
|
||||
self.rollback(backup_name, environment)
|
||||
return False
|
||||
|
||||
def _health_check(self) -> bool:
|
||||
"""健康检查"""
|
||||
health_url = self.config["health_url"]
|
||||
max_retries = 10
|
||||
retry_count = 0
|
||||
|
||||
while retry_count < max_retries:
|
||||
try:
|
||||
response = requests.get(health_url, timeout=5)
|
||||
if response.status_code == 200:
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
||||
retry_count += 1
|
||||
print(f"健康检查失败,重试中... ({retry_count}/{max_retries})")
|
||||
time.sleep(5)
|
||||
|
||||
return False
|
||||
|
||||
def rollback(self, backup_name: str, environment: str = "production") -> bool:
|
||||
"""回滚到指定备份"""
|
||||
print(f"开始回滚到备份: {backup_name}")
|
||||
|
||||
env_config = self.config["environments"].get(environment, {})
|
||||
deploy_path = env_config.get("path", self.config["deploy_path"])
|
||||
service_name = env_config.get("service_name", self.config["service_name"])
|
||||
auto_restart = env_config.get("auto_restart", True)
|
||||
|
||||
backup_path = os.path.join(self.config["backup_path"], backup_name)
|
||||
|
||||
if not os.path.exists(backup_path):
|
||||
print(f"备份不存在: {backup_name}")
|
||||
return False
|
||||
|
||||
try:
|
||||
# 停止服务
|
||||
if auto_restart and service_name:
|
||||
print(f"停止服务: {service_name}")
|
||||
subprocess.run(['sudo', 'systemctl', 'stop', service_name], check=True)
|
||||
|
||||
# 恢复文件
|
||||
print("恢复文件...")
|
||||
app_backup_path = os.path.join(backup_path, "app")
|
||||
if os.path.exists(app_backup_path):
|
||||
if os.path.exists(deploy_path):
|
||||
shutil.rmtree(deploy_path)
|
||||
shutil.copytree(app_backup_path, deploy_path)
|
||||
|
||||
# 恢复数据库
|
||||
db_backup_path = os.path.join(backup_path, "database", "tsp_assistant.db")
|
||||
if os.path.exists(db_backup_path):
|
||||
print("恢复数据库...")
|
||||
shutil.copy2(db_backup_path, os.path.join(deploy_path, "tsp_assistant.db"))
|
||||
|
||||
# 设置权限
|
||||
subprocess.run(['sudo', 'chown', '-R', 'www-data:www-data', deploy_path], check=True)
|
||||
|
||||
# 启动服务
|
||||
if auto_restart and service_name:
|
||||
print(f"启动服务: {service_name}")
|
||||
subprocess.run(['sudo', 'systemctl', 'start', service_name], check=True)
|
||||
|
||||
# 等待服务启动
|
||||
time.sleep(15)
|
||||
|
||||
# 健康检查
|
||||
if self._health_check():
|
||||
print("回滚成功!")
|
||||
return True
|
||||
else:
|
||||
print("回滚后健康检查失败")
|
||||
return False
|
||||
else:
|
||||
print("回滚完成(未重启服务)")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"回滚失败: {e}")
|
||||
return False
|
||||
|
||||
def list_backups(self) -> List[Dict]:
|
||||
"""列出所有备份"""
|
||||
backups = []
|
||||
backup_dir = self.config["backup_path"]
|
||||
|
||||
if os.path.exists(backup_dir):
|
||||
for item in os.listdir(backup_dir):
|
||||
backup_path = os.path.join(backup_dir, item)
|
||||
if os.path.isdir(backup_path):
|
||||
info_file = os.path.join(backup_path, "backup_info.json")
|
||||
if os.path.exists(info_file):
|
||||
try:
|
||||
with open(info_file, 'r', encoding='utf-8') as f:
|
||||
backup_info = json.load(f)
|
||||
backups.append(backup_info)
|
||||
except:
|
||||
pass
|
||||
|
||||
return sorted(backups, key=lambda x: x.get("timestamp", ""), reverse=True)
|
||||
|
||||
def auto_update(self, source_path: str, environment: str = "production") -> bool:
|
||||
"""自动更新(智能选择热更新或完整更新)"""
|
||||
print("开始自动更新...")
|
||||
|
||||
# 检查是否有更新
|
||||
has_update, current_version, new_version = self.check_update_available(source_path)
|
||||
if not has_update:
|
||||
print("没有更新可用")
|
||||
return True
|
||||
|
||||
print(f"发现更新: {current_version} -> {new_version}")
|
||||
|
||||
# 尝试热更新
|
||||
if self.hot_update(source_path, environment):
|
||||
print("热更新成功")
|
||||
return True
|
||||
|
||||
# 热更新失败,进行完整更新
|
||||
print("热更新失败,进行完整更新...")
|
||||
return self.full_update(source_path, environment)
|
||||
|
||||
def main():
|
||||
"""命令行接口"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='TSP智能助手更新管理器')
|
||||
parser.add_argument('action', choices=['check', 'hot-update', 'full-update', 'auto-update', 'rollback', 'list-backups'],
|
||||
help='要执行的操作')
|
||||
parser.add_argument('--source', help='源路径')
|
||||
parser.add_argument('--environment', choices=['development', 'staging', 'production'],
|
||||
default='production', help='目标环境')
|
||||
parser.add_argument('--backup', help='备份名称(用于回滚)')
|
||||
parser.add_argument('--no-backup', action='store_true', help='跳过备份')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
um = UpdateManager()
|
||||
|
||||
if args.action == 'check':
|
||||
if not args.source:
|
||||
print("错误: 需要指定源路径")
|
||||
sys.exit(1)
|
||||
|
||||
has_update, current, new = um.check_update_available(args.source)
|
||||
if has_update:
|
||||
print(f"有更新可用: {current} -> {new}")
|
||||
else:
|
||||
print(f"没有更新可用 (当前版本: {current})")
|
||||
|
||||
elif args.action == 'hot-update':
|
||||
if not args.source:
|
||||
print("错误: 需要指定源路径")
|
||||
sys.exit(1)
|
||||
|
||||
success = um.hot_update(args.source, args.environment)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif args.action == 'full-update':
|
||||
if not args.source:
|
||||
print("错误: 需要指定源路径")
|
||||
sys.exit(1)
|
||||
|
||||
success = um.full_update(args.source, args.environment, not args.no_backup)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif args.action == 'auto-update':
|
||||
if not args.source:
|
||||
print("错误: 需要指定源路径")
|
||||
sys.exit(1)
|
||||
|
||||
success = um.auto_update(args.source, args.environment)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif args.action == 'rollback':
|
||||
if not args.backup:
|
||||
print("错误: 需要指定备份名称")
|
||||
sys.exit(1)
|
||||
|
||||
success = um.rollback(args.backup, args.environment)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif args.action == 'list-backups':
|
||||
backups = um.list_backups()
|
||||
if backups:
|
||||
print("可用备份:")
|
||||
for backup in backups:
|
||||
print(f" {backup['backup_name']} - {backup['timestamp']} - {backup.get('version', 'unknown')}")
|
||||
else:
|
||||
print("没有找到备份")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Agent模块初始化文件
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Agent动作执行器 - 执行具体的Agent动作
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Agent核心模块
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
自动监控服务
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
任务执行器
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
目标管理器
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
智能Agent核心 - 集成大模型和智能决策
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
大模型客户端 - 统一的LLM接口
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
任务规划器
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
推理引擎
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
工具管理器
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
增强版TSP助手 - 集成Agent功能
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
TSP助手智能预警系统
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
TSP助手监控服务
|
||||
|
||||
@@ -10,7 +10,7 @@ class Config:
|
||||
ALIBABA_MODEL_NAME = "qwen-plus-latest"
|
||||
|
||||
# 数据库配置
|
||||
DATABASE_URL = "mysql+pymysql://root:123456@localhost/tsp_assistant?charset=utf8mb4"
|
||||
DATABASE_URL = "mysql+pymysql://tsp_assistant:123456@43.134.68.207/tsp_assistant?charset=utf8mb4"
|
||||
|
||||
# 知识库配置
|
||||
KNOWLEDGE_BASE_PATH = "data/knowledge_base"
|
||||
|
||||
@@ -102,3 +102,16 @@ class Alert(Base):
|
||||
is_active = Column(Boolean, default=True)
|
||||
created_at = Column(DateTime, default=datetime.now)
|
||||
resolved_at = Column(DateTime)
|
||||
|
||||
class WorkOrderSuggestion(Base):
|
||||
"""工单AI建议与人工描述表"""
|
||||
__tablename__ = "work_order_suggestions"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
work_order_id = Column(Integer, ForeignKey("work_orders.id"), nullable=False)
|
||||
ai_suggestion = Column(Text)
|
||||
human_resolution = Column(Text)
|
||||
ai_similarity = Column(Float)
|
||||
approved = Column(Boolean, default=False)
|
||||
created_at = Column(DateTime, default=datetime.now)
|
||||
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
实时对话管理器
|
||||
@@ -16,6 +16,7 @@ from ..core.llm_client import QwenClient
|
||||
from ..knowledge_base.knowledge_manager import KnowledgeManager
|
||||
from ..core.database import db_manager
|
||||
from ..core.models import Conversation, WorkOrder
|
||||
from ..vehicle.vehicle_data_manager import VehicleDataManager
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -36,6 +37,7 @@ class RealtimeChatManager:
|
||||
def __init__(self):
|
||||
self.llm_client = QwenClient()
|
||||
self.knowledge_manager = KnowledgeManager()
|
||||
self.vehicle_manager = VehicleDataManager()
|
||||
self.active_sessions = {} # 存储活跃的对话会话
|
||||
self.message_history = {} # 存储消息历史
|
||||
|
||||
@@ -82,6 +84,27 @@ class RealtimeChatManager:
|
||||
# 搜索相关知识
|
||||
knowledge_results = self._search_knowledge(user_message)
|
||||
|
||||
# 识别VIN并查询实时数据,注入上下文
|
||||
vin = self._extract_vin(user_message)
|
||||
realtime_snippets = []
|
||||
if vin:
|
||||
latest = self.vehicle_manager.get_latest_vehicle_data_by_vin(vin)
|
||||
if latest:
|
||||
# 组织为知识片段参与提示
|
||||
realtime_snippets.append({
|
||||
"question": f"VIN {vin} 的最新实时数据",
|
||||
"answer": json.dumps(latest, ensure_ascii=False),
|
||||
"similarity_score": 1.0,
|
||||
"source": "vehicle_realtime"
|
||||
})
|
||||
# 也放入上下文,便于模型参考
|
||||
session["context"].append({
|
||||
"role": "system",
|
||||
"content": f"车辆VIN {vin} 最新数据: {json.dumps(latest, ensure_ascii=False)}"
|
||||
})
|
||||
if realtime_snippets:
|
||||
knowledge_results = (realtime_snippets + knowledge_results)[:5]
|
||||
|
||||
# 生成回复
|
||||
assistant_response = self._generate_response(
|
||||
user_message,
|
||||
@@ -217,6 +240,19 @@ class RealtimeChatManager:
|
||||
|
||||
return prompt
|
||||
|
||||
def _extract_vin(self, text: str) -> Optional[str]:
|
||||
"""从文本中提取VIN(17位,I/O/Q不使用,常见校验)"""
|
||||
try:
|
||||
import re
|
||||
# 允许大小写字母和数字,排除 I,O,Q,长度17
|
||||
pattern = r"\b(?!.*[IOQ])[A-HJ-NPR-Z0-9]{17}\b"
|
||||
match = re.search(pattern, text.upper())
|
||||
if match:
|
||||
return match.group(0)
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def _calculate_confidence(self, knowledge_results: List[Dict], response_content: str) -> float:
|
||||
"""计算回复置信度"""
|
||||
if not knowledge_results:
|
||||
|
||||
@@ -125,16 +125,36 @@ class KnowledgeManager:
|
||||
query_filter = query_filter.filter(KnowledgeEntry.is_verified == True)
|
||||
|
||||
entries = query_filter.all()
|
||||
# 若已验证为空,则回退到全部活跃条目
|
||||
if not entries and verified_only:
|
||||
entries = session.query(KnowledgeEntry).filter(KnowledgeEntry.is_active == True).all()
|
||||
|
||||
if not entries:
|
||||
return []
|
||||
|
||||
# 计算相似度
|
||||
texts = [entry.question + " " + entry.answer for entry in entries]
|
||||
|
||||
# 确保向量器已训练
|
||||
try:
|
||||
vocab_ok = hasattr(self.vectorizer, 'vocabulary_') and bool(self.vectorizer.vocabulary_)
|
||||
if not vocab_ok:
|
||||
self.vectorizer.fit(texts)
|
||||
query_vector = self.vectorizer.transform([query])
|
||||
entry_vectors = self.vectorizer.transform(texts)
|
||||
|
||||
similarities = cosine_similarity(query_vector, entry_vectors)[0]
|
||||
except Exception as vec_err:
|
||||
logger.warning(f"TF-IDF搜索失败,回退到子串匹配: {vec_err}")
|
||||
# 回退:子串匹配评分
|
||||
similarities = []
|
||||
q = query.strip()
|
||||
for t in texts:
|
||||
if not q:
|
||||
similarities.append(0.0)
|
||||
else:
|
||||
score = 1.0 if q in t else 0.0
|
||||
similarities.append(score)
|
||||
similarities = np.array(similarities, dtype=float)
|
||||
|
||||
# 获取top_k个最相似的条目
|
||||
top_indices = np.argsort(similarities)[-top_k:][::-1]
|
||||
|
||||
29
src/main.py
29
src/main.py
@@ -16,6 +16,7 @@ from src.dialogue.dialogue_manager import DialogueManager
|
||||
from src.analytics.analytics_manager import AnalyticsManager
|
||||
from src.analytics.alert_system import AlertSystem
|
||||
from src.analytics.monitor_service import MonitorService
|
||||
from src.core.models import WorkOrder
|
||||
|
||||
class TSPAssistant:
|
||||
"""TSP助手主类"""
|
||||
@@ -300,6 +301,34 @@ class TSPAssistant:
|
||||
self.logger.error(f"获取预警统计失败: {e}")
|
||||
return {}
|
||||
|
||||
def get_workorders(self, limit: int = 100) -> List[Dict[str, Any]]:
|
||||
"""获取最近的工单列表(按创建时间倒序)"""
|
||||
try:
|
||||
with db_manager.get_session() as session:
|
||||
q = session.query(WorkOrder).order_by(WorkOrder.created_at.desc())
|
||||
if limit:
|
||||
q = q.limit(limit)
|
||||
rows = q.all()
|
||||
results: List[Dict[str, Any]] = []
|
||||
for w in rows:
|
||||
results.append({
|
||||
"id": w.id,
|
||||
"order_id": w.order_id,
|
||||
"title": w.title,
|
||||
"description": w.description,
|
||||
"category": w.category,
|
||||
"priority": w.priority,
|
||||
"status": w.status,
|
||||
"created_at": w.created_at.isoformat() if w.created_at else None,
|
||||
"updated_at": w.updated_at.isoformat() if w.updated_at else None,
|
||||
"resolution": w.resolution,
|
||||
"satisfaction_score": w.satisfaction_score
|
||||
})
|
||||
return results
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取工单列表失败: {e}")
|
||||
return []
|
||||
|
||||
def get_system_health(self) -> Dict[str, Any]:
|
||||
"""获取系统健康状态"""
|
||||
try:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
车辆数据管理模块
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
车辆实时数据管理器
|
||||
@@ -90,6 +90,43 @@ class VehicleDataManager:
|
||||
logger.error(f"获取车辆数据失败: {e}")
|
||||
return []
|
||||
|
||||
def get_vehicle_data_by_vin(
|
||||
self,
|
||||
vehicle_vin: str,
|
||||
data_type: str = None,
|
||||
limit: int = 10
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""按VIN获取车辆实时数据"""
|
||||
try:
|
||||
with db_manager.get_session() as session:
|
||||
query = session.query(VehicleData).filter(
|
||||
VehicleData.vehicle_vin == vehicle_vin,
|
||||
VehicleData.is_active == True
|
||||
)
|
||||
if data_type:
|
||||
query = query.filter(VehicleData.data_type == data_type)
|
||||
vehicle_data_list = query.order_by(desc(VehicleData.timestamp)).limit(limit).all()
|
||||
|
||||
results = []
|
||||
for data in vehicle_data_list:
|
||||
try:
|
||||
data_value = json.loads(data.data_value)
|
||||
except:
|
||||
data_value = data.data_value
|
||||
results.append({
|
||||
"id": data.id,
|
||||
"vehicle_id": data.vehicle_id,
|
||||
"vehicle_vin": data.vehicle_vin,
|
||||
"data_type": data.data_type,
|
||||
"data_value": data_value,
|
||||
"timestamp": data.timestamp.isoformat(),
|
||||
"is_active": data.is_active
|
||||
})
|
||||
return results
|
||||
except Exception as e:
|
||||
logger.error(f"按VIN获取车辆数据失败: {e}")
|
||||
return []
|
||||
|
||||
def get_latest_vehicle_data(self, vehicle_id: str) -> Dict[str, Any]:
|
||||
"""获取车辆最新数据"""
|
||||
try:
|
||||
@@ -122,6 +159,34 @@ class VehicleDataManager:
|
||||
logger.error(f"获取车辆最新数据失败: {e}")
|
||||
return {}
|
||||
|
||||
def get_latest_vehicle_data_by_vin(self, vehicle_vin: str) -> Dict[str, Any]:
|
||||
"""按VIN获取车辆最新数据"""
|
||||
try:
|
||||
with db_manager.get_session() as session:
|
||||
data_types = ['location', 'status', 'fault', 'battery', 'engine']
|
||||
latest_data: Dict[str, Any] = {}
|
||||
for data_type in data_types:
|
||||
data = session.query(VehicleData).filter(
|
||||
VehicleData.vehicle_vin == vehicle_vin,
|
||||
VehicleData.data_type == data_type,
|
||||
VehicleData.is_active == True
|
||||
).order_by(desc(VehicleData.timestamp)).first()
|
||||
if data:
|
||||
try:
|
||||
data_value = json.loads(data.data_value)
|
||||
except:
|
||||
data_value = data.data_value
|
||||
latest_data[data_type] = {
|
||||
"value": data_value,
|
||||
"timestamp": data.timestamp.isoformat(),
|
||||
"vehicle_id": data.vehicle_id,
|
||||
"vehicle_vin": data.vehicle_vin
|
||||
}
|
||||
return latest_data
|
||||
except Exception as e:
|
||||
logger.error(f"按VIN获取车辆最新数据失败: {e}")
|
||||
return {}
|
||||
|
||||
def search_vehicle_data(
|
||||
self,
|
||||
vehicle_id: str = None,
|
||||
|
||||
701
src/web/app.py
701
src/web/app.py
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
TSP助手预警管理Web应用
|
||||
@@ -8,6 +8,7 @@ TSP助手预警管理Web应用
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
import pandas as pd
|
||||
from datetime import datetime, timedelta
|
||||
from openpyxl import Workbook
|
||||
@@ -24,10 +25,25 @@ from src.agent_assistant import TSPAgentAssistant
|
||||
from src.analytics.alert_system import AlertRule, AlertLevel, AlertType
|
||||
from src.dialogue.realtime_chat import RealtimeChatManager
|
||||
from src.vehicle.vehicle_data_manager import VehicleDataManager
|
||||
from src.core.database import db_manager
|
||||
from src.core.models import WorkOrder, Alert, Conversation, KnowledgeEntry, WorkOrderSuggestion
|
||||
|
||||
app = Flask(__name__)
|
||||
CORS(app)
|
||||
|
||||
# 抑制 /api/health 的访问日志
|
||||
werkzeug_logger = logging.getLogger('werkzeug')
|
||||
|
||||
class HealthLogFilter(logging.Filter):
|
||||
def filter(self, record):
|
||||
try:
|
||||
msg = record.getMessage()
|
||||
return '/api/health' not in msg
|
||||
except Exception:
|
||||
return True
|
||||
|
||||
werkzeug_logger.addFilter(HealthLogFilter())
|
||||
|
||||
# 配置上传文件夹
|
||||
UPLOAD_FOLDER = 'uploads'
|
||||
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
|
||||
@@ -39,6 +55,26 @@ agent_assistant = TSPAgentAssistant()
|
||||
chat_manager = RealtimeChatManager()
|
||||
vehicle_manager = VehicleDataManager()
|
||||
|
||||
# 工具函数:确保工单模板文件存在
|
||||
def _ensure_workorder_template_file() -> str:
|
||||
"""返回已有的模板xlsx路径;不做动态生成,避免运行时依赖问题"""
|
||||
template_path = os.path.join(app.config['UPLOAD_FOLDER'], 'workorder_template.xlsx')
|
||||
# 确保目录存在
|
||||
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
|
||||
if not os.path.exists(template_path):
|
||||
# 如果运行目录不存在模板,尝试从项目根相对路径拷贝一次
|
||||
repo_template = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), '..', 'uploads', 'workorder_template.xlsx')
|
||||
repo_template = os.path.abspath(repo_template)
|
||||
try:
|
||||
if os.path.exists(repo_template):
|
||||
import shutil
|
||||
shutil.copyfile(repo_template, template_path)
|
||||
else:
|
||||
raise FileNotFoundError('模板文件缺失:uploads/workorder_template.xlsx')
|
||||
except Exception as copy_err:
|
||||
raise copy_err
|
||||
return template_path
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
"""主页 - 综合管理平台"""
|
||||
@@ -51,10 +87,28 @@ def alerts():
|
||||
|
||||
@app.route('/api/health')
|
||||
def get_health():
|
||||
"""获取系统健康状态"""
|
||||
"""获取系统健康状态(附加近1小时业务指标)"""
|
||||
try:
|
||||
health = assistant.get_system_health()
|
||||
return jsonify(health)
|
||||
base = assistant.get_system_health() or {}
|
||||
# 追加数据库近1小时指标
|
||||
from datetime import datetime, timedelta
|
||||
with db_manager.get_session() as session:
|
||||
since = datetime.now() - timedelta(hours=1)
|
||||
conv_count = session.query(Conversation).filter(Conversation.timestamp >= since).count()
|
||||
resp_times = [c.response_time for c in session.query(Conversation).filter(Conversation.timestamp >= since).all() if c.response_time]
|
||||
avg_resp = round(sum(resp_times)/len(resp_times), 2) if resp_times else 0
|
||||
open_wos = session.query(WorkOrder).filter(WorkOrder.status == 'open').count()
|
||||
levels = session.query(Alert.level).filter(Alert.is_active == True).all()
|
||||
level_map = {}
|
||||
for (lvl,) in levels:
|
||||
level_map[lvl] = level_map.get(lvl, 0) + 1
|
||||
base.update({
|
||||
"throughput_1h": conv_count,
|
||||
"avg_response_time_1h": avg_resp,
|
||||
"open_workorders": open_wos,
|
||||
"active_alerts_by_level": level_map
|
||||
})
|
||||
return jsonify(base)
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@@ -571,94 +625,34 @@ def unverify_knowledge(knowledge_id):
|
||||
# 工单相关API
|
||||
@app.route('/api/workorders')
|
||||
def get_workorders():
|
||||
"""获取工单列表"""
|
||||
"""获取工单列表(来自数据库)"""
|
||||
try:
|
||||
status_filter = request.args.get('status')
|
||||
priority_filter = request.args.get('priority')
|
||||
|
||||
# 这里应该调用工单管理器的获取方法
|
||||
workorders = [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "车辆无法远程启动",
|
||||
"description": "用户反映APP中远程启动功能无法使用",
|
||||
"category": "远程控制",
|
||||
"priority": "high",
|
||||
"status": "open",
|
||||
"created_at": "2024-01-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"title": "APP显示异常",
|
||||
"description": "APP中车辆信息显示不正确",
|
||||
"category": "APP功能",
|
||||
"priority": "medium",
|
||||
"status": "in_progress",
|
||||
"created_at": "2024-01-01T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"title": "蓝牙连接失败",
|
||||
"description": "用户无法通过蓝牙连接车辆",
|
||||
"category": "蓝牙功能",
|
||||
"priority": "high",
|
||||
"status": "open",
|
||||
"created_at": "2024-01-01T12:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"title": "车辆定位不准确",
|
||||
"description": "APP中显示的车辆位置与实际位置不符",
|
||||
"category": "定位功能",
|
||||
"priority": "medium",
|
||||
"status": "resolved",
|
||||
"created_at": "2024-01-01T13:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"title": "远程解锁失败",
|
||||
"description": "用户无法通过APP远程解锁车辆",
|
||||
"category": "远程控制",
|
||||
"priority": "urgent",
|
||||
"status": "open",
|
||||
"created_at": "2024-01-01T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"title": "APP闪退问题",
|
||||
"description": "用户反映APP在使用过程中频繁闪退",
|
||||
"category": "APP功能",
|
||||
"priority": "high",
|
||||
"status": "in_progress",
|
||||
"created_at": "2024-01-01T15:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"title": "车辆状态更新延迟",
|
||||
"description": "车辆状态信息更新不及时,存在延迟",
|
||||
"category": "数据同步",
|
||||
"priority": "low",
|
||||
"status": "open",
|
||||
"created_at": "2024-01-01T16:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"title": "用户认证失败",
|
||||
"description": "部分用户无法正常登录APP",
|
||||
"category": "用户认证",
|
||||
"priority": "high",
|
||||
"status": "resolved",
|
||||
"created_at": "2024-01-01T17:00:00Z"
|
||||
}
|
||||
]
|
||||
|
||||
# 应用过滤
|
||||
with db_manager.get_session() as session:
|
||||
q = session.query(WorkOrder)
|
||||
if status_filter and status_filter != 'all':
|
||||
workorders = [w for w in workorders if w['status'] == status_filter]
|
||||
q = q.filter(WorkOrder.status == status_filter)
|
||||
if priority_filter and priority_filter != 'all':
|
||||
workorders = [w for w in workorders if w['priority'] == priority_filter]
|
||||
|
||||
return jsonify(workorders)
|
||||
q = q.filter(WorkOrder.priority == priority_filter)
|
||||
q = q.order_by(WorkOrder.created_at.desc())
|
||||
rows = q.all()
|
||||
result = []
|
||||
for w in rows:
|
||||
result.append({
|
||||
"id": w.id,
|
||||
"order_id": w.order_id,
|
||||
"title": w.title,
|
||||
"description": w.description,
|
||||
"category": w.category,
|
||||
"priority": w.priority,
|
||||
"status": w.status,
|
||||
"created_at": w.created_at.isoformat() if w.created_at else None,
|
||||
"updated_at": w.updated_at.isoformat() if w.updated_at else None,
|
||||
"resolution": w.resolution,
|
||||
"satisfaction_score": w.satisfaction_score
|
||||
})
|
||||
return jsonify(result)
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@@ -679,36 +673,34 @@ def create_workorder():
|
||||
|
||||
@app.route('/api/workorders/<int:workorder_id>')
|
||||
def get_workorder_details(workorder_id):
|
||||
"""获取工单详情"""
|
||||
"""获取工单详情(含数据库对话记录)"""
|
||||
try:
|
||||
# 这里应该从数据库获取工单详情
|
||||
# 暂时返回模拟数据
|
||||
with db_manager.get_session() as session:
|
||||
w = session.query(WorkOrder).filter(WorkOrder.id == workorder_id).first()
|
||||
if not w:
|
||||
return jsonify({"error": "工单不存在"}), 404
|
||||
convs = session.query(Conversation).filter(Conversation.work_order_id == w.id).order_by(Conversation.timestamp.asc()).all()
|
||||
conv_list = []
|
||||
for c in convs:
|
||||
conv_list.append({
|
||||
"id": c.id,
|
||||
"user_message": c.user_message,
|
||||
"assistant_response": c.assistant_response,
|
||||
"timestamp": c.timestamp.isoformat() if c.timestamp else None
|
||||
})
|
||||
workorder = {
|
||||
"id": workorder_id,
|
||||
"order_id": f"WO{workorder_id:06d}",
|
||||
"title": "车辆无法远程启动",
|
||||
"description": "用户反映APP中远程启动功能无法使用,点击启动按钮后没有任何反应,车辆也没有响应。",
|
||||
"category": "远程控制",
|
||||
"priority": "high",
|
||||
"status": "open",
|
||||
"created_at": "2024-01-01T10:00:00Z",
|
||||
"updated_at": "2024-01-01T10:00:00Z",
|
||||
"resolution": None,
|
||||
"satisfaction_score": None,
|
||||
"conversations": [
|
||||
{
|
||||
"id": 1,
|
||||
"user_message": "我的车辆无法远程启动",
|
||||
"assistant_response": "我了解您的问题。让我帮您排查一下远程启动功能的问题。",
|
||||
"timestamp": "2024-01-01T10:05:00Z"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"user_message": "点击启动按钮后没有任何反应",
|
||||
"assistant_response": "这种情况通常是由于网络连接或车辆状态问题导致的。请检查车辆是否处于可启动状态。",
|
||||
"timestamp": "2024-01-01T10:10:00Z"
|
||||
}
|
||||
]
|
||||
"id": w.id,
|
||||
"order_id": w.order_id,
|
||||
"title": w.title,
|
||||
"description": w.description,
|
||||
"category": w.category,
|
||||
"priority": w.priority,
|
||||
"status": w.status,
|
||||
"created_at": w.created_at.isoformat() if w.created_at else None,
|
||||
"updated_at": w.updated_at.isoformat() if w.updated_at else None,
|
||||
"resolution": w.resolution,
|
||||
"satisfaction_score": w.satisfaction_score,
|
||||
"conversations": conv_list
|
||||
}
|
||||
return jsonify(workorder)
|
||||
except Exception as e:
|
||||
@@ -716,33 +708,135 @@ def get_workorder_details(workorder_id):
|
||||
|
||||
@app.route('/api/workorders/<int:workorder_id>', methods=['PUT'])
|
||||
def update_workorder(workorder_id):
|
||||
"""更新工单"""
|
||||
"""更新工单(写入数据库)"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
|
||||
# 验证必填字段
|
||||
if not data.get('title') or not data.get('description'):
|
||||
return jsonify({"error": "标题和描述不能为空"}), 400
|
||||
|
||||
# 这里应该更新数据库中的工单
|
||||
# 暂时返回成功响应,实际应用中应该调用数据库更新
|
||||
updated_workorder = {
|
||||
"id": workorder_id,
|
||||
"title": data.get('title'),
|
||||
"description": data.get('description'),
|
||||
"category": data.get('category', '技术问题'),
|
||||
"priority": data.get('priority', 'medium'),
|
||||
"status": data.get('status', 'open'),
|
||||
"resolution": data.get('resolution'),
|
||||
"satisfaction_score": data.get('satisfaction_score'),
|
||||
"updated_at": datetime.now().isoformat()
|
||||
with db_manager.get_session() as session:
|
||||
w = session.query(WorkOrder).filter(WorkOrder.id == workorder_id).first()
|
||||
if not w:
|
||||
return jsonify({"error": "工单不存在"}), 404
|
||||
w.title = data.get('title', w.title)
|
||||
w.description = data.get('description', w.description)
|
||||
w.category = data.get('category', w.category)
|
||||
w.priority = data.get('priority', w.priority)
|
||||
w.status = data.get('status', w.status)
|
||||
w.resolution = data.get('resolution', w.resolution)
|
||||
w.satisfaction_score = data.get('satisfaction_score', w.satisfaction_score)
|
||||
w.updated_at = datetime.now()
|
||||
session.commit()
|
||||
updated = {
|
||||
"id": w.id,
|
||||
"title": w.title,
|
||||
"description": w.description,
|
||||
"category": w.category,
|
||||
"priority": w.priority,
|
||||
"status": w.status,
|
||||
"resolution": w.resolution,
|
||||
"satisfaction_score": w.satisfaction_score,
|
||||
"updated_at": w.updated_at.isoformat() if w.updated_at else None
|
||||
}
|
||||
return jsonify({"success": True, "message": "工单更新成功", "workorder": updated})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "工单更新成功",
|
||||
"workorder": updated_workorder
|
||||
})
|
||||
# 工单AI建议:生成、保存人工描述、审批入库
|
||||
@app.route('/api/workorders/<int:workorder_id>/ai-suggestion', methods=['POST'])
|
||||
def generate_workorder_ai_suggestion(workorder_id):
|
||||
"""根据工单描述与知识库生成AI建议草稿"""
|
||||
try:
|
||||
with db_manager.get_session() as session:
|
||||
w = session.query(WorkOrder).filter(WorkOrder.id == workorder_id).first()
|
||||
if not w:
|
||||
return jsonify({"error": "工单不存在"}), 404
|
||||
# 调用知识库搜索与LLM生成
|
||||
query = f"{w.title} {w.description}"
|
||||
kb_results = assistant.search_knowledge(query, top_k=3)
|
||||
kb_list = kb_results.get('results', []) if isinstance(kb_results, dict) else []
|
||||
# 组装提示词
|
||||
context = "\n".join([f"Q: {k.get('question','')}\nA: {k.get('answer','')}" for k in kb_list])
|
||||
from src.core.llm_client import QwenClient
|
||||
llm = QwenClient()
|
||||
prompt = f"请基于以下工单描述与知识库片段,给出简洁、可执行的处理建议。\n工单描述:\n{w.description}\n\n知识库片段:\n{context}\n\n请直接输出建议文本:"
|
||||
llm_resp = llm.chat_completion(messages=[{"role":"user","content":prompt}], temperature=0.3, max_tokens=800)
|
||||
suggestion = ""
|
||||
if llm_resp and 'choices' in llm_resp:
|
||||
suggestion = llm_resp['choices'][0]['message']['content']
|
||||
# 保存/更新草稿记录
|
||||
rec = session.query(WorkOrderSuggestion).filter(WorkOrderSuggestion.work_order_id == w.id).first()
|
||||
if not rec:
|
||||
rec = WorkOrderSuggestion(work_order_id=w.id, ai_suggestion=suggestion)
|
||||
session.add(rec)
|
||||
else:
|
||||
rec.ai_suggestion = suggestion
|
||||
rec.updated_at = datetime.now()
|
||||
session.commit()
|
||||
return jsonify({"success": True, "ai_suggestion": suggestion})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@app.route('/api/workorders/<int:workorder_id>/human-resolution', methods=['POST'])
|
||||
def save_workorder_human_resolution(workorder_id):
|
||||
"""保存人工描述,并计算与AI建议相似度;若≥95%可自动审批入库"""
|
||||
try:
|
||||
data = request.get_json() or {}
|
||||
human_text = data.get('human_resolution','').strip()
|
||||
if not human_text:
|
||||
return jsonify({"error":"人工描述不能为空"}), 400
|
||||
with db_manager.get_session() as session:
|
||||
w = session.query(WorkOrder).filter(WorkOrder.id == workorder_id).first()
|
||||
if not w:
|
||||
return jsonify({"error": "工单不存在"}), 404
|
||||
rec = session.query(WorkOrderSuggestion).filter(WorkOrderSuggestion.work_order_id == w.id).first()
|
||||
if not rec:
|
||||
rec = WorkOrderSuggestion(work_order_id=w.id)
|
||||
session.add(rec)
|
||||
rec.human_resolution = human_text
|
||||
# 计算相似度(使用简单cosine TF-IDF,避免外部服务依赖)
|
||||
try:
|
||||
from sklearn.feature_extraction.text import TfidfVectorizer
|
||||
from sklearn.metrics.pairwise import cosine_similarity
|
||||
texts = [rec.ai_suggestion or "", human_text]
|
||||
vec = TfidfVectorizer(max_features=1000)
|
||||
mat = vec.fit_transform(texts)
|
||||
sim = float(cosine_similarity(mat[0:1], mat[1:2])[0][0])
|
||||
except Exception:
|
||||
sim = 0.0
|
||||
rec.ai_similarity = sim
|
||||
# 自动审批条件≥0.95
|
||||
approved = sim >= 0.95
|
||||
rec.approved = approved
|
||||
session.commit()
|
||||
return jsonify({"success": True, "similarity": sim, "approved": approved})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@app.route('/api/workorders/<int:workorder_id>/approve-to-knowledge', methods=['POST'])
|
||||
def approve_workorder_to_knowledge(workorder_id):
|
||||
"""将已审批的AI建议入库为知识条目"""
|
||||
try:
|
||||
with db_manager.get_session() as session:
|
||||
w = session.query(WorkOrder).filter(WorkOrder.id == workorder_id).first()
|
||||
if not w:
|
||||
return jsonify({"error": "工单不存在"}), 404
|
||||
rec = session.query(WorkOrderSuggestion).filter(WorkOrderSuggestion.work_order_id == w.id).first()
|
||||
if not rec or not rec.approved or not rec.ai_suggestion:
|
||||
return jsonify({"error": "未找到可入库的已审批AI建议"}), 400
|
||||
# 入库为知识条目(问=工单标题;答=AI建议;类目用工单分类)
|
||||
entry = KnowledgeEntry(
|
||||
question=w.title or (w.description[:20] if w.description else '工单问题'),
|
||||
answer=rec.ai_suggestion,
|
||||
category=w.category or '其他',
|
||||
confidence_score=0.95,
|
||||
is_active=True,
|
||||
is_verified=True,
|
||||
verified_by='auto_approve',
|
||||
verified_at=datetime.now()
|
||||
)
|
||||
session.add(entry)
|
||||
session.commit()
|
||||
return jsonify({"success": True, "knowledge_id": entry.id})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@@ -751,98 +845,112 @@ def update_workorder(workorder_id):
|
||||
def get_analytics():
|
||||
"""获取分析数据"""
|
||||
try:
|
||||
time_range = request.args.get('timeRange', '30')
|
||||
# 支持多种参数名
|
||||
time_range = request.args.get('timeRange', request.args.get('days', '30'))
|
||||
dimension = request.args.get('dimension', 'workorders')
|
||||
|
||||
# 生成模拟分析数据
|
||||
analytics = generate_analytics_data(int(time_range), dimension)
|
||||
analytics = generate_db_analytics(int(time_range), dimension)
|
||||
return jsonify(analytics)
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
def generate_analytics_data(days, dimension):
|
||||
"""生成分析数据"""
|
||||
import random
|
||||
from datetime import datetime, timedelta
|
||||
def generate_db_analytics(days: int, dimension: str) -> dict:
|
||||
"""基于数据库生成真实分析数据"""
|
||||
from collections import defaultdict, Counter
|
||||
end_time = datetime.now()
|
||||
start_time = end_time - timedelta(days=days-1)
|
||||
|
||||
# 生成时间序列数据
|
||||
trend_data = []
|
||||
for i in range(days):
|
||||
date = (datetime.now() - timedelta(days=days-i-1)).strftime('%Y-%m-%d')
|
||||
workorders = random.randint(5, 25)
|
||||
alerts = random.randint(0, 10)
|
||||
trend_data.append({
|
||||
'date': date,
|
||||
'workorders': workorders,
|
||||
'alerts': alerts
|
||||
})
|
||||
with db_manager.get_session() as session:
|
||||
# 拉取数据
|
||||
workorders = session.query(WorkOrder).filter(WorkOrder.created_at >= start_time).all()
|
||||
alerts = session.query(Alert).filter(Alert.created_at >= start_time).all()
|
||||
conversations = session.query(Conversation).filter(Conversation.timestamp >= start_time).all()
|
||||
knowledge_entries = session.query(KnowledgeEntry).all()
|
||||
|
||||
# 趋势数据(按天)
|
||||
day_keys = [(start_time + timedelta(days=i)).strftime('%Y-%m-%d') for i in range(days)]
|
||||
wo_by_day = Counter([(wo.created_at.strftime('%Y-%m-%d') if wo.created_at else end_time.strftime('%Y-%m-%d')) for wo in workorders])
|
||||
alert_by_day = Counter([(al.created_at.strftime('%Y-%m-%d') if al.created_at else end_time.strftime('%Y-%m-%d')) for al in alerts])
|
||||
trend = [{
|
||||
'date': d,
|
||||
'workorders': int(wo_by_day.get(d, 0)),
|
||||
'alerts': int(alert_by_day.get(d, 0))
|
||||
} for d in day_keys]
|
||||
|
||||
# 工单统计
|
||||
total = len(workorders)
|
||||
status_counts = Counter([wo.status for wo in workorders])
|
||||
category_counts = Counter([wo.category for wo in workorders])
|
||||
priority_counts = Counter([wo.priority for wo in workorders])
|
||||
resolved_count = status_counts.get('resolved', 0)
|
||||
workorders_stats = {
|
||||
'total': random.randint(100, 500),
|
||||
'open': random.randint(10, 50),
|
||||
'in_progress': random.randint(5, 30),
|
||||
'resolved': random.randint(50, 200),
|
||||
'closed': random.randint(20, 100),
|
||||
'by_category': {
|
||||
'技术问题': random.randint(20, 80),
|
||||
'业务问题': random.randint(15, 60),
|
||||
'系统故障': random.randint(10, 40),
|
||||
'功能需求': random.randint(5, 30),
|
||||
'其他': random.randint(5, 20)
|
||||
},
|
||||
'by_priority': {
|
||||
'low': random.randint(20, 60),
|
||||
'medium': random.randint(30, 80),
|
||||
'high': random.randint(10, 40),
|
||||
'urgent': random.randint(5, 20)
|
||||
}
|
||||
'total': total,
|
||||
'open': status_counts.get('open', 0),
|
||||
'in_progress': status_counts.get('in_progress', 0),
|
||||
'resolved': resolved_count,
|
||||
'closed': status_counts.get('closed', 0),
|
||||
'by_category': dict(category_counts),
|
||||
'by_priority': dict(priority_counts)
|
||||
}
|
||||
|
||||
# 满意度分析
|
||||
# 满意度
|
||||
scores = []
|
||||
for wo in workorders:
|
||||
if wo.satisfaction_score not in (None, ''):
|
||||
try:
|
||||
score = float(wo.satisfaction_score)
|
||||
scores.append(score)
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
avg_satisfaction = round(sum(scores)/len(scores), 1) if scores else 0
|
||||
dist = Counter([str(int(round(s))) for s in scores]) if scores else {}
|
||||
satisfaction_stats = {
|
||||
'average': round(random.uniform(3.5, 4.8), 1),
|
||||
'distribution': {
|
||||
'1': random.randint(0, 5),
|
||||
'2': random.randint(0, 10),
|
||||
'3': random.randint(5, 20),
|
||||
'4': random.randint(20, 50),
|
||||
'5': random.randint(30, 80)
|
||||
}
|
||||
'average': avg_satisfaction,
|
||||
'distribution': {k: int(v) for k, v in dist.items()}
|
||||
}
|
||||
|
||||
# 预警统计
|
||||
level_counts = Counter([al.level for al in alerts])
|
||||
active_alerts = len([al for al in alerts if al.is_active])
|
||||
resolved_alerts = len([al for al in alerts if not al.is_active and al.resolved_at])
|
||||
alerts_stats = {
|
||||
'total': random.randint(50, 200),
|
||||
'active': random.randint(5, 30),
|
||||
'resolved': random.randint(20, 100),
|
||||
'by_level': {
|
||||
'low': random.randint(10, 40),
|
||||
'medium': random.randint(15, 50),
|
||||
'high': random.randint(5, 25),
|
||||
'critical': random.randint(2, 10)
|
||||
}
|
||||
'total': len(alerts),
|
||||
'active': active_alerts,
|
||||
'resolved': resolved_alerts,
|
||||
'by_level': {k: int(v) for k, v in level_counts.items()}
|
||||
}
|
||||
|
||||
# 性能指标
|
||||
# 性能指标(基于对话响应时间粗略估计)
|
||||
resp_times = []
|
||||
for c in conversations:
|
||||
if c.response_time not in (None, ''):
|
||||
try:
|
||||
resp_time = float(c.response_time)
|
||||
resp_times.append(resp_time)
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
avg_resp = round(sum(resp_times)/len(resp_times), 2) if resp_times else 0
|
||||
throughput = len(conversations) # 期间内的对话数量
|
||||
# 错误率:用严重预警比例粗估
|
||||
critical = level_counts.get('critical', 0)
|
||||
error_rate = round((critical / alerts_stats['total']) * 100, 2) if alerts_stats['total'] > 0 else 0
|
||||
performance_stats = {
|
||||
'response_time': round(random.uniform(0.5, 2.0), 2),
|
||||
'uptime': round(random.uniform(95, 99.9), 1),
|
||||
'error_rate': round(random.uniform(0.1, 2.0), 2),
|
||||
'throughput': random.randint(1000, 5000)
|
||||
'response_time': avg_resp,
|
||||
'uptime': 99.0, # 可接入真实监控后更新
|
||||
'error_rate': error_rate,
|
||||
'throughput': throughput
|
||||
}
|
||||
|
||||
return {
|
||||
'trend': trend_data,
|
||||
'trend': trend,
|
||||
'workorders': workorders_stats,
|
||||
'satisfaction': satisfaction_stats,
|
||||
'alerts': alerts_stats,
|
||||
'performance': performance_stats,
|
||||
'summary': {
|
||||
'total_workorders': workorders_stats['total'],
|
||||
'resolution_rate': round((workorders_stats['resolved'] / workorders_stats['total']) * 100, 1) if workorders_stats['total'] > 0 else 0,
|
||||
'avg_satisfaction': satisfaction_stats['average'],
|
||||
'active_alerts': alerts_stats['active']
|
||||
'total_workorders': total,
|
||||
'resolution_rate': round((resolved_count/total)*100, 1) if total > 0 else 0,
|
||||
'avg_satisfaction': avg_satisfaction,
|
||||
'active_alerts': active_alerts
|
||||
}
|
||||
}
|
||||
|
||||
@@ -850,8 +958,8 @@ def generate_analytics_data(days, dimension):
|
||||
def export_analytics():
|
||||
"""导出分析报告"""
|
||||
try:
|
||||
# 生成Excel报告
|
||||
analytics = generate_analytics_data(30, 'workorders')
|
||||
# 生成Excel报告(使用数据库真实数据)
|
||||
analytics = generate_db_analytics(30, 'workorders')
|
||||
|
||||
# 创建工作簿
|
||||
wb = Workbook()
|
||||
@@ -882,6 +990,50 @@ def export_analytics():
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
# Agent 工具统计与自定义工具
|
||||
@app.route('/api/agent/tools/stats')
|
||||
def get_agent_tools_stats():
|
||||
try:
|
||||
tools = agent_assistant.agent_core.tool_manager.get_available_tools()
|
||||
performance = agent_assistant.agent_core.tool_manager.get_tool_performance_report()
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"tools": tools,
|
||||
"performance": performance
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@app.route('/api/agent/tools/register', methods=['POST'])
|
||||
def register_custom_tool():
|
||||
"""注册自定义工具(仅登记元数据,函数为占位)"""
|
||||
try:
|
||||
data = request.get_json() or {}
|
||||
name = data.get('name')
|
||||
description = data.get('description', '')
|
||||
if not name:
|
||||
return jsonify({"error": "缺少工具名称"}), 400
|
||||
|
||||
def _placeholder_tool(**kwargs):
|
||||
return {"message": f"自定义工具 {name} 已登记(占位),当前不可执行", "params": kwargs}
|
||||
|
||||
agent_assistant.agent_core.tool_manager.register_tool(
|
||||
name,
|
||||
_placeholder_tool,
|
||||
metadata={"description": description, "custom": True}
|
||||
)
|
||||
return jsonify({"success": True, "message": "工具已注册"})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@app.route('/api/agent/tools/unregister/<name>', methods=['DELETE'])
|
||||
def unregister_custom_tool(name):
|
||||
try:
|
||||
success = agent_assistant.agent_core.tool_manager.unregister_tool(name)
|
||||
return jsonify({"success": success})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
# 工单导入相关API
|
||||
@app.route('/api/workorders/import', methods=['POST'])
|
||||
def import_workorders():
|
||||
@@ -953,24 +1105,7 @@ def import_workorders():
|
||||
def download_import_template():
|
||||
"""下载工单导入模板"""
|
||||
try:
|
||||
# 创建模板数据
|
||||
template_data = {
|
||||
'标题': ['车辆无法启动', '空调不制冷', '导航系统故障'],
|
||||
'描述': ['用户反映车辆无法正常启动', '空调系统无法制冷', '导航系统显示异常'],
|
||||
'分类': ['技术问题', '技术问题', '技术问题'],
|
||||
'优先级': ['high', 'medium', 'low'],
|
||||
'状态': ['open', 'in_progress', 'resolved'],
|
||||
'解决方案': ['检查电池和启动系统', '检查制冷剂和压缩机', '更新导航软件'],
|
||||
'满意度': [5, 4, 5]
|
||||
}
|
||||
|
||||
df = pd.DataFrame(template_data)
|
||||
|
||||
# 保存为Excel文件
|
||||
template_path = 'uploads/workorder_template.xlsx'
|
||||
os.makedirs('uploads', exist_ok=True)
|
||||
df.to_excel(template_path, index=False)
|
||||
|
||||
template_path = _ensure_workorder_template_file()
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"template_url": f"/uploads/workorder_template.xlsx"
|
||||
@@ -979,6 +1114,15 @@ def download_import_template():
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@app.route('/api/workorders/import/template/file')
|
||||
def download_import_template_file():
|
||||
"""直接返回工单导入模板文件(下载)"""
|
||||
try:
|
||||
template_path = _ensure_workorder_template_file()
|
||||
return send_file(template_path, as_attachment=True, download_name='工单导入模板.xlsx')
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@app.route('/uploads/<filename>')
|
||||
def uploaded_file(filename):
|
||||
"""提供上传文件的下载服务"""
|
||||
@@ -989,13 +1133,46 @@ def uploaded_file(filename):
|
||||
def get_settings():
|
||||
"""获取系统设置"""
|
||||
try:
|
||||
import json
|
||||
settings_path = os.path.join('data', 'system_settings.json')
|
||||
os.makedirs('data', exist_ok=True)
|
||||
if os.path.exists(settings_path):
|
||||
with open(settings_path, 'r', encoding='utf-8') as f:
|
||||
settings = json.load(f)
|
||||
# 掩码API Key
|
||||
if settings.get('api_key'):
|
||||
settings['api_key'] = '******'
|
||||
settings['api_key_masked'] = True
|
||||
else:
|
||||
settings = {
|
||||
"api_timeout": 30,
|
||||
"max_history": 10,
|
||||
"refresh_interval": 10,
|
||||
"auto_monitoring": True,
|
||||
"agent_mode": True
|
||||
"agent_mode": True,
|
||||
# LLM与API配置(仅持久化,不直接热更新LLM客户端)
|
||||
"api_provider": "openai",
|
||||
"api_base_url": "",
|
||||
"api_key": "",
|
||||
"model_name": "qwen-turbo",
|
||||
"model_temperature": 0.7,
|
||||
"model_max_tokens": 1000,
|
||||
# 服务配置
|
||||
"server_port": 5000,
|
||||
"websocket_port": 8765,
|
||||
"log_level": "INFO"
|
||||
}
|
||||
with open(settings_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(settings, f, ensure_ascii=False, indent=2)
|
||||
# 添加当前服务状态信息
|
||||
import time
|
||||
import psutil
|
||||
settings['current_server_port'] = app.config.get('SERVER_PORT', 5000)
|
||||
settings['current_websocket_port'] = app.config.get('WEBSOCKET_PORT', 8765)
|
||||
settings['uptime_seconds'] = int(time.time() - app.config.get('START_TIME', time.time()))
|
||||
settings['memory_usage_percent'] = psutil.virtual_memory().percent
|
||||
settings['cpu_usage_percent'] = psutil.cpu_percent()
|
||||
|
||||
return jsonify(settings)
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
@@ -1005,7 +1182,26 @@ def save_settings():
|
||||
"""保存系统设置"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
# 这里应该保存设置到配置文件
|
||||
import json
|
||||
os.makedirs('data', exist_ok=True)
|
||||
settings_path = os.path.join('data', 'system_settings.json')
|
||||
# 读取旧值,处理api_key掩码
|
||||
old = {}
|
||||
if os.path.exists(settings_path):
|
||||
try:
|
||||
with open(settings_path, 'r', encoding='utf-8') as f:
|
||||
old = json.load(f)
|
||||
except Exception:
|
||||
old = {}
|
||||
# 如果前端传回掩码或空,则保留旧的api_key
|
||||
if 'api_key' in data:
|
||||
if not data['api_key'] or data['api_key'] == '******':
|
||||
data['api_key'] = old.get('api_key', '')
|
||||
# 移除mask标志
|
||||
if 'api_key_masked' in data:
|
||||
data.pop('api_key_masked')
|
||||
with open(settings_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
return jsonify({"success": True, "message": "设置保存成功"})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
@@ -1033,10 +1229,13 @@ def get_vehicle_data():
|
||||
"""获取车辆数据"""
|
||||
try:
|
||||
vehicle_id = request.args.get('vehicle_id')
|
||||
vehicle_vin = request.args.get('vehicle_vin')
|
||||
data_type = request.args.get('data_type')
|
||||
limit = request.args.get('limit', 10, type=int)
|
||||
|
||||
if vehicle_id:
|
||||
if vehicle_vin:
|
||||
data = vehicle_manager.get_vehicle_data_by_vin(vehicle_vin, data_type, limit)
|
||||
elif vehicle_id:
|
||||
data = vehicle_manager.get_vehicle_data(vehicle_id, data_type, limit)
|
||||
else:
|
||||
data = vehicle_manager.search_vehicle_data(limit=limit)
|
||||
@@ -1045,6 +1244,15 @@ def get_vehicle_data():
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@app.route('/api/vehicle/data/vin/<vehicle_vin>/latest')
|
||||
def get_latest_vehicle_data_by_vin(vehicle_vin):
|
||||
"""按VIN获取车辆最新数据"""
|
||||
try:
|
||||
data = vehicle_manager.get_latest_vehicle_data_by_vin(vehicle_vin)
|
||||
return jsonify(data)
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@app.route('/api/vehicle/data/<vehicle_id>/latest')
|
||||
def get_latest_vehicle_data(vehicle_id):
|
||||
"""获取车辆最新数据"""
|
||||
@@ -1087,5 +1295,50 @@ def init_sample_vehicle_data():
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
# API测试相关接口
|
||||
@app.route('/api/test/connection', methods=['POST'])
|
||||
def test_api_connection():
|
||||
"""测试API连接"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
api_provider = data.get('api_provider', 'openai')
|
||||
api_base_url = data.get('api_base_url', '')
|
||||
api_key = data.get('api_key', '')
|
||||
model_name = data.get('model_name', 'qwen-turbo')
|
||||
|
||||
# 这里可以调用LLM客户端进行连接测试
|
||||
# 暂时返回模拟结果
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": f"API连接测试成功 - {api_provider}",
|
||||
"response_time": "150ms",
|
||||
"model_status": "可用"
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({"success": False, "error": str(e)}), 500
|
||||
|
||||
@app.route('/api/test/model', methods=['POST'])
|
||||
def test_model_response():
|
||||
"""测试模型回答"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
test_message = data.get('test_message', '你好,请简单介绍一下你自己')
|
||||
|
||||
# 这里可以调用LLM客户端进行回答测试
|
||||
# 暂时返回模拟结果
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"test_message": test_message,
|
||||
"response": "你好!我是TSP智能助手,基于大语言模型构建的智能客服系统。我可以帮助您解决车辆相关问题,提供技术支持和服务。",
|
||||
"response_time": "1.2s",
|
||||
"tokens_used": 45
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({"success": False, "error": str(e)}), 500
|
||||
|
||||
if __name__ == '__main__':
|
||||
import time
|
||||
app.config['START_TIME'] = time.time()
|
||||
app.config['SERVER_PORT'] = 5000
|
||||
app.config['WEBSOCKET_PORT'] = 8765
|
||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
||||
|
||||
@@ -604,3 +604,64 @@ body {
|
||||
color: #6c757d;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
| ||||