Compare commits

27 Commits

Author SHA1 Message Date
540df49331 Merge pull request 'sit' (#1) from sit into test
Reviewed-on: #1
2025-12-24 13:09:35 +08:00
e3c68b5133 Update config, core models, and web app; refresh Python 3.11 cache
This commit includes general updates to application configuration, core data models, and various web application components (knowledge base, error handling, static assets, and websocket server). It also refreshes the Python 3.11 bytecode cache, likely due to underlying code changes and environment alignment.
2025-12-12 13:39:43 +08:00
2026007045 refactor: 移除冗余文件并优化代码结构
- 删除多个不再使用的脚本和配置文件,包括 `auto_push.bat`, `check_and_fix_users.py`, `init.sql` 等。
- 新增 `git_push.bat` 和 `git_push.sh` 脚本以简化 Git 推送流程。
- 更新 `README.md` 以反映最新的功能和结构变化。
- 优化前端代码,添加新的页面和组件,提升用户体验。

此提交旨在清理项目结构并增强代码可维护性。
2025-12-08 00:53:23 +08:00
65d69358d7 revert 96e1cc4e70
revert docs: Update README with AI accuracy optimization and modular architecture features
2025-12-07 14:50:52 +08:00
4e5ece0829 revert e81e6bdc4e
revert 更新 README.md
2025-12-07 14:47:59 +08:00
13ff67a4f5 revert 96e1cc4e70
revert docs: Update README with AI accuracy optimization and modular architecture features
2025-12-07 14:44:00 +08:00
Jeason
20c5ce355a fix: 修复前端导航和页面跳转问题
- 添加统一的导航菜单到所有页面
- 修复页面路由映射和高亮状态
- 创建 navigation.js 统一管理页面跳转
- 添加 test_navigation.py 路由测试工具
- 支持仪表板、预警管理、智能对话、HTTP对话页面间无缝切换

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-07 10:12:17 +08:00
96e1cc4e70 docs: Update README with AI accuracy optimization and modular architecture features 2025-11-05 15:23:23 +08:00
148a2fc9d6 feat:测试验证 2025-11-05 10:43:36 +08:00
赵杰 Jie Zhao (雄狮汽车科技)
c9d5c80f42 feat: 娣诲姞澶氫釜鏂板姛鑳藉拰淇 - 鍖呮嫭鐢ㄦ埛绠$悊銆佹暟鎹簱杩佺Щ銆丟it鎺ㄩ€佸伐鍏风瓑 2025-11-05 10:16:34 +08:00
赵杰 Jie Zhao (雄狮汽车科技)
a4261ef06f feat: optimize AI suggestion and workorder sync - support same-day multiple update numbering - insert new suggestions at top maintaining reverse chronological order - reference process history when generating suggestions - simplify prompts to avoid forcing log analysis - fix Chinese comment encoding issues 2025-10-27 10:34:33 +08:00
赵杰
18d59b71cb feat: 快速提交 - 周三 2025/10/08 10:49:52.83 2025-10-08 10:49:55 +01:00
e81e6bdc4e 更新 README.md 2025-09-25 21:53:27 +08:00
赵杰
95501736ec 优化推送脚本 2025-09-23 15:37:59 +01:00
赵杰
63600d1bc2 feat: 自动提交 - 周二 2025/09/23 15:32:55.51 2025-09-23 15:32:55 +01:00
赵杰
6b0c03439f feat: 自动提交 - 周二 2025/09/23 14:03:10.47 2025-09-23 14:03:10 +01:00
赵杰
4da97d600a 优化界面布局,参考CRM系统,调整字体,优化分页显示 2025-09-22 17:06:43 +01:00
赵杰
eff24947e0 feat: 自动提交 - 周一 2025/09/22 16:50:40.70 2025-09-22 16:50:40 +01:00
赵杰
1e4376ba56 添加docker部署方式,优化目前项目结构,更新了readme文件 2025-09-22 16:36:50 +01:00
赵杰
d6c88d87dd feat: 自动提交 - 周一 2025/09/22 16:28:00.19 2025-09-22 16:28:00 +01:00
赵杰
f75176ec69 feat: 自动提交 - 周一 2025/09/22 15:18:57.75 2025-09-22 15:18:57 +01:00
赵杰
b635c9e7d4 feat: 自动提交 - 周一 2025/09/22 15:12:38.91 2025-09-22 15:12:38 +01:00
赵杰
9306e7a401 feat: 自动提交 - 周一 2025/09/22 14:48:02.54 2025-09-22 14:48:02 +01:00
赵杰
1f55f65fa0 feat: 自动提交 - 周一 2025/09/22 14:40:25.43 2025-09-22 14:40:25 +01:00
赵杰
070422cd06 减少不必要模块,增加中英文切换 2025-09-22 13:55:29 +01:00
赵杰
87552148fd feat: 自动提交 - 周一 2025/09/22 13:30:40.76 2025-09-22 13:30:40 +01:00
赵杰 Jie Zhao (雄狮汽车科技)
54a13531c4 feat: 快速提交 - 周一 2025/09/22 13:29:14.32 2025-09-22 13:29:14 +01:00
262 changed files with 24232 additions and 9123 deletions

View File

@@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"Bash(curl:*)"
],
"deny": [],
"ask": []
}
}

57
.editorconfig Normal file
View File

@@ -0,0 +1,57 @@
# EditorConfig is awesome: https://EditorConfig.org
# 顶级配置文件
root = true
# 所有文件
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
# Python 文件
[*.py]
charset = utf-8
indent_style = space
indent_size = 4
# JSON 文件
[*.json]
charset = utf-8
indent_style = space
indent_size = 2
# Markdown 文件
[*.md]
charset = utf-8
trim_trailing_whitespace = false
# YAML 文件
[*.{yml,yaml}]
charset = utf-8
indent_style = space
indent_size = 2
# JavaScript/TypeScript 文件
[*.{js,ts,jsx,tsx}]
charset = utf-8
indent_style = space
indent_size = 2
# HTML/CSS 文件
[*.{html,css}]
charset = utf-8
indent_style = space
indent_size = 2
# Batch 文件 (Windows)
[*.bat]
charset = utf-8
end_of_line = crlf
# Shell 脚本
[*.sh]
charset = utf-8
end_of_line = lf

107
.gitignore vendored
View File

@@ -1,107 +0,0 @@
# 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

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

12
.idea/dataSources.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="@43.134.68.207" uuid="715b070d-f258-43df-a066-49e825a9b04f">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://43.134.68.207:3306</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

6
.idea/data_source_mapping.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourcePerFileMappings">
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/715b070d-f258-43df-a066-49e825a9b04f/console.sql" value="715b070d-f258-43df-a066-49e825a9b04f" />
</component>
</project>

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.11 (tsp-assistant)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (tsp-assistant)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/tsp-assistant.iml" filepath="$PROJECT_DIR$/.idea/tsp-assistant.iml" />
</modules>
</component>
</project>

14
.idea/tsp-assistant.iml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.11 (tsp-assistant)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

26
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,26 @@
{
"files.autoGuessEncoding": false,
"files.encoding": "utf8",
"files.eol": "\n",
"[python]": {
"files.encoding": "utf8",
"files.eol": "\n"
},
"[json]": {
"files.encoding": "utf8"
},
"[javascript]": {
"files.encoding": "utf8"
},
"[html]": {
"files.encoding": "utf8"
},
"[css]": {
"files.encoding": "utf8"
},
"[markdown]": {
"files.encoding": "utf8"
},
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/Scripts/python.exe",
"Codegeex.RepoIndex": true
}

View File

@@ -1,218 +0,0 @@
# AI建议权限问题最终解决方案
## 🔍 问题确认
通过深度诊断工具确认:
-**访问令牌获取正常**tenant_access_token获取成功
-**表格访问正常**:可以成功访问表格和字段信息
-**记录读取正常**:可以成功读取表格记录
-**AI建议字段存在**:确认表格中有"AI建议"字段
-**记录写入失败**403 Forbidden权限不足
**根本原因**:飞书应用缺少**记录写入权限**
## 🛠️ 最终解决方案
### 步骤1飞书开放平台权限配置
#### 1.1 登录飞书开放平台
1. 访问https://open.feishu.cn/
2. 使用管理员账号登录
3. 进入"应用管理" → "我的应用"
#### 1.2 找到您的应用
- 应用ID`cli_a8b50ec0eed1500d`
- 应用名称您的TSP智能助手应用
#### 1.3 添加必需权限
在"权限管理"页面,确保应用具有以下权限:
**核心权限**
```
bitable:app # 多维表格应用权限
bitable:app:readonly # 多维表格只读权限
bitable:app:readwrite # 多维表格读写权限 ⭐ 关键权限
base:record:write # 记录写入权限 ⭐ 关键权限
```
#### 1.4 重新发布应用
- 权限修改后,点击"发布"或"上线"
- 等待权限生效通常需要1-5分钟
### 步骤2飞书多维表格协作者权限
#### 2.1 打开飞书多维表格
- 使用浏览器打开您的飞书多维表格
- 确保您有表格的管理权限
#### 2.2 添加应用为协作者
1. 点击表格右上角的"分享"按钮
2. 点击"添加协作者"
3. 搜索您的飞书应用名称或应用ID
4. 将应用添加为协作者
#### 2.3 设置协作者权限
**重要**:将权限设置为以下之一:
- **编辑者** ✅ (推荐)
- **管理员** ✅ (完全权限)
**不要设置为**
- **查看者** ❌ (只能读取,无法写入)
### 步骤3验证修复结果
#### 3.1 使用Web界面验证
1. 打开TSP智能助手主页面
2. 点击"飞书同步"标签页
3. 点击"权限检查"按钮
4. 查看检查结果
#### 3.2 测试AI建议功能
1. 点击"同步+AI建议"按钮
2. 查看是否还有403错误
3. 检查飞书表格中是否出现AI建议
## 📋 详细修复步骤
### 🔧 飞书开放平台操作
1. **登录飞书开放平台**
```
URL: https://open.feishu.cn/
账号: 管理员账号
```
2. **进入应用管理**
```
路径: 应用管理 → 我的应用
应用ID: cli_a8b50ec0eed1500d
```
3. **权限配置**
```
页面: 权限管理
操作: 添加权限
权限列表:
- bitable:app
- bitable:app:readonly
- bitable:app:readwrite ⭐
- base:record:write ⭐
```
4. **发布应用**
```
操作: 点击"发布"按钮
等待: 1-5分钟权限生效
```
### 🔧 飞书多维表格操作
1. **打开表格**
```
方式: 浏览器访问飞书多维表格
权限: 确保有管理权限
```
2. **添加协作者**
```
操作: 点击右上角"分享"按钮
步骤: 添加协作者 → 搜索应用名称
应用: 您的TSP智能助手应用
```
3. **设置权限**
```
权限级别: 编辑者 或 管理员
不要选择: 查看者
保存: 确认设置
```
## 🚨 常见问题解决
### 问题1找不到权限设置
**解决方案**
- 确保使用管理员账号登录飞书开放平台
- 检查应用是否已发布
- 联系飞书技术支持
### 问题2权限添加后仍然失败
**解决方案**
- 等待5-10分钟让权限生效
- 重新发布应用
- 清除浏览器缓存后重试
### 问题3找不到应用名称
**解决方案**
- 使用应用ID`cli_a8b50ec0eed1500d`
- 在飞书开放平台搜索应用ID
- 确认应用状态为"已发布"
### 问题4表格分享设置找不到
**解决方案**
- 确保您有表格的管理权限
- 使用表格创建者账号
- 联系表格管理员协助设置
## 📊 权限配置检查清单
### ✅ 飞书开放平台
- [ ] 应用已启用并发布
- [ ] 已添加`bitable:app`权限
- [ ] 已添加`bitable:app:readonly`权限
- [ ] 已添加`bitable:app:readwrite`权限 ⭐
- [ ] 已添加`base:record:write`权限 ⭐
- [ ] 权限修改后已重新发布
### ✅ 飞书多维表格
- [ ] 应用已添加为表格协作者
- [ ] 协作者权限设置为"编辑者"或"管理员"
- [ ] 表格未被锁定或设置为只读
- [ ] "AI建议"字段存在且类型正确
## 🎯 验证成功标志
修复成功后,您应该看到:
1. **权限检查通过**
```
✅ 访问令牌获取成功
✅ 表格访问权限正常
✅ 记录读取权限正常
✅ 记录写入权限正常
✅ AI建议字段存在
```
2. **AI建议功能正常**
```
- 点击"同步+AI建议"无403错误
- 飞书表格中出现AI建议内容
- 日志显示"更新飞书AI建议成功"
```
3. **系统日志正常**
```
2025-09-22 XX:XX:XX - INFO - 更新飞书AI建议成功
2025-09-22 XX:XX:XX - INFO - 飞书同步完成
```
## 📞 技术支持
如果按照以上步骤仍然无法解决问题,请:
1. **收集信息**
- 飞书应用ID`cli_a8b50ec0eed1500d`
- 表格ID`tblnl3vJPpgMTSiP`
- 完整的错误日志
- 权限检查结果截图
2. **联系支持**
- 飞书开放平台技术支持
- TSP智能助手技术支持
3. **检查企业设置**
- 确认是否有企业级权限限制
- 联系企业飞书管理员
---
**重要提醒**403权限错误通常需要飞书管理员权限才能解决建议联系相关技术人员协助配置。修复完成后AI建议功能将可以正常工作🎉

View File

@@ -1,42 +0,0 @@
# TSP智能助手Docker镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 设置环境变量
ENV PYTHONPATH=/app
ENV PYTHONUNBUFFERED=1
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
g++ \
git \
curl \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 创建必要目录
RUN mkdir -p logs data backups
# 设置权限
RUN chmod +x scripts/deploy.sh
# 暴露端口
EXPOSE 5000
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:5000/api/health || exit 1
# 启动命令
CMD ["python", "start_dashboard.py"]

241
README.md
View File

@@ -1,7 +1,8 @@
# TSP智能助手 (TSP Assistant) # TSP智能助手 (TSP Assistant)
[![Version](https://img.shields.io/badge/version-1.3.0-blue.svg)](version.json) [![Version](https://img.shields.io/badge/version-2.1.0-blue.svg)](version.json)
[![Python](https://img.shields.io/badge/python-3.8+-green.svg)](requirements.txt) [![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) [![License](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE)
[![Status](https://img.shields.io/badge/status-production-ready-brightgreen.svg)]() [![Status](https://img.shields.io/badge/status-production-ready-brightgreen.svg)]()
@@ -14,19 +15,22 @@
- **智能规划**: 基于目标驱动的任务规划和执行 - **智能规划**: 基于目标驱动的任务规划和执行
- **自主学习**: 从用户反馈中持续优化响应质量 - **自主学习**: 从用户反馈中持续优化响应质量
- **实时监控**: 主动监控系统状态和异常情况 - **实时监控**: 主动监控系统状态和异常情况
- **模块化重构**: 代码优化,降低运行风险,提升维护 - **模块化重构**: 后端服务Agent, 车辆数据, 分析, 测试)蓝图化,提高可维护性和扩展
- **前端模块化**: 引入ES6模块化架构优化UI组件、状态管理和API服务
### 💬 智能对话系统 ### 💬 智能对话系统
- **实时通信**: WebSocket支持毫秒级响应 - **实时通信**: WebSocket支持毫秒级响应,已修复连接稳定性问题
- **上下文理解**: 多轮对话记忆和上下文关联 - **上下文理解**: 多轮对话记忆和上下文关联
- **VIN识别**: 自动识别车辆VIN码并获取实时数据 - **VIN识别**: 自动识别车辆VIN码并获取实时数据
- **知识库集成**: 基于TF-IDF和余弦相似度的智能检索 - **知识库集成**: 基于TF-IDF和余弦相似度的智能检索
- **自定义提示词**: 支持飞书同步和实时对话不同场景的LLM提示词
### 📊 数据驱动分析 ### 📊 数据驱动分析
- **真实数据**: 基于数据库的真实性能趋势分析 - **真实数据**: 基于数据库的真实性能趋势分析
- **多维度统计**: 工单、预警、满意度、性能指标 - **多维度统计**: 工单、预警、满意度、性能指标
- **可视化展示**: Chart.js图表直观的数据呈现 - **可视化展示**: Chart.js图表直观的数据呈现
- **系统监控**: 实时CPU、内存、健康状态监控 - **系统监控**: 实时CPU、内存、健康状态监控
- **专属蓝图**: 独立的数据分析API模块提供专业数据报告导出
### 🔧 企业级管理 ### 🔧 企业级管理
- **多环境部署**: 开发、测试、生产环境隔离 - **多环境部署**: 开发、测试、生产环境隔离
@@ -34,6 +38,7 @@
- **热更新**: 支持前端文件热更新,无需重启服务 - **热更新**: 支持前端文件热更新,无需重启服务
- **自动备份**: 更新前自动备份,支持一键回滚 - **自动备份**: 更新前自动备份,支持一键回滚
- **飞书集成**: 支持飞书多维表格数据同步和管理 - **飞书集成**: 支持飞书多维表格数据同步和管理
- **统一错误处理**: 后端API统一异常处理提高系统健壮性
## 🏗️ 系统架构 ## 🏗️ 系统架构
@@ -42,11 +47,20 @@
│ 前端界面 │ │ 后端服务 │ │ 数据存储 │ │ 前端界面 │ │ 后端服务 │ │ 数据存储 │
│ │ │ │ │ │ │ │ │ │ │ │
│ • 仪表板 │◄──►│ • Flask API │◄──►│ • MySQL DB │ │ • 仪表板 │◄──►│ • Flask API │◄──►│ • MySQL DB │
│ • 智能对话 │ │ • WebSocket │ │ • 知识库 │ • 智能对话 │ │ • WebSocket │ │ • Redis缓存
│ • Agent管理 │ │ • Agent核心 │ │ • 工单系统 │ • Agent管理 │ │ • Agent核心 │ │ • 知识库
│ • 数据分析 │ │ • LLM集成 │ │ • 车辆数据 │ • 数据分析 │ │ • LLM集成 │ │ • 工单系统
│ • 备份管理 │ │ • 备份系统 │ │ • SQLite备份 │ • 备份管理 │ │ • 备份系统 │ │ • 车辆数据
└─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
┌─────────────────┐
│ 监控系统 │
│ │
│ • Prometheus │
│ • Grafana │
│ • Nginx代理 │
└─────────────────┘
``` ```
## 🎯 核心功能 ## 🎯 核心功能
@@ -56,18 +70,21 @@
- **VIN识别**: 自动识别车辆VIN并获取实时数据 - **VIN识别**: 自动识别车辆VIN并获取实时数据
- **知识库检索**: 智能匹配相关技术文档和解决方案 - **知识库检索**: 智能匹配相关技术文档和解决方案
- **工单创建**: 对话中直接创建和关联工单 - **工单创建**: 对话中直接创建和关联工单
- **错误修复**: 解决了WebSocket连接TypeError问题
### 2. Agent管理 🤖 ### 2. Agent管理 🤖
- **工具管理**: 10+内置工具,支持自定义工具注册 - **工具管理**: 10+内置工具,支持自定义工具注册
- **执行监控**: 实时监控Agent任务执行状态 - **执行监控**: 实时监控Agent任务执行状态
- **性能统计**: 工具使用频率和成功率分析 - **性能统计**: 工具使用频率和成功率分析
- **智能规划**: 基于目标的任务分解和执行 - **智能规划**: 基于目标的任务分解和执行
- **专用蓝图**: Agent相关API已独立为蓝图管理
### 3. 工单系统 📋 ### 3. 工单系统 📋
- **AI建议**: 基于知识库生成工单处理建议 - **AI建议**: 基于知识库生成工单处理建议
- **人工审核**: 支持人工输入和AI建议对比 - **人工审核**: 支持人工输入和AI建议对比
- **相似度评估**: 自动计算AI与人工建议的相似度 - **相似度评估**: 自动计算AI与人工建议的相似度
- **知识库更新**: 高相似度建议自动入库 - **知识库更新**: 高相似度建议自动入库
- **飞书AI提示词**: 针对飞书同步场景提供更详细的AI建议提示词
### 4. 知识库管理 📚 ### 4. 知识库管理 📚
- **多格式支持**: TXT、PDF、DOC、DOCX、MD文件 - **多格式支持**: TXT、PDF、DOC、DOCX、MD文件
@@ -80,12 +97,14 @@
- **多维度统计**: 工单、预警、满意度等关键指标 - **多维度统计**: 工单、预警、满意度等关键指标
- **系统健康**: CPU、内存、响应时间监控 - **系统健康**: CPU、内存、响应时间监控
- **可视化展示**: 丰富的图表和仪表板 - **可视化展示**: 丰富的图表和仪表板
- **专用蓝图**: 数据分析API已独立为蓝图管理并支持Excel报告导出
### 6. 系统设置 ⚙️ ### 6. 系统设置 ⚙️
- **API管理**: 支持多种LLM提供商配置 - **API管理**: 支持多种LLM提供商配置
- **模型参数**: 温度、最大令牌数等参数调节 - **模型参数**: 温度、最大令牌数等参数调节
- **端口配置**: Web服务和WebSocket端口管理 - **端口配置**: Web服务和WebSocket端口管理
- **日志级别**: 灵活的日志级别控制 - **日志级别**: 灵活的日志级别控制
- **数据库健壮性**: 优化了数据库连接配置和错误处理
### 7. 飞书集成 📱 ### 7. 飞书集成 📱
- **多维表格同步**: 自动同步飞书多维表格数据 - **多维表格同步**: 自动同步飞书多维表格数据
@@ -97,11 +116,12 @@
## 🛠️ 技术栈 ## 🛠️ 技术栈
### 后端技术 ### 后端技术
- **Python 3.8+**: 核心开发语言 - **Python 3.11+**: 核心开发语言
- **Flask**: Web框架和API服务 - **Flask 2.3+**: Web框架和API服务
- **SQLAlchemy**: ORM数据库操作 - **SQLAlchemy 2.0+**: ORM数据库操作
- **WebSocket**: 实时通信支持 - **WebSocket**: 实时通信支持
- **psutil**: 系统资源监控 - **psutil**: 系统资源监控
- **Redis**: 缓存和会话管理
### 前端技术 ### 前端技术
- **Bootstrap 5**: UI框架 - **Bootstrap 5**: UI框架
@@ -114,21 +134,74 @@
- **TF-IDF**: 文本向量化 - **TF-IDF**: 文本向量化
- **余弦相似度**: 语义相似度计算 - **余弦相似度**: 语义相似度计算
- **Agent框架**: 智能任务规划 - **Agent框架**: 智能任务规划
- **Transformers**: 预训练模型支持
### 部署运维 ### 部署运维
- **Docker**: 容器化部署 - **Docker**: 容器化部署
- **Docker Compose**: 多服务编排
- **Nginx**: 反向代理和静态文件服务 - **Nginx**: 反向代理和静态文件服务
- **Systemd**: 服务管理 - **Prometheus**: 监控数据收集
- **Git**: 版本控制 - **Grafana**: 监控仪表板
- **MySQL 8.0**: 主数据库
- **Redis 7**: 缓存服务
## 🚀 快速开始 ## 🚀 快速开始
### 环境要求 ### 环境要求
- Python 3.8+
#### Docker部署推荐
- Docker 20.10+
- Docker Compose 2.0+
- 4GB+ 可用内存
- 10GB+ 可用磁盘空间
#### 本地部署
- Python 3.11+
- Node.js 16+ (可选,用于前端构建) - Node.js 16+ (可选,用于前端构建)
- MySQL 8.0+ 或 SQLite
- Redis 7+ (可选)
- Git - 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. **克隆项目** 1. **克隆项目**
```bash ```bash
@@ -251,10 +324,11 @@ python scripts/update_manager.py auto-update --source ./new_version --environmen
## 🔧 配置说明 ## 🔧 配置说明
### 环境变量 ### Docker环境变量
```bash ```bash
# 数据库配置 # 数据库配置
DATABASE_URL=sqlite:///tsp_assistant.db DATABASE_URL=mysql+pymysql://tsp_user:tsp_password@mysql:3306/tsp_assistant?charset=utf8mb4
REDIS_URL=redis://redis:6379/0
# LLM配置 # LLM配置
LLM_PROVIDER=openai LLM_PROVIDER=openai
@@ -265,13 +339,35 @@ LLM_MODEL=gpt-3.5-turbo
SERVER_PORT=5000 SERVER_PORT=5000
WEBSOCKET_PORT=8765 WEBSOCKET_PORT=8765
LOG_LEVEL=INFO 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/llm_config.py`: LLM客户端配置
- `config/integrations_config.json`: 飞书集成配置 - `config/integrations_config.json`: 飞书集成配置
- `update_config.json`: 更新管理器配置 - `nginx.conf`: Nginx反向代理配置
- `version.json`: 版本信息配置 - `monitoring/prometheus.yml`: Prometheus监控配置
- `init.sql`: 数据库初始化脚本
- `docker-compose.yml`: Docker服务编排配置
- `Dockerfile`: 应用镜像构建配置
## 🤝 贡献指南 ## 🤝 贡献指南
@@ -290,6 +386,37 @@ LOG_LEVEL=INFO
## 📝 更新日志 ## 📝 更新日志
### 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.4.0 (2025-09-19)
- ✅ 飞书集成功能:支持飞书多维表格数据同步 - ✅ 飞书集成功能:支持飞书多维表格数据同步
- ✅ 页面功能合并:飞书同步页面合并到主仪表板 - ✅ 页面功能合并:飞书同步页面合并到主仪表板
@@ -324,11 +451,87 @@ LOG_LEVEL=INFO
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情 本项目采用 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 - **项目地址**: http://jeason.online:3000/zhaojie/assist
- **问题反馈**: 请在Issues中提交问题 - **问题反馈**: 请在Issues中提交问题
- **功能建议**: 欢迎提交Feature Request - **功能建议**: 欢迎提交Feature Request
- **Docker问题**: 请提供docker-compose logs输出
## 🙏 致谢 ## 🙏 致谢

View File

@@ -1,524 +0,0 @@
# TSP智能助手完整文档
## 📋 目录
- [项目概述](#项目概述)
- [系统架构](#系统架构)
- [核心功能](#核心功能)
- [技术栈](#技术栈)
- [安装部署](#安装部署)
- [配置说明](#配置说明)
- [使用指南](#使用指南)
- [API接口](#api接口)
- [数据库设计](#数据库设计)
- [开发指南](#开发指南)
- [故障排除](#故障排除)
- [更新日志](#更新日志)
---
## 🚀 项目概述
TSP智能助手是一个基于大语言模型的智能客服系统专为TSPTelematics Service Provider车辆服务提供商设计。系统集成了智能对话、工单管理、知识库、数据分析、飞书集成等核心功能。
### 核心特性
- **智能Agent架构**: 多工具集成,智能规划,自主学习
- **实时对话系统**: WebSocket支持上下文理解VIN识别
- **数据驱动分析**: 真实数据统计,可视化展示,系统监控
- **企业级管理**: 多环境部署,版本控制,热更新,自动备份
- **飞书集成**: 支持飞书多维表格数据同步和管理
- **AI准确率优化**: 智能判断AI建议质量优先使用高质量内容入库
---
## 🏗️ 系统架构
### 整体架构
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 前端界面 │ │ 后端服务 │ │ 数据存储 │
│ │ │ │ │ │
│ • 仪表板 │◄──►│ • Flask API │◄──►│ • MySQL DB │
│ • 智能对话 │ │ • WebSocket │ │ • 知识库 │
│ • Agent管理 │ │ • Agent核心 │ │ • 工单系统 │
│ • 数据分析 │ │ • LLM集成 │ │ • 车辆数据 │
│ • 飞书同步 │ │ • 备份系统 │ │ • SQLite备份 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
### 模块化设计
- **Web层**: Flask蓝图架构模块化API设计
- **业务层**: Agent核心、对话管理、工单处理
- **数据层**: MySQL主库 + SQLite备份ORM映射
- **集成层**: 飞书API、LLM服务、监控系统
---
## 🎯 核心功能
### 1. 智能对话系统 💬
- **多轮对话**: 支持上下文关联的连续对话
- **VIN识别**: 自动识别车辆VIN并获取实时数据
- **知识库检索**: 基于TF-IDF和余弦相似度的智能检索
- **工单创建**: 对话中直接创建和关联工单
### 2. Agent管理系统 🤖
- **工具管理**: 10+内置工具,支持自定义工具注册
- **执行监控**: 实时监控Agent任务执行状态
- **性能统计**: 工具使用频率和成功率分析
- **智能规划**: 基于目标的任务分解和执行
### 3. 工单管理系统 📋
- **AI建议生成**: 基于知识库生成工单处理建议
- **人工审核**: 支持人工输入和AI建议对比
- **语义相似度**: 使用sentence-transformers进行准确度评估
- **智能入库**: AI准确率<90%时优先使用人工描述入库
- **知识库更新**: 高相似度建议自动入库
### 4. 知识库管理 📚
- **多格式支持**: TXT、PDF、DOC、DOCX、MD文件
- **智能提取**: 自动从文档中提取Q&A对
- **向量化检索**: TF-IDF + 余弦相似度搜索
- **质量验证**: 支持知识条目验证和置信度设置
### 5. 数据分析系统 📊
- **实时趋势**: 基于真实数据的性能趋势分析
- **多维度统计**: 工单、预警、满意度等关键指标
- **系统健康**: CPU、内存、响应时间监控
- **可视化展示**: 丰富的图表和仪表板
### 6. 飞书集成系统 📱
- **多维表格同步**: 自动同步飞书多维表格数据
- **字段映射**: 智能映射飞书字段到本地数据库
- **实时更新**: 支持增量同步和全量同步
- **数据预览**: 同步前预览数据,确保准确性
### 7. 系统设置管理 ⚙️
- **API管理**: 支持多种LLM提供商配置
- **模型参数**: 温度、最大令牌数等参数调节
- **端口配置**: Web服务和WebSocket端口管理
- **日志级别**: 灵活的日志级别控制
---
## 🛠️ 技术栈
### 后端技术
- **Python 3.8+**: 核心开发语言
- **Flask**: Web框架和API服务
- **SQLAlchemy**: ORM数据库操作
- **WebSocket**: 实时通信支持
- **psutil**: 系统资源监控
### 前端技术
- **Bootstrap 5**: UI框架
- **Chart.js**: 数据可视化
- **JavaScript ES6+**: 前端逻辑
- **WebSocket**: 实时通信客户端
### AI/ML技术
- **大语言模型**: 支持OpenAI、通义千问等
- **sentence-transformers**: 语义相似度计算
- **TF-IDF**: 文本向量化
- **余弦相似度**: 语义相似度计算
- **Agent框架**: 智能任务规划
### 部署运维
- **Docker**: 容器化部署
- **Nginx**: 反向代理和静态文件服务
- **Systemd**: 服务管理
- **Git**: 版本控制
---
## 🚀 安装部署
### 环境要求
- Python 3.8+
- Node.js 16+ (可选,用于前端构建)
- Git
- MySQL 8.0+
### 安装步骤
1. **克隆项目**
```bash
git clone http://jeason.online:3000/zhaojie/assist.git
cd assist
```
2. **安装依赖**
```bash
pip install -r requirements.txt
```
3. **配置数据库**
```bash
# 创建MySQL数据库
mysql -u root -p
CREATE DATABASE tsp_assistant CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
4. **初始化数据库**
```bash
python init_database.py
```
5. **启动服务**
```bash
python start_dashboard.py
```
6. **访问系统**
- 打开浏览器访问: `http://localhost:5000`
- 默认端口: 5000 (可在系统设置中修改)
### Windows快速启动
```cmd
# 双击运行
快速启动.bat
```
---
## ⚙️ 配置说明
### 环境变量
```bash
# 数据库配置
DATABASE_URL=mysql+pymysql://user:password@host:port/database
# 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
```
### 配置文件结构
```
config/
├── llm_config.py # LLM客户端配置
├── integrations_config.json # 飞书集成配置
├── ai_accuracy_config.py # AI准确率配置
└── README.md # 配置说明文档
```
### 飞书集成配置
```json
{
"feishu": {
"app_id": "cli_a8b50ec0eed1500d",
"app_secret": "ccxkE7ZCFQZcwkkM1rLy0ccZRXYsT2xK",
"app_token": "XXnEbiCmEaMblSs6FDJcFCqsnIg",
"table_id": "tblnl3vJPpgMTSiP",
"status": "active"
},
"system": {
"sync_limit": 10,
"ai_suggestions_enabled": true,
"auto_sync_interval": 0
}
}
```
### AI准确率配置
```python
# 默认配置
auto_approve_threshold = 0.95 # 自动审批阈值
use_human_resolution_threshold = 0.90 # 使用人工描述阈值
manual_review_threshold = 0.80 # 人工审核阈值
```
---
## 📖 使用指南
### 基础操作
#### 1. 智能对话
1. 在"智能对话"页面输入问题
2. 系统自动检索知识库并生成回答
3. 支持VIN码识别和车辆数据查询
#### 2. 工单管理
1. 创建工单并获取AI建议
2. 输入人工处理描述
3. 系统自动计算语义相似度
4. 根据相似度决定入库策略
#### 3. 知识库维护
1. 手动添加Q&A对
2. 上传文档自动提取知识
3. 设置置信度和验证状态
#### 4. 飞书数据同步
1. 配置飞书应用凭证
2. 在主仪表板"飞书同步"标签页
3. 测试连接并执行数据同步
### 高级功能
#### 1. Agent工具管理
- 查看工具使用统计
- 注册自定义工具
- 监控执行历史
#### 2. 数据分析
- 多维度数据统计
- 自定义时间范围
- 导出分析报告
#### 3. 系统配置
- API和模型参数配置
- 端口和日志级别设置
- 环境变量管理
---
## 🔌 API接口
### 工单管理API
```http
POST /api/workorders/{id}/ai-suggestion
POST /api/workorders/{id}/human-resolution
POST /api/workorders/{id}/approve-to-knowledge
GET /api/workorders
POST /api/workorders
PUT /api/workorders/{id}
DELETE /api/workorders/{id}
```
### 知识库API
```http
GET /api/knowledge
POST /api/knowledge
PUT /api/knowledge/{id}
DELETE /api/knowledge/{id}
POST /api/knowledge/search
POST /api/knowledge/upload
```
### 对话API
```http
POST /api/chat/session
GET /api/chat/session/{id}
DELETE /api/chat/session/{id}
POST /api/chat/message
```
### Agent管理API
```http
GET /api/agent/status
POST /api/agent/tools/execute
POST /api/agent/tools/register
GET /api/agent/tools/stats
```
---
## 🗄️ 数据库设计
### 核心表结构
#### work_orders (工单表)
```sql
CREATE TABLE work_orders (
id INT PRIMARY KEY AUTO_INCREMENT,
order_id VARCHAR(50) UNIQUE NOT NULL,
title VARCHAR(200) NOT NULL,
description TEXT NOT NULL,
category VARCHAR(100) NOT NULL,
priority VARCHAR(20) NOT NULL,
status VARCHAR(20) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
resolution TEXT,
satisfaction_score FLOAT,
-- 飞书集成字段
feishu_record_id VARCHAR(100),
source VARCHAR(50),
module VARCHAR(100),
created_by VARCHAR(100),
wilfulness VARCHAR(100),
date_of_close DATETIME,
vehicle_type VARCHAR(100),
vin_sim VARCHAR(50),
app_remote_control_version VARCHAR(100),
hmi_sw VARCHAR(100),
parent_record VARCHAR(100),
has_updated_same_day VARCHAR(50),
operating_time VARCHAR(100)
);
```
#### work_order_suggestions (工单建议表)
```sql
CREATE TABLE work_order_suggestions (
id INT PRIMARY KEY AUTO_INCREMENT,
work_order_id INT NOT NULL,
ai_suggestion TEXT,
human_resolution TEXT,
ai_similarity FLOAT,
approved BOOLEAN DEFAULT FALSE,
use_human_resolution BOOLEAN DEFAULT FALSE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (work_order_id) REFERENCES work_orders(id)
);
```
#### knowledge_entries (知识库表)
```sql
CREATE TABLE knowledge_entries (
id INT PRIMARY KEY AUTO_INCREMENT,
question TEXT NOT NULL,
answer TEXT NOT NULL,
category VARCHAR(100),
confidence_score FLOAT DEFAULT 0.5,
usage_count INT DEFAULT 0,
is_active BOOLEAN DEFAULT TRUE,
is_verified BOOLEAN DEFAULT FALSE,
verified_by VARCHAR(100),
verified_at DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
```
---
## 👨‍💻 开发指南
### 项目结构
```
tsp-assistant/
├── src/ # 源代码
│ ├── agent/ # Agent核心模块
│ ├── analytics/ # 数据分析模块
│ ├── config/ # 配置模块
│ ├── core/ # 核心模块
│ ├── dialogue/ # 对话模块
│ ├── integrations/ # 集成模块
│ ├── knowledge_base/ # 知识库模块
│ ├── utils/ # 工具模块
│ ├── vehicle/ # 车辆数据模块
│ └── web/ # Web应用模块
├── config/ # 配置文件
├── scripts/ # 脚本文件
├── uploads/ # 上传文件
├── requirements.txt # 依赖文件
├── init_database.py # 数据库初始化
└── start_dashboard.py # 启动脚本
```
### 代码规范
- **Python**: 遵循PEP 8规范
- **JavaScript**: 使用ES6+语法
- **提交信息**: 使用约定式提交格式
- **文档**: 新功能需要添加相应的文档
### 开发流程
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
---
## 🚨 故障排除
### 常见问题
#### 1. 数据库连接失败
```bash
# 检查数据库服务状态
systemctl status mysql
# 检查连接配置
python -c "from src.core.database import db_manager; print(db_manager.test_connection())"
```
#### 2. 飞书集成问题
- 检查飞书应用权限配置
- 验证app_token和table_id是否正确
- 确认网络连接和API访问权限
#### 3. AI建议生成失败
- 检查LLM API配置
- 验证知识库数据完整性
- 查看应用日志
#### 4. 数据库字段缺失
```bash
# 运行数据库迁移
python init_database.py
# 手动添加字段
mysql -u root -p tsp_assistant
ALTER TABLE work_order_suggestions ADD COLUMN use_human_resolution BOOLEAN DEFAULT FALSE;
```
### 日志位置
- **应用日志**: `logs/tsp_assistant.log`
- **访问日志**: Nginx访问日志
- **错误追踪**: 详细的错误堆栈信息
### 性能优化
- **数据库索引**: 为常用查询字段添加索引
- **缓存策略**: 使用Redis缓存热点数据
- **异步处理**: 耗时操作使用异步处理
- **连接池**: 配置数据库连接池
---
## 📝 更新日志
### v1.4.0 (2025-09-19)
- ✅ 飞书集成功能:支持飞书多维表格数据同步
- ✅ 页面功能合并:飞书同步页面合并到主仪表板
- ✅ 数据库架构优化:扩展工单表字段,支持飞书数据
- ✅ 代码重构优化:大文件拆分,降低运行风险
- ✅ 字段映射完善:智能映射飞书字段到本地数据库
- ✅ 数据库初始化改进:集成字段迁移到初始化流程
- ✅ AI准确率优化AI准确率<90%时优先使用人工描述入库
- ✅ 语义相似度计算使用sentence-transformers提升准确度
### v1.3.0 (2025-09-17)
- ✅ 数据库架构优化MySQL主数据库+SQLite备份系统
- ✅ 工单详情API修复解决数据库会话管理问题
- ✅ 备份管理系统自动备份MySQL数据到SQLite
- ✅ 数据库状态监控实时监控MySQL和SQLite状态
- ✅ 备份管理API支持数据备份和恢复操作
### v1.2.0 (2025-09-16)
- ✅ 系统设置扩展API管理、模型参数配置、端口管理
- ✅ 真实数据分析:修复性能趋势图表显示问题
- ✅ 工单AI建议功能智能生成处理建议
- ✅ 知识库搜索优化:提升检索准确率
- ✅ Agent管理改进工具使用统计和自定义工具
---
## 📄 许可证
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情
## 📞 支持与联系
- **项目地址**: http://jeason.online:3000/zhaojie/assist
- **问题反馈**: 请在Issues中提交问题
- **功能建议**: 欢迎提交Feature Request
## 🙏 致谢
感谢所有为项目做出贡献的开发者和用户!
---
**TSP智能助手** - 让车辆服务更智能,让客户体验更美好! 🚗✨

Binary file not shown.

View File

@@ -30,8 +30,23 @@ if /i "%confirm%" neq "y" (
:: 检查是否有更改需要提交 :: 检查是否有更改需要提交
echo. echo.
echo [2/4] 检查更改状态... echo [2/4] 检查更改状态...
git diff --quiet && git diff --cached --quiet
if %errorlevel% equ 0 ( :: 启用延迟变量扩展
setlocal enabledelayedexpansion
:: 检查未暂存的更改
git diff --quiet
set has_unstaged=%errorlevel%
:: 检查已暂存的更改
git diff --cached --quiet
set has_staged=%errorlevel%
:: 检查未跟踪的文件
git ls-files --others --exclude-standard >nul 2>&1
set has_untracked=%errorlevel%
if %has_unstaged% equ 0 if %has_staged% equ 0 if %has_untracked% neq 0 (
echo 没有检测到任何更改,无需提交 echo 没有检测到任何更改,无需提交
echo. echo.
echo ✅ 工作区干净,无需推送 echo ✅ 工作区干净,无需推送
@@ -39,6 +54,30 @@ if %errorlevel% equ 0 (
exit /b 0 exit /b 0
) )
:: 显示详细状态
echo 📊 详细状态信息:
echo 未暂存更改:
if %has_unstaged% neq 0 (
git diff --name-only
) else (
echo
)
echo 已暂存更改:
if %has_staged% neq 0 (
git diff --cached --name-only
) else (
echo
)
echo 未跟踪文件:
if %has_untracked% neq 0 (
git ls-files --others --exclude-standard
) else (
echo
)
echo.
:: 添加所有更改 :: 添加所有更改
echo 添加所有更改到暂存区... echo 添加所有更改到暂存区...
git add . git add .
@@ -160,22 +199,55 @@ echo ✅ 提交成功
:: 推送到远程仓库 :: 推送到远程仓库
echo. echo.
echo [4/4] 推送到远程仓库... echo [4/4] 推送到远程仓库...
:: 先尝试拉取最新更改
echo 🔄 检查远程更新...
git fetch origin main
if %errorlevel% neq 0 (
echo ⚠️ 无法获取远程更新,继续推送...
) else (
echo ✅ 远程更新检查完成
)
:: 推送到远程
git push origin main git push origin main
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
echo ❌ 推送失败 echo ❌ 推送失败
echo.
echo 💡 可能的原因: echo 💡 可能的原因:
echo - 网络连接问题 echo - 网络连接问题
echo - 远程仓库权限不足 echo - 远程仓库权限不足
echo - 分支冲突 echo - 分支冲突
echo - 需要先拉取远程更改 echo - 需要先拉取远程更改
echo. echo.
echo 🔧 建议解决方案: echo 🔧 尝试自动解决冲突...
echo 1. 检查网络连接 git pull origin main --rebase
echo 2. 运行: git pull origin main if %errorlevel% equ 0 (
echo 3. 重新运行推送脚本 echo ✅ 冲突已解决,重新推送...
git push origin main
if %errorlevel% equ 0 (
echo ✅ 推送成功!
) else (
echo ❌ 重新推送失败
echo.
echo 🔧 建议手动解决:
echo 1. 运行: git pull origin main
echo 2. 解决冲突后运行: git push origin main
pause pause
exit /b 1 exit /b 1
) )
) else (
echo ❌ 无法自动解决冲突
echo.
echo 🔧 建议手动解决:
echo 1. 运行: git pull origin main
echo 2. 解决冲突后运行: git push origin main
pause
exit /b 1
)
) else (
echo ✅ 推送成功!
)
echo. echo.
echo ======================================== echo ========================================

View File

@@ -1,192 +0,0 @@
# TSP智能助手 - 自动推送脚本 (PowerShell版本)
# 使用方法: .\auto_push.ps1 [提交信息]
param(
[string]$CommitMessage = "",
[switch]$Force = $false,
[switch]$NoConfirm = $false
)
# 设置控制台编码
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# 颜色输出函数
function Write-ColorOutput {
param(
[string]$Message,
[string]$Color = "White"
)
Write-Host $Message -ForegroundColor $Color
}
function Write-Step {
param(
[int]$Step,
[int]$Total,
[string]$Message
)
Write-ColorOutput "[$Step/$Total] $Message" "Cyan"
}
function Show-GitStatus {
Write-ColorOutput "`n📋 当前Git状态:" "Yellow"
$status = git status --porcelain
if ($status) {
$status | ForEach-Object {
$line = $_
if ($line.StartsWith("??")) {
Write-ColorOutput " + $($line.Substring(3))" "Green"
} elseif ($line.StartsWith(" M")) {
Write-ColorOutput " ~ $($line.Substring(3))" "Yellow"
} elseif ($line.StartsWith(" D")) {
Write-ColorOutput " - $($line.Substring(3))" "Red"
} else {
Write-ColorOutput " $line" "White"
}
}
} else {
Write-ColorOutput " 工作区干净,无更改" "Green"
}
}
function Get-CommitMessage {
if ($CommitMessage) {
return $CommitMessage
}
# 尝试从最近提交生成智能消息
$lastCommit = git log --oneline -1 2>$null
if ($lastCommit) {
$suggested = "feat: 自动提交更新 - $(Get-Date -Format 'yyyy-MM-dd HH:mm')"
} else {
$suggested = "feat: 初始提交 - $(Get-Date -Format 'yyyy-MM-dd HH:mm')"
}
Write-ColorOutput "`n💡 建议的提交信息: $suggested" "Cyan"
$custom = Read-Host "请输入自定义提交信息 (直接回车使用建议)"
if ($custom) {
return $custom
} else {
return $suggested
}
}
function Test-GitRepository {
try {
git status --porcelain >$null 2>&1
return $LASTEXITCODE -eq 0
} catch {
return $false
}
}
function Show-CommitStats {
Write-ColorOutput "`n📊 提交统计:" "Yellow"
$commitHash = git log --oneline -1 | Select-String -Pattern "^\w+" | ForEach-Object { $_.Matches[0].Value }
$filesChanged = git diff --cached --numstat | Measure-Object | Select-Object -ExpandProperty Count
$insertions = git diff --cached --numstat | ForEach-Object {
$parts = $_ -split '\s+'
if ($parts[0] -match '^\d+$') { [int]$parts[0] } else { 0 }
} | Measure-Object -Sum | Select-Object -ExpandProperty Sum
$deletions = git diff --cached --numstat | ForEach-Object {
$parts = $_ -split '\s+'
if ($parts[1] -match '^\d+$') { [int]$parts[1] } else { 0 }
} | Measure-Object -Sum | Select-Object -ExpandProperty Sum
Write-ColorOutput " 提交哈希: $commitHash" "White"
Write-ColorOutput " 文件变更: $filesChanged 个文件" "White"
Write-ColorOutput " 新增行数: $insertions" "Green"
Write-ColorOutput " 删除行数: $deletions" "Red"
Write-ColorOutput " 净增加: $($insertions - $deletions)" "Cyan"
}
# 主程序开始
Write-ColorOutput "========================================" "Magenta"
Write-ColorOutput "TSP智能助手 - 自动推送脚本 v2.0" "Magenta"
Write-ColorOutput "========================================" "Magenta"
# 检查Git仓库
Write-Step 1 4 "检查Git仓库状态"
if (-not (Test-GitRepository)) {
Write-ColorOutput "❌ Git未初始化或不在Git仓库中" "Red"
Write-ColorOutput "请确保在正确的Git仓库目录中运行此脚本" "Yellow"
Read-Host "按任意键退出"
exit 1
}
Write-ColorOutput "✅ Git仓库状态正常" "Green"
# 显示状态
Show-GitStatus
# 检查是否有更改
$hasChanges = git status --porcelain | Measure-Object | Select-Object -ExpandProperty Count
if ($hasChanges -eq 0) {
Write-ColorOutput "`n✅ 工作区干净,无需提交" "Green"
Read-Host "按任意键退出"
exit 0
}
# 确认操作
if (-not $NoConfirm) {
Write-ColorOutput "`n❓ 是否继续推送?" "Yellow"
$confirm = Read-Host "输入 'y' 继续,其他键取消"
if ($confirm -ne 'y') {
Write-ColorOutput "操作已取消" "Yellow"
Read-Host "按任意键退出"
exit 0
}
}
# 添加文件
Write-Step 2 4 "添加所有更改到暂存区"
try {
git add .
Write-ColorOutput "✅ 文件已添加到暂存区" "Green"
} catch {
Write-ColorOutput "❌ 添加文件失败: $($_.Exception.Message)" "Red"
Read-Host "按任意键退出"
exit 1
}
# 生成提交信息
Write-Step 3 4 "生成提交信息"
$finalCommitMessage = Get-CommitMessage
Write-ColorOutput "提交信息: $finalCommitMessage" "Cyan"
# 提交更改
try {
git commit -m $finalCommitMessage
Write-ColorOutput "✅ 提交成功" "Green"
} catch {
Write-ColorOutput "❌ 提交失败: $($_.Exception.Message)" "Red"
Read-Host "按任意键退出"
exit 1
}
# 推送到远程
Write-Step 4 4 "推送到远程仓库"
try {
git push origin main
Write-ColorOutput "✅ 推送成功" "Green"
} catch {
Write-ColorOutput "❌ 推送失败: $($_.Exception.Message)" "Red"
Write-ColorOutput "请检查网络连接和远程仓库权限" "Yellow"
Read-Host "按任意键退出"
exit 1
}
# 显示结果
Write-ColorOutput "`n========================================" "Magenta"
Write-ColorOutput "✅ 推送完成!" "Green"
Write-ColorOutput "========================================" "Magenta"
Show-CommitStats
Write-ColorOutput "`n🌐 远程仓库状态:" "Yellow"
git status --short
Write-ColorOutput "`n🎉 所有操作完成!" "Green"
if (-not $NoConfirm) {
Read-Host "按任意键退出"
}

Binary file not shown.

Binary file not shown.

View File

@@ -7,7 +7,7 @@
"TR Status": "status", "TR Status": "status",
"Source": "source", "Source": "source",
"Date creation": "created_at", "Date creation": "created_at",
"处理过程": "solution", "处理过程": "resolution",
"TR tracking": "resolution", "TR tracking": "resolution",
"Created by": "created_by", "Created by": "created_by",
"Module模块": "module", "Module模块": "module",
@@ -21,7 +21,10 @@
"Has it been updated on the same day": "has_updated_same_day", "Has it been updated on the same day": "has_updated_same_day",
"Operating time": "operating_time", "Operating time": "operating_time",
"AI建议": "ai_suggestion", "AI建议": "ai_suggestion",
"Issue Start Time": "updated_at" "Issue Start Time": "updated_at",
"Wilfulness责任人<E4BBBB>?": "wilfulness",
"父<>?<3F>录": "parent_record",
"AI建<49>??": "ai_suggestion"
}, },
"field_aliases": { "field_aliases": {
"order_id": [ "order_id": [
@@ -307,17 +310,17 @@
}, },
"field_priorities": { "field_priorities": {
"order_id": 3, "order_id": 3,
"description": 1, "description": 3,
"category": 1, "category": 3,
"priority": 1, "priority": 3,
"status": 1, "status": 3,
"created_at": 1, "created_at": 3,
"source": 2, "source": 3,
"solution": 2, "solution": 3,
"resolution": 2, "resolution": 3,
"created_by": 2, "created_by": 3,
"vehicle_type": 2, "vehicle_type": 3,
"vin_sim": 2, "vin_sim": 3,
"module": 3, "module": 3,
"wilfulness": 3, "wilfulness": 3,
"date_of_close": 3, "date_of_close": 3,
@@ -327,7 +330,7 @@
"has_updated_same_day": 3, "has_updated_same_day": 3,
"operating_time": 3, "operating_time": 3,
"ai_suggestion": 3, "ai_suggestion": 3,
"updated_at": 2 "updated_at": 3
}, },
"auto_mapping_enabled": true, "auto_mapping_enabled": true,
"similarity_threshold": 0.6 "similarity_threshold": 0.6

View File

@@ -34,3 +34,27 @@ ANTHROPIC_CONFIG = LLMConfig(
# 默认使用千问模型 # 默认使用千问模型
DEFAULT_CONFIG = QWEN_CONFIG DEFAULT_CONFIG = QWEN_CONFIG
def get_default_llm_config() -> LLMConfig:
"""
获取默认的LLM配置
优先从统一配置管理器获取,如果失败则使用本地配置
"""
try:
from src.config.unified_config import get_config
config = get_config()
llm_dict = config.get_llm_config()
# 创建LLMConfig对象
return LLMConfig(
provider=llm_dict.get("provider", "qwen"),
api_key=llm_dict.get("api_key", ""),
base_url=llm_dict.get("base_url", "https://dashscope.aliyuncs.com/compatible-mode/v1"),
model=llm_dict.get("model", "qwen-plus-latest"),
temperature=llm_dict.get("temperature", 0.7),
max_tokens=llm_dict.get("max_tokens", 2000)
)
except Exception:
# 如果统一配置不可用,使用本地配置
return DEFAULT_CONFIG

View File

@@ -0,0 +1,52 @@
{
"database": {
"url": "mysql+pymysql://tsp_assistant:password@jeason.online/tsp_assistant?charset=utf8mb4",
"pool_size": 10,
"max_overflow": 20,
"pool_timeout": 30,
"pool_recycle": 3600
},
"llm": {
"provider": "qwen",
"api_key": "sk-c0dbefa1718d46eaa897199135066f00",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"model": "qwen-plus-latest",
"temperature": 0.7,
"max_tokens": 2000,
"timeout": 30
},
"server": {
"host": "0.0.0.0",
"port": 5000,
"websocket_port": 8765,
"debug": false,
"log_level": "INFO"
},
"feishu": {
"app_id": "",
"app_secret": "",
"app_token": "",
"table_id": "",
"status": "active",
"sync_limit": 10,
"auto_sync_interval": 0
},
"ai_accuracy": {
"auto_approve_threshold": 0.95,
"use_human_resolution_threshold": 0.9,
"manual_review_threshold": 0.8,
"ai_suggestion_confidence": 0.95,
"human_resolution_confidence": 0.9,
"prefer_human_when_low_accuracy": true,
"enable_auto_approval": true,
"enable_human_fallback": true
},
"system": {
"backup_enabled": true,
"backup_interval": 24,
"max_backup_files": 7,
"cache_enabled": true,
"cache_ttl": 3600,
"monitoring_enabled": true
}
}

178
create_admin_user.py Normal file
View File

@@ -0,0 +1,178 @@
# -*- coding: utf-8 -*-
"""
创建或修复默认管理员用户
"""
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from src.core.database import db_manager
from src.core.models import User
# from werkzeug.security import generate_password_hash, check_password_hash
from sqlalchemy import text, inspect
print("=" * 60)
print("创建/修复管理员用户")
print("=" * 60)
try:
with db_manager.get_session() as session:
# 检查表结构
inspector = inspect(db_manager.engine)
if 'users' not in inspector.get_table_names():
print("错误: users表不存在请先运行 python init_database.py")
sys.exit(1)
existing_columns = [col['name'] for col in inspector.get_columns('users')]
print(f"users表字段: {existing_columns}")
# 检查是否存在admin用户
admin_user = session.query(User).filter(User.username == 'admin').first()
if admin_user:
print(f"\n找到admin用户 (ID: {admin_user.id})")
print(f" 邮箱: {admin_user.email}")
print(f" 角色: {admin_user.role}")
print(f" 激活状态: {admin_user.is_active}")
# 验证密码
password_ok = admin_user.check_password('admin123')
print(f" 密码验证: {'正确' if password_ok else '错误'}")
if not password_ok:
print("\n密码不匹配,正在更新密码...")
admin_user.set_password('admin123')
admin_user.is_active = True
if hasattr(admin_user, 'region'):
admin_user.region = None
session.commit()
print("密码已更新为: admin123")
if not admin_user.is_active:
print("用户未激活,正在激活...")
admin_user.is_active = True
session.commit()
print("用户已激活")
# 最终验证
test_password = admin_user.check_password('admin123')
if test_password and admin_user.is_active:
print("\n管理员用户已就绪!")
print(" 用户名: admin")
print(" 密码: admin123")
print(" 状态: 已激活")
else:
print("\n警告: 用户状态异常")
print(f" 密码正确: {test_password}")
print(f" 已激活: {admin_user.is_active}")
else:
print("\n未找到admin用户正在创建...")
# 创建用户对象来生成密码哈希
temp_user = User()
temp_user.set_password('admin123')
password_hash = temp_user.password_hash
# 检查表结构使用SQL直接插入避免字段不匹配
try:
# 先尝试使用模型创建
new_admin = User(
username='admin',
email='admin@tsp.com',
name='系统管理员',
password_hash=password_hash,
role='admin',
is_active=True
)
if 'region' in existing_columns:
new_admin.region = None
session.add(new_admin)
session.commit()
print("使用模型创建成功")
except Exception as model_error:
print(f"模型创建失败: {model_error}")
print("尝试使用SQL直接插入...")
session.rollback()
# 使用SQL直接插入
insert_fields = ['username', 'email', 'name', 'password_hash', 'role']
insert_values = {
'username': 'admin',
'email': 'admin@tsp.com',
'name': '系统管理员',
'password_hash': password_hash,
'role': 'admin'
}
if 'is_active' in existing_columns:
insert_fields.append('is_active')
insert_values['is_active'] = True
if 'region' in existing_columns:
insert_fields.append('region')
insert_values['region'] = None
fields_str = ', '.join(insert_fields)
values_str = ', '.join([f":{k}" for k in insert_fields])
sql = f"""
INSERT INTO users ({fields_str})
VALUES ({values_str})
"""
session.execute(text(sql), insert_values)
session.commit()
print("使用SQL创建成功")
# 验证创建结果
verify_user = session.query(User).filter(User.username == 'admin').first()
if verify_user:
test_password = verify_user.check_password('admin123')
print(f"\n验证结果:")
print(f" 用户ID: {verify_user.id}")
print(f" 密码正确: {test_password}")
print(f" 已激活: {verify_user.is_active}")
if test_password and verify_user.is_active:
print("\n管理员用户创建成功!")
print(" 用户名: admin")
print(" 密码: admin123")
else:
print("\n警告: 用户创建成功但状态异常")
# 创建其他示例用户
for username, name, email, password, role, region in [
('overseas_ops', '海外运维', 'overseas@tsp.com', 'ops123', 'overseas_ops', 'overseas'),
('domestic_ops', '国内运维', 'domestic@tsp.com', 'ops123', 'domestic_ops', 'domestic')
]:
ops_user = session.query(User).filter(User.username == username).first()
if not ops_user:
print(f"\n创建{username}用户...")
try:
new_user = User(
username=username,
name=name,
email=email,
role=role,
is_active=True
)
new_user.set_password(password)
if 'region' in existing_columns:
new_user.region = region
session.add(new_user)
session.commit()
print(f" {username}用户创建成功")
except Exception as e:
print(f" {username}用户创建失败: {e}")
session.rollback()
print("\n" + "=" * 60)
print("操作完成!")
print("=" * 60)
except Exception as e:
print(f"错误: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

View File

@@ -3,5 +3,14 @@
"max_history": 10, "max_history": 10,
"refresh_interval": 10, "refresh_interval": 10,
"auto_monitoring": true, "auto_monitoring": true,
"agent_mode": true "agent_mode": true,
"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"
} }

View File

@@ -1,9 +1,9 @@
{ {
"init_time": "2025-09-19T18:57:01.015501", "init_time": "2025-12-12T13:31:25.459591",
"database_version": "MySQL 8.4.6", "database_version": "SQLite 3.43.1",
"database_url": "mysql+pymysql://tsp_assistant:***@43.134.68.207/tsp_assistant?charset=utf8mb4", "database_url": "sqlite:///tsp_assistant.db",
"migrations_applied": 0, "migrations_applied": 0,
"tables_created": 15, "tables_created": 9,
"initial_data_inserted": true, "initial_data_inserted": true,
"verification_passed": true "verification_passed": true
} }

View File

@@ -1,58 +0,0 @@
version: '3.8'
services:
tsp-assistant:
build: .
container_name: tsp_assistant
ports:
- "5000:5000"
environment:
- PYTHONPATH=/app
- DATABASE_URL=sqlite:///tsp_assistant.db
volumes:
- ./data:/app/data
- ./logs:/app/logs
- ./backups:/app/backups
- tsp_db:/app
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# MySQL数据库服务可选
mysql:
image: mysql:8.0
container_name: tsp_mysql
environment:
MYSQL_ROOT_PASSWORD: root123456
MYSQL_DATABASE: tsp_assistant
MYSQL_USER: tsp_user
MYSQL_PASSWORD: tsp_password
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
restart: unless-stopped
command: --default-authentication-plugin=mysql_native_password
# Nginx反向代理可选
nginx:
image: nginx:alpine
container_name: tsp_nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl
depends_on:
- tsp-assistant
restart: unless-stopped
volumes:
tsp_db:
mysql_data:

26
git_push.bat Normal file
View File

@@ -0,0 +1,26 @@
@echo off
rem 获取当前日期和时间
for /f "tokens=1-6 delims=/ " %%a in ('date /t') do set CDATE=%%a-%%b-%%c
for /f "tokens=1-2 delims=:\ " %%a in ('time /t') do set CTIME=%%a-%%b
set COMMIT_MESSAGE="feat: %CDATE% %CTIME% - 全面架构重构、功能增强及问题修复"
rem 添加所有变更到暂存区
git add .
rem 检查是否有文件被添加、修改或删除
git diff --cached --quiet
if %errorlevel% equ 0 (
echo 没有检测到需要提交的变更。
) else (
rem 提交变更
git commit -m %COMMIT_MESSAGE%
rem 推送变更到远程仓库
git push origin master
echo Git 推送完成!
)
pause

23
git_push.sh Normal file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
# 获取当前日期和时间
COMMIT_DATE=$(date +"%Y-%m-%d %H:%M:%S")
# 添加所有变更到暂存区
git add .
# 检查是否有文件被添加、修改或删除
if git diff --cached --quiet; then
echo "没有检测到需要提交的变更。"
else
# 创建提交消息
COMMIT_MESSAGE="feat: ${COMMIT_DATE} - 全面架构重构、功能增强及问题修复"
# 提交变更
git commit -m "$COMMIT_MESSAGE"
# 推送变更到远程仓库
git push origin master
echo "Git 推送完成!"
fi

View File

@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
TSP助手数据库初始化脚本 - 重构版本 TSP助手数据库初始化脚本
结合项目新特性,提供更高效的数据库初始化和管理功能
""" """
import sys import sys
@@ -19,10 +18,12 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from src.config.config import Config from src.config.config import Config
from src.utils.helpers import setup_logging from src.utils.helpers import setup_logging
from src.core.database import db_manager from src.core.database import db_manager
from src.core.models import Base, WorkOrder, KnowledgeEntry, Conversation, Analytics, Alert, VehicleData from src.core.models import (
Base, WorkOrder, KnowledgeEntry, Conversation, Analytics, Alert, VehicleData,
WorkOrderSuggestion, WorkOrderProcessHistory, User
)
class DatabaseInitializer: class DatabaseInitializer:
"""数据库初始化器 - 重构版本"""
def __init__(self): def __init__(self):
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
@@ -57,11 +58,11 @@ class DatabaseInitializer:
def initialize_database(self, force_reset: bool = False) -> bool: def initialize_database(self, force_reset: bool = False) -> bool:
"""初始化数据库 - 主入口函数""" """初始化数据库 - 主入口函数"""
print("=" * 80) print("=" * 80)
print("🚀 TSP智能助手数据库初始化系统") print("TSP智能助手数据库初始化系统")
print("=" * 80) print("=" * 80)
print(f"📊 数据库类型: {self.db_version}") print(f"数据库类型: {self.db_version}")
print(f"🔗 连接地址: {self.db_url}") print(f"连接地址: {self.db_url}")
print(f"初始化时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print(f"初始化时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("=" * 80) print("=" * 80)
try: try:
@@ -97,49 +98,49 @@ class DatabaseInitializer:
self._generate_init_report() self._generate_init_report()
print("\n" + "=" * 80) print("\n" + "=" * 80)
print("🎉 数据库初始化完成!") print("数据库初始化完成!")
print("=" * 80) print("=" * 80)
return True return True
except Exception as e: except Exception as e:
print(f"\n数据库初始化失败: {e}") print(f"\n数据库初始化失败: {e}")
self.logger.error(f"数据库初始化失败: {e}", exc_info=True) self.logger.error(f"数据库初始化失败: {e}", exc_info=True)
return False return False
def _test_connection(self) -> bool: def _test_connection(self) -> bool:
"""测试数据库连接""" """测试数据库连接"""
print("\n🔌 测试数据库连接...") print("\n测试数据库连接...")
try: try:
if db_manager.test_connection(): if db_manager.test_connection():
print("数据库连接成功") print("数据库连接成功")
return True return True
else: else:
print("数据库连接失败") print("数据库连接失败")
return False return False
except Exception as e: except Exception as e:
print(f"数据库连接测试异常: {e}") print(f"数据库连接测试异常: {e}")
return False return False
def _reset_database(self) -> bool: def _reset_database(self) -> bool:
"""重置数据库(谨慎使用)""" """重置数据库(谨慎使用)"""
print("\n⚠️ 重置数据库...") print("\n重置数据库...")
try: try:
# 删除所有表 # 删除所有表
Base.metadata.drop_all(bind=db_manager.engine) Base.metadata.drop_all(bind=db_manager.engine)
print("数据库表删除成功") print("数据库表删除成功")
# 重新创建所有表 # 重新创建所有表
Base.metadata.create_all(bind=db_manager.engine) Base.metadata.create_all(bind=db_manager.engine)
print("数据库表重新创建成功") print("数据库表重新创建成功")
return True return True
except Exception as e: except Exception as e:
print(f"数据库重置失败: {e}") print(f"数据库重置失败: {e}")
return False return False
def _create_tables(self) -> bool: def _create_tables(self) -> bool:
"""创建数据库表""" """创建数据库表"""
print("\n📋 创建数据库表...") print("\n创建数据库表...")
try: try:
# 获取现有表信息 # 获取现有表信息
inspector = inspect(db_manager.engine) inspector = inspect(db_manager.engine)
@@ -153,26 +154,29 @@ class DatabaseInitializer:
created_tables = set(new_tables) - set(existing_tables) created_tables = set(new_tables) - set(existing_tables)
if created_tables: if created_tables:
print(f"新创建表: {', '.join(created_tables)}") print(f"新创建表: {', '.join(created_tables)}")
else: else:
print("所有表已存在") print("所有表已存在")
return True return True
except Exception as e: except Exception as e:
print(f"创建数据库表失败: {e}") print(f"创建数据库表失败: {e}")
return False return False
def _run_migrations(self) -> bool: def _run_migrations(self) -> bool:
"""执行数据库迁移""" """执行数据库迁移"""
print("\n🔄 执行数据库迁移...") print("\n执行数据库迁移...")
migrations = [ migrations = [
self._migrate_user_table_structure,
self._migrate_knowledge_verification_fields, self._migrate_knowledge_verification_fields,
self._migrate_alert_severity_field, self._migrate_alert_severity_field,
self._migrate_vehicle_data_table, self._migrate_vehicle_data_table,
self._migrate_conversation_enhancements, self._migrate_conversation_enhancements,
self._migrate_workorder_enhancements, self._migrate_workorder_enhancements,
self._migrate_workorder_suggestions_enhancements, self._migrate_workorder_suggestions_enhancements,
self._migrate_workorder_dispatch_fields,
self._migrate_workorder_process_history_table,
self._migrate_analytics_enhancements, self._migrate_analytics_enhancements,
self._migrate_system_optimization_fields self._migrate_system_optimization_fields
] ]
@@ -184,14 +188,59 @@ class DatabaseInitializer:
success_count += 1 success_count += 1
except Exception as e: except Exception as e:
self.logger.error(f"迁移失败: {migration.__name__}: {e}") self.logger.error(f"迁移失败: {migration.__name__}: {e}")
print(f"⚠️ 迁移 {migration.__name__} 失败: {e}") print(f"迁移 {migration.__name__} 失败: {e}")
print(f"完成 {success_count}/{len(migrations)} 个迁移") print(f"完成 {success_count}/{len(migrations)} 个迁移")
return success_count > 0 return success_count > 0
def _migrate_user_table_structure(self) -> bool:
"""迁移用户表结构"""
print(" 检查用户表结构...")
try:
with db_manager.get_session() as session:
# 检查users表是否存在
inspector = inspect(db_manager.engine)
if 'users' not in inspector.get_table_names():
print(" 创建users表...")
# 创建User模型的表
User.__table__.create(session.bind, checkfirst=True)
print(" users表创建成功")
return True
# 检查users表的列
existing_columns = [col['name'] for col in inspector.get_columns('users')]
print(f" users表现有字段: {existing_columns}")
# 检查必需的字段
required_fields = {
'name': 'VARCHAR(100)',
'email': 'VARCHAR(120)',
'role': 'VARCHAR(20) DEFAULT \'user\'',
'is_active': 'BOOLEAN DEFAULT TRUE',
'created_at': 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP',
'last_login': 'TIMESTAMP NULL'
}
fields_to_add = []
for field_name, field_type in required_fields.items():
if field_name not in existing_columns:
fields_to_add.append((field_name, field_type))
if fields_to_add:
print(f" 需要添加字段: {[f[0] for f in fields_to_add]}")
return self._add_table_columns('users', fields_to_add)
else:
print(" users表结构完整")
return True
except Exception as e:
print(f" 用户表结构迁移失败: {e}")
return False
def _migrate_knowledge_verification_fields(self) -> bool: def _migrate_knowledge_verification_fields(self) -> bool:
"""迁移知识库验证字段""" """迁移知识库验证字段"""
print(" 📝 检查知识库验证字段...") print(" 检查知识库验证字段...")
fields_to_add = [ fields_to_add = [
('is_verified', 'BOOLEAN DEFAULT FALSE'), ('is_verified', 'BOOLEAN DEFAULT FALSE'),
@@ -203,7 +252,7 @@ class DatabaseInitializer:
def _migrate_alert_severity_field(self) -> bool: def _migrate_alert_severity_field(self) -> bool:
"""迁移预警严重程度字段""" """迁移预警严重程度字段"""
print(" 🚨 检查预警严重程度字段...") print(" 检查预警严重程度字段...")
fields_to_add = [ fields_to_add = [
('severity', 'VARCHAR(20) DEFAULT \'medium\'') ('severity', 'VARCHAR(20) DEFAULT \'medium\'')
@@ -213,50 +262,50 @@ class DatabaseInitializer:
def _migrate_vehicle_data_table(self) -> bool: def _migrate_vehicle_data_table(self) -> bool:
"""迁移车辆数据表""" """迁移车辆数据表"""
print(" 🚗 检查车辆数据表...") print(" 检查车辆数据表...")
try: try:
with db_manager.get_session() as session: with db_manager.get_session() as session:
# 检查表是否存在 # 检查表是否存在
inspector = inspect(db_manager.engine) inspector = inspect(db_manager.engine)
if 'vehicle_data' not in inspector.get_table_names(): if 'vehicle_data' not in inspector.get_table_names():
print(" 创建vehicle_data表...") print(" 创建vehicle_data表...")
VehicleData.__table__.create(session.bind, checkfirst=True) VehicleData.__table__.create(session.bind, checkfirst=True)
print(" vehicle_data表创建成功") print(" vehicle_data表创建成功")
else: else:
print(" vehicle_data表已存在") print(" vehicle_data表已存在")
session.commit() session.commit()
return True return True
except Exception as e: except Exception as e:
print(f" 车辆数据表迁移失败: {e}") print(f" 车辆数据表迁移失败: {e}")
return False return False
def _migrate_conversation_enhancements(self) -> bool: def _migrate_conversation_enhancements(self) -> bool:
"""迁移对话增强字段""" """迁移对话增强字段"""
print(" 💬 检查对话增强字段...") print(" 检查对话增强字段...")
fields_to_add = [ fields_to_add = [
('response_time', 'FLOAT'), ('timestamp', 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP'),
('user_satisfaction', 'INTEGER'), ('knowledge_used', 'TEXT'),
('ai_confidence', 'FLOAT'), ('response_time', 'FLOAT')
('context_data', 'TEXT')
] ]
return self._add_table_columns('conversations', fields_to_add) return self._add_table_columns('conversations', fields_to_add)
def _migrate_workorder_enhancements(self) -> bool: def _migrate_workorder_enhancements(self) -> bool:
"""迁移工单增强字段""" """迁移工单增强字段"""
print(" 📋 检查工单增强字段...") print(" 检查工单增强字段...")
fields_to_add = [ fields_to_add = [
('ai_suggestion', 'TEXT'), ('resolution', 'TEXT'),
('human_resolution', 'TEXT'), ('satisfaction_score', 'FLOAT'),
('ai_similarity', 'FLOAT'), # 飞书集成字段
('ai_approved', 'BOOLEAN DEFAULT FALSE'),
('feishu_record_id', 'VARCHAR(100)'), ('feishu_record_id', 'VARCHAR(100)'),
('sync_status', 'VARCHAR(20) DEFAULT \'pending\''), ('assignee', 'VARCHAR(100)'),
# 飞书集成扩展字段 ('solution', 'TEXT'),
('ai_suggestion', 'TEXT'),
# 扩展飞书字段
('source', 'VARCHAR(50)'), ('source', 'VARCHAR(50)'),
('module', 'VARCHAR(100)'), ('module', 'VARCHAR(100)'),
('created_by', 'VARCHAR(100)'), ('created_by', 'VARCHAR(100)'),
@@ -275,17 +324,69 @@ class DatabaseInitializer:
def _migrate_workorder_suggestions_enhancements(self) -> bool: def _migrate_workorder_suggestions_enhancements(self) -> bool:
"""迁移工单建议表增强字段""" """迁移工单建议表增强字段"""
print(" 💡 检查工单建议表增强字段...") print(" 检查工单建议表增强字段...")
fields_to_add = [ fields_to_add = [
('ai_similarity', 'FLOAT'),
('approved', 'BOOLEAN DEFAULT FALSE'),
('use_human_resolution', 'BOOLEAN DEFAULT FALSE') # 是否使用人工描述入库 ('use_human_resolution', 'BOOLEAN DEFAULT FALSE') # 是否使用人工描述入库
] ]
return self._add_table_columns('work_order_suggestions', fields_to_add) return self._add_table_columns('work_order_suggestions', fields_to_add)
def _migrate_workorder_dispatch_fields(self) -> bool:
"""迁移工单分发和权限管理字段"""
print(" 检查工单分发和权限管理字段...")
fields_to_add = [
('assigned_module', 'VARCHAR(50)'),
('module_owner', 'VARCHAR(100)'),
('dispatcher', 'VARCHAR(100)'),
('dispatch_time', 'DATETIME'),
('region', 'VARCHAR(50)')
]
return self._add_table_columns('work_orders', fields_to_add)
def _migrate_workorder_process_history_table(self) -> bool:
"""迁移工单处理过程记录表"""
print(" 检查工单处理过程记录表...")
try:
with db_manager.get_session() as session:
# 检查表是否存在
inspector = inspect(db_manager.engine)
if 'work_order_process_history' not in inspector.get_table_names():
print(" 创建work_order_process_history表...")
WorkOrderProcessHistory.__table__.create(session.bind, checkfirst=True)
print(" work_order_process_history表创建成功")
else:
print(" work_order_process_history表已存在")
# 检查字段是否完整
existing_columns = [col['name'] for col in inspector.get_columns('work_order_process_history')]
required_columns = [
'processor_name', 'processor_role', 'processor_region',
'process_content', 'action_type', 'previous_status',
'new_status', 'assigned_module', 'process_time'
]
missing_columns = [col for col in required_columns if col not in existing_columns]
if missing_columns:
print(f" 缺少字段: {', '.join(missing_columns)}")
# 这里可以选择性地添加缺失字段,但通常表已经完整创建
else:
print(" 所有必需字段已存在")
session.commit()
return True
except Exception as e:
print(f" 工单处理过程记录表迁移失败: {e}")
return False
def _migrate_analytics_enhancements(self) -> bool: def _migrate_analytics_enhancements(self) -> bool:
"""迁移分析增强字段""" """迁移分析增强字段"""
print(" 📊 检查分析增强字段...") print(" 检查分析增强字段...")
fields_to_add = [ fields_to_add = [
('performance_score', 'FLOAT'), ('performance_score', 'FLOAT'),
@@ -298,7 +399,7 @@ class DatabaseInitializer:
def _migrate_system_optimization_fields(self) -> bool: def _migrate_system_optimization_fields(self) -> bool:
"""迁移系统优化字段""" """迁移系统优化字段"""
print(" ⚙️ 检查系统优化字段...") print(" 检查系统优化字段...")
# 为各个表添加系统优化相关字段 # 为各个表添加系统优化相关字段
tables_and_fields = { tables_and_fields = {
@@ -337,7 +438,7 @@ class DatabaseInitializer:
skipped_count += 1 skipped_count += 1
continue continue
print(f" 添加字段 {table_name}.{field_name}...") print(f" 添加字段 {table_name}.{field_name}...")
# 使用单独的会话添加每个字段,避免长时间锁定 # 使用单独的会话添加每个字段,避免长时间锁定
with db_manager.get_session() as session: with db_manager.get_session() as session:
@@ -345,22 +446,22 @@ class DatabaseInitializer:
session.execute(text(alter_sql)) session.execute(text(alter_sql))
session.commit() session.commit()
print(f" 字段 {field_name} 添加成功") print(f" 字段 {field_name} 添加成功")
added_count += 1 added_count += 1
except Exception as field_error: except Exception as field_error:
print(f" ⚠️ 字段 {field_name} 添加失败: {field_error}") print(f" 字段 {field_name} 添加失败: {field_error}")
# 继续处理其他字段,不中断整个过程 # 继续处理其他字段,不中断整个过程
if added_count > 0: if added_count > 0:
print(f" 📊 成功添加 {added_count} 个字段,跳过 {skipped_count} 个已存在字段") print(f" 成功添加 {added_count} 个字段,跳过 {skipped_count} 个已存在字段")
else: else:
print(f" 📊 所有字段都已存在,跳过 {skipped_count} 个字段") print(f" 所有字段都已存在,跳过 {skipped_count} 个字段")
return True return True
except Exception as e: except Exception as e:
print(f" 添加字段过程失败: {e}") print(f" 添加字段过程失败: {e}")
return False return False
def _column_exists(self, table_name: str, column_name: str) -> bool: def _column_exists(self, table_name: str, column_name: str) -> bool:
@@ -395,14 +496,25 @@ class DatabaseInitializer:
def _insert_initial_data(self) -> bool: def _insert_initial_data(self) -> bool:
"""插入初始数据""" """插入初始数据"""
print("\n📊 插入初始数据...") print("\n插入初始数据...")
try: try:
with db_manager.get_session() as session: with db_manager.get_session() as session:
# 检查是否已有数据 # 检查是否已有用户数据
existing_users = session.query(User).count()
if existing_users == 0:
# 创建默认管理员用户
from src.core.auth_manager import auth_manager
admin_user = auth_manager.create_default_admin()
if admin_user:
print(" 默认管理员用户已创建: admin/admin123")
else:
print(" 创建默认管理员用户失败")
# 检查是否已有知识库数据
existing_count = session.query(KnowledgeEntry).count() existing_count = session.query(KnowledgeEntry).count()
if existing_count > 0: if existing_count > 0:
print(f" 数据库中已有 {existing_count} 条知识库条目,跳过初始数据插入") print(f" 数据库中已有 {existing_count} 条知识库条目,跳过初始数据插入")
return True return True
# 插入初始知识库数据 # 插入初始知识库数据
@@ -412,7 +524,7 @@ class DatabaseInitializer:
session.add(entry) session.add(entry)
session.commit() session.commit()
print(f" 成功插入 {len(initial_data)} 条知识库条目") print(f" 成功插入 {len(initial_data)} 条知识库条目")
# 添加示例车辆数据 # 添加示例车辆数据
self._add_sample_vehicle_data() self._add_sample_vehicle_data()
@@ -422,7 +534,7 @@ class DatabaseInitializer:
return True return True
except Exception as e: except Exception as e:
print(f" 插入初始数据失败: {e}") print(f" 插入初始数据失败: {e}")
return False return False
def _get_initial_knowledge_data(self) -> List[Dict[str, Any]]: def _get_initial_knowledge_data(self) -> List[Dict[str, Any]]:
@@ -549,13 +661,13 @@ class DatabaseInitializer:
success = vehicle_manager.add_sample_vehicle_data() success = vehicle_manager.add_sample_vehicle_data()
if success: if success:
print(" 示例车辆数据添加成功") print(" 示例车辆数据添加成功")
else: else:
print(" 示例车辆数据添加失败") print(" 示例车辆数据添加失败")
return success return success
except Exception as e: except Exception as e:
print(f" 添加示例车辆数据失败: {e}") print(f" 添加示例车辆数据失败: {e}")
return False return False
def _verify_existing_knowledge(self) -> bool: def _verify_existing_knowledge(self) -> bool:
@@ -568,7 +680,7 @@ class DatabaseInitializer:
).all() ).all()
if unverified_entries: if unverified_entries:
print(f" 📝 发现 {len(unverified_entries)} 条未验证的知识库条目") print(f" 发现 {len(unverified_entries)} 条未验证的知识库条目")
# 将现有的知识库条目标记为已验证 # 将现有的知识库条目标记为已验证
for entry in unverified_entries: for entry in unverified_entries:
@@ -581,29 +693,32 @@ class DatabaseInitializer:
entry.relevance_score = 0.7 entry.relevance_score = 0.7
session.commit() session.commit()
print(f" 成功验证 {len(unverified_entries)} 条知识库条目") print(f" 成功验证 {len(unverified_entries)} 条知识库条目")
else: else:
print(" 所有知识库条目已验证") print(" 所有知识库条目已验证")
return True return True
except Exception as e: except Exception as e:
print(f" 验证知识库条目失败: {e}") print(f" 验证知识库条目失败: {e}")
return False return False
def _verify_database_integrity(self) -> bool: def _verify_database_integrity(self) -> bool:
"""验证数据库完整性""" """验证数据库完整性"""
print("\n🔍 验证数据库完整性...") print("\n验证数据库完整性...")
try: try:
with db_manager.get_session() as session: with db_manager.get_session() as session:
# 检查各表的记录数 # 检查各表的记录数
tables_info = { tables_info = {
'users': User,
'work_orders': WorkOrder, 'work_orders': WorkOrder,
'conversations': Conversation, 'conversations': Conversation,
'knowledge_entries': KnowledgeEntry, 'knowledge_entries': KnowledgeEntry,
'analytics': Analytics, 'analytics': Analytics,
'alerts': Alert, 'alerts': Alert,
'vehicle_data': VehicleData 'vehicle_data': VehicleData,
'work_order_suggestions': WorkOrderSuggestion,
'work_order_process_history': WorkOrderProcessHistory
} }
total_records = 0 total_records = 0
@@ -611,19 +726,19 @@ class DatabaseInitializer:
try: try:
count = session.query(model_class).count() count = session.query(model_class).count()
total_records += count total_records += count
print(f" 📋 {table_name}: {count} 条记录") print(f" {table_name}: {count} 条记录")
except Exception as e: except Exception as e:
print(f" ⚠️ {table_name}: 检查失败 - {e}") print(f" {table_name}: 检查失败 - {e}")
print(f" 📊 总记录数: {total_records}") print(f" 总记录数: {total_records}")
# 检查关键字段 # 检查关键字段
self._check_critical_fields() self._check_critical_fields()
print(" 数据库完整性验证通过") print(" 数据库完整性验证通过")
return True return True
except Exception as e: except Exception as e:
print(f" 数据库完整性验证失败: {e}") print(f" 数据库完整性验证失败: {e}")
return False return False
def _check_critical_fields(self): def _check_critical_fields(self):
@@ -632,19 +747,23 @@ class DatabaseInitializer:
("knowledge_entries", "is_verified"), ("knowledge_entries", "is_verified"),
("alerts", "severity"), ("alerts", "severity"),
("vehicle_data", "vehicle_id"), ("vehicle_data", "vehicle_id"),
("conversations", "timestamp"),
("conversations", "response_time"), ("conversations", "response_time"),
("work_orders", "ai_suggestion") ("work_orders", "ai_suggestion"),
("work_orders", "assigned_module"),
("work_order_process_history", "processor_name"),
("work_order_suggestions", "ai_similarity")
] ]
for table_name, field_name in critical_checks: for table_name, field_name in critical_checks:
if self._column_exists(table_name, field_name): if self._column_exists(table_name, field_name):
print(f" {table_name}.{field_name} 字段存在") print(f" {table_name}.{field_name} 字段存在")
else: else:
print(f" ⚠️ {table_name}.{field_name} 字段缺失") print(f" {table_name}.{field_name} 字段缺失")
def _generate_init_report(self): def _generate_init_report(self):
"""生成初始化报告""" """生成初始化报告"""
print("\n📋 生成初始化报告...") print("\n生成初始化报告...")
try: try:
report = { report = {
@@ -662,10 +781,10 @@ class DatabaseInitializer:
with open(report_path, 'w', encoding='utf-8') as f: with open(report_path, 'w', encoding='utf-8') as f:
json.dump(report, f, indent=2, ensure_ascii=False) json.dump(report, f, indent=2, ensure_ascii=False)
print(f" 初始化报告已保存到: {report_path}") print(f" 初始化报告已保存到: {report_path}")
except Exception as e: except Exception as e:
print(f" ⚠️ 生成初始化报告失败: {e}") print(f" 生成初始化报告失败: {e}")
def _get_table_count(self) -> int: def _get_table_count(self) -> int:
"""获取表数量""" """获取表数量"""
@@ -678,7 +797,7 @@ class DatabaseInitializer:
def check_database_status(self) -> Dict[str, Any]: def check_database_status(self) -> Dict[str, Any]:
"""检查数据库状态""" """检查数据库状态"""
print("\n" + "=" * 80) print("\n" + "=" * 80)
print("📊 数据库状态检查") print("数据库状态检查")
print("=" * 80) print("=" * 80)
try: try:
@@ -690,7 +809,9 @@ class DatabaseInitializer:
'knowledge_entries': KnowledgeEntry, 'knowledge_entries': KnowledgeEntry,
'analytics': Analytics, 'analytics': Analytics,
'alerts': Alert, 'alerts': Alert,
'vehicle_data': VehicleData 'vehicle_data': VehicleData,
'work_order_suggestions': WorkOrderSuggestion,
'work_order_process_history': WorkOrderProcessHistory
} }
status = { status = {
@@ -706,10 +827,10 @@ class DatabaseInitializer:
count = session.query(model_class).count() count = session.query(model_class).count()
status["tables"][table_name] = count status["tables"][table_name] = count
status["total_records"] += count status["total_records"] += count
print(f"📋 {table_name}: {count} 条记录") print(f"{table_name}: {count} 条记录")
except Exception as e: except Exception as e:
status["tables"][table_name] = f"错误: {e}" status["tables"][table_name] = f"错误: {e}"
print(f"⚠️ {table_name}: 检查失败 - {e}") print(f"{table_name}: 检查失败 - {e}")
# 检查车辆数据详情 # 检查车辆数据详情
if 'vehicle_data' in status["tables"] and isinstance(status["tables"]['vehicle_data'], int): if 'vehicle_data' in status["tables"] and isinstance(status["tables"]['vehicle_data'], int):
@@ -736,18 +857,18 @@ class DatabaseInitializer:
"unverified": unverified_count "unverified": unverified_count
} }
print(f"\n📊 总记录数: {status['total_records']}") print(f"\n总记录数: {status['total_records']}")
print("\n数据库状态检查完成") print("\n数据库状态检查完成")
return status return status
except Exception as e: except Exception as e:
print(f"数据库状态检查失败: {e}") print(f"数据库状态检查失败: {e}")
return {"error": str(e)} return {"error": str(e)}
def main(): def main():
"""主函数""" """主函数"""
print("🚀 TSP智能助手数据库初始化工具 - 重构版本") print("TSP智能助手数据库初始化工具")
print("=" * 80) print("=" * 80)
# 创建初始化器 # 创建初始化器
@@ -757,7 +878,7 @@ def main():
force_reset = '--reset' in sys.argv or '--force' in sys.argv force_reset = '--reset' in sys.argv or '--force' in sys.argv
if force_reset: if force_reset:
print("⚠️ 警告:将重置数据库,所有数据将被删除!") print("警告:将重置数据库,所有数据将被删除!")
try: try:
confirm = input("确定要继续吗?(y/N): ") confirm = input("确定要继续吗?(y/N): ")
if confirm.lower() != 'y': if confirm.lower() != 'y':
@@ -772,39 +893,13 @@ def main():
initializer.check_database_status() initializer.check_database_status()
print("\n" + "=" * 80) print("\n" + "=" * 80)
print("🎉 数据库初始化成功!") print("数据库初始化成功!")
print("=" * 80) print("=" * 80)
print("✅ 已完成的操作:")
print(" - 创建所有数据库表")
print(" - 执行数据库迁移")
print(" - 添加知识库验证字段")
print(" - 创建车辆数据表")
print(" - 插入初始知识库数据")
print(" - 添加示例车辆数据")
print(" - 验证所有知识库条目")
print(" - 生成初始化报告")
print("\n🚀 现在您可以运行以下命令启动系统:")
print(" python start_dashboard.py")
print("\n🧪 或运行功能测试:")
print(" python test_new_features.py")
print("\n📋 新功能包括:")
print(" - 知识库分页显示")
print(" - 知识库验证机制")
print(" - 车辆实时数据管理")
print(" - 文件上传生成知识库")
print(" - 智能对话结合车辆数据")
print(" - 飞书同步功能")
print(" - 系统性能优化")
else: else:
print("\n" + "=" * 80) print("\n" + "=" * 80)
print("数据库初始化失败!") print("数据库初始化失败!")
print("=" * 80) print("=" * 80)
print("请检查:")
print("1. 数据库文件权限")
print("2. 数据库服务是否运行")
print("3. 磁盘空间是否充足")
print("4. Python依赖库是否完整")
print("5. 配置文件是否正确")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

BIN
local_test.db Normal file

Binary file not shown.

5992
logs/dashboard.log Normal file

File diff suppressed because one or more lines are too long

9
logs/tsp_assistant.log Normal file
View File

@@ -0,0 +1,9 @@
2025-12-12 13:30:49,040 - src.core.database - ERROR - 数据库操作失败: 'search_frequency' is an invalid keyword argument for KnowledgeEntry
2025-12-12 13:31:25,399 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - location
2025-12-12 13:31:25,404 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - status
2025-12-12 13:31:25,409 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - battery
2025-12-12 13:31:25,414 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - engine
2025-12-12 13:31:25,419 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - location
2025-12-12 13:31:25,424 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - status
2025-12-12 13:31:25,429 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - fault
2025-12-12 13:31:25,429 - src.vehicle.vehicle_data_manager - INFO - 示例车辆数据添加成功

Binary file not shown.

Binary file not shown.

102
nginx.conf Normal file
View File

@@ -0,0 +1,102 @@
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
# 基本设置
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 100M;
# Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
# 上游服务器
upstream tsp_backend {
server tsp-assistant:5000;
}
# HTTP服务器
server {
listen 80;
server_name localhost;
# 健康检查
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# API代理
location /api/ {
proxy_pass http://tsp_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# WebSocket代理
location /ws/ {
proxy_pass http://tsp_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 静态文件
location /static/ {
proxy_pass http://tsp_backend;
expires 1y;
add_header Cache-Control "public, immutable";
}
# 主应用
location / {
proxy_pass http://tsp_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# HTTPS服务器可选
# server {
# listen 443 ssl http2;
# server_name localhost;
#
# ssl_certificate /etc/nginx/ssl/cert.pem;
# ssl_certificate_key /etc/nginx/ssl/key.pem;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
# ssl_prefer_server_ciphers off;
#
# # 其他配置与HTTP相同...
# }
}

View File

@@ -105,9 +105,19 @@ if "%1"=="" (
echo 📝 提交信息: %commit_msg% echo 📝 提交信息: %commit_msg%
echo. echo.
:: 检查是否有更改需要提交 :: 检查是否有更改需要提交(含未跟踪文件)
git diff --quiet && git diff --cached --quiet setlocal enabledelayedexpansion
if %errorlevel% equ 0 (
git diff --quiet
set has_unstaged=%errorlevel%
git diff --cached --quiet
set has_staged=%errorlevel%
set has_untracked=0
for /f "delims=" %%f in ('git ls-files --others --exclude-standard') do set has_untracked=1
if %has_unstaged% equ 0 if %has_staged% equ 0 if %has_untracked% equ 0 (
echo 没有检测到任何更改,无需提交 echo 没有检测到任何更改,无需提交
echo. echo.
echo ✅ 工作区干净,无需推送 echo ✅ 工作区干净,无需推送
@@ -134,6 +144,7 @@ if %errorlevel% neq 0 (
exit /b 1 exit /b 1
) )
git fetch origin main
git push origin main git push origin main
if %errorlevel% equ 0 ( if %errorlevel% equ 0 (
echo. echo.
@@ -142,11 +153,22 @@ if %errorlevel% equ 0 (
git log --oneline -1 git log --oneline -1
) else ( ) else (
echo. echo.
echo ❌ 推送失败,请检查错误信息 echo ❌ 推送失败,尝试自动解决...
echo 💡 可能的原因: echo 🔄 执行: git pull origin main --rebase
echo - 网络连接问题 git pull origin main --rebase
echo - 远程仓库权限不足 if %errorlevel% equ 0 (
echo - 分支冲突 echo ✅ 重试推送...
git push origin main
if %errorlevel% equ 0 (
echo ✅ 推送成功!
echo 📊 最新提交:
git log --oneline -1
) else (
echo ❌ 重试推送失败,请手动处理
)
) else (
echo ❌ 自动rebase失败请手动处理冲突后重试
)
) )
echo. echo.

View File

@@ -1,50 +1,66 @@
# 核心依赖 # 核心依赖
sqlalchemy>=2.0.0 sqlalchemy==2.0.32
requests>=2.31.0 requests==2.32.3
numpy>=1.24.0 numpy==1.26.4
scikit-learn>=1.3.0 scikit-learn==1.4.2
# 数据库驱动 # 数据库驱动
pymysql>=1.1.0 pymysql==1.1.1
cryptography>=3.4.0 cryptography==43.0.1
flask>=2.0.0 flask==3.0.3
flask-cors>=3.0.0 flask-cors==5.0.0
websockets>=10.0 websockets==15.0.1
# 中文处理 # 中文处理
jieba>=0.42.1 jieba==0.42.1
# 系统监控 # 系统监控
psutil>=5.9.0 psutil==5.9.8
# 数据处理 # 数据处理
pandas>=2.0.0 pandas==2.2.2
openpyxl>=3.1.0 openpyxl==3.1.5
# 向量化
sentence-transformers>=2.2.0
# 日志和配置 # 日志和配置
python-dotenv>=1.0.0 python-dotenv==1.0.1
structlog==24.4.0
# 时间处理 # 时间处理
python-dateutil>=2.8.0 python-dateutil==2.9.0
# JSON处理 # JSON处理
ujson>=5.8.0 ujson==5.10.0
# 异步支持(可选) # 异步支持
aiohttp>=3.8.0 aiohttp==3.10.10
asyncio>=3.4.3 # asyncio是Python内置模块不需要安装
# Redis缓存 # Redis缓存
redis>=4.5.0
# 测试框架 # 测试框架
pytest>=7.4.0 pytest==8.3.3
pytest-asyncio>=0.21.0 pytest-asyncio==0.24.0
pytest-cov==6.0.0
# 代码质量 # 代码质量
black>=23.0.0 black==24.8.0
flake8>=6.0.0 flake8==7.1.1
mypy>=1.5.0 mypy==1.11.1
isort==5.13.2
# 安全
bcrypt==4.2.1
pyjwt==2.9.0
# 文件处理
python-magic==0.4.27
pillow==11.0.0
# 网络工具
urllib3==2.2.3
httpx==0.27.2
# 数据验证
pydantic==2.9.2
marshmallow==3.23.3

Binary file not shown.

204
scripts/docker_deploy.sh Normal file
View File

@@ -0,0 +1,204 @@
#!/bin/bash
# TSP智能助手Docker部署脚本
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查Docker和Docker Compose
check_dependencies() {
log_info "检查依赖..."
if ! command -v docker &> /dev/null; then
log_error "Docker未安装请先安装Docker"
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
log_error "Docker Compose未安装请先安装Docker Compose"
exit 1
fi
log_success "依赖检查通过"
}
# 创建必要的目录
create_directories() {
log_info "创建必要的目录..."
mkdir -p logs/nginx
mkdir -p monitoring/grafana/provisioning/datasources
mkdir -p monitoring/grafana/provisioning/dashboards
mkdir -p ssl
mkdir -p data
mkdir -p backups
mkdir -p uploads
mkdir -p config
log_success "目录创建完成"
}
# 构建镜像
build_images() {
log_info "构建Docker镜像..."
# 构建主应用镜像
docker-compose build --no-cache tsp-assistant
log_success "镜像构建完成"
}
# 启动服务
start_services() {
log_info "启动服务..."
# 启动基础服务MySQL, Redis
docker-compose up -d mysql redis
# 等待数据库启动
log_info "等待数据库启动..."
sleep 30
# 启动主应用
docker-compose up -d tsp-assistant
# 启动其他服务
docker-compose up -d nginx prometheus grafana
log_success "服务启动完成"
}
# 检查服务状态
check_services() {
log_info "检查服务状态..."
sleep 10
# 检查主应用
if curl -f http://localhost:5000/api/health &> /dev/null; then
log_success "TSP助手服务正常"
else
log_warning "TSP助手服务可能未完全启动"
fi
# 检查Nginx
if curl -f http://localhost/health &> /dev/null; then
log_success "Nginx服务正常"
else
log_warning "Nginx服务可能未完全启动"
fi
# 检查Prometheus
if curl -f http://localhost:9090 &> /dev/null; then
log_success "Prometheus服务正常"
else
log_warning "Prometheus服务可能未完全启动"
fi
# 检查Grafana
if curl -f http://localhost:3000 &> /dev/null; then
log_success "Grafana服务正常"
else
log_warning "Grafana服务可能未完全启动"
fi
}
# 显示服务信息
show_info() {
log_info "服务访问信息:"
echo " TSP助手: http://localhost:5000"
echo " Nginx代理: http://localhost"
echo " Prometheus: http://localhost:9090"
echo " Grafana: http://localhost:3000 (admin/admin123456)"
echo " MySQL: localhost:3306 (root/root123456)"
echo " Redis: localhost:6379 (密码: redis123456)"
echo ""
log_info "查看日志命令:"
echo " docker-compose logs -f tsp-assistant"
echo " docker-compose logs -f mysql"
echo " docker-compose logs -f redis"
echo " docker-compose logs -f nginx"
}
# 停止服务
stop_services() {
log_info "停止服务..."
docker-compose down
log_success "服务已停止"
}
# 清理资源
cleanup() {
log_info "清理Docker资源..."
docker system prune -f
log_success "清理完成"
}
# 主函数
main() {
case "${1:-start}" in
"start")
check_dependencies
create_directories
build_images
start_services
check_services
show_info
;;
"stop")
stop_services
;;
"restart")
stop_services
sleep 5
start_services
check_services
show_info
;;
"cleanup")
stop_services
cleanup
;;
"logs")
docker-compose logs -f "${2:-tsp-assistant}"
;;
"status")
docker-compose ps
;;
*)
echo "用法: $0 {start|stop|restart|cleanup|logs|status}"
echo " start - 启动所有服务"
echo " stop - 停止所有服务"
echo " restart - 重启所有服务"
echo " cleanup - 清理Docker资源"
echo " logs - 查看日志 (可选指定服务名)"
echo " status - 查看服务状态"
exit 1
;;
esac
}
# 执行主函数
main "$@"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -37,8 +37,7 @@ class TSPAgentAssistantCore(TSPAssistant):
# 初始化智能Agent # 初始化智能Agent
self.intelligent_agent = IntelligentAgent( self.intelligent_agent = IntelligentAgent(
llm_manager=self.llm_manager, llm_client=self.llm_manager
agent_core=self.agent_core
) )
# 初始化动作执行器 # 初始化动作执行器
@@ -60,15 +59,30 @@ class TSPAgentAssistantCore(TSPAssistant):
if llm_config: if llm_config:
self.llm_manager = LLMManager(llm_config) self.llm_manager = LLMManager(llm_config)
else: else:
# 使用默认配置 - 千问模型 # 从统一配置管理器获取LLM配置
try:
from src.config.unified_config import get_config
unified_llm = get_config().llm
# 将统一配置的LLMConfig转换为agent需要的LLMConfig
agent_llm_config = LLMConfig(
provider=unified_llm.provider,
api_key=unified_llm.api_key,
base_url=unified_llm.base_url,
model=unified_llm.model,
temperature=unified_llm.temperature,
max_tokens=unified_llm.max_tokens
)
self.llm_manager = LLMManager(agent_llm_config)
except Exception as e:
logger.warning(f"无法从统一配置加载LLM配置使用config/llm_config.py: {e}")
try: try:
from config.llm_config import DEFAULT_CONFIG from config.llm_config import DEFAULT_CONFIG
self.llm_manager = LLMManager(DEFAULT_CONFIG) self.llm_manager = LLMManager(DEFAULT_CONFIG)
except ImportError: except ImportError:
# 如果配置文件不存在,使用内置配置 # 最后的fallback
default_config = LLMConfig( default_config = LLMConfig(
provider="openai", provider="qwen",
api_key="sk-your-qwen-api-key-here", api_key="",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen-turbo", model="qwen-turbo",
temperature=0.7, temperature=0.7,

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -167,6 +167,17 @@ class AlertSystem:
except Exception as e: except Exception as e:
logger.error(f"检查规则 {rule_name} 失败: {e}") logger.error(f"检查规则 {rule_name} 失败: {e}")
# 如果规则检查失败,也可以考虑生成一个系统级别的预警
system_alert = {
"rule_name": f"系统预警 - 规则检查失败: {rule_name}",
"alert_type": AlertType.SYSTEM.value,
"level": AlertLevel.ERROR.value,
"message": f"规则 \'{rule_name}\' 检查失败: {e}",
"data": {"error": str(e)},
"timestamp": datetime.now().isoformat(),
"rule_id": "system_rule_check_failure"
}
self._save_alert(system_alert) # 保存系统预警
return triggered_alerts return triggered_alerts
@@ -238,6 +249,8 @@ class AlertSystem:
except Exception as e: except Exception as e:
logger.error(f"获取规则数据失败: {e}") logger.error(f"获取规则数据失败: {e}")
# 重新抛出异常,让上层调用者决定如何处理
raise
return data return data

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -11,6 +11,7 @@ class Config:
# 数据库配置 # 数据库配置
DATABASE_URL = "mysql+pymysql://tsp_assistant:123456@43.134.68.207/tsp_assistant?charset=utf8mb4" DATABASE_URL = "mysql+pymysql://tsp_assistant:123456@43.134.68.207/tsp_assistant?charset=utf8mb4"
# DATABASE_URL = "sqlite:///tsp_assistant.db" # 本地测试数据库
# 知识库配置 # 知识库配置
KNOWLEDGE_BASE_PATH = "data/knowledge_base" KNOWLEDGE_BASE_PATH = "data/knowledge_base"

View File

@@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
@dataclass @dataclass
class DatabaseConfig: class DatabaseConfig:
"""数据库配置""" """数据库配置"""
url: str = "mysql+pymysql://tsp_assistant:password@43.134.68.207/tsp_assistant?charset=utf8mb4" url: str = "mysql+pymysql://tsp_assistant:password@jeason.online/tsp_assistant?charset=utf8mb4"
pool_size: int = 10 pool_size: int = 10
max_overflow: int = 20 max_overflow: int = 20
pool_timeout: int = 30 pool_timeout: int = 30
@@ -27,10 +27,10 @@ class DatabaseConfig:
@dataclass @dataclass
class LLMConfig: class LLMConfig:
"""LLM配置""" """LLM配置"""
provider: str = "openai" provider: str = "qwen"
api_key: str = "" api_key: str = "sk-c0dbefa1718d46eaa897199135066f00"
base_url: str = "https://dashscope.aliyuncs.com/compatible-mode/v1" base_url: str = "https://dashscope.aliyuncs.com/compatible-mode/v1"
model: str = "qwen-turbo" model: str = "qwen-plus-latest"
temperature: float = 0.7 temperature: float = 0.7
max_tokens: int = 2000 max_tokens: int = 2000
timeout: int = 30 timeout: int = 30
@@ -84,9 +84,9 @@ class UnifiedConfig:
self.config_dir = Path(config_dir) self.config_dir = Path(config_dir)
self.config_file = self.config_dir / "unified_config.json" self.config_file = self.config_dir / "unified_config.json"
# 默认配置 # 默认配置 - 从config/llm_config.py加载默认LLM配置
self.database = DatabaseConfig() self.database = DatabaseConfig()
self.llm = LLMConfig() self.llm = self._load_default_llm_config()
self.server = ServerConfig() self.server = ServerConfig()
self.feishu = FeishuConfig() self.feishu = FeishuConfig()
self.ai_accuracy = AIAccuracyConfig() self.ai_accuracy = AIAccuracyConfig()
@@ -95,6 +95,23 @@ class UnifiedConfig:
# 加载配置 # 加载配置
self.load_config() self.load_config()
def _load_default_llm_config(self) -> LLMConfig:
"""加载默认LLM配置"""
try:
from config.llm_config import DEFAULT_CONFIG
# 将config/llm_config.py中的配置转换为统一配置的格式
return LLMConfig(
provider=DEFAULT_CONFIG.provider,
api_key=DEFAULT_CONFIG.api_key,
base_url=DEFAULT_CONFIG.base_url,
model=DEFAULT_CONFIG.model,
temperature=DEFAULT_CONFIG.temperature,
max_tokens=DEFAULT_CONFIG.max_tokens
)
except Exception as e:
logger.warning(f"无法加载默认LLM配置使用内置默认值: {e}")
return LLMConfig()
def load_config(self): def load_config(self):
"""加载配置文件""" """加载配置文件"""
try: try:

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More