一、这次更新改了什么
VVCMS 5.12.3 已于 2026-10-20 发布。这是 5.12.x 的又一个维护性增强版本:一边把站点配置与 SEO 输出补得更完整,一边修掉两个影响线上交易的 P1 问题。
- 页面配置能返回非 HTML 了——每条页面配置新增「返回类型」,/ads.txt 这类纯文本文件可以直接用模板渲染输出
- SEO 三件套补齐——站点配置新增 llms-full.txt;robots.txt 留空时自动生成带 Sitemap 引用的最小默认
- 外部令牌看得见、更长——管理员在个人中心直接查看令牌(默认掩码),新签发令牌加长到 64 位随机串
- 模板选择不用背文件名——栏目与页面配置的模板输入改为下拉 + 搜索,可一键跳转模板编辑器
- 修了「确认收货不发积分」——会员自己确认收货的订单,积分与推广返利此前永远是 0,现已与后台确认签收同口径计提
- 修了「下单转圈 60 秒」——协程池饱和死锁导致下单/退款接口无限期挂起,派发与邮件提交全面改为不阻塞提交
- 内容 URL 全面收敛——购物车行项、sitemap、百度推送统一由路由引擎生成,开启内容重写后不再 404
二、核心更新
1. 页面配置支持返回类型(content_type)
后台「页面配置」每条记录新增「返回类型」参数,默认 html,可选 txt / json / xml。访问路由时仍按 uri 匹配页面配置、渲染同一个 views/*.html 模板,只是命中非 html 时把响应头 Content-Type 改为对应 MIME(text/plain | application/json | application/xml),并跳过 HTML 翻译。
- 典型用例:
/ads.txt→ 新建页面配置 uri=/ads.txt、视图 views/ads.html、返回类型 txt,即可按纯文本输出 - 非 html 仍复用 html/template 引擎渲染(模板函数、include 都可用),仅切换响应头
- 后台页面配置编辑器同步增加返回类型下拉,老记录默认按 html 处理
2. 站点配置新增 llms-full.txt
llms.txt 规范里 llms-full.txt 是「全量内容版」。站点配置在 llms.txt 之外新增同款配置项,机制完全一致:管理员填写后 /llms-full.txt 以 text/plain 返回,留空则 404,不影响现有 /llms.txt。
3. robots.txt:填了就按原文返回
robots.txt 的输出语义本周明确为「不猜、不改」:
- 填了内容——TrimSpace 后纯原文返回,系统一个字都不追加(自带 Sitemap 引用也不会被重复补)
- 留空但配了站点 URL——自动生成最小默认:
User-agent: * / Allow: /,并附上 Sitemap、llms.txt、llms-full.txt 三条引用 - 两者都空——返回 404,与旧版一致
后台 robots 输入框下新增了对应提示,运营不必再猜「系统会不会动我的内容」。
4. 个人中心可直接查看外部 API 令牌
此前外部 API 令牌只在「重置」后一次性展示,想再看一眼必须先重置。本版新增仅管理员可查的查看接口:
- 新增
GET /api/sys/token,挂RequireAdminToken中间件,只允许管理员读取当前令牌 - 绝不把令牌放回 /api/sys/userinfo——那个接口普通会员也能调,放回去就是越权泄露(已有源码级回归测试钉死)
- 前端个人中心进入即自动拉取,输入框默认掩码,点眼睛图标明文显示,复制逻辑不变
5. 外部令牌加长(安全)
令牌生成从 uuid.NewString()(36 字符 UUID v4,约 122 位熵)升级为 rand.RandStr(64)(62 字符字母表、加密级随机源,约 381 位熵),仍在 User.Token 字段 varchar(255) 限度内。存量旧令牌继续有效,仅新签发时使用新格式;令牌依然只经 resetoken / token 两条管理员接口返回,安全边界不变。
6. 模板选择改为下拉 + 搜索
栏目「列表模板 / 内容模板」与页面配置「视图」从手输文件名改为可搜索下拉:
- 新增可复用组件
TemplateSelect:filterable + allow-create + clearable,自动拉取当前主题 views/ 下的 .html 文件列表 - 页面配置每行带「编辑」按钮,点击直达模板编辑器对应文件(
/system/template?path=views/xxx.html) - 后端口径不变:
normalizeViewName仍只接受 views/ 下单层裸文件名,含/、..一律回落 404.html,目录穿越依然进不来
三、问题修复
1. 会员确认收货不计提积分与推广返利(P1)
积分/返利计提(ReferralUseCase.RewardOnComplete)此前唯一入口是后台「确认签收」,会员主流程的「确认收货」完全没有接线——会员自己在会员中心确认收货的订单,积分与推广返利永远是 0,与「第一版直接挂确认收货」的设计意图相反。
- 现会员端确认收货与后台确认签收走同一计提口径:买家得积分、推广人得返利
- 重复确认不会重复发放(订单状态机 + 双唯一索引兜底)
- 游客订单没有账户,什么都不发且不报错
- 新增 4 条不变量守卫测试(会员 / 后台 / 重复确认 / 游客四种场景)
2. 协程池饱和导致下单/退款接口挂起(P1)
派发器原来用阻塞式 Pond.Submit,而池配的是 MaxWorkers=2 + 无缓冲队列。两个并发通知各占一个 worker,执行中又要经 sendRepo 向同一个池提交邮件任务(池内提交),互相等对方空出 worker → 全池死锁:下单/退款接口 20-60 秒无响应(数据照常落库,纯前端转圈)。会员「确认收货」一次连发 paid + done 两条通知,必爆。
- 派发 async 改为 TrySubmit:队列满立即失败并记日志丢弃——通知可丢,接口不能挂
- sendRepo 池内提交改为 trySubmitOrSpawn:池满时退裸 goroutine 兜底,邮件照常发送
- 两个池的饱和场景均有单测覆盖(占住唯一 worker 后验证调用方零阻塞)
3. 内容 URL 统一由路由引擎生成
购物车行项链接、sitemap(栏目走 BuildPageURL 跟随 .html 后缀开关、内容走 BuildContentURLWithColumn)、百度推送链接等全部收敛到 ContentRouteEngine 生成。此前这些位置存在手拼 URL,开启「内容重写」(match 前缀 / .html 后缀)后链接变 404——sitemap 与购物车行项各踩过一次。新增源码级守卫测试:shop / order / content 三个 usecase 里再出现手拼内容 URL,测试直接报红。
四、质量与测试
- 新增回归测试:order_confirm_reward(4 条不变量)、dispatcher_pond、send_repo_pond、token_guard(源码扫描钉死 /resetoken 与 /token 必须挂管理员中间件)、content_url_guard(禁止手拼内容 URL)、page_option(content_type 归一化与匹配)、buildRobotsContent(4 子用例)
- 本版构建与全部新增用例随包验证通过,go build / go test 全绿
五、升级建议
- 升级前备份数据库、uploads 上传目录与当前主题目录
- 需要 /ads.txt 等纯文本输出:升级后在「页面配置」新增记录(uri=/ads.txt、视图 views/ads.html、返回类型 txt),模板里按纯文本写即可
- 想让 /llms-full.txt 生效:在站点配置填写 llms-full.txt 内容;不填则保持 404
- robots.txt 行为变化点:升级后 robots 留空且配了站点 URL 的站点,/robots.txt 将从 404 变为返回最小默认(含 Sitemap 引用);本就填了 robots 的站点无感知
- 依赖「只有后台确认签收才计提积分/返利」运营口径的站点请注意:升级后会员自己确认收货也会计提
六、兼容性说明
- content_type 默认 html,老页面配置记录无需改动;非 html 复用 html/template 渲染,JSON/XML 动态值含 < > & 会按 HTML 上下文转义,更适合 ads.txt、security.txt 这类静态文本文件
- llms-full.txt 为纯新增能力,不写入不影响任何现有行为
- /api/sys/token 为新接口;/api/sys/userinfo 行为不变(令牌依旧不回传)
- 令牌仅新签发时变长,存量 UUID 格式令牌继续有效
- URL 引擎收敛修复的是「开启重写后 404」,未开启内容重写的站点无行为变化
七、小结
VVCMS 5.12.3 把站点配置与 SEO 输出补齐全(页面返回类型、llms-full.txt、robots 默认生成),让外部令牌「看得见、猜不破」(管理员直查 + 64 位加长),并修掉两个真金白银的 P1:会员确认收货的积分返利、下单/退款接口的池死锁挂起。如果你是自建站或已经开了商城,这一版建议尽快平滑升级。