fix(build): 消除构建期远程拉取隐患 + 评论提交反馈 + 友链卡片移动端

构建隐患(本次丢构建的根因)
- footer.html 用 resources.GetRemote 在每个页面渲染时拉 api/links 与 api/feeds,
  构建节点连不上 Cloudflare 时重试撞穿 Hugo partial 30s 超时 → 整站构建失败
- 改为「流水线 curl 快照 + 模板读本地文件」:
  · 新增 scripts/fetch_snapshots.sh,一次拉齐 conf / friend_links / friend_feeds
    (--max-time 30 --retry 2,JSON 校验,失败一律删文件且恒 exit 0)
  · .cnb.yml Hugo 构建 stage 改为调用该脚本
  · footer.html 改读 site.Data.friend_links / site.Data.friend_feeds,缺失渲染空值
  · .gitignore 忽略 /data/friend_links.json 与 /data/friend_feeds.json
- 降级实测:删掉快照后构建仍 EXIT=0,产物 friendLinks 为空数组

评论提交反馈(artalk.js 新增 __atkSubmit 模块)
- 校验:config.beforeSubmit 拦下 内容空 / 昵称空 / 邮箱空 / 邮箱格式错(网址不校验)
- 发送中:editor-submit 常驻 loading,超 7s 补「网络较慢」
- 成功:editor-submitted 按 normal/reply/edit 分文案,is_pending 提示等待审核
- 失败:拦 POST /api/v2/comments,403/429/4xx/5xx/网络异常全部翻译成人话
- 失败时输入内容保留,并清掉 Artalk 自带的重复小字通知
- 无头浏览器实测 19/19 通过(POST 走 mock,未向线上写数据)

友链申请卡片移动端
- max-width:640px 下隐藏 .atk-fl-nick(昵称 + 博主徽章),桌面端不变

改动:6 files, +282 / -61
This commit is contained in:
zqlit committed 2026-10-04 17:38:04 +08:00
1 parent 836743b16d
commit 571d552c9d
6 files changed
+355 -61

No files matched your search

+33 -38
View File
@@ -79,28 +79,29 @@
window.enableInfiniteScroll = {{ .Site.Params.infiniteScroll.enable | default false }};
</script>
{{/* ====== 3. 远程数据获取 - 构建时 ====== */}}
{{/* Fetch friend data at build time — no runtime network requests */}}
{{/* ====== 3. 友链 / 友圈数据 —— 构建期快照,模板**不发网络请求** ====== */}}
{{/* ★ 这里以前是 resources.GetRemote。它是在「每个页面的模板渲染过程中」同步发请求的,
而 footer 每页都要走一遍:构建节点(国内)到 api.200181.xyz(Cloudflare)一抖动,
两个拉取就会重试到撞穿 Hugo 的 partial 30 秒超时 → 整站构建失败、站点不更新
(2026-10-04 实测:WARN Links API fetch failed ... i/o timeout →
ERROR render of "home" failed: partial "footer.html" timed out after 30s)。
现在改为读 data/ 下的本地快照,由流水线 stage 里的 scripts/fetch_snapshots.sh
curl 落盘(见 .cnb.yml「Hugo 构建」)。快照缺失(本地预览 / 拉取失败)时
with 判空 → 渲染空数组,最坏只是评论区少了「友链 / 友圈」徽章,构建立马过。 */}}
{{ $linkHosts := slice }}
{{ $linkNames := slice }}
{{ with resources.GetRemote (printf "%s/api/links?all=1" (site.Params.rssapi.base | default "https://api.200181.xyz")) }}
{{ with .Err }}
{{ warnf "Links API fetch failed: %s" . }}
{{ else }}
{{ with .Content | transform.Unmarshal }}
{{ range .links }}
{{ $host := "" }}
{{ with .url | urls.Parse }}
{{ $host = .Host | strings.TrimPrefix "www." }}
{{ end }}
{{ $title := .name | default "" }}
{{ if $host }}
{{ $linkHosts = $linkHosts | append (dict "host" $host "title" $title) }}
{{ end }}
{{ if $title }}
{{ $linkNames = $linkNames | append (dict "lower" (lower $title) "title" $title) }}
{{ end }}
{{ end }}
{{ with site.Data.friend_links }}
{{ range .links }}
{{ $host := "" }}
{{ with .url | urls.Parse }}
{{ $host = .Host | strings.TrimPrefix "www." }}
{{ end }}
{{ $title := .name | default "" }}
{{ if $host }}
{{ $linkHosts = $linkHosts | append (dict "host" $host "title" $title) }}
{{ end }}
{{ if $title }}
{{ $linkNames = $linkNames | append (dict "lower" (lower $title) "title" $title) }}
{{ end }}
{{ end }}
{{ end }}
@@ -110,24 +111,18 @@
{{ $feedHosts := slice }}
{{ $feedNames := slice }}
{{ with resources.GetRemote (printf "%s/api/feeds" (site.Params.rssapi.base | default "https://api.200181.xyz")) }}
{{ with .Err }}
{{ warnf "Feeds API fetch failed: %s" . }}
{{ else }}
{{ with .Content | transform.Unmarshal }}
{{ range .feeds }}
{{ $host := "" }}
{{ with .url | urls.Parse }}
{{ $host = .Host | strings.TrimPrefix "www." }}
{{ end }}
{{ $title := .feedTitle | default "" }}
{{ if $host }}
{{ $feedHosts = $feedHosts | append (dict "host" $host "title" $title) }}
{{ end }}
{{ if $title }}
{{ $feedNames = $feedNames | append (dict "lower" (lower $title) "title" $title) }}
{{ end }}
{{ end }}
{{ with site.Data.friend_feeds }}
{{ range .feeds }}
{{ $host := "" }}
{{ with .url | urls.Parse }}
{{ $host = .Host | strings.TrimPrefix "www." }}
{{ end }}
{{ $title := .feedTitle | default "" }}
{{ if $host }}
{{ $feedHosts = $feedHosts | append (dict "host" $host "title" $title) }}
{{ end }}
{{ if $title }}
{{ $feedNames = $feedNames | append (dict "lower" (lower $title) "title" $title) }}
{{ end }}
{{ end }}
{{ end }}