103 lines
6.5 KiB
Markdown
103 lines
6.5 KiB
Markdown
# DusunIoT 重建版(TanStack Start + Bun + PostgreSQL)
|
||
|
||
将原 WordPress + Elementor + WooCommerce + GTranslate 站点(dusuniot.com)重构为单体应用:
|
||
前台 SSR 1:1 还原、后台 React + Ant Design 功能等价实现、PostgreSQL 关系型数据模型。
|
||
|
||
> 方案文档:`docs/dusuniot-rebuild-tanstack-bun-pg-v2.md`
|
||
|
||
## 技术栈
|
||
|
||
| 领域 | 选型 |
|
||
| --- | --- |
|
||
| 运行时 / 包管理 | Bun 1.4+ |
|
||
| 前台 SSR / 路由 | TanStack Start(Vite)+ React 19 + TS |
|
||
| 数据库 | PostgreSQL 16(Bun.sql + Drizzle ORM) |
|
||
| 后台 UI | React + Ant Design 6(**仅 SVG 图标**,禁 emoji/图标字体) |
|
||
| 后台任务 | jobs 表持久化队列(`scripts/jobs-worker.ts`,独立进程) |
|
||
|
||
## 快速开始
|
||
|
||
```sh
|
||
bun install
|
||
# .env 默认 DATABASE_URL=postgres://dusuniot:dusuniot@127.0.0.1:25432/dusuniot
|
||
bun run db:migrate # 应用迁移(src/db/migrations)
|
||
bun run import:wordpress # 全量导入 WP 备份库(需 MariaDB 容器 dusuniot-mariadb, 端口 13306)
|
||
bun run dev # 开发服务器 http://localhost:3311
|
||
bun run build && bun run start # 生产构建(Nitro .output)
|
||
bun run scripts/jobs-worker.ts # 后台任务 worker
|
||
bun test # 单元/集成测试
|
||
```
|
||
|
||
## WordPress 数据迁移
|
||
|
||
- 备份源:`dusuniot-full-20261029.tar.gz`(站点文件 + mysqldump)。媒体已硬链接到 `public/uploads`。
|
||
- 导入脚本:`scripts/wordpress-import/import.ts`,支持 `--only=step1,step2` 分步重跑(步骤:reset/media/users/categories/attributes/products/contents/views/orders/flamingo/elementor/forms/menus/filters/redirects/languages/final)。
|
||
- 导入规模:148 产品(含属性/筛选映射)、674 内容(含 Elementor JSON)、53,101 询盘(Flamingo + Elementor 双源)、108 订单、8,210 媒体、493 条 301 重定向、104 语言、4 菜单 283 菜单项。
|
||
- 旧 ID 映射存 `legacy_id_mappings` 表;WP 旧密码(phpass $P$)保留在 `users.legacy_password_hash`,客户登录时透明升级 bcrypt。
|
||
|
||
## 与原站插件的功能等价映射
|
||
|
||
| 原插件 | 新实现 |
|
||
| --- | --- |
|
||
| WooCommerce | products/orders/order_items/payments 关系模型 + 购物车/结账/账户(PayPal 回调位预留,幂等键 transaction_id) |
|
||
| Contact Form 7 + Flamingo | inquiry_forms(表单定义)+ inquiries(统一询盘表)+ 邮件任务队列 |
|
||
| Filter Everything | filters 配置表 + product_attributes/values/map 关系型筛选(复合索引 + EXISTS 交集查询) |
|
||
| GTranslate | /`<lang>`/ 前缀路由 + UI 壳层字符串 + content/product_translations 真实发布版本(缺翻译不生成伪语言页) |
|
||
| Redirection | redirects 表 + 请求中间件(301/302,支持正则) |
|
||
| Elementor(前台) | src/components/elementor/Renderer.tsx(section/column/heading/text-editor/image/button/image-box/icon-list/tabs/toggle 等 20+ widget) |
|
||
| Rank Math SEO | contents/products 内置 SEO 字段 + sitemap.xml + robots.txt + hreflang |
|
||
| WP Rocket | 设计上按 URL/语言做服务端缓存(Cloudflare/Nginx 层),登录态/购物车禁共享缓存 |
|
||
| Dusun Flamingo Reader | 后台询盘模块 + REST API(保留给 AI 线索管道) |
|
||
|
||
## URL 兼容(SEO 硬性要求)
|
||
|
||
- 页面 `/<slug>/`、文章 `/<category>/<slug>/`、产品 `/product/<slug>/`、产品分类 `/collection/<slug>/`(与原站 permalink 一致,trailingSlash always)。
|
||
- 493 条旧重定向规则原样生效;canonical/hreflang/sitemap 由 SEO 模块输出。
|
||
|
||
## 后台
|
||
|
||
`/admin`(默认管理员见导入输出)。模块:Dashboard / 内容 / 产品 / 订单 / 询盘 / 媒体 / 语言 / SEO 重定向 / 筛选 / 用户 / 设置。
|
||
所有接口 `requireAdmin()` 权限校验,敏感操作写 `audit_logs`。
|
||
|
||
## Docker 部署(v0.15.0)
|
||
|
||
生产环境部署在 OVH(OVH-US-BAK)`/home/docker/dusuniot/`,域名 `dusuniot.ibug.qzz.io`(Cloudflare 橙云):
|
||
|
||
```
|
||
/home/docker/dusuniot/
|
||
├── docker-compose.yml # 即仓库 deploy/docker-compose.yml
|
||
├── app/ # 仓库源码 rsync(.dockerignore 排除 node_modules/dist/uploads 等)
|
||
└── data/
|
||
├── pg/ # PostgreSQL 18 数据卷
|
||
└── uploads/ # 媒体库(容器内双挂载:/app/public/uploads 写入 + /app/dist/client/uploads 服务)
|
||
```
|
||
|
||
- 应用容器 `dusuniot-app`(oven/bun 构建,`bun scripts/prod-server.ts`,PORT 3312),仅绑定 `127.0.0.1:3320`;数据库容器 `dusuniot-db-1`(postgres:18,不对外暴露)。
|
||
- nginx 站点 `/etc/nginx/sites-available/dusuniot.ibug.qzz.io.conf`:80 + 443(Let's Encrypt,certbot webroot 续期自动 reload)→ `proxy_pass http://127.0.0.1:3320`。CF SSL 模式 Full/Full(strict)/Flexible 均兼容。
|
||
- 数据迁移:本机 `pg_dump -Fc` → 服务器 `pg_restore`;媒体经 tar+zstd 流式同步到 `data/uploads`。
|
||
- 更新发布:rsync 源码后 `cd /home/docker/dusuniot && docker compose up -d --build app`。
|
||
- `scripts/prod-server.ts` 的 `/uploads/*` 运行时直读磁盘(媒体上传后无需重启即可访问,本地裸跑同样受益)。
|
||
|
||
## v0.16.0 升级要点(后台体验)
|
||
|
||
- **数据清洗(生产必跑一次)**:询盘表存量 WordPress PHP 序列化串还原为 JSON/纯文本
|
||
(productInterest → 逗号连接、fields/utm 递归还原)。幂等,重复执行零更新:
|
||
`bun scripts/cleanup-php-serialize.ts`(先 `--dry` 核对)。
|
||
- **数据库迁移**:`users` 新增 avatar / locale / theme / mcp_token 四列(0001_user_profile.sql)。
|
||
- **后台 i18n**:默认英文,词典 `src/admin-i18n/locales/en.ts`(键=中文源串);
|
||
偏好存 localStorage(admin_locale / admin_theme)。新增语言时注册词典并在
|
||
`src/admin-i18n/shared.ts` 的 ADMIN_LOCALES 加选项;`tests/admin-i18n.test.ts` 强制 en 全覆盖。
|
||
- **主题/字号**:antd 主题 token 改动(fontSize 15、深色算法)后需重跑 `bun scripts/gen-antd-css.tsx`。
|
||
- **MCP 令牌**:个人设置页生成 `users.mcp_token`;MCP server 以
|
||
`DUSUN_MCP_TOKEN=<token> bun mcp/server.ts` 启动即校验(角色须在权限管理中允许 MCP)。
|
||
- **关站**:设置 → 关闭网站(settings.maintenance),前台 503 维护页,/admin 不受影响,
|
||
配置读取缓存 60s。
|
||
|
||
## 目录结构
|
||
|
||
见方案文档第 6 节。`src/server/*` 按业务域拆分(auth/content→data/products→data/filters/orders→commerce/inquiries/translations/seo/jobs)。
|
||
|
||
## 版本
|
||
|
||
版本号以 `package.json` `version` 为准,每轮交付自增(patch/minor/major)。
|