Files
video-gen/video-gen-api/app/services/material_admin_service.py

380 lines
15 KiB
Python

from typing import Optional, List, Tuple
from datetime import datetime
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.user import User
from app.models.user_oauth import UserOAuth
from app.models.user_oauth_account import UserOAuthAccount
from app.models.resources_material import ResourcesMaterial
from app.models.pre_test_template import PreTestTemplate
from app.models.upload_task import UploadTask
from app.utils.datetime_util import BEIJING_TZ, datetime_to_db_tz_str, db_tz_str_to_datetime, parse_date_range
async def get_oauth_list(
id: Optional[str] = None,
db: AsyncSession = None,
phone: Optional[str] = None,
account_id: Optional[str] = None,
account_userid: Optional[str] = None,
created_at: Optional[datetime] = None,
appid: Optional[str] = None,
open_type: Optional[int] = None,
page: int = 1,
page_size: int = 10,
) -> Tuple[List[UserOAuth], int]:
offset = (page - 1) * page_size
query = select(UserOAuth).where(UserOAuth.deleted_at.is_(None))
if id:
query = query.where(UserOAuth.id == id)
if phone:
query = query.join(User, User.id == UserOAuth.user_id).where(User.phone == phone)
if account_id:
query = query.where(UserOAuth.account_id == account_id)
if account_userid:
query = query.where(UserOAuth.account_userid == account_userid)
# 【改动3】适配入参 created_at=["2025-01-01","2026-01-01"] 字符串日期场景
if created_at and len(created_at) == 2:
try:
start_dt, end_dt = parse_date_range(created_at, is_timezone=True)
# 直接用datetime范围匹配,不走func.date,保留时分秒精度,命中索引
query = query.where(
UserOAuth.created_at >= start_dt,
UserOAuth.created_at <= end_dt
)
except ValueError:
# 捕获日期格式错误,非法时间直接不附加该查询条件
pass
if appid:
query = query.where(UserOAuth.appid == appid)
if open_type:
query = query.where(UserOAuth.open_type == open_type)
count_query = select(func.count(UserOAuth.id)).where(UserOAuth.deleted_at.is_(None))
if phone:
count_query = count_query.join(User, User.id == UserOAuth.user_id).where(User.phone == phone)
if account_id:
count_query = count_query.where(UserOAuth.account_id == account_id)
if account_userid:
count_query = count_query.where(UserOAuth.account_userid == account_userid)
if created_at:
try:
start_dt, end_dt = parse_date_range(created_at, is_timezone=True)
# 直接用datetime范围匹配,不走func.date,保留时分秒精度,命中索引
count_query = count_query.where(
UserOAuth.created_at >= start_dt,
UserOAuth.created_at <= end_dt
)
except ValueError:
# 捕获日期格式错误,非法时间直接不附加该查询条件
pass
if appid:
count_query = count_query.where(UserOAuth.appid == appid)
if open_type:
count_query = count_query.where(UserOAuth.open_type == open_type)
total_result = await db.execute(count_query)
total = total_result.scalar_one()
query = query.order_by(UserOAuth.id.desc()).offset(offset).limit(page_size)
result = await db.execute(query)
list = [];
for oauth in result.scalars().all():
user_query = select(User).where(User.id == oauth.user_id)
user_result = await db.execute(user_query)
user = user_result.scalar_one()
if user:
phone = user.phone
else:
phone = None
item = {
"id": oauth.id,
"account_id": oauth.account_id,
"account_name": oauth.account_name,
"account_role": oauth.account_role,
"account_username": oauth.account_username,
"account_userid": oauth.account_userid,
"user_id": oauth.user_id,
"user_phone": phone,
"open_type": oauth.open_type,
"port_type": oauth.port_type,
"appid": oauth.appid,
"access_token": oauth.access_token,
"refresh_token": oauth.refresh_token,
"access_token_expired": oauth.access_token_expired,
"refresh_token_expired": oauth.refresh_token_expired,
"created_at": oauth.created_at,
"updated_at": oauth.updated_at,
}
list.append(item)
return list, total
async def get_material_list(
db: AsyncSession,
phone: Optional[str] = None,
id: Optional[str] = None,
resource_type: Optional[str] = None,
advertiser_id: Optional[str] = None,
material_id: Optional[str] = None,
upload_id: Optional[str] = None,
created_at: Optional[datetime] = None,
status: Optional[str] = None,
page: int = 1,
page_size: int = 20,
) -> Tuple[List[ResourcesMaterial], int]:
offset = (page - 1) * page_size
query = select(ResourcesMaterial).where(ResourcesMaterial.deleted_at.is_(None))
if phone:
query = query.join(UserOAuth, UserOAuth.id == ResourcesMaterial.oauth_id).join(User, User.id == UserOAuth.user_id).where(User.phone == phone)
if id:
query = query.where(ResourcesMaterial.id == id)
if resource_type:
query = query.where(ResourcesMaterial.resource_type == resource_type)
if advertiser_id:
query = query.where(ResourcesMaterial.advertiser_id == advertiser_id)
if material_id:
query = query.where(ResourcesMaterial.material_id == material_id)
if upload_id:
query = query.where(ResourcesMaterial.upload_id == upload_id)
if created_at:
start_dt, end_dt = parse_date_range(created_at, is_timezone=True)
# 直接用datetime范围匹配,不走func.date,保留时分秒精度,命中索引
query = query.where(
ResourcesMaterial.created_at >= start_dt,
ResourcesMaterial.created_at <= end_dt
)
if status:
query = query.where(ResourcesMaterial.status == status)
count_query = select(func.count(ResourcesMaterial.id)).where(ResourcesMaterial.deleted_at.is_(None))
if phone:
count_query = count_query.join(UserOAuth, UserOAuth.id == ResourcesMaterial.oauth_id).join(User, User.id == UserOAuth.user_id).where(User.phone == phone)
if id:
count_query = count_query.where(ResourcesMaterial.id == id)
if resource_type:
count_query = count_query.where(ResourcesMaterial.resource_type == resource_type)
if advertiser_id:
count_query = count_query.where(ResourcesMaterial.advertiser_id == advertiser_id)
if material_id:
count_query = count_query.where(ResourcesMaterial.material_id == material_id)
if upload_id:
count_query = count_query.where(ResourcesMaterial.upload_id == upload_id)
if created_at:
start_dt, end_dt = parse_date_range(created_at, is_timezone=True)
# 直接用datetime范围匹配,不走func.date,保留时分秒精度,命中索引
count_query = count_query.where(
ResourcesMaterial.created_at >= start_dt,
ResourcesMaterial.created_at <= end_dt
)
if status:
count_query = count_query.where(ResourcesMaterial.status == status)
total_result = await db.execute(count_query)
total = total_result.scalar_one()
query = query.order_by(ResourcesMaterial.id.desc()).offset(offset).limit(page_size)
result = await db.execute(query)
list = []
for item in result.scalars().all():
user_query = select(User).where(User.id == item.user_id)
user_result = await db.execute(user_query)
user = user_result.scalar_one()
if user:
phone = user.phone
else:
phone = None
item = {
"id": item.id,
"oauth_id": item.oauth_id,
"user_phone": phone,
"advertiser_id": item.advertiser_id,
"target_table": item.target_table,
"target_id": item.target_id,
"material_id": item.material_id,
"upload_id": item.upload_id,
"resource_type": item.resource_type,
"user_id": item.user_id,
"created_at": item.created_at,
"updated_at": item.updated_at,
"task_id": item.task_id,
"note": item.note,
"status": item.status,
"pre_result": item.pre_result,
"pre_test_template_id": item.pre_test_template_id,
}
list.append(item)
return list, total
async def get_pre_test_template_list(
db: AsyncSession,
phone: Optional[str] = None,
id: Optional[str] = None,
created_at: Optional[datetime] = None,
page: int = 1,
page_size: int = 10,
) -> Tuple[List[PreTestTemplate], int]:
offset = (page - 1) * page_size
query = select(PreTestTemplate).where(PreTestTemplate.deleted_at.is_(None))
if phone:
query = query.join(User, User.id == PreTestTemplate.user_id).where(User.phone == phone)
if id:
query = query.where(PreTestTemplate.id == id)
if created_at:
start_dt, end_dt = parse_date_range(created_at, is_timezone=True)
# 直接用datetime范围匹配,不走func.date,保留时分秒精度,命中索引
query = query.where(
PreTestTemplate.created_at >= start_dt,
PreTestTemplate.created_at <= end_dt
)
count_query = select(func.count(PreTestTemplate.id)).where(PreTestTemplate.deleted_at.is_(None))
if phone:
count_query = count_query.join(User, User.id == PreTestTemplate.user_id).where(User.phone == phone)
if id:
count_query = count_query.where(PreTestTemplate.id == id)
if created_at:
# 直接用datetime范围匹配,不走func.date,保留时分秒精度,命中索引
start_dt, end_dt = parse_date_range(created_at, is_timezone=True)
count_query = count_query.where(
PreTestTemplate.created_at >= start_dt,
PreTestTemplate.created_at <= end_dt
)
total_result = await db.execute(count_query)
total = total_result.scalar_one()
query = query.order_by(PreTestTemplate.id.desc()).offset(offset).limit(page_size)
result = await db.execute(query)
list = []
for item in result.scalars().all():
user_query = select(User).where(User.id == item.user_id)
user_result = await db.execute(user_query)
user = user_result.scalar_one()
if user:
phone = user.phone
else:
phone = None
item = {
"id": item.id,
"name": item.name,
"user_phone": phone,
"user_id": item.user_id,
"platform": item.platform,
"external_action": item.external_action,
"cpa_bid": item.cpa_bid,
"audience_gender": item.audience_gender,
"audience_age": item.audience_age,
"audience_region": item.audience_region,
"audience_network": item.audience_network,
"cus_name": item.cus_name,
"pricing_type": item.pricing_type,
"cost_cap": item.cost_cap,
"target_cost": item.target_cost,
"nobid": item.nobid,
"cpc_bid": item.cpc_bid,
"budget": item.budget,
"is_default": item.is_default,
"created_at": item.created_at,
"updated_at": item.updated_at,
"note": item.note,
}
list.append(item)
return list, total
async def get_upload_task_list(
db: AsyncSession,
phone: Optional[str] = None,
id: Optional[str] = None,
created_at: Optional[List[str]] = None,
advertiser_id: Optional[str] = None,
status: Optional[int] = None,
resource_id: Optional[str] = None,
page: int = 1,
page_size: int = 10,
) -> Tuple[List[UploadTask], int]:
offset = (page - 1) * page_size
query = select(UploadTask).where(UploadTask.deleted_at.is_(None))
if phone:
query = query.join(User, User.id == UploadTask.user_id).where(User.phone == phone)
if id:
query = query.where(UploadTask.id == id)
if created_at and len(created_at) >= 2:
# 直接用datetime范围匹配,不走func.date,保留时分秒精度,命中索引
start_dt, end_dt = parse_date_range(created_at, is_timezone=True)
query = query.where(
UploadTask.created_at >= start_dt,
UploadTask.created_at <= end_dt
)
if advertiser_id:
query = query.where(UploadTask.advertiser_id == advertiser_id)
if status:
query = query.where(UploadTask.status == status)
if resource_id:
query = query.where(UploadTask.resource_id == resource_id)
count_query = select(func.count(UploadTask.id)).where(UploadTask.deleted_at.is_(None))
if phone:
count_query = count_query.join(User, User.id == UploadTask.user_id).where(User.phone == phone)
if id:
count_query = count_query.where(UploadTask.id == id)
if created_at and len(created_at) >= 2:
# 直接用datetime范围匹配,不走func.date,保留时分秒精度,命中索引
start_dt, end_dt = parse_date_range(created_at, is_timezone=True)
count_query = count_query.where(
UploadTask.created_at >= start_dt,
UploadTask.created_at <= end_dt
)
if advertiser_id:
count_query = count_query.where(UploadTask.advertiser_id == advertiser_id)
if status:
count_query = count_query.where(UploadTask.status == status)
if resource_id:
count_query = count_query.where(UploadTask.resource_id == resource_id)
total_result = await db.execute(count_query)
total = total_result.scalar_one()
query = query.order_by(UploadTask.id.desc()).offset(offset).limit(page_size)
result = await db.execute(query)
list = []
for item in result.scalars().all():
user_query = select(User).where(User.id == item.user_id)
user_result = await db.execute(user_query)
user = user_result.scalar_one()
if user:
phone = user.phone
else:
phone = None
item = {
"id": item.id,
"user_phone": phone,
"user_id": item.user_id,
"advertiser_id": item.advertiser_id,
"resource_id": item.resource_id,
"status": item.status,
"note": item.note,
"oauth_id": item.oauth_id,
"created_at": item.created_at,
"updated_at": item.updated_at,
"other_info": item.other_info,
}
list.append(item)
return list, total