升级模板版本
用栖梧模板建好自己的项目以后,模板还会继续发布新版本(修复问题、增加功能)。这一页讲怎样把新版本合并进你的项目。本页是概览,命令和细节以仓库的升级模板版本为准。
两件事不要混淆:
- 合并代码(本页):把模板新版本的代码并进你的项目仓库;
- 升级数据库:代码合并以后,对已有的数据库执行迁移和种子(
pnpm db:migrate→pnpm db:seed),见部署。
先少改模板的文件
升级时冲突多不多,取决于你的项目改了多少模板的文件。项目自己的代码和登记,尽量只写在项目自己的文件里:
| 归属 | 文件 |
|---|---|
| 项目 | 项目域目录(apps/server/src/modules/<域>/、apps/web/src/views/<域>/、apps/web/src/api/<域>/、packages/shared/src/<域>/)、modules/project.module.ts、db/seeds/project/*、db/project-tables.ts、项目自己的迁移、.env* 配置 |
| 模板 | apps/server/src/core/、modules/platform/、modules/workflow/,apps/web/src/core/、views/platform/、views/workflow/,packages/shared 的平台与公共部分,core/db/tenant-tables.ts,模板发布过的迁移,scripts/,模板的测试和文档 |
| 两边都改 | 语言包 JSON、db/seeds/index.ts(SEEDS.project 的登记)、各个 package.json、pnpm-lock.yaml |
模板里的 biz、demo 是示例项目域,可以修改或删除,删改过以后升级时按项目文件处理。确实要改模板文件时,改动尽量小而集中,并在提交说明里写清原因,升级时更容易认出来。见仓库的哪些文件属于谁。
项目的平台表和全局唯一键
开启多租户时,新建的表默认是租户表(带 tenant_id,数据按租户隔离),不需要登记。只有两种情况要登记:
- 平台表:由平台统一维护、所有租户共用的表;
- 全局唯一键:必须在所有租户之间都不重复的唯一键,同时写明占用的值怎样释放(
none、row-delete、takeover)。
项目的这两类登记写在项目自己的文件 apps/server/src/db/project-tables.ts 里(PROJECT_PLATFORM_TABLES、PROJECT_GLOBAL_UNIQUE),不要改模板的 apps/server/src/core/db/tenant-tables.ts。模板发布时这个项目文件是空的,升级也不会改它,所以这里不会冲突。规则见编写租户感知的代码和仓库的项目自己的表、迁移与模板升级。
迁移的时间戳
迁移文件名是 <14 位时间戳>-<名称>.ts,类名以同一个时间戳结尾,比如 20261020153817-crm-order.ts 里的 CrmOrder20261020153817。
- 时间戳用创建迁移时真实的当前时间,精确到秒,不要用整点或整分。模板自己的迁移也在同一个目录里,整点时间容易和模板以后发布的迁移撞上;
- 每个时间戳必须唯一。
pnpm verify会检查,遇到重复的时间戳或者不是 14 位的文件名就报错。
取得新版本
模板的公开仓库是 732124645/qiwu-vue-admin,每个版本有一个标签(比如 v1.6.0)。在项目仓库里加一次远端(叫 upstream),以后每次升级只需要取标签:
git remote add upstream https://github.com/732124645/qiwu-vue-admin.git # 只需执行一次
git fetch upstream --tags
git tag --list 'v*' --sort=-v:refname | headgit remote add upstream https://github.com/732124645/qiwu-vue-admin.git # 只需执行一次
git fetch upstream --tags
git tag --list "v*" --sort=-v:refname | Select-Object -First 10先在一个新分支上合并,确认没问题再并回主分支:
git switch -c upgrade-v1.6.0
git merge v1.6.0合并前先读一遍更新日志,留意不兼容的变化和新的环境变量。想要线性历史时,也可以把项目的提交变基到新标签上(git rebase v1.6.0);但已经推送、多人共用的分支请用合并,不要变基。见仓库的取得模板的新版本。
常见冲突
- 项目文件(
project.module.ts、seeds/project/*、project-tables.ts):保留项目的登记,再看模板那边改了什么(比如新增的示例模块),决定要不要一起保留; db/seeds/index.ts:模板会在这里加平台种子,项目只在SEEDS.project里登记自己的种子。两边的条目都保留,顺序以模板的注释为准;- 语言包 JSON:两边各自新增的键都保留,注意 JSON 的逗号和括号;同一个键两边都改过时,以项目的文案为准。合并后运行
pnpm i18n:check,它会报出只在一种语言里有的键; - 迁移:迁移文件各自独立,一般不冲突。模板发布过的迁移不要修改或改名,已安装的数据库按名字记录它。项目迁移和模板迁移时间戳相同时,
pnpm verify会报出这两个文件:改项目自己的那个(文件名和类名换成当前时间);如果它已经在某些数据库上执行过,还要在这些库里把执行记录改成新名字,做法见仓库; - 执行顺序:已有的数据库只执行还没执行过的迁移,按时间戳先后。项目迁移如果要用到模板新版本改过的表结构,它的时间戳必须晚于对应的模板迁移;
package.json和pnpm-lock.yaml:先按两边的依赖合并package.json;锁文件不要手工合并,取模板那一侧,再执行pnpm i重新生成;- 模板的测试:迁移测试从迁移目录读取清单、按规则检查每张表,项目新增的表和迁移不需要改模板的测试。
见仓库的常见冲突与处理。
合并后的检查
在仓库根目录依次执行:
pnpm i
pnpm --filter @qiwu/shared build
pnpm ai:map
pnpm verify
pnpm --filter @qiwu/server build
pnpm --filter @qiwu/server test最后做一次完整检查,它会清空重建测试库:
pnpm ci:localpnpm ci:local --serial- 合并后运行
pnpm ai:map重新生成项目地图docs/ai/project-map.md并提交:模板和项目两边的改动都会让它过期,pnpm verify会检查它;这个文件有冲突时也不要手工解决,直接重新生成; - 本地反复调试服务端测试时,可以用快速模式
QW_TEST_REUSE_DB=1(见后端测试 · 加快测试),但升级是否成功,以完整重建测试库的那次运行为准; - 开发库用
pnpm db:migrate和pnpm db:seed升级,不要对已有的库执行pnpm db:reset(它会清空数据); - 生产环境先备份数据库,再按部署的步骤执行迁移和种子。
新版本带来的可选模块由开关控制,默认关闭,比如微信公众号(APP_WXOA)和 MCP 智能体接入(APP_MCP)。升级后它们保持关闭,数据表照常由迁移创建;需要时在 .env 里打开开关,再重启全部实例。见仓库的合并后的检查。