134 lines
4.9 KiB
Python
134 lines
4.9 KiB
Python
from pydantic import BaseModel, Field, field_validator, ConfigDict
|
|
from typing import Optional, List
|
|
import datetime
|
|
import uuid
|
|
from app.core.exceptions import ValidationException
|
|
from app.core.error_codes import BizCode
|
|
|
|
|
|
class TenantBase(BaseModel):
|
|
"""租户基础Schema"""
|
|
name: str = Field(..., description="租户名称", max_length=255)
|
|
description: Optional[str] = Field(None, description="租户描述", max_length=1000)
|
|
is_active: bool = Field(True, description="是否激活")
|
|
default_language: Optional[str] = Field('zh', description="租户默认语言", max_length=10)
|
|
supported_languages: Optional[List[str]] = Field(['zh', 'en'], description="租户支持的语言列表")
|
|
|
|
@field_validator('name')
|
|
@classmethod
|
|
def validate_name(cls, v):
|
|
if not v or not v.strip():
|
|
raise ValidationException('租户名称不能为空', code=BizCode.VALIDATION_FAILED)
|
|
return v.strip()
|
|
|
|
@field_validator('default_language')
|
|
@classmethod
|
|
def validate_default_language(cls, v):
|
|
if v:
|
|
# Validate language code format (2-letter code, optionally with region)
|
|
import re
|
|
if not re.match(r'^[a-z]{2}(-[A-Z]{2})?$', v):
|
|
raise ValidationException('语言代码格式不正确', code=BizCode.VALIDATION_FAILED)
|
|
return v
|
|
|
|
@field_validator('supported_languages')
|
|
@classmethod
|
|
def validate_supported_languages(cls, v):
|
|
if v:
|
|
import re
|
|
for lang in v:
|
|
if not re.match(r'^[a-z]{2}(-[A-Z]{2})?$', lang):
|
|
raise ValidationException(f'语言代码格式不正确: {lang}', code=BizCode.VALIDATION_FAILED)
|
|
return v
|
|
|
|
|
|
class TenantCreate(TenantBase):
|
|
"""创建租户Schema"""
|
|
pass
|
|
|
|
|
|
class TenantUpdate(BaseModel):
|
|
"""更新租户Schema"""
|
|
name: Optional[str] = Field(None, description="租户名称", max_length=255)
|
|
description: Optional[str] = Field(None, description="租户描述", max_length=1000)
|
|
is_active: Optional[bool] = Field(None, description="是否激活")
|
|
default_language: Optional[str] = Field(None, description="租户默认语言", max_length=10)
|
|
supported_languages: Optional[List[str]] = Field(None, description="租户支持的语言列表")
|
|
|
|
@field_validator('name')
|
|
@classmethod
|
|
def validate_name(cls, v):
|
|
if v is not None and (not v or not v.strip()):
|
|
raise ValidationException('租户名称不能为空', code=BizCode.VALIDATION_FAILED)
|
|
return v.strip() if v else v
|
|
|
|
@field_validator('default_language')
|
|
@classmethod
|
|
def validate_default_language(cls, v):
|
|
if v:
|
|
import re
|
|
if not re.match(r'^[a-z]{2}(-[A-Z]{2})?$', v):
|
|
raise ValidationException('语言代码格式不正确', code=BizCode.VALIDATION_FAILED)
|
|
return v
|
|
|
|
@field_validator('supported_languages')
|
|
@classmethod
|
|
def validate_supported_languages(cls, v):
|
|
if v:
|
|
import re
|
|
for lang in v:
|
|
if not re.match(r'^[a-z]{2}(-[A-Z]{2})?$', lang):
|
|
raise ValidationException(f'语言代码格式不正确: {lang}', code=BizCode.VALIDATION_FAILED)
|
|
return v
|
|
|
|
|
|
class Tenant(TenantBase):
|
|
"""租户Schema"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: uuid.UUID
|
|
created_at: datetime.datetime
|
|
updated_at: datetime.datetime
|
|
|
|
|
|
class TenantQuery(BaseModel):
|
|
"""租户查询Schema"""
|
|
is_active: Optional[bool] = Field(None, description="激活状态筛选")
|
|
search: Optional[str] = Field(None, description="搜索关键词", max_length=255)
|
|
page: int = Field(1, description="页码", ge=1)
|
|
size: int = Field(10, description="每页数量", ge=1, le=100)
|
|
|
|
|
|
class TenantList(BaseModel):
|
|
"""租户列表响应Schema"""
|
|
items: List[Tenant]
|
|
total: int
|
|
page: int
|
|
size: int
|
|
pages: int
|
|
|
|
|
|
class TenantLanguageConfig(BaseModel):
|
|
"""租户语言配置Schema"""
|
|
default_language: str = Field(..., description="租户默认语言", max_length=10)
|
|
supported_languages: List[str] = Field(..., description="租户支持的语言列表")
|
|
|
|
@field_validator('default_language')
|
|
@classmethod
|
|
def validate_default_language(cls, v):
|
|
import re
|
|
if not re.match(r'^[a-z]{2}(-[A-Z]{2})?$', v):
|
|
raise ValidationException('语言代码格式不正确', code=BizCode.VALIDATION_FAILED)
|
|
return v
|
|
|
|
@field_validator('supported_languages')
|
|
@classmethod
|
|
def validate_supported_languages(cls, v):
|
|
if not v:
|
|
raise ValidationException('支持的语言列表不能为空', code=BizCode.VALIDATION_FAILED)
|
|
import re
|
|
for lang in v:
|
|
if not re.match(r'^[a-z]{2}(-[A-Z]{2})?$', lang):
|
|
raise ValidationException(f'语言代码格式不正确: {lang}', code=BizCode.VALIDATION_FAILED)
|
|
return v
|