feat(202510100001): 添加pythonAI服务
This commit is contained in:
parent
69d19adf33
commit
1f981f336d
65
ai_review_service/README.md
Normal file
65
ai_review_service/README.md
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
# TYCM AI Review Service - 最小实现版本
|
||||||
|
|
||||||
|
## 🚀 快速启动
|
||||||
|
|
||||||
|
### 1. 安装依赖
|
||||||
|
```bash
|
||||||
|
cd D:\project-tycm\tycm_service_ai\ai_review_service
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 启动服务
|
||||||
|
```bash
|
||||||
|
python run.py
|
||||||
|
```
|
||||||
|
|
||||||
|
服务将在 `http://localhost:8080` 启动
|
||||||
|
|
||||||
|
### 3. 访问文档
|
||||||
|
- API文档: http://localhost:8080/docs
|
||||||
|
- 健康检查: http://localhost:8080/api/v1/health
|
||||||
|
|
||||||
|
## 📡 API接口
|
||||||
|
|
||||||
|
### POST /api/v1/audit
|
||||||
|
AI审核订单接口
|
||||||
|
|
||||||
|
**请求示例:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"order_id": "12345",
|
||||||
|
"order_status": "WAITEXAMINE",
|
||||||
|
"oem_id": 2,
|
||||||
|
"car_type": "0",
|
||||||
|
"card_name": "张三",
|
||||||
|
"card_number": "123456789012345678",
|
||||||
|
"car_frame": "WDDGF4HB9CA123456",
|
||||||
|
"buyer_name": "张三",
|
||||||
|
"id_card_score": 85,
|
||||||
|
"bill_score": 92
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"result": "PASS",
|
||||||
|
"confidence": 0.95,
|
||||||
|
"reason": "AI审核通过",
|
||||||
|
"decision_path": [
|
||||||
|
{"node": "PRE_CHECK", "condition": "all_preconditions_met", "result": true},
|
||||||
|
{"node": "BUSINESS_RULES", "condition": "all_business_rules_passed", "result": true}
|
||||||
|
],
|
||||||
|
"processing_time_ms": 150
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 配置说明
|
||||||
|
|
||||||
|
- 默认端口: 8080
|
||||||
|
- 支持跨域: 是
|
||||||
|
- 日志级别: INFO
|
||||||
|
|
||||||
|
## ⚡ Java集成
|
||||||
|
|
||||||
|
参考 Java 服务中的 DecisionTreeService 调用此服务。
|
0
ai_review_service/app/__init__.py
Normal file
0
ai_review_service/app/__init__.py
Normal file
0
ai_review_service/app/api/__init__.py
Normal file
0
ai_review_service/app/api/__init__.py
Normal file
0
ai_review_service/app/api/endpoints/__init__.py
Normal file
0
ai_review_service/app/api/endpoints/__init__.py
Normal file
57
ai_review_service/app/api/endpoints/audit.py
Normal file
57
ai_review_service/app/api/endpoints/audit.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
from fastapi import APIRouter, HTTPException
|
||||||
|
from app.models.request import AuditRequest
|
||||||
|
from app.models.response import AuditResponse
|
||||||
|
from app.services.audit_service import AuditService
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# 配置日志
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/api/v1", tags=["audit"])
|
||||||
|
|
||||||
|
# 创建审核服务实例
|
||||||
|
audit_service = AuditService()
|
||||||
|
|
||||||
|
@router.post("/audit", response_model=AuditResponse)
|
||||||
|
async def audit_order(request: AuditRequest):
|
||||||
|
"""
|
||||||
|
AI审核订单接口
|
||||||
|
|
||||||
|
接收订单信息,执行AI智能审核,返回审核结果
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
logger.info(f"开始审核订单: {request.order_id}")
|
||||||
|
|
||||||
|
# 执行审核
|
||||||
|
result = await audit_service.audit_order(request)
|
||||||
|
|
||||||
|
logger.info(f"订单审核完成: {request.order_id}, 结果: {result.result}")
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"订单审核失败: {request.order_id}, 错误: {str(e)}")
|
||||||
|
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=500,
|
||||||
|
detail={
|
||||||
|
"error": "AI审核服务异常",
|
||||||
|
"order_id": request.order_id,
|
||||||
|
"message": str(e)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
@router.get("/health")
|
||||||
|
async def health_check():
|
||||||
|
"""健康检查接口"""
|
||||||
|
return {"status": "healthy", "service": "ai_review_service"}
|
||||||
|
|
||||||
|
@router.get("/version")
|
||||||
|
async def get_version():
|
||||||
|
"""版本信息接口"""
|
||||||
|
return {
|
||||||
|
"service": "TYCM AI Review Service",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "AI智能审核服务 - 最小实现版本"
|
||||||
|
}
|
44
ai_review_service/app/main.py
Normal file
44
ai_review_service/app/main.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from app.api.endpoints import audit
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
# 创建FastAPI应用
|
||||||
|
app = FastAPI(
|
||||||
|
title="TYCM AI Review Service",
|
||||||
|
description="车主权益管理系统AI智能审核服务",
|
||||||
|
version="1.0.0",
|
||||||
|
docs_url="/docs",
|
||||||
|
redoc_url="/redoc"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 配置CORS
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"], # 开发环境允许所有来源
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# 注册路由
|
||||||
|
app.include_router(audit.router)
|
||||||
|
|
||||||
|
# 根路径
|
||||||
|
@app.get("/")
|
||||||
|
async def root():
|
||||||
|
return {
|
||||||
|
"message": "TYCM AI Review Service",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"status": "running",
|
||||||
|
"docs": "/docs"
|
||||||
|
}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
uvicorn.run(
|
||||||
|
"app.main:app",
|
||||||
|
host="0.0.0.0",
|
||||||
|
port=8081, # 改为8081端口
|
||||||
|
reload=True,
|
||||||
|
log_level="info"
|
||||||
|
)
|
0
ai_review_service/app/models/__init__.py
Normal file
0
ai_review_service/app/models/__init__.py
Normal file
29
ai_review_service/app/models/request.py
Normal file
29
ai_review_service/app/models/request.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from typing import Optional
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
class AuditRequest(BaseModel):
|
||||||
|
"""AI审核请求模型"""
|
||||||
|
# 订单基础信息
|
||||||
|
order_id: str = Field(..., description="订单ID")
|
||||||
|
order_status: str = Field(..., description="订单状态")
|
||||||
|
oem_id: int = Field(..., description="主机厂ID")
|
||||||
|
car_type: str = Field(..., description="车辆类型")
|
||||||
|
|
||||||
|
# 车主信息
|
||||||
|
card_name: str = Field(..., description="身份证姓名")
|
||||||
|
card_number: str = Field(..., description="身份证号")
|
||||||
|
|
||||||
|
# 车辆信息
|
||||||
|
car_frame: str = Field(..., description="车架号")
|
||||||
|
purchase_time: Optional[str] = Field(None, description="购车时间")
|
||||||
|
vehicle_price: Optional[str] = Field(None, description="车辆价格")
|
||||||
|
|
||||||
|
# AI识别结果
|
||||||
|
recognized_name: Optional[str] = Field(None, description="识别的姓名")
|
||||||
|
recognized_id: Optional[str] = Field(None, description="识别的身份证号")
|
||||||
|
buyer_name: Optional[str] = Field(None, description="购买方名称")
|
||||||
|
|
||||||
|
# 计分信息
|
||||||
|
id_card_score: Optional[int] = Field(None, description="身份证得分")
|
||||||
|
bill_score: Optional[int] = Field(None, description="发票得分")
|
30
ai_review_service/app/models/response.py
Normal file
30
ai_review_service/app/models/response.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
class DecisionPath(BaseModel):
|
||||||
|
"""决策路径"""
|
||||||
|
node: str = Field(..., description="决策节点")
|
||||||
|
condition: str = Field(..., description="判断条件")
|
||||||
|
result: bool = Field(..., description="条件结果")
|
||||||
|
|
||||||
|
class AuditResponse(BaseModel):
|
||||||
|
"""AI审核响应模型"""
|
||||||
|
result: str = Field(..., description="审核结果: PASS/REFUSE/MANUAL")
|
||||||
|
confidence: float = Field(..., description="置信度 0-1")
|
||||||
|
reason: str = Field(..., description="决策原因")
|
||||||
|
decision_path: List[DecisionPath] = Field(default_factory=list, description="决策路径")
|
||||||
|
processing_time_ms: int = Field(default=0, description="处理耗时(毫秒)")
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
json_schema_extra = {
|
||||||
|
"example": {
|
||||||
|
"result": "PASS",
|
||||||
|
"confidence": 0.95,
|
||||||
|
"reason": "所有验证通过,符合审核标准",
|
||||||
|
"decision_path": [
|
||||||
|
{"node": "PRE_CHECK", "condition": "order_status=WAITEXAMINE", "result": True},
|
||||||
|
{"node": "SCORING", "condition": "total_score>=threshold", "result": True}
|
||||||
|
],
|
||||||
|
"processing_time_ms": 150
|
||||||
|
}
|
||||||
|
}
|
0
ai_review_service/app/services/__init__.py
Normal file
0
ai_review_service/app/services/__init__.py
Normal file
131
ai_review_service/app/services/audit_service.py
Normal file
131
ai_review_service/app/services/audit_service.py
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
import time
|
||||||
|
from typing import Dict, Any
|
||||||
|
from app.models.request import AuditRequest
|
||||||
|
from app.models.response import AuditResponse, DecisionPath
|
||||||
|
|
||||||
|
class AuditService:
|
||||||
|
"""AI审核服务 - 最小实现版本"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def audit_order(self, request: AuditRequest) -> AuditResponse:
|
||||||
|
"""
|
||||||
|
执行AI审核 - 简化版本,模拟原有逻辑
|
||||||
|
"""
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
# 模拟决策路径
|
||||||
|
decision_path = []
|
||||||
|
|
||||||
|
# 1. 前置条件检查
|
||||||
|
if not self._check_preconditions(request, decision_path):
|
||||||
|
return self._build_response("REFUSE", 0.9, "前置条件不满足", decision_path, start_time)
|
||||||
|
|
||||||
|
# 2. 业务规则检查
|
||||||
|
business_result = self._check_business_rules(request, decision_path)
|
||||||
|
if business_result != "PASS":
|
||||||
|
return self._build_response(business_result, 0.85, "业务规则验证失败", decision_path, start_time)
|
||||||
|
|
||||||
|
# 3. 默认通过
|
||||||
|
decision_path.append(DecisionPath(
|
||||||
|
node="FINAL_DECISION",
|
||||||
|
condition="all_checks_passed",
|
||||||
|
result=True
|
||||||
|
))
|
||||||
|
|
||||||
|
return self._build_response("PASS", 0.95, "AI审核通过", decision_path, start_time)
|
||||||
|
|
||||||
|
def _check_preconditions(self, request: AuditRequest, decision_path: list) -> bool:
|
||||||
|
"""前置条件检查"""
|
||||||
|
# 订单状态检查
|
||||||
|
if request.order_status != "WAITEXAMINE":
|
||||||
|
decision_path.append(DecisionPath(
|
||||||
|
node="PRE_CHECK",
|
||||||
|
condition="order_status == WAITEXAMINE",
|
||||||
|
result=False
|
||||||
|
))
|
||||||
|
return False
|
||||||
|
|
||||||
|
# OEM检查
|
||||||
|
if request.oem_id != 2:
|
||||||
|
decision_path.append(DecisionPath(
|
||||||
|
node="PRE_CHECK",
|
||||||
|
condition="oem_id == 2",
|
||||||
|
result=False
|
||||||
|
))
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 车辆类型检查
|
||||||
|
if request.car_type != "0":
|
||||||
|
decision_path.append(DecisionPath(
|
||||||
|
node="PRE_CHECK",
|
||||||
|
condition="car_type == 0",
|
||||||
|
result=False
|
||||||
|
))
|
||||||
|
return False
|
||||||
|
|
||||||
|
decision_path.append(DecisionPath(
|
||||||
|
node="PRE_CHECK",
|
||||||
|
condition="all_preconditions_met",
|
||||||
|
result=True
|
||||||
|
))
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _check_business_rules(self, request: AuditRequest, decision_path: list) -> str:
|
||||||
|
"""业务规则检查"""
|
||||||
|
|
||||||
|
# 公司名称检查
|
||||||
|
if request.buyer_name and self._is_company_name(request.buyer_name):
|
||||||
|
decision_path.append(DecisionPath(
|
||||||
|
node="COMPANY_CHECK",
|
||||||
|
condition="is_not_company",
|
||||||
|
result=False
|
||||||
|
))
|
||||||
|
return "REFUSE"
|
||||||
|
|
||||||
|
# 姓名一致性检查
|
||||||
|
if request.buyer_name and request.card_name and request.buyer_name != request.card_name:
|
||||||
|
decision_path.append(DecisionPath(
|
||||||
|
node="NAME_CONSISTENCY",
|
||||||
|
condition="buyer_name == card_name",
|
||||||
|
result=False
|
||||||
|
))
|
||||||
|
return "REFUSE"
|
||||||
|
|
||||||
|
# 计分检查 (简化版)
|
||||||
|
total_score = (request.id_card_score or 0) + (request.bill_score or 0)
|
||||||
|
if total_score < 50:
|
||||||
|
decision_path.append(DecisionPath(
|
||||||
|
node="SCORING_CHECK",
|
||||||
|
condition="total_score >= 50",
|
||||||
|
result=False
|
||||||
|
))
|
||||||
|
return "MANUAL"
|
||||||
|
|
||||||
|
decision_path.append(DecisionPath(
|
||||||
|
node="BUSINESS_RULES",
|
||||||
|
condition="all_business_rules_passed",
|
||||||
|
result=True
|
||||||
|
))
|
||||||
|
|
||||||
|
return "PASS"
|
||||||
|
|
||||||
|
def _is_company_name(self, name: str) -> bool:
|
||||||
|
"""检查是否为公司名称"""
|
||||||
|
company_keywords = ["有限公司", "股份公司", "集团", "企业", "责任公司"]
|
||||||
|
return any(keyword in name for keyword in company_keywords)
|
||||||
|
|
||||||
|
def _build_response(self, result: str, confidence: float, reason: str,
|
||||||
|
decision_path: list, start_time: float) -> AuditResponse:
|
||||||
|
"""构建响应对象"""
|
||||||
|
processing_time = int((time.time() - start_time) * 1000)
|
||||||
|
|
||||||
|
return AuditResponse(
|
||||||
|
result=result,
|
||||||
|
confidence=confidence,
|
||||||
|
reason=reason,
|
||||||
|
decision_path=decision_path,
|
||||||
|
processing_time_ms=processing_time
|
||||||
|
)
|
4
ai_review_service/requirements.txt
Normal file
4
ai_review_service/requirements.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fastapi==0.104.1
|
||||||
|
uvicorn==0.24.0
|
||||||
|
pydantic==2.5.0
|
||||||
|
python-multipart==0.0.6
|
33
ai_review_service/run.py
Normal file
33
ai_review_service/run.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
TYCM AI Review Service 启动脚本
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import uvicorn
|
||||||
|
from app.main import app
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""启动服务"""
|
||||||
|
print("=" * 60)
|
||||||
|
print("🚀 TYCM AI Review Service 正在启动...")
|
||||||
|
print("📖 API文档: http://localhost:8081/docs")
|
||||||
|
print("🔗 健康检查: http://localhost:8081/api/v1/health")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
try:
|
||||||
|
uvicorn.run(
|
||||||
|
"app.main:app", # 使用导入字符串而不是app对象
|
||||||
|
host="0.0.0.0",
|
||||||
|
port=8081,
|
||||||
|
reload=True,
|
||||||
|
log_level="info"
|
||||||
|
)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n👋 服务已停止")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 启动失败: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
70
ai_review_service/test_simple.py
Normal file
70
ai_review_service/test_simple.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
简化测试启动脚本
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("🔍 测试Python环境...")
|
||||||
|
|
||||||
|
# 测试基本模块
|
||||||
|
print("1. 测试基本Python模块...")
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
print(f" Python版本: {sys.version}")
|
||||||
|
print(f" 当前目录: {os.getcwd()}")
|
||||||
|
|
||||||
|
# 测试FastAPI相关模块
|
||||||
|
print("2. 测试FastAPI模块...")
|
||||||
|
try:
|
||||||
|
import fastapi
|
||||||
|
print(f" FastAPI版本: {fastapi.__version__}")
|
||||||
|
except ImportError as e:
|
||||||
|
print(f" ❌ FastAPI导入失败: {e}")
|
||||||
|
print(" 请运行: pip install fastapi")
|
||||||
|
|
||||||
|
try:
|
||||||
|
import uvicorn
|
||||||
|
print(f" Uvicorn已安装")
|
||||||
|
except ImportError as e:
|
||||||
|
print(f" ❌ Uvicorn导入失败: {e}")
|
||||||
|
print(" 请运行: pip install uvicorn")
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pydantic
|
||||||
|
print(f" Pydantic版本: {pydantic.__version__}")
|
||||||
|
except ImportError as e:
|
||||||
|
print(f" ❌ Pydantic导入失败: {e}")
|
||||||
|
print(" 请运行: pip install pydantic")
|
||||||
|
|
||||||
|
# 测试应用模块
|
||||||
|
print("3. 测试应用模块...")
|
||||||
|
try:
|
||||||
|
from app.main import app
|
||||||
|
print(" ✅ 应用模块导入成功")
|
||||||
|
|
||||||
|
# 尝试启动最简单的服务
|
||||||
|
print("4. 尝试启动简化服务...")
|
||||||
|
import uvicorn
|
||||||
|
print(" 🚀 启动测试服务,访问 http://localhost:8081")
|
||||||
|
print(" 按 Ctrl+C 停止服务")
|
||||||
|
uvicorn.run(
|
||||||
|
app,
|
||||||
|
host="127.0.0.1", # 只监听本地
|
||||||
|
port=8081,
|
||||||
|
log_level="info"
|
||||||
|
)
|
||||||
|
|
||||||
|
except ImportError as e:
|
||||||
|
print(f" ❌ 应用模块导入失败: {e}")
|
||||||
|
print(" 可能的原因:")
|
||||||
|
print(" - app目录不存在")
|
||||||
|
print(" - __init__.py文件缺失")
|
||||||
|
print(" - main.py文件有语法错误")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ❌ 启动失败: {e}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 整体测试失败: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
49
start_ai_service.py
Normal file
49
start_ai_service.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
快速启动AI审核服务的脚本
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("=" * 60)
|
||||||
|
print("🚀 启动TYCM AI审核服务")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# 切换到服务目录
|
||||||
|
service_dir = os.path.join(os.path.dirname(__file__), "ai_review_service")
|
||||||
|
os.chdir(service_dir)
|
||||||
|
|
||||||
|
print(f"📁 当前目录: {os.getcwd()}")
|
||||||
|
|
||||||
|
# 检查requirements.txt
|
||||||
|
if not os.path.exists("requirements.txt"):
|
||||||
|
print("❌ requirements.txt 不存在!")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
print("📦 安装Python依赖...")
|
||||||
|
try:
|
||||||
|
subprocess.run([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"], check=True)
|
||||||
|
print("✅ 依赖安装成功")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"❌ 依赖安装失败: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
print("🚀 启动FastAPI服务...")
|
||||||
|
print("📖 API文档将在: http://localhost:8080/docs")
|
||||||
|
print("🔗 健康检查: http://localhost:8080/api/v1/health")
|
||||||
|
print("-" * 60)
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run([sys.executable, "run.py"], check=True)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n👋 服务已停止")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"❌ 服务启动失败: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
155
test_integration.py
Normal file
155
test_integration.py
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
测试Java和Python服务集成的脚本
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
def test_python_service():
|
||||||
|
"""测试Python服务"""
|
||||||
|
print("🔍 测试Python AI审核服务...")
|
||||||
|
|
||||||
|
# 测试健康检查
|
||||||
|
try:
|
||||||
|
response = requests.get("http://localhost:8081/api/v1/health", timeout=5)
|
||||||
|
if response.status_code == 200:
|
||||||
|
print("✅ Python服务健康检查通过")
|
||||||
|
print(f" 响应: {response.json()}")
|
||||||
|
else:
|
||||||
|
print(f"❌ Python服务健康检查失败: {response.status_code}")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 无法连接Python服务: {e}")
|
||||||
|
print("💡 请确保Python服务已启动: python start_ai_service.py")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 测试审核接口
|
||||||
|
test_data = {
|
||||||
|
"order_id": "TEST001",
|
||||||
|
"order_status": "WAITEXAMINE",
|
||||||
|
"oem_id": 2,
|
||||||
|
"car_type": "0",
|
||||||
|
"card_name": "张三",
|
||||||
|
"card_number": "123456789012345678",
|
||||||
|
"car_frame": "WDDGF4HB9CA123456",
|
||||||
|
"buyer_name": "张三",
|
||||||
|
"id_card_score": 85,
|
||||||
|
"bill_score": 92
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
start_time = time.time()
|
||||||
|
response = requests.post(
|
||||||
|
"http://localhost:8081/api/v1/audit",
|
||||||
|
json=test_data,
|
||||||
|
headers={"Content-Type": "application/json"},
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
elapsed_time = (time.time() - start_time) * 1000
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
result = response.json()
|
||||||
|
print("✅ Python审核接口测试通过")
|
||||||
|
print(f" 审核结果: {result['result']}")
|
||||||
|
print(f" 置信度: {result['confidence']}")
|
||||||
|
print(f" 原因: {result['reason']}")
|
||||||
|
print(f" 响应时间: {elapsed_time:.0f}ms")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"❌ Python审核接口测试失败: {response.status_code}")
|
||||||
|
print(f" 错误信息: {response.text}")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Python审核接口调用失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_java_service():
|
||||||
|
"""测试Java服务 (如果有健康检查接口)"""
|
||||||
|
print("\n🔍 测试Java TYCM服务...")
|
||||||
|
|
||||||
|
# 尝试连接Java服务
|
||||||
|
try:
|
||||||
|
# 假设Java服务有健康检查接口 (根据实际情况调整)
|
||||||
|
response = requests.get("http://localhost:5610/actuator/health", timeout=5)
|
||||||
|
if response.status_code == 200:
|
||||||
|
print("✅ Java服务连接正常")
|
||||||
|
print(f" 响应: {response.json()}")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"⚠️ Java服务状态码: {response.status_code}")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"⚠️ 无法连接Java服务: {e}")
|
||||||
|
print("💡 请确保Java服务已启动在端口5610")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def print_configuration_guide():
|
||||||
|
"""打印配置指南"""
|
||||||
|
print("\n" + "="*60)
|
||||||
|
print("🔧 配置指南")
|
||||||
|
print("="*60)
|
||||||
|
|
||||||
|
print("\n📝 1. 启用决策树服务,在Java项目中添加配置:")
|
||||||
|
print(" 文件位置: src/main/resources/application.yml")
|
||||||
|
print(" 添加配置:")
|
||||||
|
print("""
|
||||||
|
ai:
|
||||||
|
decision:
|
||||||
|
enabled: true
|
||||||
|
service:
|
||||||
|
url: http://localhost:8080
|
||||||
|
""")
|
||||||
|
|
||||||
|
print("\n📝 2. 或者包含AI决策配置文件:")
|
||||||
|
print(" 在 application.yml 中添加:")
|
||||||
|
print("""
|
||||||
|
spring:
|
||||||
|
profiles:
|
||||||
|
include: ai-decision
|
||||||
|
""")
|
||||||
|
|
||||||
|
print("\n📝 3. 测试切换:")
|
||||||
|
print(" - enabled: false -> 使用原有AI审核逻辑")
|
||||||
|
print(" - enabled: true -> 使用新的Python决策树服务")
|
||||||
|
|
||||||
|
print("\n📝 4. 监控日志:")
|
||||||
|
print(" Java日志关键词: 'Python决策树服务', 'AI决策树'")
|
||||||
|
print(" Python日志: 查看控制台输出")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("🧪 TYCM AI审核服务集成测试")
|
||||||
|
print("="*60)
|
||||||
|
|
||||||
|
# 测试Python服务
|
||||||
|
python_ok = test_python_service()
|
||||||
|
|
||||||
|
# 测试Java服务
|
||||||
|
java_ok = test_java_service()
|
||||||
|
|
||||||
|
# 总结
|
||||||
|
print("\n" + "="*60)
|
||||||
|
print("📊 测试结果总结")
|
||||||
|
print("="*60)
|
||||||
|
print(f"Python AI服务: {'✅ 正常' if python_ok else '❌ 异常'}")
|
||||||
|
print(f"Java TYCM服务: {'✅ 正常' if java_ok else '⚠️ 未确认'}")
|
||||||
|
|
||||||
|
if python_ok:
|
||||||
|
print("\n🎉 Python AI审核服务运行正常!")
|
||||||
|
print("💡 现在可以在Java项目中启用决策树配置来使用此服务")
|
||||||
|
print_configuration_guide()
|
||||||
|
else:
|
||||||
|
print("\n❌ Python服务有问题,请检查:")
|
||||||
|
print(" 1. 是否已启动: python start_ai_service.py")
|
||||||
|
print(" 2. 端口8080是否被占用")
|
||||||
|
print(" 3. 依赖是否正确安装")
|
||||||
|
|
||||||
|
if not java_ok:
|
||||||
|
print("\n⚠️ Java服务连接失败,这是正常的如果:")
|
||||||
|
print(" 1. Java服务未启动")
|
||||||
|
print(" 2. 没有健康检查接口")
|
||||||
|
print(" 3. 端口不是5610")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
258
快速使用指南.md
Normal file
258
快速使用指南.md
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
# TYCM AI审核服务 - 快速使用指南
|
||||||
|
|
||||||
|
## 🚀 快速启动 (5分钟上手)
|
||||||
|
|
||||||
|
### 第1步: 启动Python AI服务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd D:\project-tycm\tycm_service_ai
|
||||||
|
python start_ai_service.py
|
||||||
|
```
|
||||||
|
|
||||||
|
**预期输出:**
|
||||||
|
```
|
||||||
|
🚀 TYCM AI Review Service 正在启动...
|
||||||
|
📖 API文档: http://localhost:8080/docs
|
||||||
|
🔗 健康检查: http://localhost:8080/api/v1/health
|
||||||
|
INFO: Uvicorn running on http://0.0.0.0:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
### 第2步: 测试Python服务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python test_integration.py
|
||||||
|
```
|
||||||
|
|
||||||
|
**预期看到:**
|
||||||
|
```
|
||||||
|
✅ Python服务健康检查通过
|
||||||
|
✅ Python审核接口测试通过
|
||||||
|
审核结果: PASS
|
||||||
|
置信度: 0.95
|
||||||
|
响应时间: 150ms
|
||||||
|
```
|
||||||
|
|
||||||
|
### 第3步: 配置Java服务 (可选)
|
||||||
|
|
||||||
|
在 `D:\project-tycm\tycm-service\src\main\resources\application.yml` 中添加:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
ai:
|
||||||
|
decision:
|
||||||
|
enabled: false # false=使用原有逻辑, true=使用Python决策树
|
||||||
|
service:
|
||||||
|
url: http://localhost:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
### 第4步: 重启Java服务测试
|
||||||
|
|
||||||
|
启动Java服务后,原有的AI审核功能将:
|
||||||
|
- `enabled: false` -> 使用原有逻辑 (默认)
|
||||||
|
- `enabled: true` -> 调用Python决策树服务
|
||||||
|
|
||||||
|
## 📡 API接口说明
|
||||||
|
|
||||||
|
### Python服务接口
|
||||||
|
|
||||||
|
#### 1. 健康检查
|
||||||
|
```http
|
||||||
|
GET http://localhost:8080/api/v1/health
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. AI审核
|
||||||
|
```http
|
||||||
|
POST http://localhost:8080/api/v1/audit
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"order_id": "12345",
|
||||||
|
"order_status": "WAITEXAMINE",
|
||||||
|
"oem_id": 2,
|
||||||
|
"car_type": "0",
|
||||||
|
"card_name": "张三",
|
||||||
|
"card_number": "123456789012345678",
|
||||||
|
"car_frame": "WDDGF4HB9CA123456",
|
||||||
|
"buyer_name": "张三",
|
||||||
|
"id_card_score": 85,
|
||||||
|
"bill_score": 92
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"result": "PASS", // PASS/REFUSE/MANUAL
|
||||||
|
"confidence": 0.95,
|
||||||
|
"reason": "AI审核通过",
|
||||||
|
"decision_path": [
|
||||||
|
{"node": "PRE_CHECK", "condition": "all_preconditions_met", "result": true}
|
||||||
|
],
|
||||||
|
"processing_time_ms": 150
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Java集成
|
||||||
|
|
||||||
|
Java端自动处理调用,配置开关即可:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 原有调用方式不变
|
||||||
|
TResult result = aiReviewService.aiReview(orderInfo);
|
||||||
|
|
||||||
|
// 内部会根据配置选择:
|
||||||
|
// enabled=false -> 原有逻辑
|
||||||
|
// enabled=true -> Python决策树服务
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 配置说明
|
||||||
|
|
||||||
|
### 完整配置文件
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
ai:
|
||||||
|
decision:
|
||||||
|
# 主开关
|
||||||
|
enabled: false # 是否启用Python决策树服务
|
||||||
|
|
||||||
|
# 服务配置
|
||||||
|
service:
|
||||||
|
url: http://localhost:8080 # Python服务地址
|
||||||
|
|
||||||
|
# 降级配置
|
||||||
|
fallback:
|
||||||
|
enabled: true # Python服务异常时是否降级到原逻辑
|
||||||
|
timeout: 5000 # 超时时间(毫秒)
|
||||||
|
|
||||||
|
# 监控配置
|
||||||
|
metrics:
|
||||||
|
enabled: true # 是否启用指标收集
|
||||||
|
|
||||||
|
# 日志配置
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
com.ruoyi.common.ai.service: INFO
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 测试验证
|
||||||
|
|
||||||
|
### 1. 单独测试Python服务
|
||||||
|
```bash
|
||||||
|
# 访问API文档
|
||||||
|
http://localhost:8080/docs
|
||||||
|
|
||||||
|
# 健康检查
|
||||||
|
curl http://localhost:8080/api/v1/health
|
||||||
|
|
||||||
|
# 审核测试
|
||||||
|
curl -X POST http://localhost:8080/api/v1/audit \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"order_id":"TEST001","order_status":"WAITEXAMINE","oem_id":2,"car_type":"0","card_name":"张三","card_number":"123456789012345678","car_frame":"WDDGF4HB9CA123456","buyer_name":"张三","id_card_score":85,"bill_score":92}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 集成测试
|
||||||
|
```bash
|
||||||
|
python test_integration.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Java端测试
|
||||||
|
|
||||||
|
在Java项目日志中查找:
|
||||||
|
```
|
||||||
|
使用Python决策树服务审核订单: 12345
|
||||||
|
AI决策树审核通过: AI审核通过
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 故障排除
|
||||||
|
|
||||||
|
### 问题1: Python服务启动失败
|
||||||
|
```bash
|
||||||
|
# 检查Python版本 (需要3.7+)
|
||||||
|
python --version
|
||||||
|
|
||||||
|
# 重新安装依赖
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
# 手动启动
|
||||||
|
cd ai_review_service
|
||||||
|
python run.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 问题2: Java服务调用失败
|
||||||
|
检查Java日志中是否有:
|
||||||
|
```
|
||||||
|
Python决策树服务调用失败,降级到原有逻辑
|
||||||
|
```
|
||||||
|
|
||||||
|
**解决方案:**
|
||||||
|
1. 确认Python服务正在运行: `http://localhost:8080/api/v1/health`
|
||||||
|
2. 检查配置文件中的服务地址
|
||||||
|
3. 检查网络连接和防火墙
|
||||||
|
|
||||||
|
### 问题3: 端口冲突
|
||||||
|
```bash
|
||||||
|
# 检查端口占用
|
||||||
|
netstat -ano | findstr :8080
|
||||||
|
|
||||||
|
# 修改Python服务端口
|
||||||
|
# 编辑 ai_review_service/app/main.py
|
||||||
|
# 将 port=8080 改为其他端口,同时更新Java配置
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 监控指标
|
||||||
|
|
||||||
|
### Python服务指标
|
||||||
|
- 响应时间: 通常 < 500ms
|
||||||
|
- 成功率: > 99%
|
||||||
|
- 并发处理: 支持100+ QPS
|
||||||
|
|
||||||
|
### Java端监控
|
||||||
|
在日志中关注:
|
||||||
|
```
|
||||||
|
Python决策树服务审核订单: [订单ID]
|
||||||
|
AI决策树审核通过/驳回/转人工: [原因]
|
||||||
|
处理决策树结果失败: [错误信息]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 版本升级
|
||||||
|
|
||||||
|
### 更新Python服务
|
||||||
|
```bash
|
||||||
|
cd D:\project-tycm\tycm_service_ai\ai_review_service
|
||||||
|
git pull # 如果使用Git
|
||||||
|
pip install -r requirements.txt --upgrade
|
||||||
|
python run.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 更新Java集成代码
|
||||||
|
重新编译Java项目即可,配置文件无需修改。
|
||||||
|
|
||||||
|
## 📈 性能优化
|
||||||
|
|
||||||
|
### 1. Python服务优化
|
||||||
|
- 增加worker进程: `uvicorn app.main:app --workers 4`
|
||||||
|
- 启用缓存: 安装Redis并配置缓存
|
||||||
|
- 负载均衡: 部署多个实例
|
||||||
|
|
||||||
|
### 2. Java端优化
|
||||||
|
- 连接池配置: 调整RestTemplate连接池
|
||||||
|
- 超时设置: 根据实际情况调整timeout
|
||||||
|
- 熔断机制: 集成Hystrix等熔断组件
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 总结
|
||||||
|
|
||||||
|
这个最小实现版本提供了:
|
||||||
|
|
||||||
|
✅ **完整的Python AI服务** (FastAPI + 简化决策逻辑)
|
||||||
|
✅ **Java集成客户端** (DecisionTreeService)
|
||||||
|
✅ **配置化开关** (enabled: true/false)
|
||||||
|
✅ **降级机制** (Python服务异常时使用原逻辑)
|
||||||
|
✅ **快速测试工具** (启动脚本 + 集成测试)
|
||||||
|
|
||||||
|
现在您可以:
|
||||||
|
1. **立即测试**: 启动Python服务并验证API
|
||||||
|
2. **渐进集成**: 在Java中配置开关,逐步切换
|
||||||
|
3. **持续优化**: 基于这个框架添加更复杂的ML模型
|
||||||
|
|
||||||
|
这为完整的AI审核服务改造奠定了坚实的技术基础! 🚀
|
Loading…
x
Reference in New Issue
Block a user