befly 3.10.17 → 3.10.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/README.md +83 -307
  2. package/dist/befly.config.d.ts +7 -0
  3. package/{befly.config.ts → dist/befly.config.js} +8 -31
  4. package/dist/checks/checkApi.d.ts +1 -0
  5. package/{checks/checkApi.ts → dist/checks/checkApi.js} +10 -27
  6. package/dist/checks/checkHook.d.ts +1 -0
  7. package/{checks/checkHook.ts → dist/checks/checkHook.js} +10 -19
  8. package/dist/checks/checkMenu.d.ts +7 -0
  9. package/{checks/checkMenu.ts → dist/checks/checkMenu.js} +15 -50
  10. package/dist/checks/checkPlugin.d.ts +1 -0
  11. package/{checks/checkPlugin.ts → dist/checks/checkPlugin.js} +10 -19
  12. package/dist/checks/checkTable.d.ts +6 -0
  13. package/{checks/checkTable.ts → dist/checks/checkTable.js} +16 -40
  14. package/dist/configs/presetFields.d.ts +4 -0
  15. package/{configs/presetFields.ts → dist/configs/presetFields.js} +1 -1
  16. package/dist/configs/presetRegexp.d.ts +145 -0
  17. package/{utils/regex.ts → dist/configs/presetRegexp.js} +8 -31
  18. package/dist/hooks/auth.d.ts +5 -0
  19. package/{hooks/auth.ts → dist/hooks/auth.js} +5 -9
  20. package/dist/hooks/cors.d.ts +9 -0
  21. package/{hooks/cors.ts → dist/hooks/cors.js} +2 -12
  22. package/dist/hooks/parser.d.ts +12 -0
  23. package/{hooks/parser.ts → dist/hooks/parser.js} +27 -42
  24. package/dist/hooks/permission.d.ts +12 -0
  25. package/{hooks/permission.ts → dist/hooks/permission.js} +11 -22
  26. package/dist/hooks/validator.d.ts +9 -0
  27. package/{hooks/validator.ts → dist/hooks/validator.js} +5 -12
  28. package/dist/lib/asyncContext.d.ts +21 -0
  29. package/dist/lib/asyncContext.js +27 -0
  30. package/dist/lib/cacheHelper.d.ts +95 -0
  31. package/{lib/cacheHelper.ts → dist/lib/cacheHelper.js} +43 -103
  32. package/dist/lib/cacheKeys.d.ts +23 -0
  33. package/{lib/cacheKeys.ts → dist/lib/cacheKeys.js} +5 -10
  34. package/dist/lib/cipher.d.ts +153 -0
  35. package/{lib/cipher.ts → dist/lib/cipher.js} +23 -44
  36. package/dist/lib/connect.d.ts +91 -0
  37. package/{lib/connect.ts → dist/lib/connect.js} +46 -87
  38. package/dist/lib/dbDialect.d.ts +87 -0
  39. package/{lib/dbDialect.ts → dist/lib/dbDialect.js} +32 -112
  40. package/dist/lib/dbHelper.d.ts +204 -0
  41. package/{lib/dbHelper.ts → dist/lib/dbHelper.js} +73 -230
  42. package/dist/lib/dbUtils.d.ts +68 -0
  43. package/{lib/dbUtils.ts → dist/lib/dbUtils.js} +49 -123
  44. package/dist/lib/jwt.d.ts +13 -0
  45. package/{lib/jwt.ts → dist/lib/jwt.js} +11 -32
  46. package/dist/lib/logger.d.ts +32 -0
  47. package/{lib/logger.ts → dist/lib/logger.js} +201 -278
  48. package/dist/lib/redisHelper.d.ts +185 -0
  49. package/{lib/redisHelper.ts → dist/lib/redisHelper.js} +95 -139
  50. package/dist/lib/sqlBuilder.d.ts +160 -0
  51. package/{lib/sqlBuilder.ts → dist/lib/sqlBuilder.js} +131 -277
  52. package/dist/lib/sqlCheck.d.ts +23 -0
  53. package/{lib/sqlCheck.ts → dist/lib/sqlCheck.js} +24 -41
  54. package/dist/lib/validator.d.ts +45 -0
  55. package/{lib/validator.ts → dist/lib/validator.js} +43 -60
  56. package/dist/loader/loadApis.d.ts +12 -0
  57. package/{loader/loadApis.ts → dist/loader/loadApis.js} +7 -17
  58. package/dist/loader/loadHooks.d.ts +8 -0
  59. package/{loader/loadHooks.ts → dist/loader/loadHooks.js} +5 -19
  60. package/dist/loader/loadPlugins.d.ts +8 -0
  61. package/{loader/loadPlugins.ts → dist/loader/loadPlugins.js} +8 -20
  62. package/dist/main.d.ts +26 -0
  63. package/{main.ts → dist/main.js} +39 -78
  64. package/dist/paths.d.ts +93 -0
  65. package/{paths.ts → dist/paths.js} +6 -19
  66. package/dist/plugins/cache.d.ts +14 -0
  67. package/{plugins/cache.ts → dist/plugins/cache.js} +4 -11
  68. package/dist/plugins/cipher.d.ts +10 -0
  69. package/{plugins/cipher.ts → dist/plugins/cipher.js} +1 -5
  70. package/dist/plugins/config.d.ts +10 -0
  71. package/dist/plugins/config.js +6 -0
  72. package/dist/plugins/db.d.ts +14 -0
  73. package/{plugins/db.ts → dist/plugins/db.js} +5 -13
  74. package/dist/plugins/jwt.d.ts +10 -0
  75. package/{plugins/jwt.ts → dist/plugins/jwt.js} +2 -7
  76. package/dist/plugins/logger.d.ts +28 -0
  77. package/{plugins/logger.ts → dist/plugins/logger.js} +2 -7
  78. package/dist/plugins/redis.d.ts +14 -0
  79. package/{plugins/redis.ts → dist/plugins/redis.js} +4 -9
  80. package/dist/plugins/tool.d.ts +79 -0
  81. package/{plugins/tool.ts → dist/plugins/tool.js} +7 -30
  82. package/dist/router/api.d.ts +14 -0
  83. package/dist/router/api.js +107 -0
  84. package/dist/router/static.d.ts +9 -0
  85. package/{router/static.ts → dist/router/static.js} +17 -31
  86. package/dist/scripts/ensureDist.d.ts +1 -0
  87. package/dist/scripts/ensureDist.js +80 -0
  88. package/dist/sync/syncApi.d.ts +3 -0
  89. package/{sync/syncApi.ts → dist/sync/syncApi.js} +33 -53
  90. package/dist/sync/syncCache.d.ts +2 -0
  91. package/{sync/syncCache.ts → dist/sync/syncCache.js} +1 -6
  92. package/dist/sync/syncDev.d.ts +6 -0
  93. package/{sync/syncDev.ts → dist/sync/syncDev.js} +27 -60
  94. package/dist/sync/syncMenu.d.ts +14 -0
  95. package/{sync/syncMenu.ts → dist/sync/syncMenu.js} +61 -121
  96. package/dist/sync/syncTable.d.ts +151 -0
  97. package/{sync/syncTable.ts → dist/sync/syncTable.js} +168 -375
  98. package/{types → dist/types}/api.d.ts +12 -51
  99. package/dist/types/api.js +4 -0
  100. package/{types → dist/types}/befly.d.ts +32 -223
  101. package/dist/types/befly.js +4 -0
  102. package/{types → dist/types}/cache.d.ts +7 -15
  103. package/dist/types/cache.js +4 -0
  104. package/dist/types/cipher.d.ts +27 -0
  105. package/dist/types/cipher.js +7 -0
  106. package/{types → dist/types}/common.d.ts +8 -33
  107. package/dist/types/common.js +5 -0
  108. package/{types → dist/types}/context.d.ts +3 -5
  109. package/dist/types/context.js +4 -0
  110. package/{types → dist/types}/crypto.d.ts +0 -3
  111. package/dist/types/crypto.js +4 -0
  112. package/dist/types/database.d.ts +138 -0
  113. package/dist/types/database.js +4 -0
  114. package/dist/types/hook.d.ts +15 -0
  115. package/dist/types/hook.js +6 -0
  116. package/dist/types/jwt.d.ts +75 -0
  117. package/dist/types/jwt.js +4 -0
  118. package/dist/types/logger.d.ts +47 -0
  119. package/dist/types/logger.js +6 -0
  120. package/dist/types/plugin.d.ts +14 -0
  121. package/dist/types/plugin.js +6 -0
  122. package/dist/types/redis.d.ts +71 -0
  123. package/dist/types/redis.js +4 -0
  124. package/{types/roleApisCache.ts → dist/types/roleApisCache.d.ts} +0 -2
  125. package/dist/types/roleApisCache.js +8 -0
  126. package/dist/types/sync.d.ts +92 -0
  127. package/dist/types/sync.js +4 -0
  128. package/dist/types/table.d.ts +34 -0
  129. package/dist/types/table.js +4 -0
  130. package/dist/types/validate.d.ts +67 -0
  131. package/dist/types/validate.js +4 -0
  132. package/dist/utils/arrayKeysToCamel.d.ts +13 -0
  133. package/{utils/arrayKeysToCamel.ts → dist/utils/arrayKeysToCamel.js} +4 -4
  134. package/dist/utils/calcPerfTime.d.ts +4 -0
  135. package/{utils/calcPerfTime.ts → dist/utils/calcPerfTime.js} +3 -3
  136. package/dist/utils/configTypes.d.ts +1 -0
  137. package/dist/utils/configTypes.js +1 -0
  138. package/dist/utils/convertBigIntFields.d.ts +11 -0
  139. package/{utils/convertBigIntFields.ts → dist/utils/convertBigIntFields.js} +5 -9
  140. package/dist/utils/cors.d.ts +8 -0
  141. package/{utils/cors.ts → dist/utils/cors.js} +1 -3
  142. package/dist/utils/disableMenusGlob.d.ts +13 -0
  143. package/{utils/disableMenusGlob.ts → dist/utils/disableMenusGlob.js} +9 -29
  144. package/dist/utils/fieldClear.d.ts +11 -0
  145. package/{utils/fieldClear.ts → dist/utils/fieldClear.js} +15 -33
  146. package/dist/utils/genShortId.d.ts +10 -0
  147. package/{utils/genShortId.ts → dist/utils/genShortId.js} +1 -1
  148. package/dist/utils/getClientIp.d.ts +6 -0
  149. package/{utils/getClientIp.ts → dist/utils/getClientIp.js} +1 -7
  150. package/dist/utils/importDefault.d.ts +1 -0
  151. package/dist/utils/importDefault.js +29 -0
  152. package/dist/utils/isDirentDirectory.d.ts +2 -0
  153. package/{utils/isDirentDirectory.ts → dist/utils/isDirentDirectory.js} +3 -8
  154. package/dist/utils/keysToCamel.d.ts +10 -0
  155. package/{utils/keysToCamel.ts → dist/utils/keysToCamel.js} +4 -5
  156. package/dist/utils/keysToSnake.d.ts +10 -0
  157. package/{utils/keysToSnake.ts → dist/utils/keysToSnake.js} +4 -5
  158. package/dist/utils/loadMenuConfigs.d.ts +5 -0
  159. package/{utils/loadMenuConfigs.ts → dist/utils/loadMenuConfigs.js} +22 -49
  160. package/dist/utils/pickFields.d.ts +4 -0
  161. package/{utils/pickFields.ts → dist/utils/pickFields.js} +2 -5
  162. package/dist/utils/process.d.ts +24 -0
  163. package/{utils/process.ts → dist/utils/process.js} +2 -18
  164. package/dist/utils/processFields.d.ts +4 -0
  165. package/{utils/processFields.ts → dist/utils/processFields.js} +4 -8
  166. package/dist/utils/regex.d.ts +145 -0
  167. package/{configs/presetRegexp.ts → dist/utils/regex.js} +8 -31
  168. package/dist/utils/response.d.ts +20 -0
  169. package/{utils/response.ts → dist/utils/response.js} +27 -48
  170. package/dist/utils/scanAddons.d.ts +17 -0
  171. package/{utils/scanAddons.ts → dist/utils/scanAddons.js} +4 -38
  172. package/dist/utils/scanConfig.d.ts +26 -0
  173. package/{utils/scanConfig.ts → dist/utils/scanConfig.js} +22 -59
  174. package/dist/utils/scanFiles.d.ts +30 -0
  175. package/{utils/scanFiles.ts → dist/utils/scanFiles.js} +25 -65
  176. package/dist/utils/scanSources.d.ts +10 -0
  177. package/{utils/scanSources.ts → dist/utils/scanSources.js} +16 -39
  178. package/dist/utils/sortModules.d.ts +28 -0
  179. package/{utils/sortModules.ts → dist/utils/sortModules.js} +24 -64
  180. package/dist/utils/sqlLog.d.ts +14 -0
  181. package/{utils/sqlLog.ts → dist/utils/sqlLog.js} +2 -14
  182. package/package.json +15 -32
  183. package/.gitignore +0 -0
  184. package/bunfig.toml +0 -3
  185. package/docs/README.md +0 -98
  186. package/docs/api/api.md +0 -1921
  187. package/docs/guide/examples.md +0 -926
  188. package/docs/guide/quickstart.md +0 -354
  189. package/docs/hooks/auth.md +0 -38
  190. package/docs/hooks/cors.md +0 -28
  191. package/docs/hooks/hook.md +0 -838
  192. package/docs/hooks/parser.md +0 -19
  193. package/docs/hooks/rateLimit.md +0 -47
  194. package/docs/infra/redis.md +0 -628
  195. package/docs/plugins/cipher.md +0 -61
  196. package/docs/plugins/database.md +0 -189
  197. package/docs/plugins/plugin.md +0 -986
  198. package/docs/reference/addon.md +0 -510
  199. package/docs/reference/config.md +0 -573
  200. package/docs/reference/logger.md +0 -495
  201. package/docs/reference/sync.md +0 -478
  202. package/docs/reference/table.md +0 -763
  203. package/docs/reference/validator.md +0 -620
  204. package/lib/asyncContext.ts +0 -43
  205. package/plugins/config.ts +0 -13
  206. package/router/api.ts +0 -130
  207. package/tsconfig.json +0 -54
  208. package/types/database.d.ts +0 -541
  209. package/types/hook.d.ts +0 -25
  210. package/types/jwt.d.ts +0 -118
  211. package/types/logger.d.ts +0 -65
  212. package/types/plugin.d.ts +0 -19
  213. package/types/redis.d.ts +0 -83
  214. package/types/sync.d.ts +0 -398
  215. package/types/table.d.ts +0 -216
  216. package/types/validate.d.ts +0 -69
  217. package/utils/configTypes.ts +0 -3
  218. package/utils/importDefault.ts +0 -21
@@ -1,478 +0,0 @@
1
- # Sync 同步流程
2
-
3
- > 数据库结构、API路由、菜单配置、开发账户同步
4
-
5
- ## 目录
6
-
7
- - [概述](#概述)
8
- - [强约束清单](#强约束清单)
9
- - [syncTable 数据库同步](#synctable-数据库同步)
10
- - [syncApi 接口同步](#syncapi-接口同步)
11
- - [syncMenu 菜单同步](#syncmenu-菜单同步)
12
- - [syncDev 开发账户同步](#syncdev-开发账户同步)
13
- - [syncCache 缓存同步](#synccache-缓存同步)
14
- - [表名规则](#表名规则)
15
- - [注意事项](#注意事项)
16
- - [FAQ](#faq)
17
-
18
- ---
19
-
20
- ## 概述
21
-
22
- Sync 同步系统用于将代码定义同步到数据库,包括:
23
-
24
- | 命令 | 功能 | 目标表 |
25
- | ----------- | ----------------- | --------------------------------------- |
26
- | `syncTable` | 同步表结构定义 | 所有业务表 |
27
- | `syncApi` | 同步 API 路由信息 | `addon_admin_api` |
28
- | `syncMenu` | 同步菜单配置 | `addon_admin_menu` |
29
- | `syncDev` | 创建开发者账户 | `addon_admin_role`, `addon_admin_admin` |
30
- | `syncCache` | 同步缓存 | Redis(apis/menu/role-permissions) |
31
-
32
- **执行顺序**:`syncTable` → `syncApi` → `syncMenu` → `syncDev` → `syncCache`
33
-
34
- ---
35
-
36
- ## 强约束清单
37
-
38
- - **API routePath 必须是 pathname**:`syncApi` 写入数据库的 `routePath` 仅允许 `url.pathname`(例如 `/api/user/login`),禁止出现 method 前缀(`POST/api/...`、`POST /api/...`)。
39
- - **角色权限 apis 仅允许 pathname 字符串数组**:`syncDev` 写入角色表的 `apis` 必须是 pathname 字符串数组(严格模式不允许 numeric id)。
40
- - **权限缓存 Set member 仅允许 pathname**:角色接口权限缓存的 Set 成员为 pathname,与 method 无关。
41
- - **Redis prefix 不允许包含冒号**:配置 `redis.prefix` 不要包含 `:`(系统会自动拼接分隔符)。例如写 `befly`,不要写 `befly:`。
42
-
43
- > 说明:当前版本不提供 CLI 同步命令;同步逻辑在服务启动时由主进程自动执行(见 `packages/core/main.ts`)。
44
-
45
- ---
46
-
47
- ## syncTable 数据库同步
48
-
49
- 将 `tables/*.json` 表定义同步到数据库结构。
50
-
51
- ### 基本用法
52
-
53
- 默认会在服务启动时自动执行(仅主进程)。如需在代码中手动执行:
54
-
55
- ```typescript
56
- import { syncTable } from "../sync/syncTable.js";
57
- import { scanSources } from "../utils/scanSources.js";
58
-
59
- // ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.cache / ctx.config)
60
- const sources = await scanSources();
61
- await syncTable(ctx, sources.tables);
62
- ```
63
-
64
- ### 命令选项
65
-
66
-
67
-
68
- ### 同步逻辑
69
-
70
- ```
71
- ┌─────────────────────────────────────────────────────┐
72
- │ syncTable │
73
- ├─────────────────────────────────────────────────────┤
74
- │ 1. 校验 ctx.db / ctx.redis / ctx.config │
75
- │ 2. 检查数据库版本 (ensureDbVersion) │
76
- │ 3. 同步传入的表定义列表(通常来自 scanSources) │
77
- │ ├── 表存在?→ modifyTable (修改) │
78
- │ └── 表不存在?→ createTable (新建) │
79
- │ 4. 清理 Redis 缓存 (tableColumns) │
80
- └─────────────────────────────────────────────────────┘
81
- ```
82
-
83
- ### 自动添加字段
84
-
85
- 每个表自动添加以下系统字段:
86
-
87
- | 字段 | 类型 | 说明 |
88
- | ------------ | ------- | ------------------------------- |
89
- | `id` | BIGINT | 主键,自增 |
90
- | `created_at` | BIGINT | 创建时间戳 |
91
- | `updated_at` | BIGINT | 更新时间戳 |
92
- | `state` | TINYINT | 状态(1=正常,0=禁用,-1=删除) |
93
-
94
- ### 示例
95
-
96
- **表定义文件** `tables/user.json`:
97
-
98
- ```json
99
- {
100
- "email": "邮箱|string|5|100||true|^[\\w.-]+@[\\w.-]+\\.[a-zA-Z]{2,}$",
101
- "password": "密码|string|6|100||true",
102
- "nickname": "昵称|string|2|50|用户",
103
- "avatar": "头像|string|0|500",
104
- "phone": "手机号|string|0|20"
105
- }
106
- ```
107
-
108
- **同步结果**:创建/更新 `user` 表,包含定义的字段 + 系统字段。
109
-
110
- ---
111
-
112
- ## syncApi 接口同步
113
-
114
- 将 API 路由定义同步到 `addon_admin_api` 表。
115
-
116
- ### 基本用法
117
-
118
- 通常无需单独调用:服务启动流程会按顺序执行 `syncTable` → `syncApi` → `syncMenu` → `syncDev` → `syncCache`。
119
-
120
- 如需在代码中手动调用:
121
-
122
- ```typescript
123
- import { syncApi } from "../sync/syncApi.js";
124
- import { scanSources } from "../utils/scanSources.js";
125
-
126
- const sources = await scanSources();
127
- await syncApi(ctx, sources.apis as any);
128
- ```
129
-
130
- ### 同步逻辑
131
-
132
- ```
133
- ┌─────────────────────────────────────────────────────┐
134
- │ syncApi │
135
- ├─────────────────────────────────────────────────────┤
136
- │ 1. 扫描 API 文件: │
137
- │ - 项目 API:tpl/apis/**/*.ts │
138
- │ - Addon API:addons/*/apis/**/*.ts │
139
- │ ↓ │
140
- │ 2. 提取 API 信息: │
141
- │ - name: 接口名称 │
142
- │ - path: 路由路径 │
143
- │ - method: 请求方法 │
144
- │ - description: 接口描述 │
145
- │ - addonName: 所属 Addon │
146
- │ ↓ │
147
- │ 3. 同步到 addon_admin_api 表: │
148
- │ - 新增不存在的 API │
149
- │ - 更新已存在的 API │
150
- │ - 删除代码中已移除的 API │
151
- └─────────────────────────────────────────────────────┘
152
- ```
153
-
154
- ### 存储字段(重要)
155
-
156
- `syncApi` 会把扫描到的 API 信息同步到 `addon_admin_api` 表,核心字段为:
157
-
158
- - `routePath`:只存 `url.pathname`(例如 `/api/user/login`),与 method 无关
159
- - `name`:接口名称
160
- - `addonName`:所属 addon(无 addon 时为空字符串)
161
-
162
- > 注意:`routePath` 必须是 pathname(以 `/` 开头),不允许写成 `POST /api/...` 或 `POST/api/...`。
163
-
164
- ### 统计信息
165
-
166
- ```typescript
167
- interface SyncApiStats {
168
- totalApis: number; // API 总数
169
- created: number; // 新增数量
170
- updated: number; // 更新数量
171
- deleted: number; // 删除数量
172
- }
173
- ```
174
-
175
- ---
176
-
177
- ## syncMenu 菜单同步
178
-
179
- 将 `views/**/index.vue` 中的 `definePage({ meta })` 菜单配置同步到 `addon_admin_menu` 表。
180
-
181
- ### 基本用法
182
-
183
- 同 `syncApi`,通常由启动流程统一触发。
184
-
185
- 如需手动调用,需要先对菜单配置做校验/过滤(例如 disableMenus):
186
-
187
- ```typescript
188
- import { checkMenu } from "../checks/checkMenu.js";
189
- import { syncMenu } from "../sync/syncMenu.js";
190
- import { scanSources } from "../utils/scanSources.js";
191
-
192
- const sources = await scanSources();
193
- const checkedMenus = await checkMenu(sources.addons, { disableMenus: ctx.config.disableMenus || [] });
194
- await syncMenu(ctx, checkedMenus);
195
- ```
196
-
197
- ### 菜单配置文件
198
-
199
- 在 `views/{menuName}/index.vue` 中用 `definePage()` 定义菜单:
200
-
201
- ```vue
202
- <script setup>
203
- definePage({
204
- meta: {
205
- title: "用户管理",
206
- order: 10
207
- }
208
- });
209
- </script>
210
- ```
211
-
212
- **配置字段**:
213
-
214
- | 字段 | 类型 | 必填 | 说明 |
215
- | ------- | ------ | ---- | -------------------- |
216
- | `title` | string | 是 | 菜单名称 |
217
- | `order` | number | 否 | 排序权重,越小越靠前 |
218
-
219
- ### 目录结构
220
-
221
- ```
222
- views/
223
- ├── index/ # 首页
224
- │ ├── index.vue
225
- │ └── index.vue # definePage({ meta: { title: "首页", order: 1 } })
226
- ├── user/ # 用户管理(父菜单)
227
- │ ├── index.vue # definePage({ meta: { title: "用户管理", order: 10 } })
228
- │ ├── list/ # 用户列表(子菜单)
229
- │ │ └── index.vue # definePage({ meta: { title: "用户列表", order: 1 } })
230
- │ └── detail/ # 用户详情(子菜单)
231
- │ └── index.vue # definePage({ meta: { title: "用户详情", order: 2 } })
232
- └── setting/ # 系统设置
233
- └── index.vue # definePage({ meta: { title: "系统设置", order: 99 } })
234
- ```
235
-
236
- ### 同步逻辑
237
-
238
- ```
239
- ┌─────────────────────────────────────────────────────┐
240
- │ syncMenu │
241
- ├─────────────────────────────────────────────────────┤
242
- │ 1. 扫描 views 目录: │
243
- │ - 项目:tpl/views/ │
244
- │ - Addon:addons/*/views/ │
245
- │ ↓ │
246
- │ 2. 读取每个目录 index.vue 的 definePage(meta) 配置 │
247
- │ ↓ │
248
- │ 3. 构建菜单树(父子关系由目录层级决定) │
249
- │ ↓ │
250
- │ 4. 过滤隐藏菜单(hidden: true) │
251
- │ ↓ │
252
- │ 5. 同步到 addon_admin_menu 表: │
253
- │ - 新增不存在的菜单 │
254
- │ - 更新已存在的菜单 │
255
- │ - 删除代码中已移除的菜单 │
256
- └─────────────────────────────────────────────────────┘
257
- ```
258
-
259
- ### 统计信息
260
-
261
- ```typescript
262
- interface SyncMenuStats {
263
- totalMenus: number; // 菜单总数
264
- parentMenus: number; // 父菜单数量
265
- childMenus: number; // 子菜单数量
266
- created: number; // 新增数量
267
- updated: number; // 更新数量
268
- deleted: number; // 删除数量
269
- }
270
- ```
271
-
272
- ---
273
-
274
- ## syncDev 开发账户同步
275
-
276
- 创建开发环境的管理员账户和角色。
277
-
278
- ### 基本用法
279
-
280
- 同 `syncApi`,通常由启动流程统一触发。
281
-
282
- ### 同步逻辑
283
-
284
- ```
285
- ┌─────────────────────────────────────────────────────┐
286
- │ syncDev │
287
- ├─────────────────────────────────────────────────────┤
288
- │ 1. 创建/更新开发角色: │
289
- │ - 角色名称:开发者 │
290
- │ - 角色标识:dev │
291
- │ - 权限:所有菜单 + 所有 API │
292
- │ ↓ │
293
- │ 2. 获取所有菜单 path 列表 │
294
- │ ↓ │
295
- │ 3. 获取所有 API routePath 列表 │
296
- │ ↓ │
297
- │ 4. 更新角色权限: │
298
- │ - menus: 所有菜单 path(字符串数组) │
299
- │ - apis: 所有 API routePath(pathname 字符串数组)│
300
- │ ↓ │
301
- │ 5. 创建/更新开发管理员: │
302
- │ - 用户名:dev │
303
- │ - 密码:从配置读取 │
304
- │ - 角色:开发者角色 │
305
- └─────────────────────────────────────────────────────┘
306
- ```
307
-
308
- ### 配置说明
309
-
310
- 开发账户配置在 `befly.config.ts` 或环境配置文件中(仅当 `devPassword` 有值时才会创建 dev 账号):
311
-
312
- ```json
313
- {
314
- "devEmail": "dev@qq.com",
315
- "devPassword": "beflydev123456"
316
- }
317
- ```
318
-
319
- > 注意:`syncDev` 会把 `menus/apis` 写入角色表,并且 `apis` 必须是 pathname 字符串数组(严格模式下不允许 numeric id)。
320
-
321
- ---
322
-
323
- ## syncCache 缓存同步
324
-
325
- 同步缓存(统一收敛到启动流程末尾执行):
326
-
327
- - `cacheApis()`:缓存接口列表
328
- - `cacheMenus()`:缓存菜单列表
329
- - `rebuildRoleApiPermissions()`:重建角色接口权限 Set(member 为 pathname,与 method 无关)
330
-
331
- ---
332
-
333
- ## 代码调用
334
-
335
- ```typescript
336
- import { syncTable } from "./sync/syncTable.js";
337
- import { syncApi } from "./sync/syncApi.js";
338
- import { syncCache } from "./sync/syncCache.js";
339
- import { syncDev } from "./sync/syncDev.js";
340
- import { syncMenu } from "./sync/syncMenu.js";
341
- import { scanSources } from "./utils/scanSources.js";
342
- import { checkMenu } from "./checks/checkMenu.js";
343
-
344
- // 启动前/启动中手动触发同步
345
- // ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.cache / ctx.config)
346
- const sources = await scanSources();
347
- const checkedMenus = await checkMenu(sources.addons, { disableMenus: ctx.config.disableMenus || [] });
348
-
349
- await syncTable(ctx, sources.tables);
350
- await syncApi(ctx, sources.apis as any);
351
- await syncMenu(ctx, checkedMenus);
352
- await syncDev(ctx, { devEmail: ctx.config.devEmail, devPassword: ctx.config.devPassword });
353
- await syncCache(ctx);
354
- ```
355
-
356
- ---
357
-
358
- ## 表名规则
359
-
360
- ### 项目表
361
-
362
- 项目表直接使用文件名(转换为下划线格式):
363
-
364
- ```
365
- tables/user.json → user
366
- tables/userProfile.json → user_profile
367
- tables/order_item.json → order_item
368
- ```
369
-
370
- ### Addon 表
371
-
372
- Addon 表使用 `addon_{addonName}_{tableName}` 格式:
373
-
374
- ```
375
- addons/admin/tables/role.json → addon_admin_role
376
- addons/admin/tables/menu.json → addon_admin_menu
377
- addons/demo/tables/article.json → addon_demo_article
378
- ```
379
-
380
- ### 命名转换
381
-
382
- | 源文件名 | 表名 |
383
- | ------------------- | -------------- |
384
- | `user.json` | `user` |
385
- | `userProfile.json` | `user_profile` |
386
- | `UserProfile.json` | `user_profile` |
387
- | `user_profile.json` | `user_profile` |
388
-
389
- ---
390
-
391
- ## 注意事项
392
-
393
- ### 1. 执行顺序
394
-
395
- **必须按顺序执行**:`syncTable` → `syncApi` → `syncMenu` → `syncDev` → `syncCache`
396
-
397
- - `syncApi` 依赖 `addon_admin_api` 表(由 `syncTable` 创建)
398
- - `syncMenu` 依赖 `addon_admin_menu` 表(由 `syncTable` 创建)
399
- - `syncDev` 依赖角色表和权限数据(由前面命令创建)
400
-
401
- ### 2. 破坏性操作
402
-
403
- 默认模式下,`syncTable` **不会删除列**,只会:
404
-
405
- - 新增缺失的列
406
- - 修改现有列的类型/默认值
407
-
408
- 此外,`syncTable` **不会执行长度收缩等可能导致数据截断的危险变更**:
409
-
410
- - 例如:`VARCHAR(200)` → `VARCHAR(50)`
411
- - 这类变更会被跳过,并输出告警;需要手动评估并处理
412
-
413
- ### 3. 缓存清理
414
-
415
- `syncTable` 执行后会自动清理 Redis 中的表结构缓存:
416
-
417
- ```typescript
418
- // 自动清理以下缓存键
419
- CacheKeys.tableColumns(tableName); // table:columns:{tableName}
420
- ```
421
-
422
- ### 4. 连接管理
423
-
424
- `sync*` 函数本身不会负责建立连接/加载插件:
425
-
426
- - 你需要在调用前确保 `Connect.connect(...)` 已执行,并且 `Db/Redis/cache` 插件已注入到 `ctx`。
427
- - 服务启动流程已内置这套顺序(见 `packages/core/main.ts`)。
428
-
429
- ---
430
-
431
- ## FAQ
432
-
433
- ### Q: sync 命令报错 "表不存在" 怎么办?
434
-
435
- A: 确保 `syncTable()` 已先执行(服务启动时会自动执行)。`syncApi/syncMenu/syncDev` 依赖对应的表结构存在。
436
-
437
- ### Q: 为什么修改了表定义但数据库没变化?
438
-
439
- A: 检查以下几点:
440
-
441
- 1. JSON 文件语法是否正确
442
- 2. 字段定义格式是否正确
443
- 3. 是否保存了文件
444
- 4. 确认表定义文件与配置已保存
445
-
446
- ### Q: 如何处理“字段长度收缩”这类危险变更?
447
-
448
- A: `syncTable()` 会跳过长度收缩并告警;请手动评估并处理(例如先清理/截断数据,再手动执行 DDL),再重新启动服务或再次调用 `syncTable()`。
449
-
450
- ### Q: Addon 表名太长怎么办?
451
-
452
- A: Addon 表名格式为 `addon_{addonName}_{tableName}`,建议:
453
-
454
- - 使用简短的 Addon 名称
455
- - 使用简短的表名
456
- - MySQL 表名限制 64 字符
457
-
458
- ### Q: 同步失败后如何恢复?
459
-
460
- A:
461
-
462
- 1. 检查错误日志确定失败原因(例如表不存在、字段变更被跳过等)
463
- 2. sync 命令是幂等的,可以安全地多次执行
464
-
465
- ### Q: 如何只同步某个 Addon 的表?
466
-
467
- A: 当前不支持按 Addon 或单表筛选;会同步项目与所有 Addon 的表定义。
468
-
469
- ### Q: 开发账户密码在哪里配置?
470
-
471
- A: 在配置文件中设置(仅当 `devPassword` 有值时才会创建 dev 账号):
472
-
473
- ```json
474
- {
475
- "devEmail": "dev@qq.com",
476
- "devPassword": "beflydev123456"
477
- }
478
- ```