Files
shanxia2.0/backend/app/crud/sop_document.py
T
2026-05-20 18:06:21 +08:00

187 lines
5.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""SOP文档 CRUD(biz_sop_document)"""
from __future__ import annotations
import math
from datetime import datetime
from typing import Any, Dict, List, Optional, Tuple
from sqlalchemy import and_, func, or_
from sqlalchemy.orm import Session
from app.core.utils import generate_uuid
from app.crud.collection_protocol import urls_to_attachment_list
from app.models.models import BizSopDocument
def _row_to_dict(
s: BizSopDocument,
db: Optional[Session] = None,
tenant_no: Optional[str] = None,
) -> Dict[str, Any]:
tn = tenant_no or s.tenant_no
return {
"id": s.id,
"sopCode": s.sop_code,
"sopName": s.sop_name,
"versionNo": s.version_no or "",
"sopAttachments": s.sop_attachments or "",
"attachmentFiles": urls_to_attachment_list(s.sop_attachments, db, tn) if db else [],
"tenantNo": s.tenant_no,
"orderNum": s.order_num if s.order_num is not None else 0,
"remark": s.remark or "",
"createTime": s.create_time.strftime("%Y-%m-%d %H:%M:%S") if s.create_time else "",
"updateTime": s.update_time.strftime("%Y-%m-%d %H:%M:%S") if s.update_time else "",
}
def list_sop_documents(
db: Session,
*,
page: int = 1,
page_size: int = 10,
keyword: Optional[str] = None,
tenant_no: Optional[str] = None,
user_info=None,
) -> Tuple[List[Dict[str, Any]], int]:
def _filtered():
q0 = db.query(BizSopDocument).filter(BizSopDocument.del_flag == 0)
if tenant_no:
q0 = q0.filter(BizSopDocument.tenant_no == tenant_no)
kw = (keyword or "").strip()
if kw:
like = f"%{kw}%"
q0 = q0.filter(
or_(
BizSopDocument.sop_code.like(like),
BizSopDocument.sop_name.like(like),
)
)
if user_info:
from app.core.data_scope import apply_data_scope
q0 = apply_data_scope(q0, BizSopDocument, user_info, db, tenant_no)
return q0
total = _filtered().order_by(None).with_entities(func.count(BizSopDocument.id)).scalar() or 0
page = max(1, page)
page_size = min(max(1, page_size), 100)
rows = (
_filtered()
.order_by(BizSopDocument.create_time.desc())
.offset((page - 1) * page_size)
.limit(page_size)
.all()
)
return [_row_to_dict(x, db, tenant_no) for x in rows], int(total)
def get_sop_document(db: Session, sop_id: str) -> Optional[BizSopDocument]:
return (
db.query(BizSopDocument)
.filter(and_(BizSopDocument.id == sop_id, BizSopDocument.del_flag == 0))
.first()
)
def sop_code_exists(db: Session, code: str, tenant_no: str, exclude_id: Optional[str] = None) -> bool:
q = db.query(BizSopDocument).filter(
and_(BizSopDocument.sop_code == code.strip(), BizSopDocument.tenant_no == tenant_no, BizSopDocument.del_flag == 0)
)
if exclude_id:
q = q.filter(BizSopDocument.id != exclude_id)
return q.first() is not None
def create_sop_document(
db: Session,
*,
sop_code: str,
sop_name: str,
version_no: Optional[str] = None,
sop_attachments: Optional[str] = None,
tenant_no: str = "zkxw",
order_num: Optional[int] = None,
remark: Optional[str] = None,
user_id: Optional[str] = None,
) -> BizSopDocument:
sc = (sop_code or "").strip()
if not sc:
raise ValueError("SOP编码不能为空")
if sop_code_exists(db, sc, tenant_no):
raise ValueError("SOP编码已存在")
obj = BizSopDocument(
id=generate_uuid(),
sop_code=sc,
sop_name=(sop_name or "").strip() or sc,
version_no=(version_no or "").strip() or None,
sop_attachments=(sop_attachments or "").strip() or None,
tenant_no=tenant_no,
order_num=order_num if order_num is not None else 0,
remark=(remark or "").strip() or None,
create_by=user_id,
create_dept_id="",
create_time=datetime.now(),
update_by=user_id,
update_time=datetime.now(),
del_flag=0,
)
db.add(obj)
db.commit()
db.refresh(obj)
return obj
def update_sop_document(
db: Session,
sop_id: str,
*,
sop_code: Optional[str] = None,
sop_name: Optional[str] = None,
version_no: Optional[str] = None,
sop_attachments: Optional[str] = None,
order_num: Optional[int] = None,
remark: Optional[str] = None,
user_id: Optional[str] = None,
) -> BizSopDocument:
obj = get_sop_document(db, sop_id)
if not obj:
raise ValueError("SOP文档不存在")
if sop_code is not None:
new_code = sop_code.strip()
if not new_code:
raise ValueError("SOP编码不能为空")
if new_code != obj.sop_code and sop_code_exists(db, new_code, obj.tenant_no, exclude_id=sop_id):
raise ValueError("SOP编码已存在")
obj.sop_code = new_code
if sop_name is not None:
obj.sop_name = (sop_name or "").strip() or obj.sop_name
if version_no is not None:
obj.version_no = (version_no or "").strip() or None
if sop_attachments is not None:
obj.sop_attachments = (sop_attachments or "").strip() or None
if order_num is not None:
obj.order_num = order_num
if remark is not None:
obj.remark = (remark or "").strip() or None
obj.update_by = user_id
obj.update_time = datetime.now()
db.add(obj)
db.commit()
db.refresh(obj)
return obj
def soft_delete_sop_document(db: Session, sop_id: str) -> None:
obj = get_sop_document(db, sop_id)
if not obj:
raise ValueError("SOP文档不存在")
obj.del_flag = 1
obj.update_time = datetime.now()
db.add(obj)
db.commit()
def total_pages(total: int, page_size: int) -> int:
if total <= 0:
return 0
return int(math.ceil(total / float(page_size)))