79 lines
4.0 KiB
Python
79 lines
4.0 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Depends, Query
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.dependencies import get_db
|
|
from app.enums.home_material import HomeMaterialMediaType, HomeMaterialPublicResponseMode
|
|
from app.schemas.home_material import (
|
|
HomeMaterialPublicCategoryListOut,
|
|
HomeMaterialPublicFlatOut,
|
|
HomeMaterialPublicGroupedOut,
|
|
)
|
|
from app.services.home_material import home_material_service
|
|
|
|
router = APIRouter(prefix="/home-materials", tags=["home-materials"])
|
|
|
|
|
|
@router.get(
|
|
"/categories",
|
|
response_model=HomeMaterialPublicCategoryListOut,
|
|
summary="获取首页素材行业列表",
|
|
description=(
|
|
"获取首页素材行业列表,用于前端渲染行业 Tab/筛选。"
|
|
"只返回已启用、未软删行业;only_has_assets=true 时只返回存在 success + is_active + watermarked_url 的行业。"
|
|
"统计素材数量时不连表,先查行业列表,再按 category_id 批量 group by 查询素材数量并 map 回填。"
|
|
),
|
|
)
|
|
async def get_public_home_material_categories(
|
|
with_asset_count: bool = Query(True, description="是否返回每个行业下可展示素材数量。"),
|
|
media_type: HomeMaterialMediaType | None = Query(None, description="统计指定素材类型:image图片,video视频。不传表示全部。"),
|
|
only_has_assets: bool = Query(True, description="是否只返回有可展示素材的行业。"),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
return await home_material_service.get_public_categories(
|
|
db,
|
|
with_asset_count=with_asset_count,
|
|
media_type=media_type,
|
|
only_has_assets=only_has_assets,
|
|
)
|
|
|
|
|
|
@router.get(
|
|
"",
|
|
response_model=HomeMaterialPublicGroupedOut | HomeMaterialPublicFlatOut,
|
|
summary="获取首页素材展示数据",
|
|
description=(
|
|
"获取首页素材展示数据。支持不传行业返回全部行业分组;支持 category_id/category_key/category_ids/category_keys 按行业过滤,"
|
|
"优先级为 category_id > category_key > category_ids > category_keys。"
|
|
"response_mode=grouped 时按行业分组并限制每个行业 limit_per_category 条;"
|
|
"response_mode=flat 时返回平铺分页素材流。前台接口只返回水印素材 url,不返回原始素材 original_url。"
|
|
),
|
|
)
|
|
async def get_public_home_materials(
|
|
category_id: str | None = Query(None, description="单个行业ID。优先级最高。"),
|
|
category_key: str | None = Query(None, description="单个行业key。未传 category_id 时生效。"),
|
|
category_ids: str | None = Query(None, description="多个行业ID,英文逗号分隔。未传单行业参数时生效。"),
|
|
category_keys: str | None = Query(None, description="多个行业key,英文逗号分隔。优先级最低。"),
|
|
media_type: HomeMaterialMediaType | None = Query(None, description="素材类型筛选:image图片,video视频。不传表示全部。"),
|
|
limit_per_category: int = Query(8, ge=1, le=50, description="grouped 模式下每个行业最多返回几条素材,默认8,最大50。"),
|
|
include_empty_categories: bool = Query(False, description="grouped 模式下是否返回无素材行业。默认 false。"),
|
|
response_mode: HomeMaterialPublicResponseMode = Query(HomeMaterialPublicResponseMode.GROUPED, description="返回模式:grouped按行业分组,flat平铺分页。"),
|
|
page: int = Query(1, ge=1, description="flat 模式页码,默认1。"),
|
|
page_size: int = Query(20, ge=1, le=100, description="flat 模式每页数量,默认20,最大100。"),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
return await home_material_service.get_public_home_materials(
|
|
db,
|
|
category_id=category_id,
|
|
category_key=category_key,
|
|
category_ids=category_ids,
|
|
category_keys=category_keys,
|
|
media_type=media_type,
|
|
limit_per_category=limit_per_category,
|
|
include_empty_categories=include_empty_categories,
|
|
response_mode=response_mode,
|
|
page=page,
|
|
page_size=page_size,
|
|
)
|