172 lines
5.6 KiB
Python
172 lines
5.6 KiB
Python
from __future__ import annotations
|
|
|
|
from sqlalchemy import or_
|
|
from sqlalchemy.orm import Session
|
|
|
|
from ..database.orm import EmployeeORM
|
|
|
|
|
|
class EmployeeRepository:
|
|
"""员工仓库:封装 employees 表的基础维护。"""
|
|
|
|
def __init__(self, session: Session):
|
|
self.session = session
|
|
|
|
def create_employee(
|
|
self,
|
|
*,
|
|
employee_no: str,
|
|
name: str,
|
|
dingtalk_user_id: str = "",
|
|
department: str = "",
|
|
position: str = "",
|
|
phone: str = "",
|
|
employment_status: str = "active",
|
|
remark: str = "",
|
|
) -> EmployeeORM:
|
|
employee = EmployeeORM(
|
|
employee_no=employee_no,
|
|
name=name,
|
|
dingtalk_user_id=dingtalk_user_id,
|
|
department=department,
|
|
position=position,
|
|
phone=phone,
|
|
employment_status=employment_status,
|
|
remark=remark,
|
|
)
|
|
self.session.add(employee)
|
|
self.session.commit()
|
|
self.session.refresh(employee)
|
|
return employee
|
|
|
|
def update_employee(
|
|
self,
|
|
employee_id: int,
|
|
*,
|
|
employee_no: str,
|
|
name: str,
|
|
dingtalk_user_id: str,
|
|
department: str,
|
|
position: str,
|
|
phone: str,
|
|
employment_status: str,
|
|
remark: str,
|
|
) -> EmployeeORM:
|
|
employee = self.require_by_id(employee_id)
|
|
employee.employee_no = employee_no
|
|
employee.name = name
|
|
employee.dingtalk_user_id = dingtalk_user_id
|
|
employee.department = department
|
|
employee.position = position
|
|
employee.phone = phone
|
|
employee.employment_status = employment_status
|
|
employee.remark = remark
|
|
self.session.commit()
|
|
self.session.refresh(employee)
|
|
return employee
|
|
|
|
def get_by_id(self, employee_id: int) -> EmployeeORM | None:
|
|
return self.session.query(EmployeeORM).filter(EmployeeORM.id == employee_id).one_or_none()
|
|
|
|
def require_by_id(self, employee_id: int) -> EmployeeORM:
|
|
employee = self.get_by_id(employee_id)
|
|
if employee is None:
|
|
raise ValueError("员工不存在")
|
|
return employee
|
|
|
|
def get_by_employee_no(self, employee_no: str) -> EmployeeORM | None:
|
|
return self.session.query(EmployeeORM).filter(EmployeeORM.employee_no == employee_no).one_or_none()
|
|
|
|
def list_employee_numbers_by_prefix(self, prefix: str) -> list[str]:
|
|
"""查询指定前缀的员工编号,供服务层生成下一个编号。"""
|
|
rows = (
|
|
self.session.query(EmployeeORM.employee_no)
|
|
.filter(EmployeeORM.employee_no.like(f"{prefix}%"))
|
|
.all()
|
|
)
|
|
return [row[0] for row in rows]
|
|
|
|
def list_employees(
|
|
self,
|
|
*,
|
|
keyword: str | None = None,
|
|
employee_keyword: str | None = None,
|
|
organization_keyword: str | None = None,
|
|
employment_status: str | None = None,
|
|
) -> list[EmployeeORM]:
|
|
query = self._filtered_query(
|
|
keyword=keyword,
|
|
employee_keyword=employee_keyword,
|
|
organization_keyword=organization_keyword,
|
|
employment_status=employment_status,
|
|
)
|
|
return query.order_by(EmployeeORM.id.desc()).all()
|
|
|
|
def list_employees_page(
|
|
self,
|
|
*,
|
|
page: int,
|
|
page_size: int,
|
|
keyword: str | None = None,
|
|
employee_keyword: str | None = None,
|
|
organization_keyword: str | None = None,
|
|
employment_status: str | None = None,
|
|
) -> tuple[list[EmployeeORM], int]:
|
|
query = self._filtered_query(
|
|
keyword=keyword,
|
|
employee_keyword=employee_keyword,
|
|
organization_keyword=organization_keyword,
|
|
employment_status=employment_status,
|
|
)
|
|
total = query.count()
|
|
items = (
|
|
query.order_by(EmployeeORM.id.desc())
|
|
.offset((page - 1) * page_size)
|
|
.limit(page_size)
|
|
.all()
|
|
)
|
|
return items, total
|
|
|
|
def _filtered_query(
|
|
self,
|
|
*,
|
|
keyword: str | None,
|
|
employee_keyword: str | None,
|
|
organization_keyword: str | None,
|
|
employment_status: str | None,
|
|
):
|
|
query = self.session.query(EmployeeORM)
|
|
if employment_status:
|
|
query = query.filter(EmployeeORM.employment_status == employment_status)
|
|
if keyword:
|
|
like_keyword = f"%{keyword}%"
|
|
query = query.filter(
|
|
or_(
|
|
EmployeeORM.employee_no.like(like_keyword),
|
|
EmployeeORM.name.like(like_keyword),
|
|
EmployeeORM.dingtalk_user_id.like(like_keyword),
|
|
EmployeeORM.department.like(like_keyword),
|
|
EmployeeORM.position.like(like_keyword),
|
|
EmployeeORM.phone.like(like_keyword),
|
|
)
|
|
)
|
|
if employee_keyword:
|
|
like_employee_keyword = f"%{employee_keyword}%"
|
|
query = query.filter(
|
|
or_(
|
|
EmployeeORM.employee_no.like(like_employee_keyword),
|
|
EmployeeORM.name.like(like_employee_keyword),
|
|
EmployeeORM.dingtalk_user_id.like(like_employee_keyword),
|
|
EmployeeORM.phone.like(like_employee_keyword),
|
|
)
|
|
)
|
|
if organization_keyword:
|
|
like_organization_keyword = f"%{organization_keyword}%"
|
|
query = query.filter(
|
|
or_(
|
|
EmployeeORM.department.like(like_organization_keyword),
|
|
EmployeeORM.position.like(like_organization_keyword),
|
|
)
|
|
)
|
|
return query
|