"""SQLAlchemy implementation of TemplateClipConfigRepository.""" from __future__ import annotations from typing import List, Optional from sqlalchemy.orm import Session from packages.adapters.sqlalchemy_impl.models import TemplateClipConfigModel from packages.domain.template_clip_config import ( ClipType, TemplateClipConfig, TransitionEffect, ) class SQLAlchemyTemplateClipConfigRepository: """SQLAlchemy 模板片段配置仓储""" def __init__(self, session: Session) -> None: self.session = session def list_by_template( self, template_id: str, *, clip_type: Optional[ClipType] = None, skip: int = 0, limit: int = 100, ) -> List[TemplateClipConfig]: """按模板列出片段配置,按 order 排序""" query = self.session.query(TemplateClipConfigModel).filter( TemplateClipConfigModel.template_id == template_id, ) if clip_type: query = query.filter(TemplateClipConfigModel.clip_type == clip_type) query = query.order_by(TemplateClipConfigModel.order) models = query.offset(skip).limit(limit).all() return [self._model_to_entity(m) for m in models] def get(self, config_id: str) -> Optional[TemplateClipConfig]: """根据 ID 获取配置""" model = self.session.query(TemplateClipConfigModel).filter(TemplateClipConfigModel.id == config_id).first() if model is None: return None return self._model_to_entity(model) def create(self, config: TemplateClipConfig) -> TemplateClipConfig: """创建配置""" model = TemplateClipConfigModel( id=config.id, template_id=config.template_id, clip_type=config.clip_type, order=config.order, min_duration=config.min_duration, max_duration=config.max_duration, text_template=config.text_template, material_requirements=config.material_requirements, transition_effect=config.transition_effect, config=config.config, ) self.session.add(model) self.session.commit() self.session.refresh(model) return self._model_to_entity(model) def update(self, config: TemplateClipConfig) -> TemplateClipConfig: """更新配置""" model = self.session.query(TemplateClipConfigModel).filter(TemplateClipConfigModel.id == config.id).first() if model is None: raise ValueError(f"TemplateClipConfig {config.id} not found") model.template_id = config.template_id model.clip_type = config.clip_type model.order = config.order model.min_duration = config.min_duration model.max_duration = config.max_duration model.text_template = config.text_template model.material_requirements = config.material_requirements model.transition_effect = config.transition_effect model.config = config.config model.updated_at = config.updated_at self.session.commit() self.session.refresh(model) return self._model_to_entity(model) def delete(self, config_id: str) -> bool: """删除配置""" model = self.session.query(TemplateClipConfigModel).filter(TemplateClipConfigModel.id == config_id).first() if model is None: return False self.session.delete(model) self.session.commit() return True def delete_by_template(self, template_id: str) -> int: """删除模板下所有片段配置,返回删除数量""" count = ( self.session.query(TemplateClipConfigModel) .filter(TemplateClipConfigModel.template_id == template_id) .delete() ) self.session.commit() return count def count(self, *, template_id: Optional[str] = None) -> int: """统计配置数量""" query = self.session.query(TemplateClipConfigModel) if template_id: query = query.filter(TemplateClipConfigModel.template_id == template_id) return query.count() @staticmethod def _model_to_entity(model: TemplateClipConfigModel) -> TemplateClipConfig: return TemplateClipConfig( id=model.id, template_id=model.template_id, clip_type=ClipType(model.clip_type), order=model.order, min_duration=model.min_duration or 0.0, max_duration=model.max_duration or 0.0, text_template=model.text_template or "", material_requirements=model.material_requirements or {}, transition_effect=( TransitionEffect(model.transition_effect) if model.transition_effect else TransitionEffect.CUT ), config=model.config or {}, created_at=model.created_at, updated_at=model.updated_at, )