feat(admin): 站点外观 - 支持 Tab 分类与主题渐变按钮配置

This commit is contained in:
ddCat
2026-09-18 23:28:57 +08:00
parent f77bd2bfa0
commit 3cb1423f7e
27 changed files with 869 additions and 375 deletions

View File

@@ -2,7 +2,7 @@
## 1. 目标与边界
本模块让部署方在不修改源码的前提下管理站点身份、登录页内容、搜索摘要、首页收尾信息与全站皮肤。默认 `classic` 皮肤必须等同项目既有样式;自定义品牌不得在首次渲染、邮件、诊断包、素材插件或后台说明中短暂或持续露出内置品牌。
本模块让部署方在不修改源码的前提下管理站点身份、登录页内容、搜索摘要、首页收尾信息与全站皮肤。默认 `classic` 皮肤采用黑白基础配色与紫蓝渐变主按钮;自定义品牌不得在首次渲染、邮件、诊断包、素材插件或后台说明中短暂或持续露出内置品牌。
技术兼容标识不属于品牌文案:仓库名、容器/升级器路径、剪贴板协议、localStorage key、插件 API version、数据库基线校验值和 User-Agent 可以继续使用 `open-ai-canvas` 或 `infinite-canvas`。英文品牌标识只用于新资源路径建议,不能自动改写已有对象存储前缀或历史资源。
@@ -17,7 +17,7 @@
| 首页收尾 | 版权信息、备案开关、备案号 | 备案号只有在显式开启且非空时显示,并链接工信部备案系统 |
| 皮肤 | `skinId`、`skinThemes` | 选择当前皮肤并维护主题库;每套同时定义亮色、暗色与组件参数 |
配置继续存储在 `system_settings.appearance` JSON 中,schema version 为 6,不增加关系型数据库迁移。旧配置缺失 SEO、版权、备案、主题库、独立开关状态或破坏性操作交互色时,运行时会按原有主色、控件色和危险色向后补齐;只有管理员保存后才写回数据库。管理接口返回完整 `skinThemes`,公开接口只返回当前 `activeSkin`,避免将未启用的运营草稿暴露给前台。
配置继续存储在 `system_settings.appearance` JSON 中,schema version 为 8,不增加关系型数据库迁移。旧配置缺失 SEO、版权、备案、主题库、独立开关状态或破坏性操作交互色时,运行时会按原有主色、控件色和危险色向后补齐;只有管理员保存后才写回数据库。管理接口返回完整 `skinThemes`,公开接口只返回当前 `activeSkin`,避免将未启用的运营草稿暴露给前台。
## 3. 皮肤架构
@@ -28,7 +28,11 @@
3. Component:按钮、输入、卡片、弹层、菜单与复选框圆角,以及控件高度、描边、焦点环、图标、字重、悬停抬升、动效和阴影。
4. Adapter:将同一份语义令牌同时映射到 CSS Custom Properties 和 Ant Design 全局/组件 token。
皮肤合同位于 `backend/internal/service/appearance_skins.go`,前端映射位于 `web/src/lib/skin-themes.ts`。页面不得按皮肤 ID 写条件样式;业务组件只能消费语义 token。`classic` 在运行时不写覆盖变量,使既有 `globals.css` 与 `app-theme.ts` 保持原样式唯一事实源;服务端会逐字段比对经典主题,任何删除或伪造修改都会被拒绝。其他主题均为可编辑数据,用根节点 CSS 变量覆盖自研组件语义层,并向 Ant Design `ConfigProvider` 提供同一套颜色、交互状态、圆角、尺寸、动效和阴影值。
皮肤合同位于 `backend/internal/app/appearance_skins.go`,前端映射位于 `web/src/lib/skin-themes.ts`。页面不得按皮肤 ID 写条件样式;业务组件只能消费语义 token。`classic` 只注入主按钮填充变量,基础表面继续由 `globals.css` 与 `app-theme.ts` 提供;服务端会逐字段比对经典主题,任何删除或伪造修改都会被拒绝。其他主题均为可编辑数据,用根节点 CSS 变量覆盖自研组件语义层,并向 Ant Design `ConfigProvider` 提供同一套颜色、交互状态、圆角、尺寸、动效和阴影值。
`tokens.buttons.light/dark` 分别配置主按钮填充:`mode` 为 `solid` 或 `gradient`,`angle` 为 0–360 的整数;`start/end`、`hoverStart/hoverEnd`、`activeStart/activeEnd` 和 `foreground` 为 HEX 色值。纯色模式消费原有 `primary/primaryHover/primaryActive/primaryForeground`,渐变模式使用独立参数,不改变链接、选中态、开关或危险操作。经典默认角度为 115°,常态 `#6554df → #386fbc`,悬停 `#5744cf → #356bbb`,按下 `#4938b8 → #2c5da5`,文字为白色。后台可复制经典主题后调整两种模式的全部参数。
旧数据整块缺少 `buttons` 时,经典主题补入默认渐变,其余主题保留纯色;局部缺失或非法写入被拒绝。读取补齐不自动写库,保存后写入版本 8;回退旧版本前应备份外观 JSON,旧版本不会呈现新渐变配置。
主题库初始包含:
@@ -73,7 +77,9 @@ SEO 标题建议控制在 70 字符内,描述 200 字符内,关键词 300
## 6. 后台交互合同
后台入口名称为“站点及外观”,继续复用系统设置页的页面框架、状态操作栏、`SettingsSectionCard`、Ant Form/Input/Switch 与统一保存模型。五个顺序固定为:品牌识别、登录页内容与媒体、SEO 信息、首页收尾与备案、皮肤主题。主题编辑器由主题库、身份编辑、浅/深模式切换、实时控件预览、语义颜色分组和组件参数分组组成;默认主题展示锁定原因,自定义主题显示复制与删除动作。
后台入口名称为“站点及外观”,继续复用系统设置页的页面框架、状态操作栏、`SettingsSectionCard`、Ant Form/Input/Switch 与统一保存模型。内容按六个 Tab 展示:品牌识别、登录页、欢迎页、SEO 信息、页尾与备案、皮肤主题。切换 Tab 保留页面草稿与待上传文件;统一保存校验失败时切回问题字段所在分类。欢迎页开关沿用独立接口,切换后立即保存,其余分类共用保存、撤销和未保存离开保护。主题编辑器由主题库、身份编辑、浅/深模式切换、实时控件预览、语义颜色分组和组件参数分组组成;默认主题展示锁定原因,自定义主题显示复制与删除动作。
用户工作台和后台的主按钮通过公共 Ant Design 主题及 `primary-buttons.css` 适配器消费皮肤参数,创作页复合按钮使用相同的 `--button-primary-*` 填充变量;页面不再硬编码渐变颜色。危险、幽灵和禁用按钮不套用渐变。后台路由不挂载用户工作台外壳和浮层样式;后台保留独立表面与控件密度。输入、数字输入、选择和日期控件关闭焦点阴影,按钮关闭点击波纹;键盘导航仍保留可见焦点,校验错误状态保留。
所有调整先形成页面草稿;只有点击“保存修改”才上传新资源并提交配置。保存响应成为新基线。离开、刷新覆盖和恢复内置品牌需要沿用现有未保存保护;恢复操作不删除已经上传的存储资源。皮肤卡必须可键盘操作,并以 radio/`aria-checked` 语义暴露选中状态。原生取色器只在点击颜色方块本身时打开;点击字段名称、说明或 HEX 输入不会代理触发系统取色器。取色器与 HEX 输入共享同一字段,非法中间值允许留在草稿中便于继续编辑,但前端保存校验和后端权威校验都会阻止其生效。