feat: restore source parity and harden agent runtime
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
电子签章服务层
|
||||
"""
|
||||
from typing import Optional, List, Tuple
|
||||
|
||||
from sqlalchemy import select, func, and_, or_
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.base_service import BaseService
|
||||
from online_dev.electronic_seal.model import ElectronicSeal, SealUsageLog
|
||||
from online_dev.electronic_seal.schema import ElectronicSealCreate, ElectronicSealUpdate
|
||||
|
||||
|
||||
class ElectronicSealService(BaseService[ElectronicSeal, ElectronicSealCreate, ElectronicSealUpdate]):
|
||||
"""电子签章服务"""
|
||||
|
||||
model = ElectronicSeal
|
||||
|
||||
@classmethod
|
||||
async def get_list(
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
page: int = 1,
|
||||
page_size: int = 20,
|
||||
seal_type: Optional[str] = None,
|
||||
status: Optional[str] = None,
|
||||
keyword: Optional[str] = None,
|
||||
) -> Tuple[List[ElectronicSeal], int]:
|
||||
"""获取签章列表"""
|
||||
conditions = [cls.model.is_deleted == False]
|
||||
|
||||
if seal_type:
|
||||
conditions.append(cls.model.seal_type == seal_type)
|
||||
if status:
|
||||
conditions.append(cls.model.status == status)
|
||||
if keyword:
|
||||
conditions.append(
|
||||
or_(
|
||||
cls.model.name.ilike(f"%{keyword}%"),
|
||||
cls.model.description.ilike(f"%{keyword}%"),
|
||||
)
|
||||
)
|
||||
|
||||
# 查询总数
|
||||
count_stmt = select(func.count()).select_from(cls.model).where(and_(*conditions))
|
||||
total = (await db.execute(count_stmt)).scalar() or 0
|
||||
|
||||
# 查询列表
|
||||
stmt = (
|
||||
select(cls.model)
|
||||
.where(and_(*conditions))
|
||||
.order_by(cls.model.sys_create_datetime.desc())
|
||||
.offset((page - 1) * page_size)
|
||||
.limit(page_size)
|
||||
)
|
||||
result = await db.execute(stmt)
|
||||
items = list(result.scalars().all())
|
||||
|
||||
return items, total
|
||||
|
||||
@classmethod
|
||||
async def get_available_seals(
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
user_id: str,
|
||||
dept_id: Optional[str] = None,
|
||||
role_ids: Optional[List[str]] = None,
|
||||
template_id: Optional[str] = None,
|
||||
) -> List[ElectronicSeal]:
|
||||
"""获取用户可用的签章"""
|
||||
conditions = [
|
||||
cls.model.is_deleted == False,
|
||||
cls.model.status == "active",
|
||||
]
|
||||
|
||||
stmt = select(cls.model).where(and_(*conditions))
|
||||
result = await db.execute(stmt)
|
||||
all_seals = list(result.scalars().all())
|
||||
|
||||
available_seals = []
|
||||
for seal in all_seals:
|
||||
# 检查所有者权限
|
||||
if seal.owner_type == "all":
|
||||
pass
|
||||
elif seal.owner_type == "user":
|
||||
if not seal.owner_ids or user_id not in seal.owner_ids:
|
||||
continue
|
||||
elif seal.owner_type == "dept":
|
||||
if not seal.owner_ids or not dept_id or dept_id not in seal.owner_ids:
|
||||
continue
|
||||
elif seal.owner_type == "role":
|
||||
if not seal.owner_ids or not role_ids:
|
||||
continue
|
||||
if not any(r in seal.owner_ids for r in role_ids):
|
||||
continue
|
||||
|
||||
# 检查模板范围
|
||||
if seal.scope == "specific" and template_id:
|
||||
if not seal.allowed_template_ids or template_id not in seal.allowed_template_ids:
|
||||
continue
|
||||
|
||||
available_seals.append(seal)
|
||||
|
||||
return available_seals
|
||||
|
||||
|
||||
class SealUsageLogService(BaseService[SealUsageLog, None, None]):
|
||||
"""签章使用记录服务"""
|
||||
|
||||
model = SealUsageLog
|
||||
|
||||
@classmethod
|
||||
async def log_usage(
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
seal_id: str,
|
||||
seal_name: str,
|
||||
document_id: str,
|
||||
document_name: str,
|
||||
user_id: str,
|
||||
user_name: str,
|
||||
position_x: int = 0,
|
||||
position_y: int = 0,
|
||||
page_number: int = 1,
|
||||
) -> SealUsageLog:
|
||||
"""记录签章使用"""
|
||||
log = SealUsageLog(
|
||||
seal_id=seal_id,
|
||||
seal_name=seal_name,
|
||||
document_id=document_id,
|
||||
document_name=document_name,
|
||||
user_id=user_id,
|
||||
user_name=user_name,
|
||||
position_x=position_x,
|
||||
position_y=position_y,
|
||||
page_number=page_number,
|
||||
)
|
||||
|
||||
db.add(log)
|
||||
await db.commit()
|
||||
await db.refresh(log)
|
||||
return log
|
||||
|
||||
@classmethod
|
||||
async def get_logs_by_seal(
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
seal_id: str,
|
||||
page: int = 1,
|
||||
page_size: int = 20,
|
||||
) -> Tuple[List[SealUsageLog], int]:
|
||||
"""获取签章的使用记录"""
|
||||
conditions = [
|
||||
cls.model.is_deleted == False,
|
||||
cls.model.seal_id == seal_id,
|
||||
]
|
||||
|
||||
# 查询总数
|
||||
count_stmt = select(func.count()).select_from(cls.model).where(and_(*conditions))
|
||||
total = (await db.execute(count_stmt)).scalar() or 0
|
||||
|
||||
# 查询列表
|
||||
stmt = (
|
||||
select(cls.model)
|
||||
.where(and_(*conditions))
|
||||
.order_by(cls.model.sys_create_datetime.desc())
|
||||
.offset((page - 1) * page_size)
|
||||
.limit(page_size)
|
||||
)
|
||||
result = await db.execute(stmt)
|
||||
items = list(result.scalars().all())
|
||||
|
||||
return items, total
|
||||
|
||||
@classmethod
|
||||
async def get_logs_by_document(
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
document_id: str,
|
||||
) -> List[SealUsageLog]:
|
||||
"""获取文档的签章记录"""
|
||||
stmt = (
|
||||
select(cls.model)
|
||||
.where(
|
||||
and_(
|
||||
cls.model.is_deleted == False,
|
||||
cls.model.document_id == document_id,
|
||||
)
|
||||
)
|
||||
.order_by(cls.model.sys_create_datetime.desc())
|
||||
)
|
||||
result = await db.execute(stmt)
|
||||
return list(result.scalars().all())
|
||||
Reference in New Issue
Block a user