90 lines
7.1 KiB
Markdown
90 lines
7.1 KiB
Markdown
# 后台(Admin / CRM)与 MCP 说明
|
||
|
||
> v0.13.0 起:前台导航修复(loader 服务函数化)、全站图片占位图 + 懒加载、favicon。
|
||
> v0.12.0 起:PG 16 → 18.6(增量备份能力)、备份系统(全量/增量/S3)、用户权限分层。
|
||
> v0.11.0 起:后台按「功能接近原版 WordPress + 现代化 CRM 界面」重做一轮,并新增站点管理 MCP 服务器。
|
||
|
||
## 前台约定(v0.13.0 起生效)
|
||
|
||
- **TanStack Start loader 是同构运行的**:客户端导航(点击 LOGO / `<Link>` / 分页)会在浏览器重跑一遍
|
||
loader。凡直接调用 `db`/查询层的写法(依赖 `bun:sql`,客户端是 stub)全部失败,页面退化为空数据。
|
||
**loader 的数据获取必须走 `createServerFn`**(服务端执行返回纯 JSON);`redirect()/notFound()` 不能在
|
||
serverFn 内抛给 Router,用协议标记(如 `$.tsx` 的 `__redirect/__notFound`)回传后由 loader 本地抛出。
|
||
已改造:`loadHomePage`(/)、`loadCatchAll`(/$)、`loadProduct`、`loadCollectionCategory`、`loadShopData`、
|
||
`loadSearchData`、`loadContactData`、`loadBlogPost`、`loadSolutionPage`、`loadBlogArchive`、`loadSolutionArchive`、
|
||
`loadCollection`(/collection/)等;购物车/结账/账户本来就用 serverFn(getCart/getCurrentUser/getMyOrders)。
|
||
- **图片占位图与懒加载**:`public/uploads/placeholder.jpg`(灰底 + 低透明度 LOGO,300×260,ImageMagick 生成);
|
||
全部前台 `<img>` 由 Layout 内联脚本补 `loading="lazy" decoding="async"`(MutationObserver 覆盖新增节点),
|
||
加载完成前显示占位背景(`app.css` 的 `.ds-site img` 规则;作用域为 Layout 的 `<main class="ds-site">`)。
|
||
注意透明 PNG 加载完成后会透出占位图——导出透明图时慎用。
|
||
- **缺失图片补齐**:`bun run scripts/sync-missing-uploads.ts` 幂等——扫库(contents/products/media)引用路径,
|
||
与 public/uploads 比对,缺失文件从原站下载(v0.13.0 补回 90 张;原站已失效 38 张不可恢复,走占位图)。
|
||
- **favicon**:`public/favicon.ico`(原站 32×32 PNG 转 ICO,ImageMagick)+ `apple-touch-icon.png`(LOGO 180×180),
|
||
根路由 `head().links` 注入。
|
||
- **导航宽度**:Header 顶栏与主导航行统一 `max-w-[1400px] mx-auto` 居中(2026-11-04 用户指定,原站基准)。
|
||
|
||
## 用户权限分层(RBAC)
|
||
|
||
两类用户:**普通用户**(customer,仅商城账号)与**后台用户**(admin > manager > editor)。能力矩阵(`src/server/auth.ts` requireCapability):
|
||
|
||
| 能力域 | 允许角色 | 覆盖操作 |
|
||
| --- | --- | --- |
|
||
| content | admin/manager/editor | 内容保存/删除、修订恢复、媒体上传/编辑、菜单项、筛选、重定向 |
|
||
| commerce | admin/manager | 产品保存/删除、订单状态、询盘状态 |
|
||
| system | admin | 用户管理、系统设置、语言、备份、审计日志查看 |
|
||
|
||
用户页 `/admin/users/` 提供「全部 / 后台用户 / 普通用户」Tab。
|
||
|
||
## 备份系统(PostgreSQL 18 物理备份)
|
||
|
||
- PG 已升级 **16.15 → 18.6**(容器 `dusuniot-pg`,`summarize_wal=on`,命名卷 `dusuniot-pg18-data`,`--restart unless-stopped`;旧 16 容器保留为 `dusuniot-pg16-old` 可回滚)
|
||
- 全量:`pg_basebackup -Fp -Xs` → `backups/pg/full-<ts>/`
|
||
- 增量:`pg_basebackup --incremental=<最近备份>/backup_manifest`(PG 17+ 能力;实测全量 124MB → 增量 5.4MB)
|
||
- 归档:每次备份 tar.gz → `backups/artifacts/`;配置 S3 后上传(Bun.S3Client,支持 multipart 大文件)
|
||
- 保留:保留最近 N 个全量链(该全量及其后全部增量),本地与 S3 同步清理
|
||
- 恢复:`pg_combinebackup 全量 增量…` 合并 → 作为 PGDATA 启动(已在容器内实测恢复 699 内容完整)
|
||
- 定时:settings.backup.schedule 开启后,jobs worker(`bun scripts/jobs-worker.ts`)按间隔执行 `backup.run`(自动增量、无备份时全量),完成后自排下一轮
|
||
- UI:`/admin/backups`(仅 admin):立即全量/增量、本地+S3 列表、删除、S3/保留/定时配置
|
||
|
||
## 后台功能清单(/admin,React + Ant Design)
|
||
|
||
| 模块 | 路由 | 能力 |
|
||
| --- | --- | --- |
|
||
| Dashboard | `/admin/` | KPI 卡(30 天环比:订单/营收/新询盘)、近 30 天订单/询盘/营收三趋势图、询盘漏斗(new/read/replied/spam/archived 占比)、最近订单 + 最新询盘、快捷入口 |
|
||
| 页面 / 文章 | `/admin/contents/` | page/post/landing Tab、搜索、分页、删除;编辑页支持 **分类目录/标签绑定**(content_terms)、**Elementor JSON** 编辑(meta.elementor,前台 `/slug/` 通栏渲染)、**修订历史**(保存自动留档、查看/恢复)、已发布页面前台预览链接 |
|
||
| 菜单 | `/admin/menus/` | menus 4 个位置(menu-1/menu-2/max_mega_menu_1/max_mega_menu_2)+ menu_items 树编辑(父级/排序/新窗口),前台 Header/Footer 即时读取 |
|
||
| 媒体库 | `/admin/media/` | 列表/搜索/预览、alt 与标题编辑、**上传**(≤20MB,写入 uploads/YYYY/MM/,自动解析 PNG/JPEG/GIF/WebP 宽高) |
|
||
| 产品 | `/admin/products/` | CRUD + 属性/分类/特色图/图集 |
|
||
| 订单 | `/admin/orders/` | 列表/详情/状态流转 |
|
||
| 询盘 | `/admin/inquiries/` | 状态 Tab、关键字、详情抽屉、跟进流转(new→read→replied) |
|
||
| 语言 | `/admin/languages/` | 启用开关 |
|
||
| SEO / 重定向 | `/admin/seo/` | 重定向 CRUD(301/302/正则) |
|
||
| 筛选 | `/admin/filters/` | 前台产品筛选器配置 |
|
||
| 用户 | `/admin/users/` | 列表/搜索;admin 可新建用户、改角色、重置密码(最后一个 admin 防降级锁死) |
|
||
| 系统设置 | `/admin/settings/` | settings 表 kv JSON 编辑器(site/woocommerce/mail/seo),仅 admin 可保存 |
|
||
| 审计日志 | `/admin/audit/` | 全部后台写操作留痕(操作人/动作/实体/摘要),含 MCP 调用(actor 为空) |
|
||
|
||
规范:所有 server function 第一步 `requireAdmin()`;写操作落 `audit_logs`;图标全 SVG(lucide / antd icons)。
|
||
|
||
## MCP 服务器(dusuniot-cms)
|
||
|
||
- 入口:`mcp/server.ts`(Bun 直跑,stdio JSON-RPC,MCP 2024-11-05,无 SDK 依赖)
|
||
- 注册:`.zcode/config.json`(workspace 级,会话启动自动连接)
|
||
- 直连 PostgreSQL(`DATABASE_URL`,默认 `postgres://dusuniot:dusuniot@127.0.0.1:25432/dusuniot`),仅限受信任本机;写操作落审计日志(actor 为空 = MCP)
|
||
- 工具(17 个):
|
||
- `dashboard_stats` 看板统计
|
||
- `list_contents` / `get_content` / `create_content` / `update_content` / `delete_content`(自定义单页面:type=page + elementorJson,保存/更新自动留修订快照,slug 冲突自动加后缀)
|
||
- `list_revisions` / `restore_revision`
|
||
- `list_media` / `upload_media`(base64,≤20MB,自动解析宽高)
|
||
- `list_products` / `list_orders` / `update_order_status`
|
||
- `list_inquiries` / `update_inquiry_status`
|
||
- `get_setting` / `set_setting`
|
||
|
||
## 手动测试
|
||
|
||
```sh
|
||
bun mcp/server.ts # stdio;initialize → tools/list → tools/call
|
||
bun test # 11 pass
|
||
bun run build && bun scripts/prod-server.ts # 站点 + 后台 :3312
|
||
```
|