This commit is contained in:
2026-07-01 10:28:40 +08:00
11 changed files with 722 additions and 67 deletions
@@ -0,0 +1,27 @@
"""add max image and video count to video engines
Revision ID: f7a3b2c1d4e5
Revises: e5f260ed1459
Create Date: 2026-07-01 00:00:00.000000
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
revision: str = 'f7a3b2c1d4e5'
down_revision: Union[str, None] = 'e5f260ed1459'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.add_column('video_engines', sa.Column('max_image_count', sa.Integer(), server_default='2', nullable=False))
op.add_column('video_engines', sa.Column('max_video_count', sa.Integer(), server_default='0', nullable=False))
def downgrade() -> None:
op.drop_column('video_engines', 'max_video_count')
op.drop_column('video_engines', 'max_image_count')
+51 -21
View File
@@ -48,40 +48,70 @@ async def get_credit_ratios(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
async def get_ratios_for_engine_type(gen_type: str, engine_ids: list):
for engine_id in engine_ids:
import json
async def get_engine_with_ratios(gen_type: str, engines: list):
for engine in engines:
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:
return [CreditRatioOut.model_validate(r) for r in ratios]
return []
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
video_engines_result = await db.execute(
select(VideoEngine.id)
select(VideoEngine)
.where(VideoEngine.is_active == True)
.order_by(VideoEngine.priority.desc())
)
video_engine_ids = video_engines_result.scalars().all()
video_engines = video_engines_result.scalars().all()
image_engines_result = await db.execute(
select(ImageEngine.id)
select(ImageEngine)
.where(ImageEngine.is_active == True)
.order_by(ImageEngine.priority.desc())
)
image_engine_ids = image_engines_result.scalars().all()
image_engines = image_engines_result.scalars().all()
grouped = {}
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
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
return grouped
@@ -112,7 +112,7 @@ async def sync_consumption(
)
async def get_consumption_fields() -> Any | dict:
fields = [
{"field": "id", "description": "主键"},
{"field": "id", "description": "编号"},
{"field": "advertiser_id", "description": "广告主id"},
{"field": "material_id", "description": "素材id"},
{"field": "consume_date", "description": "消耗日期"},
@@ -49,5 +49,7 @@ async def list_active_engines(
"supported_ratios": ratios,
"supported_resolutions": resolutions,
"supported_durations": durations,
"max_image_count": e.max_image_count,
"max_video_count": e.max_video_count,
})
return {"items": items}
+2
View File
@@ -17,6 +17,8 @@ class VideoEngine(Base, TimestampMixin):
supported_resolutions: Mapped[str] = mapped_column(String(256), default='["480p","720p","1080p"]')
supported_durations: Mapped[str] = mapped_column(String(256), nullable=True, default='[4,5,6,7,8,9,10,11,12,13,14,15]')
max_duration: Mapped[int] = mapped_column(Integer, default=15)
max_image_count: Mapped[int] = mapped_column(Integer, default=2)
max_video_count: Mapped[int] = mapped_column(Integer, default=0)
generate_url: Mapped[str | None] = mapped_column(String(512), nullable=True, default="")
query_url: Mapped[str | None] = mapped_column(String(512), nullable=True, default="")
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
@@ -13,6 +13,8 @@ class VideoEngineCreate(BaseModel):
supported_resolutions: str = Field(default='["480p","720p","1080p"]')
supported_durations: str = Field(default='[4,5,6,7,8,9,10,11,12,13,14,15]')
max_duration: int = Field(default=15)
max_image_count: int = Field(default=2)
max_video_count: int = Field(default=0)
generate_url: str = Field(default="", max_length=512)
query_url: str = Field(default="", max_length=512)
is_active: bool = True
@@ -33,6 +35,8 @@ class VideoEnginePublic(BaseModel):
supported_ratios: list[str] = []
supported_resolutions: list[str] = []
supported_durations: list[int] = []
max_image_count: int = 2
max_video_count: int = 0
class VideoEngineListResponse(BaseModel):
+4 -3
View File
@@ -122,7 +122,7 @@ class UploadQueue:
code = -1
if code != 0:
logger.error(f"Error getting account info: {json.dumps(account_info)}")
logger.error(f"获取账户信息失败: {json.dumps(account_info)}")
else:
existing_account = await db.execute(
select(UserOAuthAccount).where(
@@ -161,8 +161,7 @@ class UploadQueue:
)
await db.commit()
message = result.get('message') or result.get('error', 'Unknown error')
logger.info(f"Upload task {task_id} completed: {'success' if result.get('success') else 'failed'}. Message: {message}")
logger.info(f"上传任务{task_id}完成: {'success' if result.get('success') else 'failed'}. 上传结果: {json.dumps(result, ensure_ascii=False)}")
except Exception as e:
async with async_session() as db:
@@ -323,6 +322,7 @@ async def _upload_to_juliang(
response = await douyin_api.upload_image_material(oauth_id, data, files)
if response["code"] != 0:
logger.error(f"上传图片素材失败: {json.dumps(response, ensure_ascii=False)}")
return {
"resource_id": resource.id,
"advertiser_id": advertiser_id,
@@ -409,6 +409,7 @@ async def _upload_to_juliang(
response = await douyin_api.upload_video_material(oauth_id, data, files)
if response["code"] != 0:
logger.error(f"上传视频素材失败: {json.dumps(response, ensure_ascii=False)}")
return {
"resource_id": resource.id,
"advertiser_id": advertiser_id,