from __future__ import annotations from sqlalchemy import or_ from sqlalchemy.orm import Session, joinedload from ..database.orm import DepartmentORM, PositionORM class OrganizationRepository: """组织架构仓库:封装部门和岗位表的读写。""" def __init__(self, session: Session): self.session = session def list_departments(self, *, active_only: bool = False, keyword: str | None = None) -> list[DepartmentORM]: query = self.session.query(DepartmentORM) if active_only: query = query.filter(DepartmentORM.is_active.is_(True)) if keyword: like_keyword = f"%{keyword}%" query = query.filter( or_( DepartmentORM.department_code.like(like_keyword), DepartmentORM.name.like(like_keyword), ) ) return query.order_by(DepartmentORM.sort_order.asc(), DepartmentORM.id.asc()).all() def create_department( self, *, parent_id: int | None, department_code: str, name: str, sort_order: int, is_active: bool, remark: str, ) -> DepartmentORM: department = DepartmentORM( parent_id=parent_id, department_code=department_code, name=name, sort_order=sort_order, is_active=is_active, remark=remark, ) self.session.add(department) self.session.commit() self.session.refresh(department) return department def update_department( self, department_id: int, *, parent_id: int | None, department_code: str, name: str, sort_order: int, is_active: bool, remark: str, ) -> DepartmentORM: department = self.require_department(department_id) department.parent_id = parent_id department.department_code = department_code department.name = name department.sort_order = sort_order department.is_active = is_active department.remark = remark self.session.commit() self.session.refresh(department) return department def require_department(self, department_id: int) -> DepartmentORM: department = self.session.query(DepartmentORM).filter(DepartmentORM.id == department_id).one_or_none() if department is None: raise ValueError("部门不存在") return department def get_department_by_name(self, name: str) -> DepartmentORM | None: return self.session.query(DepartmentORM).filter(DepartmentORM.name == name).one_or_none() def get_department_by_code(self, department_code: str) -> DepartmentORM | None: return ( self.session.query(DepartmentORM) .filter(DepartmentORM.department_code == department_code) .one_or_none() ) def list_positions( self, *, department_id: int | None = None, active_only: bool = False, keyword: str | None = None, ) -> list[PositionORM]: query = self.session.query(PositionORM).join(PositionORM.department).options(joinedload(PositionORM.department)) if department_id: query = query.filter(PositionORM.department_id == department_id) if active_only: query = query.filter(PositionORM.is_active.is_(True)) if keyword: like_keyword = f"%{keyword}%" query = query.filter( or_( PositionORM.position_code.like(like_keyword), PositionORM.name.like(like_keyword), ) ) return query.order_by( DepartmentORM.sort_order.asc(), PositionORM.sort_order.asc(), PositionORM.id.asc(), ).all() def create_position( self, *, department_id: int, position_code: str, name: str, sort_order: int, is_active: bool, remark: str, ) -> PositionORM: position = PositionORM( department_id=department_id, position_code=position_code, name=name, sort_order=sort_order, is_active=is_active, remark=remark, ) self.session.add(position) self.session.commit() return self.require_position(position.id) def update_position( self, position_id: int, *, department_id: int, position_code: str, name: str, sort_order: int, is_active: bool, remark: str, ) -> PositionORM: position = self.require_position(position_id) position.department_id = department_id position.position_code = position_code position.name = name position.sort_order = sort_order position.is_active = is_active position.remark = remark self.session.commit() return self.require_position(position_id) def require_position(self, position_id: int) -> PositionORM: position = ( self.session.query(PositionORM) .options(joinedload(PositionORM.department)) .filter(PositionORM.id == position_id) .one_or_none() ) if position is None: raise ValueError("岗位不存在") return position def get_position_by_code(self, position_code: str) -> PositionORM | None: return ( self.session.query(PositionORM) .options(joinedload(PositionORM.department)) .filter(PositionORM.position_code == position_code) .one_or_none() ) def get_position_by_department_and_name(self, department_id: int, name: str) -> PositionORM | None: """按部门和岗位名称查询,用于避免同一部门下重复维护同名岗位。""" return ( self.session.query(PositionORM) .options(joinedload(PositionORM.department)) .filter(PositionORM.department_id == department_id, PositionORM.name == name) .one_or_none() )