From 5545af003f6578559bc181207db77d73be2764a8 Mon Sep 17 00:00:00 2001 From: wwwwwwwww <526125649@qq.com> Date: Wed, 8 Jul 2026 11:30:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E5=8F=B0=E6=89=80=E6=9C=89=E7=9A=84?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B7=BB=E5=8A=A0=E7=9A=84=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E9=83=BD=E8=A6=81=E5=AF=B9=E5=BA=94=E4=BA=BA=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E5=88=B0=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=E9=87=8C=20?= =?UTF-8?q?=E2=80=8B=EF=BC=8C=E9=99=A4=E4=BA=86GET=E4=B9=8B=E5=A4=96?= =?UTF-8?q?=E9=83=BD=E8=A6=81=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/admin/video_prompt_schema_config.py | 51 ++- video-gen-api/app/api/v1/admin.py | 379 ++++++++++++++++++ 2 files changed, 424 insertions(+), 6 deletions(-) diff --git a/video-gen-api/app/api/admin/video_prompt_schema_config.py b/video-gen-api/app/api/admin/video_prompt_schema_config.py index dcce0901..57006823 100644 --- a/video-gen-api/app/api/admin/video_prompt_schema_config.py +++ b/video-gen-api/app/api/admin/video_prompt_schema_config.py @@ -1,5 +1,7 @@ from __future__ import annotations +import json + from fastapi import APIRouter, Depends from sqlalchemy.ext.asyncio import AsyncSession @@ -21,6 +23,7 @@ from app.services.video_prompt_schema_config_service import ( reset_video_prompt_schema_config, save_video_prompt_schema_config, ) +from app.services.operation_log import log_operation router = APIRouter(prefix="/admin/video-prompt-schema-config", tags=["admin-video-prompt-schema-config"]) @@ -40,8 +43,22 @@ async def save_config( admin: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db), ): - _ = admin - return await save_video_prompt_schema_config(db, data=req.data, is_enabled=req.is_enabled) + result = await save_video_prompt_schema_config(db, data=req.data, is_enabled=req.is_enabled) + await log_operation( + db, + admin.id, + admin.username, + "保存视频提词 Schema 配置", + "PUT", + "/admin/video-prompt-schema-config", + detail=json.dumps( + { + "is_enabled": req.is_enabled, + }, + ensure_ascii=False, + ), + ) + return result @router.post("/reset-default", response_model=VideoPromptSchemaConfigOut, summary="恢复默认视频提词 Schema 配置") @@ -49,8 +66,16 @@ async def reset_default( admin: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db), ): - _ = admin - return await reset_video_prompt_schema_config(db) + result = await reset_video_prompt_schema_config(db) + await log_operation( + db, + admin.id, + admin.username, + "恢复默认视频提词 Schema 配置", + "POST", + "/admin/video-prompt-schema-config/reset-default", + ) + return result @router.get("/export", response_model=VideoPromptSchemaExportOut, summary="导出视频提词 Schema 配置") @@ -68,8 +93,22 @@ async def import_config( admin: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db), ): - _ = admin - return await import_video_prompt_schema_config(db, data=req.data, is_enabled=req.is_enabled) + result = await import_video_prompt_schema_config(db, data=req.data, is_enabled=req.is_enabled) + await log_operation( + db, + admin.id, + admin.username, + "导入视频提词 Schema 配置", + "POST", + "/admin/video-prompt-schema-config/import", + detail=json.dumps( + { + "is_enabled": req.is_enabled, + }, + ensure_ascii=False, + ), + ) + return result @router.post("/preview", response_model=VideoPromptSchemaPreviewOut, summary="预览视频提词运行时 Schema") diff --git a/video-gen-api/app/api/v1/admin.py b/video-gen-api/app/api/v1/admin.py index 62181177..fb11b4b1 100644 --- a/video-gen-api/app/api/v1/admin.py +++ b/video-gen-api/app/api/v1/admin.py @@ -493,6 +493,22 @@ async def create_admin_notification( db, None, title, content, notif_type, push_ws=True ) + await log_operation( + db, + admin.id, + admin.username, + f"{'发送通知给指定用户' if target_user_id else '广播通知'}: {title}", + "POST", + "/admin/notifications", + detail=json.dumps( + { + "title": title, + "target_user_id": target_user_id, + "type": notif_type, + }, + ensure_ascii=False, + ), + ) return {"message": "ok"} @@ -513,6 +529,21 @@ async def delete_admin_notification( ) await db.delete(notif) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"删除通知: {notif.title}", + "DELETE", + f"/admin/notifications/{notification_id}", + detail=json.dumps( + { + "notification_id": notification_id, + "title": notif.title, + }, + ensure_ascii=False, + ), + ) return {"message": "ok"} @@ -577,6 +608,15 @@ async def batch_update_payment_configs( value=value, )) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + "批量更新支付配置", + "PUT", + "/admin/payment-configs/batch", + detail=json.dumps(list(req.keys()), ensure_ascii=False), + ) return {"ok": True} @@ -767,6 +807,22 @@ async def update_payment_config( raise HTTPException(status_code=404, detail="支付配置不存在") config.value = req.value await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"更新支付配置: {config.key}", + "PUT", + f"/admin/payment-configs/{config_id}", + detail=json.dumps( + { + "config_id": config_id, + "key": config.key, + "value": req.value, + }, + ensure_ascii=False, + ), + ) return { "id": config.id, "key": config.key, @@ -785,6 +841,20 @@ async def refund_payment_order( result = await process_refund(db, order_no) if not result.get("success"): raise HTTPException(status_code=400, detail=result.get("message", "退款失败")) + await log_operation( + db, + admin.id, + admin.username, + f"订单退款: {order_no}", + "POST", + f"/admin/payment-orders/{order_no}/refund", + detail=json.dumps( + { + "order_no": order_no, + }, + ensure_ascii=False, + ), + ) return result @@ -842,6 +912,22 @@ async def create_industry_config( ) db.add(config) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"创建行业配置: {req.label}", + "POST", + "/admin/industry-configs", + detail=json.dumps( + { + "config_id": config.id, + "key": req.key, + "label": req.label, + }, + ensure_ascii=False, + ), + ) return _serialize_industry(config) @@ -866,6 +952,22 @@ async def update_industry_config( config.is_active = req.is_active config.sort_order = req.sort_order await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"更新行业配置: {req.label}", + "PUT", + f"/admin/industry-configs/{config_id}", + detail=json.dumps( + { + "config_id": config_id, + "key": req.key, + "label": req.label, + }, + ensure_ascii=False, + ), + ) return _serialize_industry(config) @@ -883,6 +985,22 @@ async def delete_industry_config( raise HTTPException(status_code=404, detail="行业配置不存在") await db.delete(config) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"删除行业配置: {config.label}", + "DELETE", + f"/admin/industry-configs/{config_id}", + detail=json.dumps( + { + "config_id": config_id, + "key": config.key, + "label": config.label, + }, + ensure_ascii=False, + ), + ) return {"message": "ok"} @@ -908,6 +1026,21 @@ async def create_video_engine( engine = VideoEngine(id=generate_id(), **req.model_dump()) db.add(engine) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"创建视频引擎: {req.name}", + "POST", + "/admin/video-engines", + detail=json.dumps( + { + "engine_id": engine.id, + "name": req.name, + }, + ensure_ascii=False, + ), + ) return engine @@ -927,6 +1060,21 @@ async def update_video_engine( for k, v in req.model_dump().items(): setattr(engine, k, v) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"更新视频引擎: {engine.name}", + "PUT", + f"/admin/video-engines/{engine_id}", + detail=json.dumps( + { + "engine_id": engine_id, + "name": engine.name, + }, + ensure_ascii=False, + ), + ) return engine @@ -944,6 +1092,21 @@ async def delete_video_engine( raise HTTPException(status_code=404, detail="视频引擎不存在") await db.delete(engine) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"删除视频引擎: {engine.name}", + "DELETE", + f"/admin/video-engines/{engine_id}", + detail=json.dumps( + { + "engine_id": engine_id, + "name": engine.name, + }, + ensure_ascii=False, + ), + ) return {"message": "ok"} @@ -969,6 +1132,21 @@ async def create_image_engine( engine = ImageEngine(id=generate_id(), **req.model_dump()) db.add(engine) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"创建图片引擎: {req.name}", + "POST", + "/admin/image-engines", + detail=json.dumps( + { + "engine_id": engine.id, + "name": req.name, + }, + ensure_ascii=False, + ), + ) return engine @@ -988,6 +1166,21 @@ async def update_image_engine( for k, v in req.model_dump().items(): setattr(engine, k, v) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"更新图片引擎: {engine.name}", + "PUT", + f"/admin/image-engines/{engine_id}", + detail=json.dumps( + { + "engine_id": engine_id, + "name": engine.name, + }, + ensure_ascii=False, + ), + ) return engine @@ -1005,6 +1198,21 @@ async def delete_image_engine( raise HTTPException(status_code=404, detail="图片引擎不存在") await db.delete(engine) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"删除图片引擎: {engine.name}", + "DELETE", + f"/admin/image-engines/{engine_id}", + detail=json.dumps( + { + "engine_id": engine_id, + "name": engine.name, + }, + ensure_ascii=False, + ), + ) return {"message": "ok"} @@ -1056,6 +1264,22 @@ async def create_credit_ratio( ratio = CreditRatio(id=generate_id(), **data) db.add(ratio) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"创建积分规则: {data.get('gen_type', '')} - {data.get('model_config_id', '')}", + "POST", + "/admin/credit-ratios", + detail=json.dumps( + { + "ratio_id": ratio.id, + "gen_type": data.get("gen_type"), + "model_config_id": data.get("model_config_id"), + }, + ensure_ascii=False, + ), + ) return ratio @@ -1079,6 +1303,22 @@ async def update_credit_ratio( for k, v in data.items(): setattr(ratio, k, v) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"更新积分规则: {data.get('gen_type', '')} - {data.get('model_config_id', '')}", + "PUT", + f"/admin/credit-ratios/{ratio_id}", + detail=json.dumps( + { + "ratio_id": ratio_id, + "gen_type": data.get("gen_type"), + "model_config_id": data.get("model_config_id"), + }, + ensure_ascii=False, + ), + ) return ratio @@ -1096,6 +1336,22 @@ async def delete_credit_ratio( raise HTTPException(status_code=404, detail="积分比例不存在") await db.delete(ratio) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"删除积分规则: {ratio.gen_type} - {ratio.model_config_id}", + "DELETE", + f"/admin/credit-ratios/{ratio_id}", + detail=json.dumps( + { + "ratio_id": ratio_id, + "gen_type": ratio.gen_type, + "model_config_id": ratio.model_config_id, + }, + ensure_ascii=False, + ), + ) return {"message": "ok"} @@ -1136,6 +1392,21 @@ async def create_model_config( config = ModelConfig(id=generate_id(), **req.model_dump()) db.add(config) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"创建模型配置: {req.name}", + "POST", + "/admin/model-configs", + detail=json.dumps( + { + "config_id": config.id, + "name": req.name, + }, + ensure_ascii=False, + ), + ) return config @@ -1153,6 +1424,21 @@ async def update_model_config( for k, v in req.model_dump().items(): setattr(config, k, v) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"更新模型配置: {config.name}", + "PUT", + f"/admin/model-configs/{config_id}", + detail=json.dumps( + { + "config_id": config_id, + "name": config.name, + }, + ensure_ascii=False, + ), + ) return config @@ -1168,6 +1454,21 @@ async def delete_model_config( raise HTTPException(status_code=404, detail="配置不存在") await db.delete(config) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"删除模型配置: {config.name}", + "DELETE", + f"/admin/model-configs/{config_id}", + detail=json.dumps( + { + "config_id": config_id, + "name": config.name, + }, + ensure_ascii=False, + ), + ) return {"message": "ok"} @@ -1195,6 +1496,22 @@ async def update_system_config( raise HTTPException(status_code=404, detail="配置不存在") config.value = str(req.value) await db.commit() + await log_operation( + db, + admin.id, + admin.username, + f"更新系统配置: {config.key}", + "PUT", + f"/admin/system-configs/{config_id}", + detail=json.dumps( + { + "config_id": config_id, + "key": config.key, + "value": req.value, + }, + ensure_ascii=False, + ), + ) return config @@ -1557,6 +1874,21 @@ async def admin_update_generation_status( if new_status == "completed": record.generated_at = datetime.now() await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"更新生成记录状态: {new_status}", + "PUT", + f"/admin/generation-records/{record_id}/status", + detail=json.dumps( + { + "record_id": record_id, + "new_status": new_status, + }, + ensure_ascii=False, + ), + ) return {"message": "ok"} @@ -1688,6 +2020,22 @@ async def admin_generate_video( ) await db.flush() + await log_operation( + db, + admin.id, + admin.username, + f"管理员触发生成{type_str}: {record_id}", + "POST", + f"/admin/generation-records/{record_id}/generate", + detail=json.dumps( + { + "record_id": record_id, + "gen_type": record.gen_type, + "project_name": project_name, + }, + ensure_ascii=False, + ), + ) return {"message": "ok", "record_id": record_id} @@ -1739,6 +2087,22 @@ async def upload_pdf( value=url, )) await db.commit() + await log_operation( + db, + admin.id, + admin.username, + f"上传PDF文件: {file.filename}", + "POST", + "/admin/upload-pdf", + detail=json.dumps( + { + "filename": file.filename, + "config_key": config_key, + "url": url, + }, + ensure_ascii=False, + ), + ) return {"url": url} @@ -1785,6 +2149,21 @@ async def upload_logo( description="网站Logo图片", )) await db.commit() + await log_operation( + db, + admin.id, + admin.username, + f"上传Logo图片: {file.filename}", + "POST", + "/admin/upload-logo", + detail=json.dumps( + { + "filename": file.filename, + "url": url, + }, + ensure_ascii=False, + ), + ) return {"url": url}