|
4 | 4 |
|
5 | 5 | --- |
6 | 6 |
|
| 7 | +## v1.16.0 - 2026-07-26 |
| 8 | + |
| 9 | +以 [ChestnutCMS](https://github.com/liweiyi/ChestnutCMS) 为参照做了一轮完整的功能对标与架构瘦身:补齐 12 项经消费方核实的真实缺口,同时**移除发布通道**这一从 ChestnutCMS 直译、在响应式 React SSR 架构下已成负债的机制。 |
| 10 | + |
| 11 | +> **破坏性变更**:`cms_publish_channels` 表与 `/api/cms/publish-channels` 接口已移除,站点默认模板配置结构由「按通道分组」拍平为单份(迁移 `0105` 自动 reshape 存量数据)。详见下方「Removed」。 |
| 12 | +
|
| 13 | +### Added |
| 14 | + |
| 15 | +#### CMS 内容模型 |
| 16 | + |
| 17 | +- **站点级扩展模型**:`cms_sites` 新增 `model_id` + `extend`,内容模型补齐**站点 / 栏目 / 内容三级绑定**。站点级运营元数据(备案信息、客服电话、App 下载地址等)不必再塞进无结构的 `settings`,主题上下文通过 `site.extend` 读取;站点编辑页新增「扩展模型」页签,按所选模型动态渲染字段;解绑模型时同步清空 `extend`,不留残余异构字段 |
| 18 | +- **字段选项支持字典来源**:`select` / `radio` / `checkbox` 三类模型字段的选项新增「系统字典」来源,只填字典编码即可,选项在读取模型时实时解析自 `dict_items`(仅取启用项、按 sort 排序)。字典维护一处,所有引用它的模型字段自动同步 |
| 19 | + |
| 20 | +#### CMS 友情链接 |
| 21 | + |
| 22 | +- **友链分组**:新建 `cms_friend_link_groups`(名称 + 稳定标识 code + 排序 + 启停),主题按组分块渲染页脚,未分组友链归入默认块、空组不渲染;列表页新增分组筛选与分组列、「分组管理」抽屉;分组删除后组内友链自动转为未分组,不连带删除运营数据;跨站引用防护拒绝把友链挂到别站分组 |
| 23 | + |
| 24 | +#### CMS 页面搭建 |
| 25 | + |
| 26 | +- **自定义访问路径**:搭建页新增 `path`,可把默认的 `/p/{slug}/` 换成 `/about.html`、`/zh/about/` 等形态。入库前归一为「无前后斜杠、无 `/index.html`」,使 URL 生成、静态产物路径与前台路由查表共用同一个 key;设了自定义路径后 `/p/{slug}/` 返回 302 指向规范 URL,既不产生重复内容、旧链接也不断 |
| 27 | +- **路径冲突双向拦截**:页面侧拒绝系统保留首段(`p` / `tag` / `interaction` / `search` / `preview` / `api` / `assets`)、`index.html`、站点内重复、以及落在任一栏目路径空间内(含详情页与分页命名空间);栏目侧对称校验新栏目路径不得等于或成为任一自定义路径的前缀,批量建栏目时遇冲突自动改名而非中途报错 |
| 28 | + |
| 29 | +#### CMS 静态化与发布 |
| 30 | + |
| 31 | +- **栏目级静态化开关**:栏目可覆盖站点静态化模式(`inherit` / `dynamic` / `hybrid` / `static`),支持把个别高频变动栏目单独切为纯动态 |
| 32 | +- **详情页目录归档**:栏目可配置详情页产物目录规则(不归档 / 年 / 年月 / 年月日 / `YYYY-MM-DD` / id 取模),控制单目录文件数并改善 SEO 路径语义。日期口径走 dayjs 本地时区,与后台展示的发布时间同源,不会出现错位一天 |
| 33 | +- **内容附件**:内容支持附件清单(名称 / 大小 / 类型),详情页模板可渲染下载区 |
| 34 | +- **标题样式**:内容支持标题样式(颜色 / 加粗 / 斜体),列表页与详情页统一生效 |
| 35 | +- **站点内容策略**:回收站保留天数、已发布内容是否可直接编辑、发布内容时重建列表页数上限等运营开关下沉到站点设置 |
| 36 | +- **跨栏目复制**:内容操作列「复制到其他栏目」可选本站任意栏目,换栏目时 `modelId` 跟随目标栏目 |
| 37 | + |
| 38 | +### Changed |
| 39 | + |
| 40 | +#### CMS 模板解析 |
| 41 | + |
| 42 | +- **模板配置降维**:站点 `settings.defaultTemplates` 与栏目 `settings.templates` 去掉发布通道维度,由 `{[通道code]: {...}}` 拍平为 `{list, detail, detailByModel}`;栏目上原本并存的两层模板槽(`listTemplate` / `detailTemplate` 列 + `settings.templates` 的 `list` / `detail`)语义完全重合,收敛为「通用走栏目自身字段、按模型细分走 JSONB」 |
| 43 | +- **解析链收敛**:列表页 = 试穿 → 栏目 → 站点默认 → 主题默认;详情页 = 试穿 → 内容 → 栏目 `detailByModel` → 栏目 → 站点 `detailByModel` → 站点 → 主题默认 |
| 44 | +- 站点与栏目编辑页的模板配置去掉通道页签,拍平为单组下拉 |
| 45 | + |
| 46 | +#### CMS 静态产物 |
| 47 | + |
| 48 | +- **单棵产物树**:静态产物统一落在 `{siteCode}/` 下,不再按发布通道复制 `__{code}/` 子树(实测两棵树的 HTML 逐字节相同)。dynamic 模式 Redis 页面缓存 key 简化为 `cms:page:{siteId}:{path}` |
| 49 | +- **内容发布快照**:`CmsContentPublishSnapshot.targets`(按通道分组)降为扁平的 `paths: string[]` |
| 50 | + |
| 51 | +#### CMS 数据分析 |
| 52 | + |
| 53 | +- **设备维度取代通道维度**:访问统计与广告事件的「发布通道」分布改为基于 UA 派生的设备类型(PC / 移动 / 爬虫)。原通道维度依赖运营给通道绑定第二个域名才有值,而设备列本就一直可用且更准 |
| 54 | + |
| 55 | +### Removed |
| 56 | + |
| 57 | +- **发布通道(publish pipe)**:删除 `cms_publish_channels` 表、`/api/cms/publish-channels` 接口、后台「发布通道」菜单与 `cms:publish-channel:*` 权限(迁移内一并回收菜单,角色绑定经 `role_menus` 外键级联删除) |
| 58 | +- **UA 302 互跳**:响应式站点做 PC / 移动双 URL 跳转是 SEO 负面(需 `rel=alternate` + `canonical` 双向配对,且 Googlebot 要以两种 UA 各抓一遍) |
| 59 | +- **通道预览段** `/__cms/{site}/__{code}/` |
| 60 | +- 广告事件的通道归属推导逻辑、`cms_ad_events.publish_channel_id`、`cms_publish_artifacts.publish_channel_id`、`cms_visit_logs.channel_code` |
| 61 | + |
| 62 | +> **替代方案**:同一站点绑多个域名走 `cms_sites.aliasDomains`;设备差异由响应式主题的 CSS 断点解决(主题 CSS 全量内联在 HTML 中,加断点零额外请求);确需 PC / 移动两套完全不同的前台时建子站点 + 站群映射分发,子站还可拥有独立的栏目结构。 |
| 63 | +
|
| 64 | +### Fixed |
| 65 | + |
| 66 | +- **孤儿静态产物清扫**:整站重建引入 mark & sweep,本次未写入的历史产物自动回收(改归档规则、删内容、改栏目路径后残留的死文件)。续跑与取消时明确跳过清扫,避免把前半程的有效产物误判为孤儿 |
| 67 | +- **失效模板引用自愈**:主题移除模板变体后,站点 `settings.defaultTemplates` 里的历史引用会变成死配置,并因「按合并后完整 settings 校验」连带卡住该站点所有与模板无关的设置写入。保存前自动摘除未改动的失效引用;本次新提交的失效模板名仍抛 400,保留拼写错误的即时反馈 |
| 68 | +- **模板下拉清空不生效**:站点 settings 深合并会让被清空的项保留旧值(表单提交的是完整状态对象,清空项在请求体里直接消失),`defaultTemplates` 改为整体替换 |
| 69 | +- **模板覆盖参数错位**:整站重建时发布通道编码被误传进 `templateOverride` 形参(同为 `string`,编译期无感知),实际会去查找名为 `pc` 的模板 |
| 70 | +- **栏目种子字段遗漏**:`db/seed.ts` 写入栏目时解构漏了 `staticMode` 与 `detailPathRule`,全新 seed 的新闻栏目归档策略会退回数据库默认值 |
| 71 | +- **模型列表不返回字段**:`GET /api/cms/models/all` 此前不返回 `fields`,导致依赖该接口的下拉无法渲染模型字段 |
| 72 | + |
| 73 | +--- |
| 74 | + |
7 | 75 | ## v1.15.0 - 2026-07-25 |
8 | 76 |
|
9 | 77 | CMS 编辑体验集中改版:新增**站内链接协议**(内链稳定引用,目标改 slug / 换栏目自动跟随),内容编辑页属性面板改为横向分组页签,栏目管理 / 内容管理 / 素材中心三页统一为**左侧树 + 右侧工作区**的两栏结构。 |
|
0 commit comments