Merge branch 'main' of https://gitee.com/wg123/video-gen
This commit is contained in:
@@ -1400,9 +1400,10 @@ async def admin_list_generation_records(
|
||||
):
|
||||
"""List all generation records across all users, with optional filters."""
|
||||
query = (
|
||||
select(GenerationRecord, User.username, Project.name)
|
||||
select(GenerationRecord, User.username, Project.name, Project.industry, IndustryConfig.label)
|
||||
.join(User, GenerationRecord.user_id == User.id)
|
||||
.join(Project, GenerationRecord.project_id == Project.id)
|
||||
.outerjoin(IndustryConfig, Project.industry == IndustryConfig.key)
|
||||
.where(GenerationRecord.deleted_at.is_(None), Project.deleted_at.is_(None))
|
||||
.order_by(GenerationRecord.created_at.desc())
|
||||
)
|
||||
@@ -1427,7 +1428,7 @@ async def admin_list_generation_records(
|
||||
rows = result.all()
|
||||
|
||||
items = []
|
||||
for record, username, project_name in rows:
|
||||
for record, username, project_name, industry, industry_label in rows:
|
||||
refs = None
|
||||
if record.media_references:
|
||||
try:
|
||||
@@ -1440,6 +1441,7 @@ async def admin_list_generation_records(
|
||||
"username": username,
|
||||
"project_id": record.project_id,
|
||||
"project_name": project_name,
|
||||
"industry": industry_label or industry,
|
||||
"original_prompt": record.original_prompt,
|
||||
"optimized_prompt": record.optimized_prompt,
|
||||
"duration": record.duration,
|
||||
|
||||
@@ -48,70 +48,40 @@ async def get_credit_ratios(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
import json
|
||||
|
||||
async def get_engine_with_ratios(gen_type: str, engines: list):
|
||||
for engine in engines:
|
||||
async def get_ratios_for_engine_type(gen_type: str, engine_ids: list):
|
||||
for engine_id in engine_ids:
|
||||
result = await db.execute(
|
||||
select(CreditRatio)
|
||||
.where(CreditRatio.gen_type == gen_type)
|
||||
.where(CreditRatio.model_config_id == engine.id)
|
||||
.where(CreditRatio.model_config_id == engine_id)
|
||||
)
|
||||
ratios = result.scalars().all()
|
||||
if ratios:
|
||||
ratios_out = [CreditRatioOut.model_validate(r) for r in ratios]
|
||||
engine_info = {
|
||||
"id": engine.id,
|
||||
"name": engine.name,
|
||||
"provider": engine.provider,
|
||||
"ratios": ratios_out,
|
||||
}
|
||||
if gen_type == "video":
|
||||
try:
|
||||
supported_ratios = json.loads(engine.supported_ratios) if engine.supported_ratios else []
|
||||
except Exception:
|
||||
supported_ratios = []
|
||||
try:
|
||||
supported_resolutions = json.loads(engine.supported_resolutions) if engine.supported_resolutions else []
|
||||
except Exception:
|
||||
supported_resolutions = []
|
||||
try:
|
||||
supported_durations = json.loads(engine.supported_durations) if engine.supported_durations else []
|
||||
except Exception:
|
||||
supported_durations = []
|
||||
engine_info.update({
|
||||
"supported_ratios": supported_ratios,
|
||||
"supported_resolutions": supported_resolutions,
|
||||
"supported_durations": supported_durations,
|
||||
"max_duration": engine.max_duration,
|
||||
"max_image_count": engine.max_image_count,
|
||||
"max_video_count": engine.max_video_count,
|
||||
})
|
||||
return engine_info
|
||||
return None
|
||||
|
||||
return [CreditRatioOut.model_validate(r) for r in ratios]
|
||||
return []
|
||||
|
||||
video_engines_result = await db.execute(
|
||||
select(VideoEngine)
|
||||
select(VideoEngine.id)
|
||||
.where(VideoEngine.is_active == True)
|
||||
.order_by(VideoEngine.priority.desc())
|
||||
)
|
||||
video_engines = video_engines_result.scalars().all()
|
||||
|
||||
video_engine_ids = video_engines_result.scalars().all()
|
||||
|
||||
image_engines_result = await db.execute(
|
||||
select(ImageEngine)
|
||||
select(ImageEngine.id)
|
||||
.where(ImageEngine.is_active == True)
|
||||
.order_by(ImageEngine.priority.desc())
|
||||
)
|
||||
image_engines = image_engines_result.scalars().all()
|
||||
|
||||
image_engine_ids = image_engines_result.scalars().all()
|
||||
|
||||
grouped = {}
|
||||
|
||||
video_data = await get_engine_with_ratios("video", video_engines)
|
||||
if video_data:
|
||||
grouped["video"] = video_data
|
||||
|
||||
image_data = await get_engine_with_ratios("image", image_engines)
|
||||
if image_data:
|
||||
grouped["image"] = image_data
|
||||
|
||||
|
||||
video_ratios = await get_ratios_for_engine_type("video", video_engine_ids)
|
||||
if video_ratios:
|
||||
grouped["video"] = video_ratios
|
||||
|
||||
image_ratios = await get_ratios_for_engine_type("image", image_engine_ids)
|
||||
if image_ratios:
|
||||
grouped["image"] = image_ratios
|
||||
|
||||
return grouped
|
||||
|
||||
@@ -44,5 +44,6 @@ async def list_active_engines(
|
||||
"supported_models": models,
|
||||
"supported_sizes": sizes,
|
||||
"default_size": e.default_size,
|
||||
"max_image_count": e.max_image_count,
|
||||
})
|
||||
return {"items": items}
|
||||
@@ -1,11 +1,18 @@
|
||||
import logging
|
||||
from typing import Any, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from fastapi import APIRouter, Depends, Query, Body
|
||||
|
||||
from app.dependencies import get_db
|
||||
from app.schemas.resources_material import ResourcesMaterialListResponse
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from app.models.resources_material import ResourcesMaterial
|
||||
from app.models.pre_test_template import PreTestTemplate
|
||||
|
||||
from app.dependencies import get_db, get_current_user
|
||||
from app.schemas.resources_material import ResourcesMaterialListResponse, PreTestMaterialRequest
|
||||
from app.services.resources_material_service import get_resources_material_list
|
||||
from app.services.pre_test_queue import pre_test_queue
|
||||
from app.utils.id_gen import generate_id
|
||||
|
||||
router = APIRouter(prefix="/resources-material", tags=["resources-material"])
|
||||
|
||||
@@ -25,6 +32,7 @@ async def get_resources_material_list_api(
|
||||
page: int = Query(1, description="页码"),
|
||||
page_size: int = Query(20, description="每页数量"),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
) -> Any | dict:
|
||||
items, total = await get_resources_material_list(
|
||||
db=db,
|
||||
@@ -35,6 +43,7 @@ async def get_resources_material_list_api(
|
||||
resource_type=resource_type,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
user_id=current_user.id,
|
||||
)
|
||||
|
||||
return {
|
||||
@@ -42,4 +51,96 @@ async def get_resources_material_list_api(
|
||||
"message": "查询成功",
|
||||
"data": items,
|
||||
"total": total,
|
||||
}
|
||||
}
|
||||
|
||||
#如果素材上传的时候没有指定前测,现在可以对已经上传好的素材进行前测
|
||||
@router.post(
|
||||
"/pre-commit",
|
||||
summary="素材列表提交前测",
|
||||
description="通过素材列表提交未前测的素材,异步处理,立即返回任务ID,结果稍后通过列表查询",
|
||||
)
|
||||
async def pre_test_material(
|
||||
req: PreTestMaterialRequest = Body(..., description="前测请求体"),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
) -> Any | dict:
|
||||
|
||||
try:
|
||||
invalid_ids = []
|
||||
grouped_videos = {}
|
||||
|
||||
#检查前测模板是否有效
|
||||
pre_test_template = await db.execute(
|
||||
select(PreTestTemplate)
|
||||
.where(
|
||||
PreTestTemplate.id == req.pre_test_template_id,
|
||||
PreTestTemplate.user_id == current_user.id,
|
||||
PreTestTemplate.deleted_at.is_(None),
|
||||
)
|
||||
)
|
||||
pre_test_template = pre_test_template.scalar_one_or_none()
|
||||
if not pre_test_template:
|
||||
return {"code": 1, "message": f"前测模板{req.pre_test_template_id}不存在或不属于当前用户"}
|
||||
|
||||
for resource_material_id in req.resources_material_ids:
|
||||
resource_material = await db.execute(
|
||||
select(ResourcesMaterial)
|
||||
.where(
|
||||
ResourcesMaterial.id == resource_material_id,
|
||||
ResourcesMaterial.user_id == current_user.id,
|
||||
ResourcesMaterial.deleted_at.is_(None),
|
||||
)
|
||||
)
|
||||
resource_material = resource_material.scalar_one_or_none()
|
||||
|
||||
if not resource_material:
|
||||
invalid_ids.append(f"{resource_material_id}: 资源不存在或不属于当前用户")
|
||||
continue
|
||||
|
||||
if resource_material.status is not None:
|
||||
invalid_ids.append(f"{resource_material_id}: 该资源已进行过前测")
|
||||
continue
|
||||
|
||||
if not resource_material.upload_id:
|
||||
invalid_ids.append(f"{resource_material_id}: 该资源未上传到平台")
|
||||
continue
|
||||
|
||||
if resource_material.resource_type != "video":
|
||||
invalid_ids.append(f"{resource_material_id}: 前测仅支持视频类型")
|
||||
continue
|
||||
|
||||
key = f"{resource_material.oauth_id}|{resource_material.advertiser_id}"
|
||||
if key not in grouped_videos:
|
||||
grouped_videos[key] = []
|
||||
grouped_videos[key].append({
|
||||
"id": resource_material.id,
|
||||
"upload_id": resource_material.upload_id,
|
||||
})
|
||||
|
||||
if invalid_ids:
|
||||
return {"code": 1, "message": "; ".join(invalid_ids)}
|
||||
|
||||
if not grouped_videos:
|
||||
return {"code": 1, "message": "没有有效的视频资源"}
|
||||
|
||||
task_id = generate_id()
|
||||
|
||||
await pre_test_queue.enqueue({
|
||||
"task_id": task_id,
|
||||
"grouped_videos": grouped_videos,
|
||||
"pre_test_template_id": req.pre_test_template_id,
|
||||
})
|
||||
|
||||
return {
|
||||
"code": 0,
|
||||
"message": "任务已提交,正在处理中",
|
||||
"data": {
|
||||
"task_id": task_id,
|
||||
"total_groups": len(grouped_videos),
|
||||
},
|
||||
}
|
||||
|
||||
except ValueError as e:
|
||||
return {"code": 1, "message": str(e)}
|
||||
except Exception as e:
|
||||
return {"code": 1, "message": str(e)}
|
||||
@@ -10,6 +10,8 @@ from pydantic import BaseModel, Field
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, func
|
||||
from sqlalchemy import select, func
|
||||
from app.models.generated_resource import GeneratedResource
|
||||
|
||||
|
||||
from app.dependencies import get_current_user, get_db
|
||||
from app.models.user import User
|
||||
@@ -355,51 +357,25 @@ async def batch_update_filename(
|
||||
.where(GeneratedResource.file_name.is_not(None))
|
||||
)
|
||||
result = await db.execute(query)
|
||||
db_existing_names = set(row[0] for row in result.all())
|
||||
|
||||
name_counters = {}
|
||||
existing_names = set(row[0] for row in result.all())
|
||||
|
||||
for item in valid_items:
|
||||
file_name = item["file_name"]
|
||||
resource = item["resource"]
|
||||
base_name, ext = os.path.splitext(file_name)
|
||||
|
||||
existing_names = db_existing_names.copy()
|
||||
|
||||
if resource.file_name and resource.file_name in existing_names:
|
||||
existing_names.remove(resource.file_name)
|
||||
|
||||
if file_name not in name_counters:
|
||||
counter = 1
|
||||
new_file_name = file_name
|
||||
|
||||
while new_file_name in existing_names:
|
||||
new_file_name = f"{base_name}{counter}{ext}"
|
||||
counter += 1
|
||||
|
||||
name_counters[file_name] = {
|
||||
"base_name": base_name,
|
||||
"ext": ext,
|
||||
"counter": counter,
|
||||
}
|
||||
existing_names.add(new_file_name)
|
||||
db_existing_names.add(new_file_name)
|
||||
else:
|
||||
counter = name_counters[file_name]["counter"]
|
||||
base_name = name_counters[file_name]["base_name"]
|
||||
ext = name_counters[file_name]["ext"]
|
||||
new_file_name = f"{base_name}{counter}{ext}"
|
||||
|
||||
while new_file_name in existing_names:
|
||||
counter += 1
|
||||
new_file_name = f"{base_name}{counter}{ext}"
|
||||
|
||||
name_counters[file_name]["counter"] = counter + 1
|
||||
existing_names.add(new_file_name)
|
||||
db_existing_names.add(new_file_name)
|
||||
counter = 1
|
||||
new_file_name = file_name
|
||||
|
||||
while new_file_name in existing_names:
|
||||
new_file_name = f"{base_name}_{counter}{ext}"
|
||||
counter += 1
|
||||
|
||||
item["resource"].file_name = new_file_name
|
||||
db.add(item["resource"])
|
||||
existing_names.add(new_file_name)
|
||||
|
||||
results.append({
|
||||
"source_id": item["source_id"],
|
||||
@@ -421,7 +397,7 @@ async def batch_update_filename(
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
"code": 0,
|
||||
"code": 1,
|
||||
"message": f"批量修改文件名失败:{str(e)}",
|
||||
"success_count": 0,
|
||||
"fail_count": 0,
|
||||
@@ -461,5 +437,3 @@ async def get_upload_history(
|
||||
"code": 0,
|
||||
"message": f"查询上传任务历史失败:{str(e)}",
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user