初始提交: Qihu-AIFlow v2.0.1 完整项目

- 前端 React+TypeScript (源码+构建产物)
- 后端 Python FastAPI
- 数据库迁移 001-015
- Docker部署配置
- 微信ClawBot API频道绑定
- 项目文档 README.md
This commit is contained in:
qyyfw committed 2026-07-02 14:40:46 +08:00
commit 78ff261b5a
199 files changed
+69126

No files matched your search

+453
View File
@@ -0,0 +1,453 @@
"""
增值服务管理 API(管理员)
四大类服务: app_custom / platform_proxy / data_custom / private_project
"""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import Optional, List
from ...database import get_db
from ...models import ValueAddedService, CustomServiceOrder, CustomServiceRequest, MarketApp, User
from ...auth import get_current_admin
from ...middleware.log_service import LogService
import uuid
import json
from datetime import datetime
router = APIRouter()
class CreateServiceRequest(BaseModel):
name: str
service_type: str
description: Optional[str] = None
price: float = 0
features: Optional[str] = None
status: str = "active"
assigned_agent_id: Optional[str] = None
class UpdateServiceRequest(BaseModel):
name: Optional[str] = None
price: Optional[float] = None
service_type: Optional[str] = None
description: Optional[str] = None
features: Optional[str] = None
status: Optional[str] = None
assigned_agent_id: Optional[str] = None
# 服务类型映射
SERVICE_TYPE_MAP = {
"app_custom": "应用定制服务",
"platform_proxy": "平台代理申请",
"data_custom": "数据定制服务",
"private_project": "私有化项目服务",
}
# ============================================================
# 增值服务 CRUD
# ============================================================
@router.get("/")
async def get_services(
service_type: str = Query(None, description="服务类型筛选: app_custom/platform_proxy/data_custom/private_project"),
status: str = Query(None, description="状态筛选: active/inactive/deleted"),
admin_user=Depends(get_current_admin),
db: Session = Depends(get_db),
):
"""获取增值服务列表"""
import logging
logger = logging.getLogger(__name__)
logger.info(f"Admin {admin_user.username} requested services list: type={service_type}, status={status}")
query = db.query(ValueAddedService).filter(ValueAddedService.status != "deleted")
if service_type:
query = query.filter(ValueAddedService.type == service_type)
if status:
query = query.filter(ValueAddedService.status == status)
services = query.order_by(ValueAddedService.created_at.desc()).all()
result = []
for s in services:
result.append({
"id": s.id,
"name": s.name,
"description": s.description,
"price": float(s.price) if s.price else 0,
"type": s.type,
"type_name": SERVICE_TYPE_MAP.get(s.type, s.type),
"features": s.features or [],
"status": s.status,
"assigned_agent_id": s.assigned_agent_id,
"created_at": s.created_at.isoformat() if s.created_at else None,
"updated_at": s.updated_at.isoformat() if s.updated_at else None,
})
return result
@router.post("/")
async def create_service(
req: CreateServiceRequest,
admin_user=Depends(get_current_admin),
db: Session = Depends(get_db),
):
"""创建增值服务"""
import logging
logger = logging.getLogger(__name__)
if req.service_type not in SERVICE_TYPE_MAP:
raise HTTPException(status_code=400, detail=f"无效的服务类型,可选值:{', '.join(SERVICE_TYPE_MAP.keys())}")
features_json = None
if req.features:
try:
features_json = json.loads(req.features) if isinstance(req.features, str) else req.features
except (json.JSONDecodeError, TypeError):
features_json = [req.features]
service = ValueAddedService(
id=str(uuid.uuid4()),
name=req.name,
description=req.description,
price=req.price,
type=req.service_type,
features=features_json,
status=req.status,
assigned_agent_id=req.assigned_agent_id,
)
db.add(service)
db.commit()
db.refresh(service)
logger.info(f"Admin {admin_user.username} created service: {service.id} - {req.name}")
LogService.log_audit(
admin_id=admin_user.id,
admin_name=admin_user.username,
action="create_service",
target_type="value_added_service",
target_id=service.id,
detail=f"创建增值服务 {req.name}(类型: {SERVICE_TYPE_MAP.get(req.service_type)})",
)
return {"message": "增值服务已创建", "id": service.id}
@router.put("/{id}")
async def update_service(
id: str,
req: UpdateServiceRequest,
admin_user=Depends(get_current_admin),
db: Session = Depends(get_db),
):
"""更新增值服务"""
import logging
logger = logging.getLogger(__name__)
service = db.query(ValueAddedService).filter(ValueAddedService.id == id).first()
if not service:
raise HTTPException(status_code=404, detail="增值服务不存在")
if req.name is not None:
service.name = req.name
if req.price is not None:
service.price = req.price
if req.service_type is not None:
if req.service_type not in SERVICE_TYPE_MAP:
raise HTTPException(status_code=400, detail=f"无效的服务类型")
service.type = req.service_type
if req.description is not None:
service.description = req.description
if req.features is not None:
try:
service.features = json.loads(req.features) if isinstance(req.features, str) else req.features
except (json.JSONDecodeError, TypeError):
service.features = [req.features]
if req.status is not None:
service.status = req.status
if req.assigned_agent_id is not None:
service.assigned_agent_id = req.assigned_agent_id
service.updated_at = datetime.now()
db.commit()
logger.info(f"Admin {admin_user.username} updated service: {id}")
LogService.log_audit(
admin_id=admin_user.id,
admin_name=admin_user.username,
action="update_service",
target_type="value_added_service",
target_id=id,
detail=f"更新增值服务 {service.name}",
)
return {"message": "增值服务已更新"}
@router.delete("/{id}")
async def delete_service(
id: str,
admin_user=Depends(get_current_admin),
db: Session = Depends(get_db),
):
"""逻辑删除增值服务(设置为 deleted 状态,保留数据记录)"""
import logging
logger = logging.getLogger(__name__)
service = db.query(ValueAddedService).filter(ValueAddedService.id == id).first()
if not service:
raise HTTPException(status_code=404, detail="增值服务不存在")
if service.status == "deleted":
raise HTTPException(status_code=400, detail="该增值服务已被删除")
logger.info(f"Admin {admin_user.username} soft-deleting service: {id} - {service.name}")
service.status = "deleted"
service.updated_at = datetime.now()
db.commit()
LogService.log_audit(
admin_id=admin_user.id,
admin_name=admin_user.username,
action="delete_service",
target_type="value_added_service",
target_id=id,
detail=f"逻辑删除增值服务 {service.name}",
)
return {"message": "增值服务已删除(逻辑删除)"}
# ============================================================
# 定制服务工单管理 (CustomServiceRequest)
# ============================================================
@router.get("/custom-requests")
async def get_custom_requests(
request_type: str = Query(None, description="工单类型: data_custom/private_project/platform_proxy"),
status: str = Query(None, description="状态: pending/processing/completed/rejected"),
admin_user=Depends(get_current_admin),
db: Session = Depends(get_db),
):
"""获取定制服务工单列表"""
import logging
logger = logging.getLogger(__name__)
logger.info(f"Admin {admin_user.username} requested custom requests: type={request_type}, status={status}")
query = db.query(CustomServiceRequest)
if request_type:
query = query.filter(CustomServiceRequest.request_type == request_type)
if status:
query = query.filter(CustomServiceRequest.status == status)
requests = query.order_by(CustomServiceRequest.created_at.desc()).all()
result = []
for r in requests:
# 查询用户名
user = db.query(User).filter(User.id == r.user_id).first()
# 查询服务名
service = db.query(ValueAddedService).filter(ValueAddedService.id == r.service_id).first()
result.append({
"id": r.id,
"user_id": r.user_id,
"username": user.username if user else "未知用户",
"service_id": r.service_id,
"service_name": service.name if service else "未知服务",
"request_type": r.request_type,
"request_type_name": SERVICE_TYPE_MAP.get(r.request_type, r.request_type),
"title": r.title,
"description": r.description,
"requirements": r.requirements or {},
"status": r.status,
"assigned_agent_id": r.assigned_agent_id,
"created_at": r.created_at.isoformat() if r.created_at else None,
"updated_at": r.updated_at.isoformat() if r.updated_at else None,
})
return result
@router.put("/custom-requests/{id}")
async def update_custom_request(
id: str,
status: str = None,
assigned_agent_id: str = None,
admin_user=Depends(get_current_admin),
db: Session = Depends(get_db),
):
"""更新定制服务工单(分配Agent / 标记完成)"""
import logging
logger = logging.getLogger(__name__)
req = db.query(CustomServiceRequest).filter(CustomServiceRequest.id == id).first()
if not req:
raise HTTPException(status_code=404, detail="工单不存在")
if status is not None:
if status not in ("pending", "processing", "completed", "rejected"):
raise HTTPException(status_code=400, detail="无效的状态值")
req.status = status
if assigned_agent_id is not None:
req.assigned_agent_id = assigned_agent_id
req.updated_at = datetime.now()
db.commit()
logger.info(f"Admin {admin_user.username} updated custom request: {id}, status={status}, agent={assigned_agent_id}")
LogService.log_audit(
admin_id=admin_user.id,
admin_name=admin_user.username,
action="update_custom_request",
target_type="custom_service_request",
target_id=id,
detail=f"更新工单状态: {status}, 分配Agent: {assigned_agent_id}",
)
return {"message": "工单已更新"}
# ============================================================
# 定制服务订单管理 (CustomServiceOrder - 保留兼容)
# ============================================================
@router.get("/custom-orders")
async def get_custom_orders(
status: str = Query(None, description="状态筛选"),
admin_user=Depends(get_current_admin),
db: Session = Depends(get_db),
):
"""获取定制服务订单列表"""
query = db.query(CustomServiceOrder)
if status:
query = query.filter(CustomServiceOrder.status == status)
orders = query.order_by(CustomServiceOrder.created_at.desc()).all()
result = []
for o in orders:
user = db.query(User).filter(User.id == o.user_id).first()
result.append({
"id": o.id,
"user_id": o.user_id,
"username": user.username if user else "未知用户",
"service_id": o.service_id,
"service_type": o.service_type,
"description": o.description,
"status": o.status,
"price": float(o.price) if o.price else 0,
"order_id": o.order_id,
"created_at": o.created_at.isoformat() if o.created_at else None,
"updated_at": o.updated_at.isoformat() if o.updated_at else None,
})
return result
@router.put("/custom-orders/{id}")
async def update_custom_order(
id: str,
status: str = None,
price: float = None,
admin_user=Depends(get_current_admin),
db: Session = Depends(get_db),
):
"""更新定制服务订单状态"""
import logging
logger = logging.getLogger(__name__)
order = db.query(CustomServiceOrder).filter(CustomServiceOrder.id == id).first()
if not order:
raise HTTPException(status_code=404, detail="定制服务订单不存在")
if status is not None:
order.status = status
if price is not None:
order.price = price
order.updated_at = datetime.now()
db.commit()
logger.info(f"Admin {admin_user.username} updated custom order: {id}, status={status}")
LogService.log_audit(
admin_id=admin_user.id,
admin_name=admin_user.username,
action="update_custom_order",
target_type="custom_service_order",
target_id=id,
detail=f"更新定制服务订单状态为 {status}",
)
return {"message": "定制服务订单已更新"}
# ============================================================
# Agent 配置(为应用定制服务绑定市场Agent)
# ============================================================
@router.get("/agents")
async def get_available_agents(
admin_user=Depends(get_current_admin),
db: Session = Depends(get_db),
):
"""获取可用的市场Agent列表(用于绑定到应用定制服务)"""
from sqlalchemy import or_
agents = db.query(MarketApp).filter(
MarketApp.type == "agent",
or_(MarketApp.status == "published", MarketApp.status == "active")
).all()
result = []
for a in agents:
result.append({
"id": a.id,
"name": a.name,
"description": a.description,
"publisher_name": a.publisher_name,
})
return result
@router.put("/{id}/agent")
async def assign_agent_to_service(
id: str,
agent_id: str,
admin_user=Depends(get_current_admin),
db: Session = Depends(get_db),
):
"""为应用定制服务绑定Agent"""
import logging
logger = logging.getLogger(__name__)
service = db.query(ValueAddedService).filter(ValueAddedService.id == id).first()
if not service:
raise HTTPException(status_code=404, detail="增值服务不存在")
# 验证agent存在
agent = db.query(MarketApp).filter(
MarketApp.id == agent_id,
MarketApp.type == "agent"
).first()
if not agent:
raise HTTPException(status_code=404, detail="Agent不存在")
service.assigned_agent_id = agent_id
service.updated_at = datetime.now()
db.commit()
logger.info(f"Admin {admin_user.username} assigned agent {agent_id} to service {id}")
LogService.log_audit(
admin_id=admin_user.id,
admin_name=admin_user.username,
action="assign_agent",
target_type="value_added_service",
target_id=id,
detail=f"为服务 {service.name} 绑定Agent: {agent.name}",
)
return {"message": "Agent绑定成功", "agent_name": agent.name}