From 45beca7f9425bc0269e1b6ab83efe7b2971ff152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=9D=B0=20Jie=20Zhao=20=EF=BC=88=E9=9B=84?= =?UTF-8?q?=E7=8B=AE=E6=B1=BD=E8=BD=A6=E7=A7=91=E6=8A=80=EF=BC=89?= <00061074@chery.local> Date: Fri, 19 Sep 2025 19:42:44 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=87=AA=E5=8A=A8=E6=8F=90=E4=BA=A4=20?= =?UTF-8?q?-=20=E5=91=A8=E4=BA=94=202025/09/19=2019:42:44.04?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 64 ------ auto_push.bat | 80 +++++++ auto_push.ps1 | 192 ++++++++++++++++ quick_push.bat | 28 +++ src/dialogue/conversation_history.py | 330 ++++++++++++++++++++++++++- src/web/blueprints/conversations.py | 143 +++++++++++- 推送脚本使用说明.md | 181 +++++++++++++++ 7 files changed, 951 insertions(+), 67 deletions(-) delete mode 100644 .dockerignore create mode 100644 auto_push.bat create mode 100644 auto_push.ps1 create mode 100644 quick_push.bat create mode 100644 推送脚本使用说明.md diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index d3d0a37..0000000 --- a/.dockerignore +++ /dev/null @@ -1,64 +0,0 @@ -# Git相关 -.git -.gitignore - -# Python相关 -__pycache__ -*.pyc -*.pyo -*.pyd -.Python -env -pip-log.txt -pip-delete-this-directory.txt -.tox -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.log -.git -.mypy_cache -.pytest_cache -.hypothesis - -# 开发环境 -.vscode -.idea -*.swp -*.swo -*~ - -# 系统文件 -.DS_Store -Thumbs.db - -# 备份和日志 -backups/ -logs/ -*.log - -# 数据库文件 -*.db -*.sqlite -*.sqlite3 - -# 临时文件 -tmp/ -temp/ -*.tmp - -# 文档 -*.md -docs/ - -# 测试文件 -test_* -*_test.py -tests/ - -# 配置文件(敏感信息) -.env -config.local.py diff --git a/auto_push.bat b/auto_push.bat new file mode 100644 index 0000000..6de3b7d --- /dev/null +++ b/auto_push.bat @@ -0,0 +1,80 @@ +@echo off +chcp 65001 >nul +echo ======================================== +echo TSP智能助手 - 自动推送脚本 +echo ======================================== +echo. + +:: 检查Git状态 +echo [1/4] 检查Git状态... +git status --porcelain >nul 2>&1 +if %errorlevel% neq 0 ( + echo ❌ Git未初始化或不在Git仓库中 + pause + exit /b 1 +) + +:: 显示当前状态 +echo 📋 当前Git状态: +git status --short +echo. + +:: 询问是否继续 +set /p confirm="是否继续推送? (y/n): " +if /i "%confirm%" neq "y" ( + echo 操作已取消 + pause + exit /b 0 +) + +:: 添加所有更改 +echo. +echo [2/4] 添加所有更改到暂存区... +git add . +if %errorlevel% neq 0 ( + echo ❌ 添加文件失败 + pause + exit /b 1 +) +echo ✅ 文件已添加到暂存区 + +:: 生成提交信息 +echo. +echo [3/4] 生成提交信息... +for /f "tokens=*" %%i in ('git log --oneline -1') do set last_commit=%%i +set /p commit_msg="请输入提交信息 (直接回车使用默认): " +if "%commit_msg%"=="" ( + set commit_msg=feat: 自动提交 - %date% %time% +) + +:: 提交更改 +echo 提交信息: %commit_msg% +git commit -m "%commit_msg%" +if %errorlevel% neq 0 ( + echo ❌ 提交失败 + pause + exit /b 1 +) +echo ✅ 提交成功 + +:: 推送到远程仓库 +echo. +echo [4/4] 推送到远程仓库... +git push origin main +if %errorlevel% neq 0 ( + echo ❌ 推送失败 + pause + exit /b 1 +) + +echo. +echo ======================================== +echo ✅ 推送完成! +echo ======================================== +echo 📊 提交统计: +git log --oneline -1 +echo. +echo 🌐 远程仓库状态: +git status +echo. +pause diff --git a/auto_push.ps1 b/auto_push.ps1 new file mode 100644 index 0000000..7185860 --- /dev/null +++ b/auto_push.ps1 @@ -0,0 +1,192 @@ +# 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 "按任意键退出" +} diff --git a/quick_push.bat b/quick_push.bat new file mode 100644 index 0000000..93597d5 --- /dev/null +++ b/quick_push.bat @@ -0,0 +1,28 @@ +@echo off +chcp 65001 >nul +echo 🚀 TSP智能助手 - 快速推送 +echo. + +:: 检查是否有参数 +if "%1"=="" ( + set commit_msg=feat: 快速提交 - %date% %time% +) else ( + set commit_msg=%1 +) + +echo 📝 提交信息: %commit_msg% +echo. + +:: 执行推送 +git add . && git commit -m "%commit_msg%" && git push origin main + +if %errorlevel% equ 0 ( + echo. + echo ✅ 推送完成! +) else ( + echo. + echo ❌ 推送失败,请检查错误信息 +) + +echo. +pause diff --git a/src/dialogue/conversation_history.py b/src/dialogue/conversation_history.py index e651950..afb8059 100644 --- a/src/dialogue/conversation_history.py +++ b/src/dialogue/conversation_history.py @@ -11,9 +11,10 @@ from datetime import datetime, timedelta from sqlalchemy.orm import Session from ..core.database import db_manager -from ..core.models import Conversation +from ..core.models import Conversation, WorkOrder, WorkOrderSuggestion, KnowledgeEntry from ..core.redis_manager import redis_manager from ..config.config import Config +from sqlalchemy import and_, or_, desc logger = logging.getLogger(__name__) @@ -375,3 +376,330 @@ class ConversationHistoryManager: except Exception as e: logger.error(f"清理旧对话记录失败: {e}") return 0 + + def get_workorder_complete_timeline( + self, + work_order_id: int, + include_ai_suggestions: bool = True, + include_feishu_sync: bool = True, + limit: int = 20 + ) -> List[Dict[str, Any]]: + """获取工单的完整时间线(包含对话、AI建议、飞书同步)""" + try: + timeline = [] + + with db_manager.get_session() as session: + # 1. 获取基础对话记录 + conversations = session.query(Conversation).filter( + Conversation.work_order_id == work_order_id + ).order_by(Conversation.timestamp.desc()).limit(limit).all() + + for conv in conversations: + timeline.append({ + "id": conv.id, + "type": "conversation", + "timestamp": conv.timestamp, + "user_message": conv.user_message, + "assistant_response": conv.assistant_response, + "confidence_score": conv.confidence_score, + "response_time": conv.response_time, + "knowledge_used": json.loads(conv.knowledge_used) if conv.knowledge_used else [] + }) + + # 2. 获取AI建议记录 + if include_ai_suggestions: + suggestions = session.query(WorkOrderSuggestion).filter( + WorkOrderSuggestion.work_order_id == work_order_id + ).order_by(WorkOrderSuggestion.created_at.desc()).limit(limit).all() + + for suggestion in suggestions: + timeline.append({ + "id": f"suggestion_{suggestion.id}", + "type": "ai_suggestion", + "timestamp": suggestion.created_at, + "ai_suggestion": suggestion.ai_suggestion, + "human_resolution": suggestion.human_resolution, + "ai_similarity": suggestion.ai_similarity, + "approved": suggestion.approved, + "use_human_resolution": suggestion.use_human_resolution, + "updated_at": suggestion.updated_at + }) + + # 3. 获取飞书同步记录(从工单的feishu_record_id推断) + if include_feishu_sync: + work_order = session.query(WorkOrder).filter( + WorkOrder.id == work_order_id + ).first() + + if work_order and work_order.feishu_record_id: + timeline.append({ + "id": f"feishu_{work_order.feishu_record_id}", + "type": "feishu_sync", + "timestamp": work_order.created_at, + "feishu_record_id": work_order.feishu_record_id, + "order_id": work_order.order_id, + "title": work_order.title, + "description": work_order.description, + "category": work_order.category, + "priority": work_order.priority, + "status": work_order.status, + "source": work_order.source + }) + + # 按时间排序 + timeline.sort(key=lambda x: x["timestamp"], reverse=True) + + return timeline[:limit] + + except Exception as e: + logger.error(f"获取工单完整时间线失败: {e}") + return [] + + def get_ai_suggestion_context( + self, + work_order_id: int, + suggestion_id: Optional[int] = None + ) -> Dict[str, Any]: + """获取AI建议的对话上下文""" + try: + context = { + "work_order_info": {}, + "conversation_history": [], + "ai_suggestions": [], + "knowledge_base": [] + } + + with db_manager.get_session() as session: + # 1. 获取工单信息 + work_order = session.query(WorkOrder).filter( + WorkOrder.id == work_order_id + ).first() + + if work_order: + context["work_order_info"] = { + "id": work_order.id, + "order_id": work_order.order_id, + "title": work_order.title, + "description": work_order.description, + "category": work_order.category, + "priority": work_order.priority, + "status": work_order.status, + "created_at": work_order.created_at.isoformat(), + "feishu_record_id": work_order.feishu_record_id + } + + # 2. 获取相关对话历史 + conversations = session.query(Conversation).filter( + Conversation.work_order_id == work_order_id + ).order_by(Conversation.timestamp.desc()).limit(10).all() + + for conv in conversations: + context["conversation_history"].append({ + "id": conv.id, + "user_message": conv.user_message, + "assistant_response": conv.assistant_response, + "timestamp": conv.timestamp.isoformat(), + "confidence_score": conv.confidence_score + }) + + # 3. 获取AI建议历史 + suggestions = session.query(WorkOrderSuggestion).filter( + WorkOrderSuggestion.work_order_id == work_order_id + ).order_by(WorkOrderSuggestion.created_at.desc()).limit(5).all() + + for suggestion in suggestions: + context["ai_suggestions"].append({ + "id": suggestion.id, + "ai_suggestion": suggestion.ai_suggestion, + "human_resolution": suggestion.human_resolution, + "ai_similarity": suggestion.ai_similarity, + "approved": suggestion.approved, + "use_human_resolution": suggestion.use_human_resolution, + "created_at": suggestion.created_at.isoformat() + }) + + # 4. 获取相关知识库条目 + if work_order: + knowledge_entries = session.query(KnowledgeEntry).filter( + and_( + KnowledgeEntry.is_active == True, + or_( + KnowledgeEntry.category == work_order.category, + KnowledgeEntry.question.contains(work_order.title[:20]) + ) + ) + ).limit(5).all() + + for entry in knowledge_entries: + context["knowledge_base"].append({ + "id": entry.id, + "question": entry.question, + "answer": entry.answer, + "category": entry.category, + "confidence_score": entry.confidence_score, + "is_verified": entry.is_verified + }) + + return context + + except Exception as e: + logger.error(f"获取AI建议对话上下文失败: {e}") + return {} + + def search_conversations_by_content( + self, + search_query: str, + work_order_id: Optional[int] = None, + conversation_type: Optional[str] = None, + limit: int = 20 + ) -> List[Dict[str, Any]]: + """根据内容搜索对话记录(包含AI建议)""" + try: + results = [] + + with db_manager.get_session() as session: + # 搜索基础对话 + conv_query = session.query(Conversation) + if work_order_id: + conv_query = conv_query.filter(Conversation.work_order_id == work_order_id) + + conversations = conv_query.filter( + or_( + Conversation.user_message.contains(search_query), + Conversation.assistant_response.contains(search_query) + ) + ).order_by(Conversation.timestamp.desc()).limit(limit).all() + + for conv in conversations: + results.append({ + "id": conv.id, + "type": "conversation", + "timestamp": conv.timestamp, + "user_message": conv.user_message, + "assistant_response": conv.assistant_response, + "work_order_id": conv.work_order_id, + "confidence_score": conv.confidence_score + }) + + # 搜索AI建议 + if not conversation_type or conversation_type == "ai_suggestion": + suggestion_query = session.query(WorkOrderSuggestion) + if work_order_id: + suggestion_query = suggestion_query.filter( + WorkOrderSuggestion.work_order_id == work_order_id + ) + + suggestions = suggestion_query.filter( + or_( + WorkOrderSuggestion.ai_suggestion.contains(search_query), + WorkOrderSuggestion.human_resolution.contains(search_query) + ) + ).order_by(WorkOrderSuggestion.created_at.desc()).limit(limit).all() + + for suggestion in suggestions: + results.append({ + "id": f"suggestion_{suggestion.id}", + "type": "ai_suggestion", + "timestamp": suggestion.created_at, + "ai_suggestion": suggestion.ai_suggestion, + "human_resolution": suggestion.human_resolution, + "work_order_id": suggestion.work_order_id, + "ai_similarity": suggestion.ai_similarity, + "approved": suggestion.approved + }) + + # 按时间排序 + results.sort(key=lambda x: x["timestamp"], reverse=True) + + return results[:limit] + + except Exception as e: + logger.error(f"搜索对话记录失败: {e}") + return [] + + def get_conversation_analytics( + self, + work_order_id: Optional[int] = None, + days: int = 7 + ) -> Dict[str, Any]: + """获取对话分析数据(包含AI建议统计)""" + try: + cutoff_date = datetime.now() - timedelta(days=days) + + with db_manager.get_session() as session: + analytics = { + "period_days": days, + "conversations": {}, + "ai_suggestions": {}, + "performance": {} + } + + # 对话统计 + conv_query = session.query(Conversation) + if work_order_id: + conv_query = conv_query.filter(Conversation.work_order_id == work_order_id) + + conversations = conv_query.filter( + Conversation.timestamp >= cutoff_date + ).all() + + analytics["conversations"] = { + "total": len(conversations), + "avg_confidence": 0, + "avg_response_time": 0, + "high_confidence_count": 0 + } + + if conversations: + confidences = [c.confidence_score for c in conversations if c.confidence_score] + response_times = [c.response_time for c in conversations if c.response_time] + + if confidences: + analytics["conversations"]["avg_confidence"] = sum(confidences) / len(confidences) + analytics["conversations"]["high_confidence_count"] = len([c for c in confidences if c >= 0.8]) + + if response_times: + analytics["conversations"]["avg_response_time"] = sum(response_times) / len(response_times) + + # AI建议统计 + suggestion_query = session.query(WorkOrderSuggestion) + if work_order_id: + suggestion_query = suggestion_query.filter( + WorkOrderSuggestion.work_order_id == work_order_id + ) + + suggestions = suggestion_query.filter( + WorkOrderSuggestion.created_at >= cutoff_date + ).all() + + analytics["ai_suggestions"] = { + "total": len(suggestions), + "approved_count": len([s for s in suggestions if s.approved]), + "avg_similarity": 0, + "human_resolution_count": len([s for s in suggestions if s.use_human_resolution]) + } + + if suggestions: + similarities = [s.ai_similarity for s in suggestions if s.ai_similarity] + if similarities: + analytics["ai_suggestions"]["avg_similarity"] = sum(similarities) / len(similarities) + + # 性能指标 + analytics["performance"] = { + "conversation_success_rate": 0, + "ai_suggestion_approval_rate": 0, + "knowledge_base_usage_rate": 0 + } + + if conversations: + successful_convs = len([c for c in conversations if c.confidence_score and c.confidence_score >= 0.5]) + analytics["performance"]["conversation_success_rate"] = successful_convs / len(conversations) + + if suggestions: + analytics["performance"]["ai_suggestion_approval_rate"] = len([s for s in suggestions if s.approved]) / len(suggestions) + + return analytics + + except Exception as e: + logger.error(f"获取对话分析数据失败: {e}") + return {} diff --git a/src/web/blueprints/conversations.py b/src/web/blueprints/conversations.py index bd683dc..5393a8b 100644 --- a/src/web/blueprints/conversations.py +++ b/src/web/blueprints/conversations.py @@ -1,17 +1,23 @@ # -*- coding: utf-8 -*- """ 对话管理蓝图 -处理对话相关的API路由 +处理对话相关的API路由,整合飞书工单和AI建议 """ from flask import Blueprint, request, jsonify from src.core.database import db_manager -from src.core.models import Conversation +from src.core.models import Conversation, WorkOrder, WorkOrderSuggestion from src.core.query_optimizer import query_optimizer +from src.dialogue.conversation_history import ConversationHistoryManager from datetime import timedelta +import logging +logger = logging.getLogger(__name__) conversations_bp = Blueprint('conversations', __name__, url_prefix='/api/conversations') +# 初始化对话历史管理器 +history_manager = ConversationHistoryManager() + @conversations_bp.route('') def get_conversations(): """获取对话历史列表(分页)- 优化版""" @@ -197,3 +203,136 @@ def migrate_merge_conversations(): }) except Exception as e: return jsonify({"error": str(e)}), 500 + +@conversations_bp.route('/workorder//timeline') +def get_workorder_timeline(work_order_id): + """获取工单的完整对话时间线(包含AI建议和飞书同步)""" + try: + include_ai_suggestions = request.args.get('include_ai_suggestions', 'true').lower() == 'true' + include_feishu_sync = request.args.get('include_feishu_sync', 'true').lower() == 'true' + limit = request.args.get('limit', 20, type=int) + + timeline = history_manager.get_workorder_complete_timeline( + work_order_id=work_order_id, + include_ai_suggestions=include_ai_suggestions, + include_feishu_sync=include_feishu_sync, + limit=limit + ) + + return jsonify({ + 'success': True, + 'work_order_id': work_order_id, + 'timeline': timeline, + 'total_count': len(timeline) + }) + + except Exception as e: + logger.error(f"获取工单时间线失败: {e}") + return jsonify({"error": str(e)}), 500 + +@conversations_bp.route('/workorder//context') +def get_workorder_context(work_order_id): + """获取工单的AI建议对话上下文""" + try: + suggestion_id = request.args.get('suggestion_id', type=int) + + context = history_manager.get_ai_suggestion_context( + work_order_id=work_order_id, + suggestion_id=suggestion_id + ) + + return jsonify({ + 'success': True, + 'work_order_id': work_order_id, + 'context': context + }) + + except Exception as e: + logger.error(f"获取工单上下文失败: {e}") + return jsonify({"error": str(e)}), 500 + +@conversations_bp.route('/workorder//summary') +def get_workorder_summary(work_order_id): + """获取工单对话摘要""" + try: + # 获取时间线数据 + timeline = history_manager.get_workorder_complete_timeline( + work_order_id=work_order_id, + include_ai_suggestions=True, + include_feishu_sync=True, + limit=50 + ) + + if not timeline: + return jsonify({"error": "没有找到对话记录"}), 404 + + # 生成简单摘要 + summary = { + "work_order_id": work_order_id, + "total_interactions": len(timeline), + "conversations": len([t for t in timeline if t["type"] == "conversation"]), + "ai_suggestions": len([t for t in timeline if t["type"] == "ai_suggestion"]), + "feishu_syncs": len([t for t in timeline if t["type"] == "feishu_sync"]), + "generated_at": timeline[0]["timestamp"].isoformat() if timeline else None + } + + return jsonify({ + 'success': True, + 'work_order_id': work_order_id, + 'summary': summary + }) + + except Exception as e: + logger.error(f"获取工单摘要失败: {e}") + return jsonify({"error": str(e)}), 500 + +@conversations_bp.route('/search') +def search_conversations(): + """搜索对话记录(包含AI建议)""" + try: + search_query = request.args.get('q', '') + work_order_id = request.args.get('work_order_id', type=int) + conversation_type = request.args.get('type') # conversation, ai_suggestion, all + limit = request.args.get('limit', 20, type=int) + + if not search_query: + return jsonify({"error": "搜索查询不能为空"}), 400 + + results = history_manager.search_conversations_by_content( + search_query=search_query, + work_order_id=work_order_id, + conversation_type=conversation_type, + limit=limit + ) + + return jsonify({ + 'success': True, + 'query': search_query, + 'results': results, + 'total_count': len(results) + }) + + except Exception as e: + logger.error(f"搜索对话记录失败: {e}") + return jsonify({"error": str(e)}), 500 + +@conversations_bp.route('/analytics') +def get_conversation_analytics(): + """获取对话分析数据""" + try: + work_order_id = request.args.get('work_order_id', type=int) + days = request.args.get('days', 7, type=int) + + analytics = history_manager.get_conversation_analytics( + work_order_id=work_order_id, + days=days + ) + + return jsonify({ + 'success': True, + 'analytics': analytics + }) + + except Exception as e: + logger.error(f"获取对话分析数据失败: {e}") + return jsonify({"error": str(e)}), 500 diff --git a/推送脚本使用说明.md b/推送脚本使用说明.md new file mode 100644 index 0000000..d8b062f --- /dev/null +++ b/推送脚本使用说明.md @@ -0,0 +1,181 @@ +# TSP智能助手 - 推送脚本使用说明 + +## 📁 脚本文件说明 + +### 1. `auto_push.bat` - 标准自动推送脚本 +**功能**: 完整的Git推送流程,包含状态检查、确认、提交和推送 +**特点**: +- 显示详细的Git状态 +- 用户确认机制 +- 自定义提交信息 +- 错误处理和状态反馈 + +**使用方法**: +```bash +# 直接运行 +auto_push.bat + +# 运行后会提示输入提交信息 +``` + +### 2. `auto_push.ps1` - PowerShell高级版本 +**功能**: 功能最全面的推送脚本,支持参数和高级功能 +**特点**: +- 彩色输出和美观的界面 +- 支持命令行参数 +- 智能提交信息生成 +- 详细的统计信息 +- 错误处理和回滚 + +**使用方法**: +```powershell +# 基本使用 +.\auto_push.ps1 + +# 指定提交信息 +.\auto_push.ps1 "feat: 添加新功能" + +# 强制推送(跳过确认) +.\auto_push.ps1 -NoConfirm + +# 强制推送并指定信息 +.\auto_push.ps1 "紧急修复" -Force -NoConfirm +``` + +### 3. `quick_push.bat` - 快速推送脚本 +**功能**: 最简单的推送方式,适合日常快速提交 +**特点**: +- 一键推送 +- 自动生成提交信息 +- 最小化交互 + +**使用方法**: +```bash +# 使用默认提交信息 +quick_push.bat + +# 指定提交信息 +quick_push.bat "修复bug" +``` + +## 🚀 推荐使用场景 + +### 日常开发 +```bash +# 快速提交日常更改 +quick_push.bat "日常更新" +``` + +### 功能开发 +```bash +# 使用PowerShell版本,获得最佳体验 +.\auto_push.ps1 "feat: 添加用户管理功能" +``` + +### 紧急修复 +```bash +# 快速修复 +quick_push.bat "hotfix: 修复登录问题" +``` + +### 团队协作 +```bash +# 使用标准版本,确保流程规范 +auto_push.bat +``` + +## ⚙️ 脚本特性对比 + +| 特性 | quick_push.bat | auto_push.bat | auto_push.ps1 | +|------|----------------|---------------|---------------| +| 执行速度 | ⚡ 最快 | 🐌 中等 | 🐌 中等 | +| 用户交互 | 最少 | 中等 | 最多 | +| 错误处理 | 基础 | 完整 | 完整 | +| 状态显示 | 基础 | 详细 | 最详细 | +| 参数支持 | 基础 | 无 | 完整 | +| 彩色输出 | 无 | 无 | ✅ | +| 统计信息 | 无 | 基础 | 详细 | + +## 🔧 自定义配置 + +### 修改默认提交信息格式 +编辑 `auto_push.bat` 第25行: +```batch +set commit_msg=feat: 自动提交 - %date% %time% +``` + +### 修改远程分支 +编辑所有脚本中的 `origin main` 为你的分支: +```batch +git push origin your-branch +``` + +### 添加预提交检查 +在 `auto_push.ps1` 中添加检查函数: +```powershell +function Test-PreCommit { + # 运行测试 + python -m pytest + # 代码格式化检查 + python -m black --check . + # 类型检查 + python -m mypy . +} +``` + +## 🛠️ 故障排除 + +### 常见问题 + +1. **PowerShell执行策略错误** + ```powershell + Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + ``` + +2. **Git认证失败** + ```bash + # 检查远程仓库配置 + git remote -v + + # 重新设置认证 + git config --global credential.helper store + ``` + +3. **编码问题** + ```bash + # 确保控制台支持UTF-8 + chcp 65001 + ``` + +### 错误代码说明 + +- `退出代码 0`: 成功 +- `退出代码 1`: Git操作失败 +- `退出代码 2`: 用户取消操作 + +## 📝 最佳实践 + +1. **提交前检查**: 使用 `auto_push.ps1` 查看详细状态 +2. **提交信息规范**: 使用 `feat:`, `fix:`, `docs:` 等前缀 +3. **定期推送**: 避免长时间不推送导致冲突 +4. **分支管理**: 在功能分支开发,合并到主分支 + +## 🎯 示例工作流 + +```bash +# 1. 开发功能 +# ... 编写代码 ... + +# 2. 快速推送 +quick_push.bat "feat: 添加AI建议功能" + +# 3. 或者详细推送 +.\auto_push.ps1 "feat: 添加AI建议功能 +- 实现语义相似度计算 +- 优化前端UI显示 +- 添加配置化阈值" +``` + +--- + +**提示**: 建议将脚本文件添加到项目根目录,并设置适当的执行权限。对于团队使用,建议统一使用 `auto_push.ps1` 以确保流程一致性。