将 feat/settings-rating-brand(基于 927592b)合并到最新 main(d03ddad): - 冲突收口:系统设置服务/契约、集成测试夹具、布局/路由/登录页、客户列表 - 迁移重编号:本分支未发布的三个迁移压成 V11(客户评级 + 站点信息 + 版本号), down_revision 接到 main 的 90653814a421,db/migration 相应改为 V11 - 站点图标上传与 logo 上传统一为同步 def,超限先按 file.size 拦截
60 lines
2.5 KiB
Python
60 lines
2.5 KiB
Python
"""系统设置(公司信息 + 站点信息)请求/响应模型。
|
||
|
||
`SettingPublicOut` 与 `SettingOut` **刻意不共用**:public 端点无鉴权,
|
||
响应字段必须白名单显式列出——将来往 SettingOut 加敏感字段时不会
|
||
顺着复用链泄漏到匿名端点。
|
||
|
||
2026-10-20 精简(用户确认):删除系统副标题与企业档案字段(信用代码/
|
||
地址/电话/邮箱);新增站点标题(浏览器标签页/侧边栏副标题)与站点图标
|
||
(浏览器标签页 favicon)。public 端点只需登录页/标签页展示字段,两者
|
||
恰好同集合,但仍保留独立 schema 作为白名单防线。
|
||
"""
|
||
|
||
from pydantic import BaseModel, ConfigDict, Field
|
||
|
||
|
||
class SettingOut(BaseModel):
|
||
"""公司信息与站点信息(管理端)。"""
|
||
|
||
company_name: str
|
||
logo_url: str | None = None
|
||
site_title: str | None = None
|
||
brand_slogan: str | None = None
|
||
footer_text: str | None = None
|
||
icp_no: str | None = None
|
||
favicon_url: str | None = None
|
||
|
||
|
||
class SettingPublicOut(BaseModel):
|
||
"""公司信息与站点信息(匿名端点白名单):登录页/浏览器标签页展示所需字段。"""
|
||
|
||
company_name: str
|
||
logo_url: str | None = None
|
||
site_title: str | None = None
|
||
brand_slogan: str | None = None
|
||
footer_text: str | None = None
|
||
icp_no: str | None = None
|
||
favicon_url: str | None = None
|
||
|
||
|
||
class SettingUpdateIn(BaseModel):
|
||
"""公司信息与站点信息更新(**部分更新**语义)。
|
||
|
||
str_strip_whitespace:全空白名称先剥再校验——否则 `" "` 过 min_length=1
|
||
后由服务层 strip 成空串入库(200 成功但 public 端点返回空公司名)。
|
||
|
||
仅提交的字段生效(``exclude_unset``),未提交或显式 null 的字段保持
|
||
不变;可选文本传空串等价清空(落库为 null、前端回退内置默认)。
|
||
company_name 若提交必须非空(DB 非空约束)。
|
||
"""
|
||
|
||
model_config = ConfigDict(str_strip_whitespace=True)
|
||
|
||
company_name: str | None = Field(
|
||
default=None, min_length=1, max_length=64, description="公司名称(提交则须非空)"
|
||
)
|
||
site_title: str | None = Field(default=None, max_length=64, description="站点标题")
|
||
brand_slogan: str | None = Field(default=None, max_length=64, description="品牌标语")
|
||
footer_text: str | None = Field(default=None, max_length=64, description="页脚版权文本")
|
||
icp_no: str | None = Field(default=None, max_length=32, description="ICP 备案号")
|