schema.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # -*- coding: utf-8 -*-
  2. import re
  3. from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
  4. from fastapi import Query
  5. from app.core.validator import DateTimeStr
  6. from app.core.base_schema import BaseSchema
  7. class DictTypeCreateSchema(BaseModel):
  8. """
  9. 字典类型表对应pydantic模型
  10. """
  11. dict_name: str = Field(..., min_length=1, max_length=64, description='字典名称')
  12. dict_type: str = Field(..., min_length=1, max_length=100, description='字典类型')
  13. status: str = Field(default='0', description='状态(0正常 1停用)')
  14. description: str | None = Field(default=None, max_length=255, description="描述")
  15. @field_validator('dict_name')
  16. def validate_dict_name(cls, value: str):
  17. if not value or value.strip() == '':
  18. raise ValueError('字典名称不能为空')
  19. return value.strip()
  20. @field_validator('dict_type')
  21. def validate_dict_type(cls, value: str):
  22. if not value or value.strip() == '':
  23. raise ValueError('字典类型不能为空')
  24. regexp = r'^[a-z][a-z0-9_]*$'
  25. if not re.match(regexp, value):
  26. raise ValueError('字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)')
  27. return value.strip()
  28. class DictTypeUpdateSchema(DictTypeCreateSchema):
  29. """字典类型更新模型"""
  30. ...
  31. class DictTypeOutSchema(DictTypeCreateSchema, BaseSchema):
  32. """字典类型响应模型"""
  33. model_config = ConfigDict(from_attributes=True)
  34. class DictTypeQueryParam:
  35. """字典类型查询参数"""
  36. def __init__(
  37. self,
  38. dict_name: str | None = Query(default=None, description="字典名称", max_length=100),
  39. dict_type: str | None = Query(default=None, description="字典类型", max_length=100),
  40. status: str | None = Query(default=None, description="状态(0正常 1停用)"),
  41. created_time: list[DateTimeStr] | None = Query(None, description="创建时间范围", examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
  42. updated_time: list[DateTimeStr] | None = Query(None, description="更新时间范围", examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
  43. ) -> None:
  44. super().__init__()
  45. # 模糊查询字段
  46. self.dict_name = ("like", f"%{dict_name.strip()}%") if dict_name and dict_name.strip() else None
  47. # 精确查询字段
  48. self.dict_type = dict_type.strip() if dict_type else None
  49. self.status = status
  50. # 时间范围查询
  51. if created_time and len(created_time) == 2:
  52. self.created_time = ("between", (created_time[0], created_time[1]))
  53. if updated_time and len(updated_time) == 2:
  54. self.updated_time = ("between", (updated_time[0], updated_time[1]))
  55. class DictDataCreateSchema(BaseModel):
  56. """
  57. 字典数据表对应pydantic模型
  58. """
  59. dict_sort: int = Field(..., ge=1, le=999, description='字典排序')
  60. dict_label: str = Field(..., max_length=100, description='字典标签')
  61. dict_value: str = Field(..., max_length=100, description='字典键值')
  62. dict_type: str = Field(..., max_length=100, description='字典类型')
  63. dict_type_id: int = Field(..., description='字典类型ID')
  64. css_class: str | None = Field(default=None, max_length=100, description='样式属性(其他样式扩展)')
  65. list_class: str | None = Field(default=None, description='表格回显样式')
  66. is_default: bool = Field(default=False, description='是否默认(True是 False否)')
  67. status: str = Field(default='0', description='状态(0正常 1停用)')
  68. description: str | None = Field(default=None, max_length=255, description="描述")
  69. @model_validator(mode='after')
  70. def validate_after(self):
  71. if not self.dict_label or not self.dict_label.strip():
  72. raise ValueError('字典标签不能为空')
  73. if not self.dict_value or not self.dict_value.strip():
  74. raise ValueError('字典键值不能为空')
  75. if not self.dict_type or not self.dict_type.strip():
  76. raise ValueError('字典类型不能为空')
  77. if not hasattr(self, 'dict_type_id') or self.dict_type_id <= 0:
  78. raise ValueError('字典类型ID不能为空且必须大于0')
  79. # 确保字符串字段被正确处理
  80. self.dict_label = self.dict_label.strip()
  81. self.dict_value = self.dict_value.strip()
  82. self.dict_type = self.dict_type.strip()
  83. return self
  84. class DictDataUpdateSchema(DictDataCreateSchema):
  85. """字典数据更新模型"""
  86. ...
  87. class DictDataOutSchema(DictDataCreateSchema, BaseSchema):
  88. """字典数据响应模型"""
  89. model_config = ConfigDict(from_attributes=True)
  90. class DictDataQueryParam:
  91. """字典数据查询参数"""
  92. def __init__(
  93. self,
  94. dict_label: str | None = Query(default=None, description="字典标签", max_length=100),
  95. dict_type: str | None = Query(default=None, description="字典类型", max_length=100),
  96. dict_type_id: int | None = Query(default=None, description="字典类型ID"),
  97. status: str | None = Query(default=None, description="状态(0正常 1停用)"),
  98. created_time: list[DateTimeStr] | None = Query(default=None, description="创建时间范围", examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
  99. updated_time: list[DateTimeStr] | None = Query(default=None, description="更新时间范围", examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
  100. ) -> None:
  101. # 模糊查询字段
  102. self.dict_label = ("like", f"%{dict_label.strip()}%") if dict_label and dict_label.strip() else None
  103. # 精确查询字段
  104. self.dict_type = dict_type.strip() if dict_type else None
  105. self.dict_type_id = dict_type_id
  106. self.status = status
  107. # 时间范围查询
  108. if created_time and len(created_time) == 2:
  109. self.created_time = ("between", (created_time[0], created_time[1]))
  110. if updated_time and len(updated_time) == 2:
  111. self.updated_time = ("between", (updated_time[0], updated_time[1]))