267 lines
8.7 KiB
Python
267 lines
8.7 KiB
Python
|
|
# =============================================================================
|
|||
|
|
# 企微IT智能服务台 — 知识库自动迭代 API
|
|||
|
|
# =============================================================================
|
|||
|
|
# 说明:知识库自动迭代相关接口
|
|||
|
|
# 1. POST /api/admin/knowledge-iteration/analyze - 触发分析并生成建议
|
|||
|
|
# 2. GET /api/admin/knowledge-iteration/suggestions - 获取建议列表
|
|||
|
|
# 3. GET /api/admin/knowledge-iteration/suggestions/{id} - 获取建议详情
|
|||
|
|
# 4. POST /api/admin/knowledge-iteration/suggestions/{id}/approve - 审核通过
|
|||
|
|
# 5. POST /api/admin/knowledge-iteration/suggestions/{id}/reject - 审核拒绝
|
|||
|
|
# 6. GET /api/admin/knowledge-iteration/stats - 获取统计
|
|||
|
|
# =============================================================================
|
|||
|
|
|
|||
|
|
import logging
|
|||
|
|
from typing import Optional
|
|||
|
|
|
|||
|
|
from fastapi import APIRouter, Depends, Query
|
|||
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|||
|
|
|
|||
|
|
from app.database import get_db
|
|||
|
|
from app.dependencies import require_admin
|
|||
|
|
from app.models.user import User
|
|||
|
|
from app.schemas.knowledge_suggestion import (
|
|||
|
|
KnowledgeSuggestionListResponse,
|
|||
|
|
KnowledgeSuggestionResponse,
|
|||
|
|
KnowledgeSuggestionStatsResponse,
|
|||
|
|
KnowledgeSuggestionApprove,
|
|||
|
|
KnowledgeSuggestionReject,
|
|||
|
|
)
|
|||
|
|
from app.services.knowledge_iteration_service import (
|
|||
|
|
KnowledgeIterationService,
|
|||
|
|
dep_knowledge_iteration_service,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
logger = logging.getLogger(__name__)
|
|||
|
|
|
|||
|
|
router = APIRouter()
|
|||
|
|
|
|||
|
|
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# 触发分析
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# POST /api/admin/knowledge-iteration/analyze
|
|||
|
|
@router.post("/analyze")
|
|||
|
|
async def trigger_analysis(
|
|||
|
|
days: int = Query(default=7, ge=1, le=90, description="分析过去N天的数据"),
|
|||
|
|
current_user: User = Depends(require_admin),
|
|||
|
|
db: AsyncSession = Depends(get_db),
|
|||
|
|
service: KnowledgeIterationService = Depends(dep_knowledge_iteration_service),
|
|||
|
|
):
|
|||
|
|
"""触发知识库迭代分析。
|
|||
|
|
|
|||
|
|
分析过去N天的标注数据和会话数据,自动生成优化建议。
|
|||
|
|
|
|||
|
|
- **days**: 分析过去N天的数据(默认7天,最大90天)
|
|||
|
|
|
|||
|
|
**需要管理员权限。**
|
|||
|
|
"""
|
|||
|
|
logger.info(f"管理员 {current_user.username} 触发了知识库迭代分析, days={days}")
|
|||
|
|
|
|||
|
|
result = await service.analyze_and_generate_suggestions(db, days=days)
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
"code": 0,
|
|||
|
|
"message": "分析完成",
|
|||
|
|
"data": result,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# 获取建议列表
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# GET /api/admin/knowledge-iteration/suggestions
|
|||
|
|
@router.get("/suggestions")
|
|||
|
|
async def list_suggestions(
|
|||
|
|
status: Optional[str] = Query(default=None, description="筛选状态"),
|
|||
|
|
suggestion_type: Optional[str] = Query(default=None, description="筛选类型"),
|
|||
|
|
page: int = Query(default=1, ge=1, description="页码"),
|
|||
|
|
page_size: int = Query(default=20, ge=1, le=100, description="每页数量"),
|
|||
|
|
current_user: User = Depends(require_admin),
|
|||
|
|
db: AsyncSession = Depends(get_db),
|
|||
|
|
service: KnowledgeIterationService = Depends(dep_knowledge_iteration_service),
|
|||
|
|
):
|
|||
|
|
"""获取知识库优化建议列表。
|
|||
|
|
|
|||
|
|
- **status**: 筛选状态(pending/approved/rejected/applied)
|
|||
|
|
- **suggestion_type**: 筛选类型(new_faq/update/outdated)
|
|||
|
|
- **page**: 页码
|
|||
|
|
- **page_size**: 每页数量
|
|||
|
|
|
|||
|
|
**需要管理员权限。**
|
|||
|
|
"""
|
|||
|
|
from sqlalchemy import select, func
|
|||
|
|
|
|||
|
|
# 构建查询
|
|||
|
|
stmt = select(KnowledgeSuggestion).order_by(
|
|||
|
|
KnowledgeSuggestion.created_at.desc()
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if status:
|
|||
|
|
stmt = stmt.where(KnowledgeSuggestion.status == status)
|
|||
|
|
if suggestion_type:
|
|||
|
|
stmt = stmt.where(KnowledgeSuggestion.suggestion_type == suggestion_type)
|
|||
|
|
|
|||
|
|
# 分页
|
|||
|
|
offset = (page - 1) * page_size
|
|||
|
|
stmt = stmt.offset(offset).limit(page_size)
|
|||
|
|
|
|||
|
|
result = await db.execute(stmt)
|
|||
|
|
suggestions = result.scalars().all()
|
|||
|
|
|
|||
|
|
# 统计总数
|
|||
|
|
count_stmt = select(func.count()).select_from(KnowledgeSuggestion)
|
|||
|
|
if status:
|
|||
|
|
count_stmt = count_stmt.where(KnowledgeSuggestion.status == status)
|
|||
|
|
if suggestion_type:
|
|||
|
|
count_stmt = count_stmt.where(
|
|||
|
|
KnowledgeSuggestion.suggestion_type == suggestion_type
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
total_result = await db.execute(count_stmt)
|
|||
|
|
total = total_result.scalar()
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
"code": 0,
|
|||
|
|
"message": "success",
|
|||
|
|
"data": {
|
|||
|
|
"total": total,
|
|||
|
|
"items": [
|
|||
|
|
KnowledgeSuggestionResponse.model_validate(s) for s in suggestions
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# 获取建议详情
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# GET /api/admin/knowledge-iteration/suggestions/{id}
|
|||
|
|
@router.get("/suggestions/{suggestion_id}")
|
|||
|
|
async def get_suggestion(
|
|||
|
|
suggestion_id: str,
|
|||
|
|
current_user: User = Depends(require_admin),
|
|||
|
|
db: AsyncSession = Depends(get_db),
|
|||
|
|
):
|
|||
|
|
"""获取知识库优化建议详情。
|
|||
|
|
|
|||
|
|
- **suggestion_id**: 建议ID
|
|||
|
|
|
|||
|
|
**需要管理员权限。**
|
|||
|
|
"""
|
|||
|
|
from sqlalchemy import select
|
|||
|
|
|
|||
|
|
stmt = select(KnowledgeSuggestion).where(
|
|||
|
|
KnowledgeSuggestion.id == suggestion_id
|
|||
|
|
)
|
|||
|
|
result = await db.execute(stmt)
|
|||
|
|
suggestion = result.scalar_one_or_none()
|
|||
|
|
|
|||
|
|
if not suggestion:
|
|||
|
|
return {"code": 404, "message": "建议不存在", "data": None}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
"code": 0,
|
|||
|
|
"message": "success",
|
|||
|
|
"data": KnowledgeSuggestionResponse.model_validate(suggestion),
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# 审核通过
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# POST /api/admin/knowledge-iteration/suggestions/{id}/approve
|
|||
|
|
@router.post("/suggestions/{suggestion_id}/approve")
|
|||
|
|
async def approve_suggestion(
|
|||
|
|
suggestion_id: str,
|
|||
|
|
body: KnowledgeSuggestionApprove,
|
|||
|
|
current_user: User = Depends(require_admin),
|
|||
|
|
db: AsyncSession = Depends(get_db),
|
|||
|
|
service: KnowledgeIterationService = Depends(dep_knowledge_iteration_service),
|
|||
|
|
):
|
|||
|
|
"""审核通过知识库优化建议。
|
|||
|
|
|
|||
|
|
审核通过后,如果是新FAQ或更新建议,将自动添加到知识库。
|
|||
|
|
|
|||
|
|
- **suggestion_id**: 建议ID
|
|||
|
|
|
|||
|
|
**需要管理员权限。**
|
|||
|
|
"""
|
|||
|
|
logger.info(
|
|||
|
|
f"管理员 {current_user.username} 审核通过建议: {suggestion_id}"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
suggestion = await service.approve_suggestion(
|
|||
|
|
db, suggestion_id, current_user.id
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if not suggestion:
|
|||
|
|
return {"code": 404, "message": "建议不存在", "data": None}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
"code": 0,
|
|||
|
|
"message": "审核通过,建议已应用到知识库",
|
|||
|
|
"data": KnowledgeSuggestionResponse.model_validate(suggestion),
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# 审核拒绝
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# POST /api/admin/knowledge-iteration/suggestions/{id}/reject
|
|||
|
|
@router.post("/suggestions/{suggestion_id}/reject")
|
|||
|
|
async def reject_suggestion(
|
|||
|
|
suggestion_id: str,
|
|||
|
|
body: KnowledgeSuggestionReject,
|
|||
|
|
current_user: User = Depends(require_admin),
|
|||
|
|
db: AsyncSession = Depends(get_db),
|
|||
|
|
service: KnowledgeIterationService = Depends(dep_knowledge_iteration_service),
|
|||
|
|
):
|
|||
|
|
"""拒绝知识库优化建议。
|
|||
|
|
|
|||
|
|
- **suggestion_id**: 建议ID
|
|||
|
|
|
|||
|
|
**需要管理员权限。**
|
|||
|
|
"""
|
|||
|
|
logger.info(
|
|||
|
|
f"管理员 {current_user.username} 拒绝建议: {suggestion_id}, "
|
|||
|
|
f"理由: {body.reject_reason}"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
suggestion = await service.reject_suggestion(
|
|||
|
|
db, suggestion_id, current_user.id, body.reject_reason
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if not suggestion:
|
|||
|
|
return {"code": 404, "message": "建议不存在", "data": None}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
"code": 0,
|
|||
|
|
"message": "已拒绝该建议",
|
|||
|
|
"data": KnowledgeSuggestionResponse.model_validate(suggestion),
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# 获取统计
|
|||
|
|
# -----------------------------------------------------------------------------
|
|||
|
|
# GET /api/admin/knowledge-iteration/stats
|
|||
|
|
@router.get("/stats")
|
|||
|
|
async def get_stats(
|
|||
|
|
current_user: User = Depends(require_admin),
|
|||
|
|
db: AsyncSession = Depends(get_db),
|
|||
|
|
service: KnowledgeIterationService = Depends(dep_knowledge_iteration_service),
|
|||
|
|
):
|
|||
|
|
"""获取知识库优化建议统计。
|
|||
|
|
|
|||
|
|
返回各状态的建议数量统计。
|
|||
|
|
|
|||
|
|
**需要管理员权限。**
|
|||
|
|
"""
|
|||
|
|
stats = await service.get_suggestion_stats(db)
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
"code": 0,
|
|||
|
|
"message": "success",
|
|||
|
|
"data": KnowledgeSuggestionStatsResponse(**stats),
|
|||
|
|
}
|