Files

141 lines
4.4 KiB
Python

"""报告备案:工作人员登记,公众按编号对照。"""
from datetime import date
from sqlalchemy import Boolean, Date, Integer, String, select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Mapped, mapped_column
from app.db import Base
FOUND_NOTICE = "以出具机构数据为准,协会结果仅供参考。"
MISSING_NOTICE = "协会备案库没有该编号,请向出具机构核实。"
def _mysql_args() -> dict:
return {"mysql_charset": "utf8mb4", "mysql_collate": "utf8mb4_unicode_ci"}
class ReportFiling(Base):
__tablename__ = "report_filing"
__table_args__ = _mysql_args()
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
institution_name: Mapped[str] = mapped_column(String(200), nullable=False)
report_number: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)
issued_on: Mapped[date] = mapped_column(Date, nullable=False)
published: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
def _institution(value: str) -> str:
if not isinstance(value, str) or not value.strip():
raise ValueError("请填写出具机构")
text = value.strip()
if len(text) > 200:
raise ValueError("出具机构过长")
return text
def _number(value: str) -> str:
if not isinstance(value, str) or not value.strip():
raise ValueError("请填写报告编号")
text = value.strip()
if len(text) > 64:
raise ValueError("报告编号过长")
return text
def _issued_on(value: str) -> date:
if not isinstance(value, str) or not value.strip():
raise ValueError("请填写出具日期")
try:
return date.fromisoformat(value.strip())
except ValueError as exc:
raise ValueError("出具日期不正确") from exc
def _admin_filing(row: ReportFiling) -> dict:
return {
"id": row.id,
"institutionName": row.institution_name,
"reportNumber": row.report_number,
"issuedOn": row.issued_on.isoformat(),
"published": bool(row.published),
}
def list_filings(db) -> dict:
rows = db.scalars(select(ReportFiling).order_by(ReportFiling.id.desc())).all()
return {"items": [_admin_filing(row) for row in rows]}
def create_filing(db, *, institution_name: str, report_number: str, issued_on: str, published: bool) -> int:
row = ReportFiling(
institution_name=_institution(institution_name),
report_number=_number(report_number),
issued_on=_issued_on(issued_on),
published=bool(published),
)
db.add(row)
try:
db.commit()
except IntegrityError as exc:
db.rollback()
raise ValueError("报告编号已存在") from exc
return row.id
def update_filing(
db,
filing_id: int,
*,
institution_name: str,
report_number: str,
issued_on: str,
published: bool,
) -> None:
row = db.get(ReportFiling, filing_id)
if row is None:
raise ValueError("备案不存在")
number = _number(report_number)
taken = db.scalar(select(ReportFiling.id).where(ReportFiling.report_number == number, ReportFiling.id != row.id))
if taken is not None:
raise ValueError("报告编号已存在")
row.institution_name = _institution(institution_name)
row.report_number = number
row.issued_on = _issued_on(issued_on)
row.published = bool(published)
try:
db.commit()
except IntegrityError as exc:
db.rollback()
raise ValueError("报告编号已存在") from exc
def delete_filing(db, filing_id: int) -> None:
row = db.get(ReportFiling, filing_id)
if row is None:
raise ValueError("备案不存在")
db.delete(row)
db.commit()
def query_filing(db, number: str) -> dict:
if not isinstance(number, str) or not number.strip():
raise ValueError("请填写报告编号")
text = number.strip()
if len(text) > 64:
return {"found": False, "notice": MISSING_NOTICE}
row = db.scalar(
select(ReportFiling).where(ReportFiling.report_number == text, ReportFiling.published.is_(True))
)
if row is None:
return {"found": False, "notice": MISSING_NOTICE}
return {
"found": True,
"institutionName": row.institution_name,
"reportNumber": row.report_number,
"issuedOn": row.issued_on.isoformat(),
"notice": FOUND_NOTICE,
}