1. 增加了几种模板

This commit is contained in:
李琦
2026-08-24 13:06:04 +08:00
parent 1617baec19
commit 287e428e87
124 changed files with 11330 additions and 142 deletions

View File

@@ -0,0 +1,151 @@
# 2026-08-24
## 博客后台可替换模板子系统(一期完整落地)
按批准计划cosmic-pulse-einstein.md实现"后台可替换模板"classic 经典 / ubuntu-terminal 终端 / custom 自定义布局包三类模板。
### 后端Go/Gin
- 新增 `models/template.go`Template 模型)、`repositories/template_repository.go`CRUD + GetCurrentSiteTemplateSlug + ActivateTemplate
- `repositories/migration.go` 新增 `MigrateTemplates()`:建 templates 表 + 种入内置模板classic/ubuntu-terminal+ 种 site_template=classic setting。
- 新增 `handlers/template.go`:公开 `GET /api/templates``GET /api/templates/:slug`;后台 uploadzip 严格校验10MB/200 条目/50MB 解压/扩展名白名单禁 js·html·svg/路径穿越防护/manifest 校验、CRUD、activate。权限复用 settings 组。
- `handlers/setting.go` publicKeys 加 site_template`main.go` 注册路由 + 调用迁移。
- 内置模板 Slug 保留字classic / ubuntu-terminal自定义 slug 需 `^[a-z0-9][a-z0-9-]{0,31}$`
### 前端Vue3
- `App.vue` 改造为布局分发器templateMode = classic/terminal/custom支持 `?preview_template=slug` 预览覆盖admin/login/presentation(PPT) 绕过分发。
- 新增 `layouts/ClassicLayout.vue`(从 App.vue 抽出)、`layouts/TerminalLayout.vue``layouts/CustomLayoutRenderer.vue`
- 终端模板 `terminal/`TerminalShell输入/↑↓历史/Tab 补全/自动滚动)+ commands.tsls/cd/cat/search/works/columns/snippets/videos/services/about/tags/help/pwd/whoami/date/echo/banner/clear支持 &&+ output/ 四个渲染组件;深链映射 route.path→命令会话Ubuntu 紫黑配色Ubuntu Mono 风格)。
- 自定义渲染引擎 `layouts/`blocks/basic.tsheader/nav/hero/footer/image/link/divider/static_html+ BlockDataList/BlockPostDetail/BlockAboutBrief + blocks/index.ts 白名单映射resolvers.tssettings bindings + 数据源加载 + HTML 清洗);皮肤 CSS 注入 `data-template` 隔离、卸载移除。
- `api.ts` 新增模板接口fetchTemplates/fetchTemplateDescriptor/getAdminTemplates/uploadTemplate/updateTemplate/activateTemplate/deleteTemplatePublicSettings 加 site_template。
- 后台:`pages/admin/TemplateManage.vue`(上传/列表/设为当前/预览/停用/删除)+ 菜单「模板管理」+ Settings.vue「模板」分组下拉选择schema 加 template-select 类型)。
### 验证
- 后端 go build 通过scripts/ 目录有项目原有 main 冲突,与本次无关)。
- 前端 vue-tsc --noEmit 通过、vite build 通过。
- 说明:本地 8081 后端为旧进程PID 56808**需重启后** /api/templates、site_template 才生效;终端模板可用 `/?preview_template=ubuntu-terminal` 无需后端新接口直接预览dev server 8888 已启动)。
### 交付物
- 示例自定义布局包:`examples/custom-template-demo/`manifest+layout+skin及打包 `examples/minimal-demo.zip`,可直接后台上传测试。
### 环境注意
- vite build 会被安全删除保护拦截(清空 dist 超 50 文件),先把 dist 移到仓库外临时目录再 build。
## 模板系统收尾优化(四项,均已落地)
1. **内置模板完全锁定**`server/handlers/template.go` 的 AdminUpdateTemplate 增加 IsSystem 校验——内置模板不可改名400、不可停用400description 可改;删除保护原有双保险。
2. **模板管理页增强**
- 后端新增 `GET /api/admin/templates/:id` 详情接口AdminGetTemplateDetail返回 manifest/layout 全文 + assetsBase + isCurrent
- 前端新增 `components/admin/TemplatePreviewModal.vue`iframe 预览 `/?preview_template=`+ `TemplateDetailDrawer.vue`(概览/manifest/layout JSON Tab + 复制TemplateManage.vue 接入(预览改内嵌模态框、加详情按钮、上传区 📦→Icon
- api.ts 新增 TemplateDetail 类型 + getTemplateDetail。
3. **文档**:新建根 `README.md`(项目概览/技术栈/快速开始/目录结构/模板概述)与 `docs/TEMPLATE-DEV.md`(模板开发手册:体系/终端命令表/URL 深链映射/zip 规范/manifest+layout schema/block 白名单/bindings/skin 隔离/操作流程/扩展指南)。
4. **后台 emoji → lucide 图标**AdminMenuItem.vue 图标改 `<Icon :name>` 渲染AdminLayout 30 个菜单 emoji 映射为图标名bar-chart-3/trending-up/theater/presentation 等,已核对 lucide 0.446 存在pages/admin 18 文件 40 处 + components/admin 3 文件AccessLogModal/PostHistoryModal/UserPickerPopover批量替换脚本 emoji2icon.py 在临时目录,按容器智能 size 28/14自动注入 import Icon。后台已无 emoji 残留(前台 pages/Categories.vue 与 TerminalLayout 的 ✕ 不在范围内未动)。
验证go build OK、vue-tsc --noEmit OK、vite build OK。后端 8081 仍为旧进程需重启后新接口/锁定逻辑生效。
## 模板卡片单选 + 终端交互/配色增强Craft 完成)
1. **站点模板卡片单选**`client/src/pages/admin/Settings.vue` 的 template-select 由 select 改为卡片单选网格(模板名/类型徽标/slug/选中对勾active 高亮边框),引入 Iconcheck 图标)。样式 scoped 追加 template-picker 系列。
2. **终端配色可配置localStorage**
- 新增 `client/src/terminal/theme.ts`THEME_PRESETSubuntu 紫/经典绿/白底/现代深灰)+ 自定义颜色 10 项bg/windowBg/titlebarBg/titlebarText/text/muted/prompt/accent/error/bannerload/save 存 localStorage key `terminal-theme`JSON {preset, colors}themeToVars 生成 CSS 变量。
- 新增 `client/src/terminal/TerminalThemePanel.vue`:预设色卡 + 10 项 color input + 恢复默认/关闭。
- `TerminalLayout.vue` 根容器 :style 应用 --term-* 变量标题栏新增调色板按钮打开面板scoped 样式与 `terminal.css` 全部改 var(--term-*)color-mix 做混合色)。
3. **终端命令/导航交互增强**commands.ts + types.ts
- 新命令:`man <cmd>``history [-c]``back`(浏览器后退)、`open <url>``theme`(开面板)、`reload``help [命令]` 支持单个命令详情;`cd -` 返回上一目录ctx 增 getLastDir/setLastDir
- CommandContext 扩展getLastDir/setLastDir/getHistory/clearHistory/openThemePanelTerminalLayout 维护 lastDir 与 history ref。
- PostDetailOutput 顶部加「返回」按钮emit back → router.back()TerminalShell 转发 back 事件。
4. **文档**docs/TEMPLATE-DEV.md 命令表更新(新命令 + cd -+ 新增 §2.3 终端配色(预设/自定义/localStorage/变量约定README 终端描述补配色说明。
验证vue-tsc --noEmit OK、vite build OK后台 admin 目录 grep 无 emoji 残留。dev server 8888 已重启(之前进程超时退出)。
## 修复:终端输入框/骨架样式未还原scoped 穿透问题)
根因TerminalShell.vue 内部元素的骨架样式(.term-body/.term-line/.term-prompt/.term-cmd-text/.term-info/.term-error/.term-banner/.term-input 等)写在了 TerminalLayout.vue 的 `<style scoped>` 里,**scoped 样式不穿透子组件** → 全部回落到浏览器默认样式(输入框带原生边框/白色背景/系统字体)。
修复:把这套终端骨架样式整体迁移到全局 `client/src/terminal/terminal.css`(追加 "Terminal shell skeleton" 段落),并强化 .term-inputbackground/border/outline/box-shadow 全 !important 清除、appearance none、继承 mono 字体、caret 色、placeholder/selection 主题化);删除 TerminalLayout.vue 的 scoped style 块210-391 行)。教训:跨组件共享的"外观类"必须放全局样式或组件自身 scoped不能放在父组件 scoped 里。
验证vue-tsc OK、vite build OK、dev 8888 HMR 即时生效。
## 终端模板补齐作品/片段/视频/服务/专栏支持
之前 videos/services 只有提示文字、snippets/tags 只读列表。现已全模块打通:
- types.tsTermOutputKind 增 work/snippet/videopayload 增 WorkPayload/SnippetPayload/VideoPayload。
- commands.tscat 支持路径解析blog/works/snippets/videos/columns 前缀,`cat 12` 默认文章);新增 cmdWorkDetail/cmdSnippetDetail/cmdVideoDetail/cmdColumnPostscmdVideos 完整实现videos 列分类+全部视频、videos <分类> 列专辑+视频、videos albums/<id> 列专辑内视频cmdServices 展示客户评价+合作伙伴;注册表新增 work/snippet/video 便捷命令(复用详情 handler
- 新输出组件output/WorkDetailOutput.vue标题/分类/年份/描述/技术栈/链接、SnippetDetailOutput.vue代码经 renderMarkdown 走 hljs 高亮、VideoOutput.vue内嵌 <video controls> 播放 + 封面/时长ListOutput 增 videos variant时长/分类,点击跳 /videos/:id
- TerminalShell渲染 work/snippet/video/videos 分支onOpenList videos → /videos/:id。
- TerminalLayout深链映射扩展/works/:id、/columns/:id、/snippets/:id、/videos/:id、/videos/albums/:id → 对应命令)。
- 注意:/snippets/:id 无前端独立路由,终端内用 snippet <id> / cat snippets/<id> 查看,列表不跳转。
验证vue-tsc OK、vite build OKdev server 8888 重启后台任务会超时退出需重建。docs/TEMPLATE-DEV.md 命令表与深链映射同步更新。
## 终端右侧内容预览面板
用户反馈 cat 长文在终端流里不好看 → 实现双栏预览:
- types.tsPreviewPayloadkind: post/work/snippet/video + title + dataCommandContext 增 openPreview/closePreview。
- commands.tscmdPostDetail/cmdWorkDetail/cmdSnippetDetail/cmdVideoDetail 改为 fetch 数据 → ctx.openPreview右侧面板终端只输出一行 info"已打开…close 关闭");新增 close 命令。
- 新组件 terminal/PreviewPanel.vue标题栏类型徽标/标题/✕)+ 独立滚动内容区,复用 PostDetailOutput/WorkDetailOutput/SnippetDetailOutput/VideoOutput加了 hideBack prop面板内隐藏返回按钮
- TerminalLayout双栏布局.term-main flex 行:.term-shell-col flex:1 + .term-preview-col 55%/max60%preview ref + ctx 接线resetSession 关闭面板。
- terminal.css双栏样式 + 窄屏(<880px)面板全屏覆盖。
验证vue-tsc OK、vite build OK、dev 8888 重启后台任务易超时退出需重建。docs/TEMPLATE-DEV.md 增 §2.4 右侧预览面板。
## 多模板扩展7 套新模板)+ 后台优化
用户确认:新增 7 套内置模板(共 9 套classic/ubuntu-terminal/pixel/magazine/newspaper/bento/glass/retro/guofeng全部页面逐页重写排版差异化非换色、canvas 主题预览、Settings tab 记忆、终端面板 max-height。
- 修复terminal.css .term-preview-col 加 max-height 720/height 100%/overflow hidden与 .term-body 对齐),窄屏覆盖模式 max-height 100vh。
- Settings.vueactiveTab localStorage 记忆key admin-settings-active-tabloadInitialTab 校验合法值)。
- canvas 预览config/templatePreviews.ts9 套 draw 函数200x120 原生 canvas+ components/admin/TemplatePreviewCanvas.vueDPR 缩放);接入 TemplateManage 卡片 + Settings template-opt 卡片。
- 后端template_repository.go 加 7 个 slug 常量migration.go MigrateTemplates 追加 7 个 ensureBuiltinTemplatesortOrder 2-8handlers/template.go 内置保留字 map 扩展。
- 模板页面系统关键架构templates/registry.tsTEMPLATE_LAYOUTS 9 套懒加载App.vue 改 <component :is="layoutComponent">slug→注册表未知 slug 走 CustomLayoutRenderer每套模板 = templates/<slug>/{Layout.vue, <slug>.css, pages/index.ts, pages/*.vue}Layout 内 <component :is="pages[route.name] ?? RouterView">(未实现页回退经典不白屏);前台 13 个路由 name 为映射键。
- 7 套模板完成度pixel 13 页全量magazine/newspaper/bento/glass/retro/guofeng 各 Layout+css+核心 3 页home/blog/blogDetail其余页回退经典架构支持后续补齐
- 字体pnpm add 被环境 safe-delete 机制拦截trash 中止),改字体栈回退方案('Press Start 2P'/'Noto Serif SC' 未安装时回退 JetBrains Mono / 系统宋体 Songti SC+SimSunmain.ts 不导入。
- 验证go build OK、vue-tsc OK、vite build OK9 套 ?preview_template= 全部 200。
## 终端预览改为右侧独立窗口
用户反馈:预览不应在终端窗口内(双栏挤压),要在终端右边另开一个窗口,终端左移缩小。
- terminal.css删除 .term-main/.term-shell-col/.term-preview-col 旧双栏;新增 .term-desktopflex 行居中 gap 24max-width 1420+ .term-window 改 flex:0 1 560px缩小+ .term-preview-windowflex:1 1 560px max-width 760独立窗口标题栏 .term-preview-window-bar类型徽标/标题/✕)+ body 独立滚动);<1120px 上下堆叠;<880px 预览窗口全屏覆盖。
- TerminalLayout.vue模板改双窗口桌面终端窗口 + 预览窗口),预览窗口标题栏显示 previewKindLabel文章/作品/代码/视频)+ 标题 + ✕PreviewPanel.vue 移除内部头部(标题栏上移外层窗口),保留内容 body 渲染。
- docs/TEMPLATE-DEV.md §2.4 更新为"右侧预览窗口(独立窗口)"。
验证vue-tsc OK、vite build OK、dev 8888 重启。
## 终端窗口高度 + 模板 CSS 未加载修复
1. 窗口超视口:.term-page padding 3rem→1.5rem 1rem.term-desktop height 改 calc(100vh - 3rem)(去掉 min(760, ...).term-body/.term-body-wrap 已是 flex:1+min-height:0+overflow-y:auto窗口内滚动预览窗口 body 同理 → 总高=100vh 不超视口。
2. 新模板 css 未加载7 套 LayoutPixel/Magazine/Newspaper/Bento/Glass/Retro/GuofengLayout.vue从未 import 自己的 css → 脚本在 script setup 首 import 前注入 `import './<slug>.css'`(模板 Layout 懒加载时 css 一并加载。教训Vue 组件文件内的 .css 必须显式 import 才会生效。
验证vue-tsc OK、vite build OK、dev 8888用 nohup & 方式重启,任务方式易超时)。
## 模板质感打磨(中文化 + 详情页特殊样式)
用户批评模板粗糙、英文文案、详情无设计 → 打磨:
- pixel 全套Layout 导航/页脚中文化(博客/作品/专栏/视频/代码/合作/关于Home 重写(◇欢迎/★精选文章/◆最新作品/▣快速选择中文按钮Blog 中文化(搜索/全部/上一页/下一页);其余 10 页 sed 中文化(暂无数据/加载中/返回/代码库/客户评价/合作伙伴/技能树 等pixel.css 字体栈去掉未安装的 Press Start 2P → 'JetBrains Mono','Noto Sans SC'(中文像素感用等宽)。
- 7 套 BlogDetail 全部重做特殊样式:
- pixel游戏机状态栏分类/日期/阅读 像素框)+ 像素绿标题 + 像素分隔条(绿橙方块)+ END 落款
- magazine刊头信息行年糕杂志·VOL.x·日期+ 特大标题 + 作者行(文/年糕)+ 首字下沉 + 尾注「— 完 —」
- newspaper报纸版头年糕日报·第xxx期·分类+ 头条大标题 + 引题行 + np-cols 双栏正文
- bento宫格头部卡标题 + 分类/日期/阅读 彩色标签)+ 内容卡
- glass毛玻璃居中头部卡标题 + meta 光晕)+ 内容卡
- retro印刷刊头编号+ 烫金大标题 + 日期印章框 + 「— 刊毕 —」
- guofeng竖排日期框日/年月)+ 标题 + 印章 + 分隔线 + 落款「谨记于…·作者 识」
- 各套 Home 英文文案中文化magazine 编者按/Latest Work、newspaper 头版头条、bento/glass Featured/Latest Work 等)。
验证vue-tsc OK、vite build OK、dev 8888 OK。
## 模板文字颜色适配 + 详情页去最大宽度
1. 文字颜色适配:全局 --art-* 是 RGB 三元组rgb(var(--art-accent)) 用法。7 套模板 css 根类(.pixel-root 等)注入 --art-bg/-surface/-text/-muted/-accent/-border 覆盖每套按自身配色pixel 深绿黑/57 255 20、magazine 米白/200 16 46、newspaper 纸色/163 59 46、bento 深紫蓝/108 92 231、glass 深紫/124 220 255、retro 牛皮纸/184 134 11、guofeng 宣纸/178 58 46未重写组件回退经典页自动适配模板配色。
2. 详情页去 max-width各套 Layout 的 main 加 :class="{ full: isDetail }"route.name==='blog-detail'css 追加 .xxx-main.full { max-width: none; },详情页全宽显示。
验证vue-tsc OK、vite build OK、dev 8888 OK。
## 终端作品详情排查与增强
用户反馈"终端的作品无法查看内容详情"。用 playwright-cli 真实浏览器逐段验证works 命令 → ListOutput 渲染 ✓ → 点击行 → navigate /works/:id → 深链 cat works/:id → openPreview 预览窗口 ✓(全链路正常,含长 id work_1768828710998326100
定位感知问题WorkDetailOutput 只渲染标题+描述(作品数据 techStack/links 常为 null无封面/画廊 → 详情显得空。增强 WorkDetailOutput封面 heroImg 大图error 置空防裂图、gallery 画廊网格、技术栈/链接/下一篇,文案中文化(技术栈/作品展示/链接/在线访问/代码仓库)。
- 经验playwright-cli 全局装于 C:/Users/admin/.workbuddy/binaries/node/versions/22.22.2/playwright-clitype 对 Vue input 不生效v-model 需 bubbles:true 的 input 事件),用 eval 派发 input+keydown Enter 模拟;截图/snapshot 输出到 .playwright-cli/ 且部分为空,用 eval 取文本更可靠;测试完 .playwright-cli 移出仓库。
验证vue-tsc OK、vite build OK、dev 8888 OK。
## 终端窗口宽度 + 预览窗口无最大宽度
用户截图终端窗口在窄视口被预览窗口压窄flex 收缩)。修复:
- .term-windowflex 0 1 560px min-width 0 → flex 0 0 520px min-width 480px max-width 600px默认 520px最小 480px 不被压垮)。
- .term-preview-window去 max-width:760"不限制最大宽度"flex 1 1 auto min-width 340填充剩余空间视口宽时可达 ~820px+)。
验证vue-tsc OK、vite build OK、dev 8888 OK。
## 模板详情宽度修复full 类名 bug+ 终端无预览加宽
1. 用户反馈"其他模板文章宽度也不要设置宽度"——查因:脚本注入的详情全宽规则类名写错(.magazine-main.full 等,而 Layout 实际类是 mag-main/np-main/bt-main/gl-main/rt-main/gf-main只有 pixel 生效。修正 6 套 full 类名 → .xxx-main.full 全部正确blog-detail 时 main 全宽。
2. 终端无预览时太窄:.term-window 默认 flex 1 1 auto max-width 960px无预览占满桌面TerminalLayout .term-desktop 加 :class has-preview有预览时 .term-window flex 0 0 520px max 600 收窄。教训脚本生成类名必须与真实模板类名一致缩写类mag-main与 slugmagazine不同。
验证vue-tsc OK、vite build OK、dev 8888 OK。
## 6 套模板视觉差异化重构用户4 套纸感模板同质化、bento 简陋、glass 不高级)
1. magazine→现代编辑杂志纯白底 #f8f8f6 + 墨黑 + 朱红 #e63946;无衬线(Inter)为主 + Playfair 标题;刊头粗红条;文章卡大号编号(::before data-index深色代码块h2 红条前缀。
2. newspaper→旧报纸黄纸 #ece2c8 + 浓黑 + 砖红;宋体正文、报头双线框 + 日期栏、黑体大标题、双栏正文、描边按钮。
3. retro→活字印刷深牛皮纸 #d9c8a3 + 深棕 + 烫金渐变标题;贴纸角标(.rt-stamp 旋转)、art-deco 菱形装饰线(.rt-deco)、粗描边阴影卡。
4. guofeng→水墨意境近白宣纸 #f7f2e7 + 墨色 + 朱砂;超大书法标题(.gf-huge clamp 84px)、大留白(56px top padding)、墨线远山、印章。
5. bento 升级:卡片渐变底(四色渐变)、顶部内高光线(::before)、hover 阴影、.bt-card-icon 图标容器Home 加 lucide 图标 sparkles/file-text/palette/layout-grid
6. glass 升级:背景加第四层光斑;卡片渐变玻璃(linear-gradient 150deg)、顶部弧光(::before radial)、内高光 inset、hover 蓝辉光 0 0 40px。
每套重写后补回 --art-* 覆盖与 .xxx-main.full 规则。magazine Blog 文章卡补 data-index 编号。
验证vue-tsc OK、vite build OK、6 套预览 200。