init: RAG 知识库服务初始提交

- 后端 API(Flask + Gunicorn)
- RAG 引擎(混合检索 + 云端 Reranker + 引用溯源)
- 文档解析(MinerU + 多格式支持)
- Docker 生产部署配置
- 排除前端项目、敏感配置、模型文件
This commit is contained in:
lacerate551
2026-06-04 17:35:27 +08:00
commit 100d1a06eb
158 changed files with 64534 additions and 0 deletions

133
api/audit_routes.py Normal file
View File

@@ -0,0 +1,133 @@
"""
审计日志 API
路由:
- GET /audit/logs - 查询审计日志(管理员)
"""
from flask import Blueprint, request, jsonify
import logging
logger = logging.getLogger(__name__)
from auth.gateway import require_gateway_auth
from data.db import get_connection
audit_bp = Blueprint('audit', __name__)
@audit_bp.route('/audit/logs', methods=['GET'])
@require_gateway_auth
def get_audit_logs():
"""
查询审计日志
参数:
- limit: 返回条数默认50
- days: 查询天数默认7
- action: 操作类型过滤(可选)
返回:
{
"logs": [
{
"id": 1,
"user_id": "admin001",
"username": "admin",
"action": "rag_query",
"query": "xxx",
"result_summary": "...",
"role": "admin",
"department": "管理部",
"ip_address": "127.0.0.1",
"duration_ms": 1234,
"timestamp": "2025-01-01 12:00:00"
}
],
"total": 100
}
"""
limit = request.args.get('limit', 50, type=int)
days = request.args.get('days', 7, type=int)
action_filter = request.args.get('action', '')
try:
with get_connection("session") as conn:
# 构建查询
where_clauses = ["created_at >= datetime('now', ?)"]
params = [f'-{days} days']
if action_filter:
where_clauses.append("action = ?")
params.append(action_filter)
where_sql = " AND ".join(where_clauses)
# 查询总数
count_sql = f"SELECT COUNT(*) FROM audit_logs WHERE {where_sql}"
total = conn.execute(count_sql, params).fetchone()[0]
# 查询日志
query_sql = f"""
SELECT id, user_id, username, action, query, result_summary,
role, department, ip_address, duration_ms, created_at
FROM audit_logs
WHERE {where_sql}
ORDER BY created_at DESC
LIMIT ?
"""
params.append(limit)
rows = conn.execute(query_sql, params).fetchall()
logs = []
for row in rows:
logs.append({
"id": row[0],
"user_id": row[1],
"username": row[2],
"action": row[3],
"query": row[4],
"result_summary": row[5],
"role": row[6],
"department": row[7],
"ip_address": row[8],
"duration_ms": row[9],
"timestamp": row[10]
})
return jsonify({"logs": logs, "total": total})
except Exception as e:
return jsonify({"error": str(e), "logs": [], "total": 0}), 500
def log_audit_event(user_id: str, username: str, action: str,
query: str = None, result_summary: str = None,
role: str = None, department: str = None,
ip_address: str = None, duration_ms: int = None):
"""
记录审计日志(供其他模块调用)
Args:
user_id: 用户ID
username: 用户名
action: 操作类型rag_query, chat, feedback, sync 等)
query: 查询内容
result_summary: 结果摘要
role: 用户角色
department: 部门
ip_address: IP地址
duration_ms: 耗时(毫秒)
"""
try:
with get_connection("session") as conn:
conn.execute("""
INSERT INTO audit_logs
(user_id, username, action, query, result_summary,
role, department, ip_address, duration_ms)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (user_id, username, action, query, result_summary,
role, department, ip_address, duration_ms))
except Exception as e:
# 审计日志写入失败不应影响主流程
logger.debug(f"审计日志写入失败: {e}")
pass