From 26737747d994347273751e873a0ceca20505bb0d Mon Sep 17 00:00:00 2001 From: Jeason <1710884619@qq.com> Date: Wed, 8 Apr 2026 09:56:23 +0800 Subject: [PATCH] =?UTF-8?q?safe:=20=E5=AE=89=E5=85=A8=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=EF=BC=88=E4=B8=8D=E5=BD=B1=E5=93=8D=E9=A3=9E=E4=B9=A6/Pipeline?= =?UTF-8?q?/Redis=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - bcrypt 密码哈希升级(兼容旧 SHA-256,登录时自动升级) - auth_manager.secret_key 从环境变量读取 - 前端事件总线(on/off/emit) - ConfigService 统一配置服务 - AI 监控错误详情修复(Conversation 没有 category/source) - README.md 重写 --- README.md | 550 +++---------------------------- src/config/config_service.py | 76 +++++ src/core/auth_manager.py | 13 +- src/core/models.py | 15 +- src/web/blueprints/monitoring.py | 4 +- src/web/static/js/dashboard.js | 7 + 6 files changed, 149 insertions(+), 516 deletions(-) create mode 100644 src/config/config_service.py diff --git a/README.md b/README.md index 656a3f3..186e3ec 100644 --- a/README.md +++ b/README.md @@ -1,521 +1,61 @@ -# TSP智能助手 (TSP Assistant) +# TSP 智能助手 -[![Version](https://img.shields.io/badge/version-2.1.0-blue.svg)](version.json) -[![Python](https://img.shields.io/badge/python-3.11+-green.svg)](requirements.txt) -[![Docker](https://img.shields.io/badge/docker-supported-blue.svg)](Dockerfile) -[![License](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE) -[![Status](https://img.shields.io/badge/status-production-ready-brightgreen.svg)]() +AI 驱动的多租户客服与工单管理系统,支持飞书机器人、WebSocket 实时对话、知识库语义搜索。 -> 基于大语言模型的智能客服系统,专为TSP(Telematics Service Provider)车辆服务提供商设计 +## 功能概览 -## 🚀 项目特色 +- **智能对话** — WebSocket 实时聊天 + 飞书机器人(长连接模式),按租户隔离知识库 +- **工单管理** — 创建、编辑、删除、飞书多维表格双向同步,AI 生成处理建议 +- **知识库** — TF-IDF + 可选 Embedding 语义搜索,支持文件导入、人工验证 +- **多租户** — 数据按 tenant_id 隔离,每个租户独立的系统提示词和飞书群绑定 +- **数据分析** — 工单趋势、预警统计、满意度分析,支持按租户筛选 +- **预警系统** — 自定义规则、多级别预警、批量管理 +- **系统管理** — 模块权限控制、流量/成本/安全配置、Token 监控 -### 🧠 智能Agent架构 -- **多工具集成**: 知识库搜索、工单管理、数据分析、通知推送等10+工具 -- **智能规划**: 基于目标驱动的任务规划和执行 -- **自主学习**: 从用户反馈中持续优化响应质量 -- **实时监控**: 主动监控系统状态和异常情况 -- **模块化重构**: 后端服务(Agent, 车辆数据, 分析, 测试)蓝图化,提高可维护性和扩展性 -- **前端模块化**: 引入ES6模块化架构,优化UI组件、状态管理和API服务 +## 快速开始 -### 💬 智能对话系统 -- **实时通信**: WebSocket支持,毫秒级响应,已修复连接稳定性问题 -- **上下文理解**: 多轮对话记忆和上下文关联 -- **VIN识别**: 自动识别车辆VIN码并获取实时数据 -- **知识库集成**: 基于TF-IDF和余弦相似度的智能检索 -- **自定义提示词**: 支持飞书同步和实时对话不同场景的LLM提示词 - -### 数据驱动分析 -- **真实数据**: 基于数据库的真实性能趋势分析 -- **多维度统计**: 工单、预警、满意度、性能指标 -- **可视化展示**: Chart.js图表,直观的数据呈现 -- **系统监控**: 实时CPU、内存、健康状态监控 -- **专属蓝图**: 独立的数据分析API模块,提供专业数据报告导出 - -### 🔧 企业级管理 -- **多环境部署**: 开发、测试、生产环境隔离 -- **版本控制**: 完整的版本管理和变更日志 -- **热更新**: 支持前端文件热更新,无需重启服务 -- **自动备份**: 更新前自动备份,支持一键回滚 -- **飞书集成**: 支持飞书多维表格数据同步和管理 -- **统一错误处理**: 后端API统一异常处理,提高系统健壮性 - -## 🏗️ 系统架构 - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ 前端界面 │ │ 后端服务 │ │ 数据存储 │ -│ │ │ │ │ │ -│ • 仪表板 │◄──►│ • Flask API │◄──►│ • MySQL DB │ -│ • 智能对话 │ │ • WebSocket │ │ • Redis缓存 │ -│ • Agent管理 │ │ • Agent核心 │ │ • 知识库 │ -│ • 数据分析 │ │ • LLM集成 │ │ • 工单系统 │ -│ • 备份管理 │ │ • 备份系统 │ │ • 车辆数据 │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ - │ - ▼ - ┌─────────────────┐ - │ 监控系统 │ - │ │ - │ • Prometheus │ - │ • Grafana │ - │ • Nginx代理 │ - └─────────────────┘ -``` - -## 🎯 核心功能 - -### 1. 智能对话 💬 -- **多轮对话**: 支持上下文关联的连续对话 -- **VIN识别**: 自动识别车辆VIN并获取实时数据 -- **知识库检索**: 智能匹配相关技术文档和解决方案 -- **工单创建**: 对话中直接创建和关联工单 -- **错误修复**: 解决了WebSocket连接TypeError问题 - -### 2. Agent管理 🤖 -- **工具管理**: 10+内置工具,支持自定义工具注册 -- **执行监控**: 实时监控Agent任务执行状态 -- **性能统计**: 工具使用频率和成功率分析 -- **智能规划**: 基于目标的任务分解和执行 -- **专用蓝图**: Agent相关API已独立为蓝图管理 - -### 3. 工单系统 📋 -- **AI建议**: 基于知识库生成工单处理建议 -- **人工审核**: 支持人工输入和AI建议对比 -- **相似度评估**: 自动计算AI与人工建议的相似度 -- **知识库更新**: 高相似度建议自动入库 -- **飞书AI提示词**: 针对飞书同步场景提供更详细的AI建议提示词 - -### 4. 知识库管理 📚 -- **多格式支持**: TXT、PDF、DOC、DOCX、MD文件 -- **智能提取**: 自动从文档中提取Q&A对 -- **向量化检索**: TF-IDF + 余弦相似度搜索 -- **质量验证**: 支持知识条目验证和置信度设置 - -### 5. 数据分析 -- **实时趋势**: 基于真实数据的性能趋势分析 -- **多维度统计**: 工单、预警、满意度等关键指标 -- **系统健康**: CPU、内存、响应时间监控 -- **可视化展示**: 丰富的图表和仪表板 -- **专用蓝图**: 数据分析API已独立为蓝图管理,并支持Excel报告导出 - -### 6. 系统设置 ⚙️ -- **API管理**: 支持多种LLM提供商配置 -- **模型参数**: 温度、最大令牌数等参数调节 -- **端口配置**: Web服务和WebSocket端口管理 -- **日志级别**: 灵活的日志级别控制 -- **数据库健壮性**: 优化了数据库连接配置和错误处理 - -### 7. 飞书集成 📱 -- **多维表格同步**: 自动同步飞书多维表格数据 -- **字段映射**: 智能映射飞书字段到本地数据库 -- **实时更新**: 支持增量同步和全量同步 -- **数据预览**: 同步前预览数据,确保准确性 -- **统一管理**: 飞书功能集成到主仪表板 - -## 🛠️ 技术栈 - -### 后端技术 -- **Python 3.11+**: 核心开发语言 -- **Flask 2.3+**: Web框架和API服务 -- **SQLAlchemy 2.0+**: ORM数据库操作 -- **WebSocket**: 实时通信支持 -- **psutil**: 系统资源监控 -- **Redis**: 缓存和会话管理 - -### 前端技术 -- **Bootstrap 5**: UI框架 -- **Chart.js**: 数据可视化 -- **JavaScript ES6+**: 前端逻辑 -- **WebSocket**: 实时通信客户端 - -### AI/ML技术 -- **大语言模型**: 支持OpenAI、通义千问等 -- **TF-IDF**: 文本向量化 -- **余弦相似度**: 语义相似度计算 -- **Agent框架**: 智能任务规划 -- **Transformers**: 预训练模型支持 - -### 部署运维 -- **Docker**: 容器化部署 -- **Docker Compose**: 多服务编排 -- **Nginx**: 反向代理和静态文件服务 -- **Prometheus**: 监控数据收集 -- **Grafana**: 监控仪表板 -- **MySQL 8.0**: 主数据库 -- **Redis 7**: 缓存服务 - -## 🚀 快速开始 - -### 环境要求 - -#### Docker部署(推荐) -- Docker 20.10+ -- Docker Compose 2.0+ -- 4GB+ 可用内存 -- 10GB+ 可用磁盘空间 - -#### 本地部署 -- Python 3.11+ -- Node.js 16+ (可选,用于前端构建) -- MySQL 8.0+ 或 SQLite -- Redis 7+ (可选) -- Git - -### 🐳 Docker部署(推荐) - -1. **克隆项目** -```bash -git clone http://jeason.online:3000/zhaojie/assist.git -cd assist -``` - -2. **一键启动所有服务** -```bash -# 使用部署脚本 -chmod +x scripts/docker_deploy.sh -./scripts/docker_deploy.sh start - -# 或直接使用docker-compose -docker-compose up -d -``` - -3. **访问系统** -- **TSP助手**: http://localhost:5000 -- **Nginx代理**: http://localhost -- **Prometheus监控**: http://localhost:9090 -- **Grafana仪表板**: http://localhost:3000 (admin/admin123456) - -4. **服务管理** -```bash -# 查看服务状态 -./scripts/docker_deploy.sh status - -# 查看日志 -./scripts/docker_deploy.sh logs tsp-assistant - -# 停止服务 -./scripts/docker_deploy.sh stop - -# 重启服务 -./scripts/docker_deploy.sh restart -``` - -### 💻 本地部署 - -1. **克隆项目** -```bash -git clone http://jeason.online:3000/zhaojie/assist.git -cd assist -``` - -2. **安装依赖** ```bash pip install -r requirements.txt -``` - -3. **初始化数据库** -```bash +cp .env.example .env # 编辑填入 LLM API Key、飞书凭证等 python init_database.py -``` - -4. **启动服务** -```bash python start_dashboard.py ``` -5. **访问系统** -- 打开浏览器访问: `http://localhost:5000` -- 默认端口: 5000 (可在系统设置中修改) +访问 http://localhost:5000,默认账号 `admin` / `admin123`。 -### Windows快速启动 -```cmd -# 双击运行 -快速启动.bat +## 项目结构 + +``` +src/ +├── config/ # 配置管理(unified_config + config_service) +├── core/ # 基础设施(数据库、LLM、缓存、认证) +├── dialogue/ # 对话管理(realtime_chat、message_pipeline) +├── knowledge_base/ # 知识库(搜索、导入、验证) +├── repositories/ # 数据访问层(自动 tenant_id 过滤) +├── analytics/ # 监控与分析(预警、Token、AI 成功率) +├── integrations/ # 外部集成(飞书客户端、工单同步) +├── agent/ # ReAct Agent(工具调度) +└── web/ # Web 层 + ├── app.py # Flask 应用 + ├── blueprints/ # API 蓝图(每个领域一个文件) + ├── service_manager.py + ├── static/js/ # 前端模块 + │ ├── dashboard.js # 核心 + │ └── modules/ # 功能模块 + └── templates/ # Jinja2 模板 ``` -## 📖 使用指南 +## 环境变量 -### 基础操作 +| 变量 | 说明 | 默认值 | +|------|------|--------| +| `SECRET_KEY` | Flask session 密钥 | 随机生成 | +| `LLM_BASE_URL` | LLM API 地址 | DashScope | +| `LLM_API_KEY` | LLM API 密钥 | - | +| `LLM_MODEL` | 模型名称 | qwen-plus-latest | +| `FEISHU_APP_ID` | 飞书应用 ID | - | +| `FEISHU_APP_SECRET` | 飞书应用密钥 | - | +| `REDIS_HOST` | Redis 地址 | localhost | +| `ADMIN_PASSWORD` | 默认管理员密码 | admin123 | -1. **智能对话** - - 在"智能对话"页面输入问题 - - 系统自动检索知识库并生成回答 - - 支持VIN码识别和车辆数据查询 - -2. **工单管理** - - 创建工单并获取AI建议 - - 人工输入解决方案 - - 系统自动评估相似度并更新知识库 - -3. **知识库维护** - - 手动添加Q&A对 - - 上传文档自动提取知识 - - 设置置信度和验证状态 - -4. **系统监控** - - 查看实时性能趋势 - - 监控系统健康状态 - - 管理预警和通知 - -### 高级功能 - -1. **Agent工具管理** - - 查看工具使用统计 - - 注册自定义工具 - - 监控执行历史 - -2. **数据分析** - - 多维度数据统计 - - 自定义时间范围 - - 导出分析报告 - -3. **系统配置** - - API和模型参数配置 - - 端口和日志级别设置 - - 环境变量管理 - -## 🔄 部署与更新 - -### 版本管理 -```bash -# 更新版本号 -python version.py increment --type minor - -# 添加变更日志 -python version.py changelog --message "新功能描述" - -# 创建发布标签 -python version.py tag --message "Release v1.3.0" -``` - -## 系统监控 - -### 健康检查 -- **API状态**: `/api/health` -- **服务监控**: 自动健康检查和故障恢复 -- **性能指标**: 响应时间、吞吐量、错误率 - -### 日志管理 -- **应用日志**: `logs/tsp_assistant.log` -- **访问日志**: Nginx访问日志 -- **错误追踪**: 详细的错误堆栈信息 - -## 🔧 配置说明 - -### Docker环境变量 -```bash -# 数据库配置 -DATABASE_URL=mysql+pymysql://tsp_user:tsp_password@mysql:3306/tsp_assistant?charset=utf8mb4 -REDIS_URL=redis://redis:6379/0 - -# LLM配置 -LLM_PROVIDER=openai -LLM_API_KEY=your_api_key -LLM_MODEL=gpt-3.5-turbo - -# 服务配置 -SERVER_PORT=5000 -WEBSOCKET_PORT=8765 -LOG_LEVEL=INFO -TZ=Asia/Shanghai -``` - -### Docker服务配置 - -#### 主要服务 -- **tsp-assistant**: 主应用服务 (端口: 5000, 8765) -- **mysql**: MySQL数据库 (端口: 3306) -- **redis**: Redis缓存 (端口: 6379) -- **nginx**: 反向代理 (端口: 80, 443) - -#### 监控服务 -- **prometheus**: 监控数据收集 (端口: 9090) -- **grafana**: 监控仪表板 (端口: 3000) - -#### 数据卷 -- `mysql_data`: MySQL数据持久化 -- `redis_data`: Redis数据持久化 -- `prometheus_data`: Prometheus数据持久化 -- `grafana_data`: Grafana配置和数据持久化 - -### 配置文件 -- `config/llm_config.py`: LLM客户端配置 -- `config/integrations_config.json`: 飞书集成配置 -- `nginx.conf`: Nginx反向代理配置 -- `monitoring/prometheus.yml`: Prometheus监控配置 -- `init.sql`: 数据库初始化脚本 -- `docker-compose.yml`: Docker服务编排配置 -- `Dockerfile`: 应用镜像构建配置 - -## 🤝 贡献指南 - -### 开发流程 -1. Fork项目到个人仓库 -2. 创建功能分支: `git checkout -b feature/new-feature` -3. 提交更改: `git commit -m "Add new feature"` -4. 推送分支: `git push origin feature/new-feature` -5. 创建Pull Request - -### 代码规范 -- Python代码遵循PEP 8规范 -- JavaScript使用ES6+语法 -- 提交信息使用约定式提交格式 -- 新功能需要添加相应的测试 - -## 📝 更新日志 - -### v2.1.0 (2025-12-08) - 全面架构优化与问题修复 -- ⚙️ **后端架构重构**: - - 将Agent、车辆数据、数据分析、API测试相关路由拆分为独立蓝图。 - - 精简 `app.py` 主应用文件,提升模块化和可维护性。 - - 引入统一错误处理装饰器和依赖注入机制。 -- 🎨 **前端架构优化**: - - 实现了JavaScript模块化架构,划分 `core`, `services`, `components` 目录。 - - 引入了统一状态管理 (`store.js`) 和API服务 (`api.js`)。 - - 优化了通知管理和预警显示组件。 -- 🛠️ **关键问题修复**: - - 修复了WebSocket连接中 `TypeError: missing 1 required positional argument: 'path'` 错误。 - - 改进了数据库连接的健壮性,优化MySQL连接池配置,并增强了异常处理和重连机制。 - - 解决了 `generator didn't stop` 错误,确保数据库会话的正确关闭。 - - 增强了预警系统异常处理,并在规则检查失败时生成系统预警。 - - 优化了API错误响应,包含更详细的错误信息。 -- ✨ **新功能增强**: - - 为飞书同步和实时对话场景引入了不同的LLM提示词,提升AI建议的针对性。 - - 增加了对`Analysising`工单状态的映射处理。 - -### v2.0.0 (2025-09-22) - Docker环境全面升级 -- 🐳 **Docker环境重构**: 升级到Python 3.11,优化镜像构建 -- 🐳 **多服务编排**: MySQL 8.0 + Redis 7 + Nginx + Prometheus + Grafana -- 🐳 **监控系统**: 集成Prometheus监控和Grafana仪表板 -- 🐳 **安全增强**: 非root用户运行,数据卷隔离 -- 🐳 **部署脚本**: 一键部署脚本,支持启动/停止/重启/清理 -- 🔧 **知识库搜索修复**: 简化搜索算法,提升检索准确率 -- 🔧 **批量删除优化**: 修复外键约束和缓存问题 -- 🔧 **日志编码修复**: 解决中文乱码问题 -- **可视化增强**: 修复预警、性能、满意度图表显示 -- 📚 **文档更新**: 完整的Docker部署和使用指南 - -### v1.4.0 (2025-09-19) -- 飞书集成功能:支持飞书多维表格数据同步 -- 页面功能合并:飞书同步页面合并到主仪表板 -- 数据库架构优化:扩展工单表字段,支持飞书数据 -- 代码重构优化:大文件拆分,降低运行风险 -- 字段映射完善:智能映射飞书字段到本地数据库 -- 数据库初始化改进:集成字段迁移到初始化流程 - -### v1.3.0 (2025-09-17) -- 数据库架构优化:MySQL主数据库+SQLite备份系统 -- 工单详情API修复:解决数据库会话管理问题 -- 备份管理系统:自动备份MySQL数据到SQLite -- 数据库状态监控:实时监控MySQL和SQLite状态 -- 备份管理API:支持数据备份和恢复操作 - -### v1.2.0 (2025-09-16) -- 系统设置扩展:API管理、模型参数配置、端口管理 -- 真实数据分析:修复性能趋势图表显示问题 -- 工单AI建议功能:智能生成处理建议 -- 知识库搜索优化:提升检索准确率 -- Agent管理改进:工具使用统计和自定义工具 - -### v1.1.0 (2025-09-16) -- 工单AI建议功能 -- 知识库搜索优化 -- Agent管理改进 - -### v1.0.0 (2024-01-01) -- 初始版本发布 - -## 📄 许可证 - -本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情 - -## 🔧 故障排除 - -### Docker部署问题 - -#### 常见问题 -1. **端口冲突** -```bash -# 检查端口占用 -netstat -tulpn | grep :5000 -# 修改docker-compose.yml中的端口映射 -``` - -2. **内存不足** -```bash -# 检查Docker资源使用 -docker stats -# 增加Docker内存限制或关闭其他服务 -``` - -3. **数据库连接失败** -```bash -# 检查MySQL服务状态 -docker-compose logs mysql -# 等待数据库完全启动(约30秒) -``` - -4. **权限问题** -```bash -# 给脚本添加执行权限 -chmod +x scripts/docker_deploy.sh -# 检查文件权限 -ls -la scripts/ -``` - -#### 日志查看 -```bash -# 查看所有服务日志 -docker-compose logs -f - -# 查看特定服务日志 -docker-compose logs -f tsp-assistant -docker-compose logs -f mysql -docker-compose logs -f redis -``` - -#### 服务重启 -```bash -# 重启特定服务 -docker-compose restart tsp-assistant - -# 重启所有服务 -docker-compose down && docker-compose up -d -``` - -### 性能优化 - -#### Docker资源限制 -```yaml -# 在docker-compose.yml中添加资源限制 -services: - tsp-assistant: - deploy: - resources: - limits: - memory: 2G - cpus: '1.0' -``` - -#### 数据库优化 -```sql --- MySQL性能优化 -SET GLOBAL innodb_buffer_pool_size = 1G; -SET GLOBAL max_connections = 200; -``` - -## 📞 支持与联系 - -- **项目地址**: http://jeason.online:3000/zhaojie/assist -- **问题反馈**: 请在Issues中提交问题 -- **功能建议**: 欢迎提交Feature Request -- **Docker问题**: 请提供docker-compose logs输出 - -## 🙏 致谢 - -感谢所有为项目做出贡献的开发者和用户! - ---- - -**TSP智能助手** - 让车辆服务更智能,让客户体验更美好! 🚗✨ +完整变量列表见 `.env.example`。 diff --git a/src/config/config_service.py b/src/config/config_service.py new file mode 100644 index 0000000..1e9531c --- /dev/null +++ b/src/config/config_service.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +""" +统一配置服务 +优先级:环境变量 > system_settings.json > 代码默认值 +""" +import os +import json +import logging +from typing import Any + +logger = logging.getLogger(__name__) +_SETTINGS_PATH = os.path.join('data', 'system_settings.json') + + +class ConfigService: + def __init__(self): + self._file_cache = None + self._file_mtime = 0 + + def _load_file(self) -> dict: + try: + if os.path.exists(_SETTINGS_PATH): + mtime = os.path.getmtime(_SETTINGS_PATH) + if mtime != self._file_mtime or self._file_cache is None: + with open(_SETTINGS_PATH, 'r', encoding='utf-8') as f: + self._file_cache = json.load(f) + self._file_mtime = mtime + return self._file_cache or {} + except Exception as e: + logger.debug(f"加载配置文件失败: {e}") + return {} + + def get(self, key: str, default: Any = None) -> Any: + env_key = key.upper().replace('.', '_') + env_val = os.environ.get(env_key) + if env_val is not None: + return self._cast(env_val, default) + settings = self._load_file() + parts = key.split('.') + val = settings + for part in parts: + if isinstance(val, dict): + val = val.get(part) + else: + return default + return val if val is not None else default + + def get_section(self, section: str) -> dict: + return self._load_file().get(section, {}) + + def set(self, key: str, value: Any): + settings = self._load_file() + parts = key.split('.') + target = settings + for part in parts[:-1]: + target = target.setdefault(part, {}) + target[parts[-1]] = value + os.makedirs('data', exist_ok=True) + with open(_SETTINGS_PATH, 'w', encoding='utf-8') as f: + json.dump(settings, f, ensure_ascii=False, indent=2) + self._file_cache = settings + + @staticmethod + def _cast(value: str, default: Any) -> Any: + if default is None: return value + if isinstance(default, bool): return value.lower() in ('true', '1', 'yes') + if isinstance(default, int): + try: return int(value) + except: return default + if isinstance(default, float): + try: return float(value) + except: return default + return value + + +config_service = ConfigService() diff --git a/src/core/auth_manager.py b/src/core/auth_manager.py index 9c21f6f..fdec479 100644 --- a/src/core/auth_manager.py +++ b/src/core/auth_manager.py @@ -18,16 +18,19 @@ class AuthManager: """认证管理器""" def __init__(self): - self.secret_key = "your-secret-key-change-this-in-production" # 应该从配置中读取 + import os + self.secret_key = os.environ.get('SECRET_KEY', 'change-this-in-production') self.token_expiry = timedelta(hours=24) def hash_password(self, password: str) -> str: - """密码哈希""" - return hashlib.sha256(password.encode()).hexdigest() + import bcrypt + return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode() def verify_password(self, password: str, password_hash: str) -> bool: - """验证密码""" - return self.hash_password(password) == password_hash + import bcrypt + if password_hash and password_hash.startswith('$2b$'): + return bcrypt.checkpw(password.encode(), password_hash.encode()) + return hashlib.sha256(password.encode()).hexdigest() == password_hash def generate_token(self, user_data: dict) -> str: """生成JWT token""" diff --git a/src/core/models.py b/src/core/models.py index e38d776..6816d0a 100644 --- a/src/core/models.py +++ b/src/core/models.py @@ -294,12 +294,19 @@ class User(Base): last_login = Column(DateTime) def set_password(self, password): - """设置密码哈希""" - self.password_hash = hashlib.sha256(password.encode()).hexdigest() + """设置密码哈希(bcrypt)""" + import bcrypt + self.password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode() def check_password(self, password): - """验证密码""" - return self.password_hash == hashlib.sha256(password.encode()).hexdigest() + """验证密码(兼容旧 SHA-256,验证通过后自动升级为 bcrypt)""" + import bcrypt + if self.password_hash and self.password_hash.startswith('$2b$'): + return bcrypt.checkpw(password.encode(), self.password_hash.encode()) + if self.password_hash == hashlib.sha256(password.encode()).hexdigest(): + self.set_password(password) + return True + return False def to_dict(self): """转换为字典格式(用于API响应)""" diff --git a/src/web/blueprints/monitoring.py b/src/web/blueprints/monitoring.py index 6e3c8b6..18a17cd 100644 --- a/src/web/blueprints/monitoring.py +++ b/src/web/blueprints/monitoring.py @@ -496,8 +496,8 @@ def get_error_detail(conv_id): 'assistant_response': conv.assistant_response, 'confidence_score': conv.confidence_score, 'response_time': conv.response_time, - 'category': conv.category, - 'source': conv.source, + 'session_id': conv.session_id, + 'invocation_method': conv.invocation_method, } }) except Exception as e: diff --git a/src/web/static/js/dashboard.js b/src/web/static/js/dashboard.js index 07ad26e..5d70a2c 100644 --- a/src/web/static/js/dashboard.js +++ b/src/web/static/js/dashboard.js @@ -69,6 +69,8 @@ function updatePageLanguage(lang) { class TSPDashboard { constructor() { + // ===== 事件总线 ===== + this._eventHandlers = {}; // ===== 共享状态(所有模块通过 this.xxx 访问)===== // 导航 this.currentTab = 'dashboard'; @@ -116,6 +118,11 @@ class TSPDashboard { updatePageLanguage(this.currentLanguage); } + // ===== 事件总线 ===== + on(event, handler) { (this._eventHandlers[event] = this._eventHandlers[event] || []).push(handler); } + off(event, handler) { const h = this._eventHandlers[event]; if (h) this._eventHandlers[event] = h.filter(fn => fn !== handler); } + emit(event, data) { (this._eventHandlers[event] || []).forEach(fn => { try { fn(data); } catch (e) { console.error(`Event ${event} error:`, e); } }); } + async applyModulePermissions() { try { const resp = await fetch('/api/settings');