| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- """环境检测登记 CRUD"""
- from __future__ import annotations
- 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 format_date, generate_uuid
- from app.crud import env_detect_item as item_svc
- from app.models.models import BizEnvDetectRecord, SysUser
- def _split_csv(value: Optional[str]) -> List[str]:
- return [x.strip() for x in (value or "").split(",") if x.strip()]
- def _join_csv(values: List[str]) -> str:
- return ",".join(values)
- def _row_to_dict(r: BizEnvDetectRecord) -> Dict[str, Any]:
- inspector_ids = _split_csv(r.inspector_ids)
- inspector_names = _split_csv(r.inspector_names)
- return {
- "id": r.id,
- "recordNo": r.record_no,
- "detectTime": format_date(r.detect_time),
- "resultTime": format_date(r.result_time) if r.result_time else "",
- "inspectorIds": inspector_ids,
- "inspectorNames": inspector_names,
- "inspectorDisplay": " / ".join(inspector_names) if inspector_names else "",
- "envDetectItemId": r.env_detect_item_id,
- "itemCode": r.item_code,
- "itemName": r.item_name,
- "resultDesc": r.result_desc or "",
- "attachmentUrls": r.attachment_urls or "",
- "tenantNo": r.tenant_no,
- "orderNum": r.order_num if r.order_num is not None else 0,
- "remark": r.remark or "",
- "createTime": r.create_time.strftime("%Y-%m-%d %H:%M:%S") if r.create_time else "",
- "updateTime": r.update_time.strftime("%Y-%m-%d %H:%M:%S") if r.update_time else "",
- }
- def _generate_record_no(db: Session, tenant_no: str) -> str:
- today_str = datetime.now().strftime("%Y%m%d")
- prefix = f"HJ{today_str}"
- existing = (
- db.query(BizEnvDetectRecord.record_no)
- .filter(
- BizEnvDetectRecord.tenant_no == tenant_no,
- BizEnvDetectRecord.record_no.like(f"{prefix}%"),
- BizEnvDetectRecord.del_flag == 0,
- )
- .order_by(BizEnvDetectRecord.record_no.desc())
- .first()
- )
- seq = 1
- if existing and existing[0]:
- try:
- seq = int(existing[0][-4:]) + 1
- except ValueError:
- seq = 1
- return f"{prefix}{seq:04d}"
- def _resolve_inspector_snapshots(
- db: Session, tenant_no: str, inspector_ids: List[str]
- ) -> Tuple[str, str]:
- ids: List[str] = []
- seen: set = set()
- for raw in inspector_ids or []:
- uid = (raw or "").strip()
- if not uid or uid in seen:
- continue
- seen.add(uid)
- ids.append(uid)
- if not ids:
- raise ValueError("请至少选择一名检测人")
- users = (
- db.query(SysUser)
- .filter(
- SysUser.id.in_(ids),
- SysUser.tenant_no == tenant_no,
- SysUser.del_flag == 0,
- )
- .all()
- )
- user_map = {u.id: u for u in users}
- names: List[str] = []
- for uid in ids:
- user = user_map.get(uid)
- if not user:
- raise ValueError("检测人无效或不存在")
- name = (user.nick_name or user.user_no or "").strip() or uid
- names.append(name)
- return _join_csv(ids), _join_csv(names)
- def _resolve_item_snapshot(
- db: Session, item_id: str, tenant_no: str
- ) -> Tuple[str, str, str]:
- item = item_svc.get_env_detect_item(db, item_id, tenant_no=tenant_no)
- if not item:
- raise ValueError("检测项目不存在")
- if item.status != "1":
- raise ValueError("检测项目已停用,请重新选择")
- return item.id, item.item_code, item.item_name
- def get_env_detect_record(
- db: Session, row_id: str, tenant_no: Optional[str] = None
- ) -> Optional[BizEnvDetectRecord]:
- q = db.query(BizEnvDetectRecord).filter(
- and_(BizEnvDetectRecord.id == row_id, BizEnvDetectRecord.del_flag == 0)
- )
- if tenant_no:
- q = q.filter(BizEnvDetectRecord.tenant_no == tenant_no)
- return q.first()
- def list_env_detect_records(
- db: Session,
- *,
- page: int = 1,
- page_size: int = 10,
- keyword: Optional[str] = None,
- env_detect_item_id: Optional[str] = None,
- inspector_id: Optional[str] = None,
- detect_time_start: Optional[datetime] = None,
- detect_time_end: Optional[datetime] = None,
- tenant_no: Optional[str] = None,
- ) -> Tuple[List[Dict[str, Any]], int]:
- def _filtered():
- q0 = db.query(BizEnvDetectRecord).filter(BizEnvDetectRecord.del_flag == 0)
- if tenant_no:
- q0 = q0.filter(BizEnvDetectRecord.tenant_no == tenant_no)
- kw = (keyword or "").strip()
- if kw:
- like = f"%{kw}%"
- q0 = q0.filter(
- or_(
- BizEnvDetectRecord.record_no.like(like),
- BizEnvDetectRecord.inspector_names.like(like),
- BizEnvDetectRecord.result_desc.like(like),
- )
- )
- item_id = (env_detect_item_id or "").strip()
- if item_id:
- q0 = q0.filter(BizEnvDetectRecord.env_detect_item_id == item_id)
- insp_id = (inspector_id or "").strip()
- if insp_id:
- q0 = q0.filter(func.find_in_set(insp_id, BizEnvDetectRecord.inspector_ids) > 0)
- if detect_time_start:
- q0 = q0.filter(BizEnvDetectRecord.detect_time >= detect_time_start)
- if detect_time_end:
- q0 = q0.filter(BizEnvDetectRecord.detect_time <= detect_time_end)
- return q0
- total = (
- _filtered()
- .order_by(None)
- .with_entities(func.count(BizEnvDetectRecord.id))
- .scalar()
- or 0
- )
- page = max(1, page)
- page_size = min(max(1, page_size), 100)
- rows = (
- _filtered()
- .order_by(BizEnvDetectRecord.detect_time.desc())
- .offset((page - 1) * page_size)
- .limit(page_size)
- .all()
- )
- return [_row_to_dict(x) for x in rows], int(total)
- def create_env_detect_record(
- db: Session,
- *,
- detect_time: datetime,
- result_time: Optional[datetime] = None,
- inspector_ids: List[str],
- env_detect_item_id: str,
- result_desc: str,
- attachment_urls: Optional[str] = None,
- tenant_no: str,
- remark: Optional[str] = None,
- user_id: Optional[str] = None,
- create_dept_id: str = "",
- ) -> BizEnvDetectRecord:
- desc = (result_desc or "").strip()
- if not desc:
- raise ValueError("检测结果描述不能为空")
- if not detect_time:
- raise ValueError("检测时间不能为空")
- ids_csv, names_csv = _resolve_inspector_snapshots(db, tenant_no, inspector_ids)
- item_id, item_code, item_name = _resolve_item_snapshot(db, env_detect_item_id, tenant_no)
- obj = BizEnvDetectRecord(
- id=generate_uuid(),
- record_no=_generate_record_no(db, tenant_no),
- detect_time=detect_time,
- result_time=result_time,
- inspector_ids=ids_csv,
- inspector_names=names_csv,
- env_detect_item_id=item_id,
- item_code=item_code,
- item_name=item_name,
- result_desc=desc,
- attachment_urls=(attachment_urls or "").strip() or None,
- tenant_no=tenant_no,
- order_num=0,
- remark=(remark or "").strip() or None,
- create_by=user_id,
- create_dept_id=create_dept_id or "",
- 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_env_detect_record(
- db: Session,
- row_id: str,
- *,
- detect_time: Optional[datetime] = None,
- result_time: Optional[datetime] = None,
- update_result_time: bool = False,
- inspector_ids: Optional[List[str]] = None,
- env_detect_item_id: Optional[str] = None,
- result_desc: Optional[str] = None,
- attachment_urls: Optional[str] = None,
- remark: Optional[str] = None,
- user_id: Optional[str] = None,
- tenant_no: Optional[str] = None,
- ) -> BizEnvDetectRecord:
- obj = get_env_detect_record(db, row_id, tenant_no=tenant_no)
- if not obj:
- raise ValueError("登记记录不存在")
- if detect_time is not None:
- if not detect_time:
- raise ValueError("检测时间不能为空")
- obj.detect_time = detect_time
- if update_result_time:
- obj.result_time = result_time
- if inspector_ids is not None:
- ids_csv, names_csv = _resolve_inspector_snapshots(db, obj.tenant_no, inspector_ids)
- obj.inspector_ids = ids_csv
- obj.inspector_names = names_csv
- if env_detect_item_id is not None:
- item_id, item_code, item_name = _resolve_item_snapshot(
- db, env_detect_item_id, obj.tenant_no
- )
- obj.env_detect_item_id = item_id
- obj.item_code = item_code
- obj.item_name = item_name
- if result_desc is not None:
- desc = (result_desc or "").strip()
- if not desc:
- raise ValueError("检测结果描述不能为空")
- obj.result_desc = desc
- if attachment_urls is not None:
- obj.attachment_urls = (attachment_urls or "").strip() or None
- if remark is not None:
- obj.remark = remark.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_env_detect_record(
- db: Session, row_id: str, tenant_no: Optional[str] = None
- ) -> None:
- obj = get_env_detect_record(db, row_id, tenant_no=tenant_no)
- if not obj:
- raise ValueError("登记记录不存在")
- obj.del_flag = 1
- obj.update_time = datetime.now()
- db.add(obj)
- db.commit()
|