From 972e5300b14066f34e60ca9b838f3d8f1b4cec09 Mon Sep 17 00:00:00 2001 From: Hommy <16620803786@163.com> Date: Fri, 20 Mar 2026 15:28:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A0=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=9Aget=5Ffilters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exceptions.py | 5 ++- src/router/v1.py | 23 ++++++++-- src/schemas/get_filters.py | 21 +++++++++ src/service/__init__.py | 3 +- src/service/get_filters.py | 87 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 src/schemas/get_filters.py create mode 100644 src/service/get_filters.py diff --git a/exceptions.py b/exceptions.py index 2318fc2..bd267ac 100644 --- a/exceptions.py +++ b/exceptions.py @@ -47,10 +47,11 @@ class CustomError(Enum): IMAGE_ANIMATION_GET_FAILED = (2033, "获取图片动画失败", "Get image animation failed") AUDIO_DURATION_GET_FAILED = (2034, "获取音频时长失败", "Get audio duration failed") INSUFFICIENT_ACCOUNT_BALANCE = (2035, "账户余额不足,当前积分需大于 1 才可继续使用服务,请完成充值后重试", "Insufficient account balance. A minimum of 1 point is required to continue using the service. Please recharge and try again.") - INVALID_APIKEY = (2036, "无效的apiKey", "Invalid apiKey") - INVALID_FILTER_INFO = (2037, "无效的滤镜信息,请检查filter_infos字段值是否正确", "Invalid filter information, please check if the value of the filter_infos field is correct.") + INVALID_APIKEY = (2036, "无效的 apiKey", "Invalid apiKey") + INVALID_FILTER_INFO = (2037, "无效的滤镜信息,请检查 filter_infos 字段值是否正确", "Invalid filter information, please check if the value of the filter_infos field is correct.") FILTER_ADD_FAILED = (2038, "滤镜添加失败", "Filter addition failed") FILTER_NOT_FOUND = (2039, "滤镜未找到,请检查滤镜名称是否正确", "Filter not found, please check if the filter name is correct.") + FILTER_GET_FAILED = (2040, "获取滤镜列表失败", "Get filter list failed") # ===== 系统错误码 (9000-9999) ===== INTERNAL_SERVER_ERROR = (9998, "系统内部错误", "Internal server error") diff --git a/src/router/v1.py b/src/router/v1.py index b046656..1f5dcb9 100644 --- a/src/router/v1.py +++ b/src/router/v1.py @@ -42,6 +42,7 @@ from src.schemas.imgs_infos import ImgsInfosRequest, ImgsInfosResponse from src.schemas.caption_infos import CaptionInfosRequest, CaptionInfosResponse from src.schemas.effect_infos import EffectInfosRequest, EffectInfosResponse from src.schemas.filter_infos import FilterInfosRequest, FilterInfosResponse +from src.schemas.get_filters import GetFiltersRequest, GetFiltersResponse from src.schemas.keyframes_infos import KeyframesInfosRequest, KeyframesInfosResponse from src.schemas.video_infos import VideoInfosRequest, VideoInfosResponse from src.schemas.search_sticker import SearchStickerRequest, SearchStickerResponse @@ -352,20 +353,36 @@ def get_text_animations(gtar: GetTextAnimationsRequest) -> GetTextAnimationsResp @router.post(path="/get_image_animations", response_model=GetImageAnimationsResponse) def get_image_animations(giar: GetImageAnimationsRequest) -> GetImageAnimationsResponse: """ - 获取图片出入场动画 (v1版本) + 获取图片出入场动画 (v1 版本) """ - # 调用service层处理业务逻辑 + # 调用 service 层处理业务逻辑 effects = service.get_image_animations( mode=giar.mode, type=giar.type ) - # 直接返回对象数组,Pydantic会自动处理序列化 + # 直接返回对象数组,Pydantic 会自动处理序列化 return GetImageAnimationsResponse( effects=effects ) +@router.post(path="/get_filters", response_model=GetFiltersResponse) +def get_filters(gfr: GetFiltersRequest) -> GetFiltersResponse: + """ + 获取滤镜列表 (v1 版本) + """ + + # 调用 service 层处理业务逻辑 + filters = service.get_filters( + mode=gfr.mode + ) + + # 直接返回对象数组,Pydantic 会自动处理序列化 + return GetFiltersResponse( + filters=filters + ) + @router.get(path="/get_draft", response_model=GetDraftResponse) def get_draft(params: Annotated[GetDraftRequest, Depends()]) -> GetDraftResponse: """ diff --git a/src/schemas/get_filters.py b/src/schemas/get_filters.py new file mode 100644 index 0000000..bdef69e --- /dev/null +++ b/src/schemas/get_filters.py @@ -0,0 +1,21 @@ +from pydantic import BaseModel, Field +from typing import List, Optional + + +class GetFiltersRequest(BaseModel): + """获取滤镜列表请求参数""" + mode: Optional[int] = Field(default=0, ge=0, le=2, description="滤镜模式,0=所有,1=VIP,2=免费,默认值为 0") + + +class FilterItem(BaseModel): + """滤镜信息项""" + name: str = Field(..., description="滤镜名称") + is_vip: bool = Field(..., description="是否为 VIP 滤镜") + resource_id: str = Field(..., description="资源 ID") + effect_id: str = Field(..., description="效果 ID") + has_params: bool = Field(..., description="是否有额外参数") + + +class GetFiltersResponse(BaseModel): + """获取滤镜列表响应参数""" + filters: List[FilterItem] = Field(..., description="滤镜对象数组") diff --git a/src/service/__init__.py b/src/service/__init__.py index 65b7ef3..70fd190 100644 --- a/src/service/__init__.py +++ b/src/service/__init__.py @@ -11,6 +11,7 @@ from .add_masks import add_masks from .add_text_style import add_text_style from .get_text_animations import get_text_animations from .get_image_animations import get_image_animations +from .get_filters import get_filters from .easy_create_material import easy_create_material from .save_draft import save_draft from .gen_video import gen_video, gen_video_status @@ -31,4 +32,4 @@ from .str_list_to_objs import str_list_to_objs from .str_to_list import str_to_list from .objs_to_str_list import objs_to_str_list -__all__ = ["create_draft", "add_videos", "add_audios", "add_images", "add_sticker", "add_keyframes", "add_captions", "add_effects", "add_filters", "add_masks", "add_text_style", "get_text_animations", "get_image_animations", "easy_create_material", "save_draft", "gen_video", "gen_video_status", "get_draft", "get_audio_duration", "timelines", "audio_timelines", "audio_infos", "imgs_infos", "caption_infos", "effect_infos", "filter_infos", "keyframes_infos", "video_infos", "search_sticker", "get_url", "str_list_to_objs", "str_to_list", "objs_to_str_list"] +__all__ = ["create_draft", "add_videos", "add_audios", "add_images", "add_sticker", "add_keyframes", "add_captions", "add_effects", "add_filters", "add_masks", "add_text_style", "get_text_animations", "get_image_animations", "get_filters", "easy_create_material", "save_draft", "gen_video", "gen_video_status", "get_draft", "get_audio_duration", "timelines", "audio_timelines", "audio_infos", "imgs_infos", "caption_infos", "effect_infos", "filter_infos", "keyframes_infos", "video_infos", "search_sticker", "get_url", "str_list_to_objs", "str_to_list", "objs_to_str_list"] diff --git a/src/service/get_filters.py b/src/service/get_filters.py new file mode 100644 index 0000000..30f6043 --- /dev/null +++ b/src/service/get_filters.py @@ -0,0 +1,87 @@ +""" +获取滤镜列表的业务逻辑处理模块 +""" +import json +from typing import List, Dict, Any +from src.utils.logger import logger +from exceptions import CustomException, CustomError + + +def get_filters(mode: int = 0) -> List[Dict[str, Any]]: + """ + 获取滤镜列表 + + Args: + mode: 滤镜模式,0=所有,1=VIP,2=免费,默认值为 0 + + Returns: + filters: 滤镜对象数组 + + Raises: + CustomException: 获取滤镜列表失败 + """ + logger.info(f"get_filters called with mode: {mode}") + + try: + # 1. 参数验证 + if mode not in [0, 1, 2]: + logger.error(f"Invalid mode: {mode}") + raise CustomException(CustomError.FILTER_GET_FAILED) + + # 2. 根据模式获取滤镜数据 + filters = _get_filters_by_mode(mode=mode) + logger.info(f"Found {len(filters)} filters for mode: {mode}") + + # 3. 直接返回对象数组 + logger.info(f"Successfully returned filters array with {len(filters)} items") + + return filters + + except CustomException: + logger.error(f"Get filters failed for mode: {mode}") + raise + except Exception as e: + logger.error(f"Unexpected error in get_filters: {str(e)}") + raise CustomException(CustomError.FILTER_GET_FAILED) + + +def _get_filters_by_mode(mode: int) -> List[Dict[str, Any]]: + """ + 根据模式获取对应的滤镜数据 + + Args: + mode: 滤镜模式(0=所有,1=VIP,2=免费) + + Returns: + 包含滤镜信息的列表 + """ + logger.info(f"Getting filters for mode: {mode}") + + # 从 FilterType 枚举中获取所有滤镜 + from src.pyJianYingDraft.metadata.filter_meta import FilterType + + all_filters = [] + for filter_type in FilterType: + filter_info = { + "name": filter_type.value.name, + "is_vip": filter_type.value.is_vip, + "resource_id": filter_type.value.resource_id, + "effect_id": filter_type.value.effect_id, + "has_params": len(filter_type.value.params) > 0 + } + all_filters.append(filter_info) + + logger.info(f"Total filters loaded: {len(all_filters)}") + + # 根据模式过滤 + if mode == 0: # 所有 + result = all_filters + elif mode == 1: # VIP + result = [f for f in all_filters if f.get("is_vip", False)] + elif mode == 2: # 免费 + result = [f for f in all_filters if not f.get("is_vip", False)] + else: + result = [] + + logger.info(f"Final filtered result: {len(result)} filters") + return result