Files
wecom_it_smart_desk/backend/app/api/knowledge_iteration.py
T

267 lines
8.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# 企微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),
}