schema.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. from fastapi import Query
  2. from pydantic import (
  3. BaseModel,
  4. ConfigDict,
  5. Field,
  6. field_validator,
  7. model_validator,
  8. )
  9. from app.common.enums import QueueEnum
  10. from app.core.base_schema import BaseSchema, UserBySchema
  11. from app.core.validator import DateTimeStr
  12. from app.utils.xss_util import sanitize_html
  13. class NoticeCreateSchema(BaseModel):
  14. """公告通知创建模型"""
  15. notice_title: str = Field(..., max_length=50, description="公告标题")
  16. notice_type: str = Field(..., description="公告类型(1通知 2公告)")
  17. notice_content: str = Field(..., description="公告内容")
  18. status: str = Field(default="0", description="是否启用(0:启用 1:禁用)")
  19. description: str | None = Field(default=None, max_length=255, description="描述")
  20. @field_validator("notice_type")
  21. @classmethod
  22. def _validate_notice_type(cls, value: str):
  23. if value not in {"1", "2"}:
  24. raise ValueError("公告类型仅支持 '1'(通知) 或 '2'(公告)")
  25. return value
  26. @field_validator("notice_content")
  27. @classmethod
  28. def _sanitize_notice_content(cls, value: str) -> str:
  29. return sanitize_html(value)
  30. @model_validator(mode="after")
  31. def _validate_after(self):
  32. if not self.notice_title.strip():
  33. raise ValueError("公告标题不能为空")
  34. if not self.notice_content.strip():
  35. raise ValueError("公告内容不能为空")
  36. return self
  37. class NoticeUpdateSchema(NoticeCreateSchema):
  38. """公告通知更新模型"""
  39. class NoticeOutSchema(NoticeCreateSchema, BaseSchema, UserBySchema):
  40. """公告通知响应模型"""
  41. model_config = ConfigDict(from_attributes=True)
  42. class NoticeQueryParam:
  43. """公告通知查询参数"""
  44. def __init__(
  45. self,
  46. notice_title: str | None = Query(None, description="公告标题"),
  47. notice_type: str | None = Query(None, description="公告类型"),
  48. description: str | None = Query(None, description="描述"),
  49. status: str | None = Query(None, description="是否启用"),
  50. created_time: list[DateTimeStr] | None = Query(
  51. None,
  52. description="创建时间范围",
  53. examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"],
  54. ),
  55. updated_time: list[DateTimeStr] | None = Query(
  56. None,
  57. description="更新时间范围",
  58. examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"],
  59. ),
  60. created_id: int | None = Query(None, description="创建人"),
  61. updated_id: int | None = Query(None, description="更新人"),
  62. ) -> None:
  63. # 模糊查询字段
  64. self.notice_title = (QueueEnum.like.value, notice_title)
  65. # 精确查询字段
  66. self.notice_type = notice_type
  67. # 模糊查询字段
  68. if description:
  69. self.description = (QueueEnum.like.value, description)
  70. # 精确查询字段
  71. if status:
  72. self.status = (QueueEnum.eq.value, status)
  73. # 时间范围查询
  74. if created_time and len(created_time) == 2:
  75. self.created_time = (QueueEnum.between.value, (created_time[0], created_time[1]))
  76. if updated_time and len(updated_time) == 2:
  77. self.updated_time = (QueueEnum.between.value, (updated_time[0], updated_time[1]))
  78. # 关联查询字段
  79. if created_id:
  80. self.created_id = (QueueEnum.eq.value, created_id)
  81. if updated_id:
  82. self.updated_id = (QueueEnum.eq.value, updated_id)