befly 3.9.38 → 3.9.40
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.
- package/README.md +37 -38
- package/befly.config.ts +62 -40
- package/checks/checkApi.ts +16 -16
- package/checks/checkApp.ts +19 -25
- package/checks/checkTable.ts +42 -42
- package/docs/README.md +42 -35
- package/docs/{api.md → api/api.md} +223 -231
- package/docs/cipher.md +71 -69
- package/docs/database.md +143 -141
- package/docs/{examples.md → guide/examples.md} +181 -181
- package/docs/guide/quickstart.md +331 -0
- package/docs/hooks/auth.md +38 -0
- package/docs/hooks/cors.md +28 -0
- package/docs/{hook.md → hooks/hook.md} +140 -57
- package/docs/hooks/parser.md +19 -0
- package/docs/hooks/rateLimit.md +47 -0
- package/docs/{redis.md → infra/redis.md} +84 -93
- package/docs/plugins/cipher.md +61 -0
- package/docs/plugins/database.md +128 -0
- package/docs/{plugin.md → plugins/plugin.md} +83 -81
- package/docs/quickstart.md +26 -26
- package/docs/{addon.md → reference/addon.md} +46 -46
- package/docs/{config.md → reference/config.md} +32 -80
- package/docs/{logger.md → reference/logger.md} +52 -52
- package/docs/{sync.md → reference/sync.md} +32 -35
- package/docs/{table.md → reference/table.md} +1 -1
- package/docs/{validator.md → reference/validator.md} +57 -57
- package/hooks/auth.ts +8 -4
- package/hooks/cors.ts +13 -13
- package/hooks/parser.ts +37 -17
- package/hooks/permission.ts +26 -14
- package/hooks/rateLimit.ts +276 -0
- package/hooks/validator.ts +8 -8
- package/lib/asyncContext.ts +43 -0
- package/lib/cacheHelper.ts +212 -77
- package/lib/cacheKeys.ts +38 -0
- package/lib/cipher.ts +30 -30
- package/lib/connect.ts +28 -28
- package/lib/dbHelper.ts +183 -102
- package/lib/jwt.ts +16 -16
- package/lib/logger.ts +610 -19
- package/lib/redisHelper.ts +185 -44
- package/lib/sqlBuilder.ts +90 -91
- package/lib/validator.ts +59 -39
- package/loader/loadApis.ts +48 -44
- package/loader/loadHooks.ts +40 -14
- package/loader/loadPlugins.ts +16 -17
- package/main.ts +57 -47
- package/package.json +47 -45
- package/paths.ts +15 -14
- package/plugins/cache.ts +5 -4
- package/plugins/cipher.ts +3 -3
- package/plugins/config.ts +2 -2
- package/plugins/db.ts +9 -9
- package/plugins/jwt.ts +3 -3
- package/plugins/logger.ts +8 -12
- package/plugins/redis.ts +8 -8
- package/plugins/tool.ts +6 -6
- package/router/api.ts +85 -56
- package/router/static.ts +12 -12
- package/sync/syncAll.ts +12 -12
- package/sync/syncApi.ts +55 -52
- package/sync/syncDb/apply.ts +20 -19
- package/sync/syncDb/constants.ts +25 -23
- package/sync/syncDb/ddl.ts +35 -36
- package/sync/syncDb/helpers.ts +6 -9
- package/sync/syncDb/schema.ts +10 -9
- package/sync/syncDb/sqlite.ts +7 -8
- package/sync/syncDb/table.ts +37 -35
- package/sync/syncDb/tableCreate.ts +21 -20
- package/sync/syncDb/types.ts +23 -20
- package/sync/syncDb/version.ts +10 -10
- package/sync/syncDb.ts +43 -36
- package/sync/syncDev.ts +74 -65
- package/sync/syncMenu.ts +190 -55
- package/tests/api-integration-array-number.test.ts +282 -0
- package/tests/befly-config-env.test.ts +78 -0
- package/tests/cacheHelper.test.ts +135 -104
- package/tests/cacheKeys.test.ts +41 -0
- package/tests/cipher.test.ts +90 -89
- package/tests/dbHelper-advanced.test.ts +140 -134
- package/tests/dbHelper-all-array-types.test.ts +316 -0
- package/tests/dbHelper-array-serialization.test.ts +258 -0
- package/tests/dbHelper-columns.test.ts +56 -55
- package/tests/dbHelper-execute.test.ts +45 -44
- package/tests/dbHelper-joins.test.ts +124 -119
- package/tests/fields-redis-cache.test.ts +29 -27
- package/tests/fields-validate.test.ts +38 -38
- package/tests/getClientIp.test.ts +54 -0
- package/tests/integration.test.ts +69 -67
- package/tests/jwt.test.ts +27 -26
- package/tests/logger.test.ts +267 -34
- package/tests/rateLimit-hook.test.ts +477 -0
- package/tests/redisHelper.test.ts +187 -188
- package/tests/redisKeys.test.ts +6 -73
- package/tests/scanConfig.test.ts +144 -0
- package/tests/sqlBuilder-advanced.test.ts +217 -215
- package/tests/sqlBuilder.test.ts +92 -91
- package/tests/sync-connection.test.ts +29 -29
- package/tests/syncDb-apply.test.ts +97 -96
- package/tests/syncDb-array-number.test.ts +160 -0
- package/tests/syncDb-constants.test.ts +48 -47
- package/tests/syncDb-ddl.test.ts +99 -98
- package/tests/syncDb-helpers.test.ts +29 -28
- package/tests/syncDb-schema.test.ts +61 -60
- package/tests/syncDb-types.test.ts +60 -59
- package/tests/syncMenu-paths.test.ts +68 -0
- package/tests/util.test.ts +42 -41
- package/tests/validator-array-number.test.ts +310 -0
- package/tests/validator-default.test.ts +373 -0
- package/tests/validator.test.ts +271 -266
- package/tsconfig.json +4 -5
- package/types/api.d.ts +7 -12
- package/types/befly.d.ts +60 -13
- package/types/cache.d.ts +8 -4
- package/types/common.d.ts +17 -9
- package/types/context.d.ts +2 -2
- package/types/crypto.d.ts +23 -0
- package/types/database.d.ts +19 -19
- package/types/hook.d.ts +2 -2
- package/types/jwt.d.ts +118 -0
- package/types/logger.d.ts +30 -0
- package/types/plugin.d.ts +4 -4
- package/types/redis.d.ts +7 -3
- package/types/roleApisCache.ts +23 -0
- package/types/sync.d.ts +10 -10
- package/types/table.d.ts +50 -9
- package/types/validate.d.ts +69 -0
- package/utils/addonHelper.ts +90 -0
- package/utils/arrayKeysToCamel.ts +18 -0
- package/utils/calcPerfTime.ts +13 -0
- package/utils/configTypes.ts +3 -0
- package/utils/cors.ts +19 -0
- package/utils/fieldClear.ts +75 -0
- package/utils/genShortId.ts +12 -0
- package/utils/getClientIp.ts +45 -0
- package/utils/keysToCamel.ts +22 -0
- package/utils/keysToSnake.ts +22 -0
- package/utils/modules.ts +98 -0
- package/utils/pickFields.ts +19 -0
- package/utils/process.ts +56 -0
- package/utils/regex.ts +225 -0
- package/utils/response.ts +115 -0
- package/utils/route.ts +23 -0
- package/utils/scanConfig.ts +142 -0
- package/utils/scanFiles.ts +48 -0
- package/.prettierignore +0 -2
- package/.prettierrc +0 -12
- package/docs/1-/345/237/272/346/234/254/344/273/213/347/273/215.md +0 -35
- package/docs/2-/345/210/235/346/255/245/344/275/223/351/252/214.md +0 -64
- package/docs/3-/347/254/254/344/270/200/344/270/252/346/216/245/345/217/243.md +0 -46
- package/docs/4-/346/223/215/344/275/234/346/225/260/346/215/256/345/272/223.md +0 -172
- package/hooks/requestLogger.ts +0 -84
- package/types/index.ts +0 -24
- package/util.ts +0 -283
|
@@ -57,7 +57,7 @@ interface LoggerConfig {
|
|
|
57
57
|
在配置文件中设置:
|
|
58
58
|
|
|
59
59
|
```json
|
|
60
|
-
// befly.
|
|
60
|
+
// befly.development.json
|
|
61
61
|
{
|
|
62
62
|
"logger": {
|
|
63
63
|
"debug": 1,
|
|
@@ -69,7 +69,7 @@ interface LoggerConfig {
|
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
```json
|
|
72
|
-
// befly.
|
|
72
|
+
// befly.production.json
|
|
73
73
|
{
|
|
74
74
|
"logger": {
|
|
75
75
|
"debug": 0,
|
|
@@ -87,27 +87,27 @@ interface LoggerConfig {
|
|
|
87
87
|
### 导入 Logger
|
|
88
88
|
|
|
89
89
|
```typescript
|
|
90
|
-
import { Logger } from
|
|
90
|
+
import { Logger } from "../lib/logger.js";
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
### 日志方法
|
|
94
94
|
|
|
95
95
|
```typescript
|
|
96
96
|
// 信息日志
|
|
97
|
-
Logger.info(
|
|
98
|
-
Logger.info({ userId: 123 },
|
|
97
|
+
Logger.info("用户登录成功");
|
|
98
|
+
Logger.info({ userId: 123 }, "用户登录成功");
|
|
99
99
|
|
|
100
100
|
// 警告日志
|
|
101
|
-
Logger.warn(
|
|
102
|
-
Logger.warn({ config:
|
|
101
|
+
Logger.warn("配置项已弃用");
|
|
102
|
+
Logger.warn({ config: "oldOption" }, "配置项已弃用");
|
|
103
103
|
|
|
104
104
|
// 错误日志
|
|
105
|
-
Logger.error(
|
|
106
|
-
Logger.error({ err: error },
|
|
105
|
+
Logger.error("数据库连接失败");
|
|
106
|
+
Logger.error({ err: error }, "数据库连接失败");
|
|
107
107
|
|
|
108
108
|
// 调试日志(仅 debug=1 时输出)
|
|
109
|
-
Logger.debug(
|
|
110
|
-
Logger.debug({ sql:
|
|
109
|
+
Logger.debug("SQL 查询");
|
|
110
|
+
Logger.debug({ sql: "SELECT * FROM user", params: [] }, "SQL 查询");
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
### 带上下文的日志
|
|
@@ -116,7 +116,7 @@ pino 风格:第一个参数为对象时作为上下文,第二个参数为消
|
|
|
116
116
|
|
|
117
117
|
```typescript
|
|
118
118
|
// 推荐:上下文 + 消息
|
|
119
|
-
Logger.info({ userId: 123, action:
|
|
119
|
+
Logger.info({ userId: 123, action: "login" }, "用户登录成功");
|
|
120
120
|
|
|
121
121
|
// 输出:
|
|
122
122
|
// {"level":30,"time":1234567890,"userId":123,"action":"login","msg":"用户登录成功"}
|
|
@@ -125,7 +125,7 @@ Logger.info({ userId: 123, action: 'login' }, '用户登录成功');
|
|
|
125
125
|
try {
|
|
126
126
|
await riskyOperation();
|
|
127
127
|
} catch (error) {
|
|
128
|
-
Logger.error({ err: error },
|
|
128
|
+
Logger.error({ err: error }, "操作失败");
|
|
129
129
|
}
|
|
130
130
|
```
|
|
131
131
|
|
|
@@ -135,7 +135,7 @@ try {
|
|
|
135
135
|
// 手动配置(通常由插件自动完成)
|
|
136
136
|
Logger.configure({
|
|
137
137
|
debug: 1,
|
|
138
|
-
dir:
|
|
138
|
+
dir: "./custom-logs",
|
|
139
139
|
console: 1,
|
|
140
140
|
maxSize: 20
|
|
141
141
|
});
|
|
@@ -163,13 +163,13 @@ Logger.configure({
|
|
|
163
163
|
|
|
164
164
|
```typescript
|
|
165
165
|
// debug=0 时
|
|
166
|
-
Logger.debug(
|
|
167
|
-
Logger.info(
|
|
168
|
-
Logger.error(
|
|
166
|
+
Logger.debug("这条不会输出"); // ❌ 被过滤
|
|
167
|
+
Logger.info("这条会输出"); // ✅
|
|
168
|
+
Logger.error("这条会输出"); // ✅
|
|
169
169
|
|
|
170
170
|
// debug=1 时
|
|
171
|
-
Logger.debug(
|
|
172
|
-
Logger.info(
|
|
171
|
+
Logger.debug("这条会输出"); // ✅
|
|
172
|
+
Logger.info("这条会输出"); // ✅
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
---
|
|
@@ -284,11 +284,11 @@ const loggerPlugin: Plugin = {
|
|
|
284
284
|
```typescript
|
|
285
285
|
// 在 API handler 中
|
|
286
286
|
export default {
|
|
287
|
-
name:
|
|
287
|
+
name: "示例接口",
|
|
288
288
|
handler: async (befly, ctx) => {
|
|
289
|
-
befly.logger.info(
|
|
290
|
-
befly.logger.debug({ body: ctx.body },
|
|
291
|
-
return Yes(
|
|
289
|
+
befly.logger.info("处理请求");
|
|
290
|
+
befly.logger.debug({ body: ctx.body }, "请求参数");
|
|
291
|
+
return Yes("成功");
|
|
292
292
|
}
|
|
293
293
|
} as ApiRoute;
|
|
294
294
|
```
|
|
@@ -297,9 +297,9 @@ export default {
|
|
|
297
297
|
|
|
298
298
|
```typescript
|
|
299
299
|
// 直接导入使用
|
|
300
|
-
import { Logger } from
|
|
300
|
+
import { Logger } from "../lib/logger.js";
|
|
301
301
|
|
|
302
|
-
Logger.info(
|
|
302
|
+
Logger.info("直接使用");
|
|
303
303
|
```
|
|
304
304
|
|
|
305
305
|
---
|
|
@@ -311,17 +311,17 @@ Logger.info('直接使用');
|
|
|
311
311
|
测试时可以设置 Mock 实例:
|
|
312
312
|
|
|
313
313
|
```typescript
|
|
314
|
-
import { Logger, setMockLogger } from
|
|
315
|
-
import pino from
|
|
314
|
+
import { Logger, setMockLogger } from "../lib/logger.js";
|
|
315
|
+
import pino from "pino";
|
|
316
316
|
|
|
317
317
|
// 创建 mock logger
|
|
318
|
-
const mockLogger = pino({ level:
|
|
318
|
+
const mockLogger = pino({ level: "silent" });
|
|
319
319
|
|
|
320
320
|
// 设置 mock
|
|
321
321
|
setMockLogger(mockLogger);
|
|
322
322
|
|
|
323
323
|
// 测试代码...
|
|
324
|
-
Logger.info(
|
|
324
|
+
Logger.info("这条日志会被 mock 处理");
|
|
325
325
|
|
|
326
326
|
// 清除 mock
|
|
327
327
|
setMockLogger(null);
|
|
@@ -330,17 +330,17 @@ setMockLogger(null);
|
|
|
330
330
|
### 测试示例
|
|
331
331
|
|
|
332
332
|
```typescript
|
|
333
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from
|
|
334
|
-
import { Logger, setMockLogger } from
|
|
335
|
-
import pino from
|
|
333
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
334
|
+
import { Logger, setMockLogger } from "../lib/logger.js";
|
|
335
|
+
import pino from "pino";
|
|
336
336
|
|
|
337
|
-
describe(
|
|
337
|
+
describe("Logger", () => {
|
|
338
338
|
let mockLogger: pino.Logger;
|
|
339
339
|
let infoSpy: any;
|
|
340
340
|
|
|
341
341
|
beforeEach(() => {
|
|
342
|
-
mockLogger = pino({ level:
|
|
343
|
-
infoSpy = vi.spyOn(mockLogger,
|
|
342
|
+
mockLogger = pino({ level: "debug" });
|
|
343
|
+
infoSpy = vi.spyOn(mockLogger, "info");
|
|
344
344
|
setMockLogger(mockLogger);
|
|
345
345
|
});
|
|
346
346
|
|
|
@@ -348,9 +348,9 @@ describe('Logger', () => {
|
|
|
348
348
|
setMockLogger(null);
|
|
349
349
|
});
|
|
350
350
|
|
|
351
|
-
it(
|
|
352
|
-
Logger.info(
|
|
353
|
-
expect(infoSpy).toHaveBeenCalledWith(
|
|
351
|
+
it("should log info message", () => {
|
|
352
|
+
Logger.info("test message");
|
|
353
|
+
expect(infoSpy).toHaveBeenCalledWith("test message");
|
|
354
354
|
});
|
|
355
355
|
});
|
|
356
356
|
```
|
|
@@ -363,7 +363,7 @@ describe('Logger', () => {
|
|
|
363
363
|
|
|
364
364
|
```typescript
|
|
365
365
|
// ✅ 推荐:结构化上下文
|
|
366
|
-
Logger.info({ userId: 123, action:
|
|
366
|
+
Logger.info({ userId: 123, action: "login", ip: "192.168.1.1" }, "用户登录");
|
|
367
367
|
|
|
368
368
|
// ❌ 避免:字符串拼接
|
|
369
369
|
Logger.info(`用户 ${userId} 从 ${ip} 登录`);
|
|
@@ -376,7 +376,7 @@ try {
|
|
|
376
376
|
await riskyOperation();
|
|
377
377
|
} catch (error) {
|
|
378
378
|
// ✅ 使用 err 属性保留完整错误信息
|
|
379
|
-
Logger.error({ err: error },
|
|
379
|
+
Logger.error({ err: error }, "操作失败");
|
|
380
380
|
|
|
381
381
|
// ❌ 避免:只记录消息
|
|
382
382
|
Logger.error(`操作失败: ${error.message}`);
|
|
@@ -387,32 +387,32 @@ try {
|
|
|
387
387
|
|
|
388
388
|
```typescript
|
|
389
389
|
// debug: 开发调试信息
|
|
390
|
-
Logger.debug({ sql: query, params: params },
|
|
390
|
+
Logger.debug({ sql: query, params: params }, "SQL 查询");
|
|
391
391
|
|
|
392
392
|
// info: 正常业务操作
|
|
393
|
-
Logger.info({ userId: 123 },
|
|
393
|
+
Logger.info({ userId: 123 }, "用户登录成功");
|
|
394
394
|
|
|
395
395
|
// warn: 潜在问题,但不影响功能
|
|
396
|
-
Logger.warn({ config:
|
|
396
|
+
Logger.warn({ config: "deprecated" }, "配置项已弃用");
|
|
397
397
|
|
|
398
398
|
// error: 操作失败
|
|
399
|
-
Logger.error({ err: error },
|
|
399
|
+
Logger.error({ err: error }, "数据库连接失败");
|
|
400
400
|
```
|
|
401
401
|
|
|
402
402
|
### 4. 不要记录敏感信息
|
|
403
403
|
|
|
404
404
|
```typescript
|
|
405
405
|
// ❌ 避免:记录密码、token 等
|
|
406
|
-
Logger.info({ password: user.password },
|
|
406
|
+
Logger.info({ password: user.password }, "用户信息");
|
|
407
407
|
|
|
408
408
|
// ✅ 推荐:只记录必要信息
|
|
409
|
-
Logger.info({ userId: user.id, email: user.email },
|
|
409
|
+
Logger.info({ userId: user.id, email: user.email }, "用户信息");
|
|
410
410
|
```
|
|
411
411
|
|
|
412
412
|
### 5. 生产环境关闭控制台
|
|
413
413
|
|
|
414
414
|
```json
|
|
415
|
-
// befly.
|
|
415
|
+
// befly.production.json
|
|
416
416
|
{
|
|
417
417
|
"logger": {
|
|
418
418
|
"debug": 0,
|
|
@@ -464,11 +464,11 @@ A: 可以创建 child logger:
|
|
|
464
464
|
|
|
465
465
|
```typescript
|
|
466
466
|
const childLogger = getLogger().child({
|
|
467
|
-
service:
|
|
468
|
-
version:
|
|
467
|
+
service: "user-service",
|
|
468
|
+
version: "1.0.0"
|
|
469
469
|
});
|
|
470
470
|
|
|
471
|
-
childLogger.info(
|
|
471
|
+
childLogger.info("所有日志都会包含 service 和 version");
|
|
472
472
|
```
|
|
473
473
|
|
|
474
474
|
### Q: 日志没有输出怎么排查?
|
|
@@ -485,8 +485,8 @@ A: 检查以下几点:
|
|
|
485
485
|
A: 使用 `setMockLogger` 设置 mock 实例,然后用 spy 捕获调用:
|
|
486
486
|
|
|
487
487
|
```typescript
|
|
488
|
-
const mockLogger = pino({ level:
|
|
489
|
-
const spy = vi.spyOn(mockLogger,
|
|
488
|
+
const mockLogger = pino({ level: "debug" });
|
|
489
|
+
const spy = vi.spyOn(mockLogger, "info");
|
|
490
490
|
setMockLogger(mockLogger);
|
|
491
491
|
|
|
492
492
|
// 执行测试...
|
|
@@ -224,7 +224,7 @@ interface SyncApiStats {
|
|
|
224
224
|
|
|
225
225
|
## syncMenu 菜单同步
|
|
226
226
|
|
|
227
|
-
将 `views
|
|
227
|
+
将 `views/**/index.vue` 中的 `definePage({ meta })` 菜单配置同步到 `addon_admin_menu` 表。
|
|
228
228
|
|
|
229
229
|
### 基本用法
|
|
230
230
|
|
|
@@ -244,24 +244,25 @@ befly sync:menu --plan
|
|
|
244
244
|
|
|
245
245
|
### 菜单配置文件
|
|
246
246
|
|
|
247
|
-
在 `views/{menuName}/
|
|
247
|
+
在 `views/{menuName}/index.vue` 中用 `definePage()` 定义菜单:
|
|
248
248
|
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
249
|
+
```vue
|
|
250
|
+
<script setup>
|
|
251
|
+
definePage({
|
|
252
|
+
meta: {
|
|
253
|
+
title: "用户管理",
|
|
254
|
+
order: 10
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
</script>
|
|
255
258
|
```
|
|
256
259
|
|
|
257
260
|
**配置字段**:
|
|
258
261
|
|
|
259
|
-
| 字段
|
|
260
|
-
|
|
|
261
|
-
| `
|
|
262
|
-
| `
|
|
263
|
-
| `sort` | number | 否 | 排序权重,越小越靠前 |
|
|
264
|
-
| `hidden` | boolean | 否 | 是否隐藏(不同步到数据库) |
|
|
262
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
263
|
+
| ------- | ------ | ---- | -------------------- |
|
|
264
|
+
| `title` | string | 是 | 菜单名称 |
|
|
265
|
+
| `order` | number | 否 | 排序权重,越小越靠前 |
|
|
265
266
|
|
|
266
267
|
### 目录结构
|
|
267
268
|
|
|
@@ -269,19 +270,15 @@ befly sync:menu --plan
|
|
|
269
270
|
views/
|
|
270
271
|
├── index/ # 首页
|
|
271
272
|
│ ├── index.vue
|
|
272
|
-
│ └──
|
|
273
|
+
│ └── index.vue # definePage({ meta: { title: "首页", order: 1 } })
|
|
273
274
|
├── user/ # 用户管理(父菜单)
|
|
274
|
-
│ ├──
|
|
275
|
-
│ ├── meta.json # { "name": "用户管理", "icon": "Users", "sort": 10 }
|
|
275
|
+
│ ├── index.vue # definePage({ meta: { title: "用户管理", order: 10 } })
|
|
276
276
|
│ ├── list/ # 用户列表(子菜单)
|
|
277
|
-
│ │
|
|
278
|
-
│ │ └── meta.json # { "name": "用户列表", "sort": 1 }
|
|
277
|
+
│ │ └── index.vue # definePage({ meta: { title: "用户列表", order: 1 } })
|
|
279
278
|
│ └── detail/ # 用户详情(子菜单)
|
|
280
|
-
│
|
|
281
|
-
│ └── meta.json # { "name": "用户详情", "sort": 2 }
|
|
279
|
+
│ └── index.vue # definePage({ meta: { title: "用户详情", order: 2 } })
|
|
282
280
|
└── setting/ # 系统设置
|
|
283
|
-
|
|
284
|
-
└── meta.json # { "name": "系统设置", "icon": "Settings", "sort": 99 }
|
|
281
|
+
└── index.vue # definePage({ meta: { title: "系统设置", order: 99 } })
|
|
285
282
|
```
|
|
286
283
|
|
|
287
284
|
### 同步逻辑
|
|
@@ -294,7 +291,7 @@ views/
|
|
|
294
291
|
│ - 项目:tpl/views/ │
|
|
295
292
|
│ - Addon:addons/*/views/ │
|
|
296
293
|
│ ↓ │
|
|
297
|
-
│ 2.
|
|
294
|
+
│ 2. 读取每个目录 index.vue 的 definePage(meta) 配置 │
|
|
298
295
|
│ ↓ │
|
|
299
296
|
│ 3. 构建菜单树(父子关系由目录层级决定) │
|
|
300
297
|
│ ↓ │
|
|
@@ -376,8 +373,8 @@ befly sync:dev --plan
|
|
|
376
373
|
// befly.config.ts
|
|
377
374
|
export default {
|
|
378
375
|
dev: {
|
|
379
|
-
username:
|
|
380
|
-
password:
|
|
376
|
+
username: "dev", // 开发账户用户名
|
|
377
|
+
password: "dev123456" // 开发账户密码
|
|
381
378
|
}
|
|
382
379
|
};
|
|
383
380
|
```
|
|
@@ -412,17 +409,17 @@ befly sync:dev --plan # 预览开发账户变更
|
|
|
412
409
|
### 代码调用
|
|
413
410
|
|
|
414
411
|
```typescript
|
|
415
|
-
import { syncAllCommand } from
|
|
416
|
-
import { syncDbCommand } from
|
|
417
|
-
import { syncApiCommand } from
|
|
418
|
-
import { syncMenuCommand } from
|
|
419
|
-
import { syncDevCommand } from
|
|
412
|
+
import { syncAllCommand } from "./sync/syncAll";
|
|
413
|
+
import { syncDbCommand } from "./sync/syncDb";
|
|
414
|
+
import { syncApiCommand } from "./sync/syncApi";
|
|
415
|
+
import { syncMenuCommand } from "./sync/syncMenu";
|
|
416
|
+
import { syncDevCommand } from "./sync/syncDev";
|
|
420
417
|
|
|
421
418
|
// 全量同步
|
|
422
419
|
await syncAllCommand();
|
|
423
420
|
|
|
424
421
|
// 单独调用
|
|
425
|
-
await syncDbCommand({ table:
|
|
422
|
+
await syncDbCommand({ table: "user" });
|
|
426
423
|
await syncApiCommand({ plan: true });
|
|
427
424
|
await syncMenuCommand({ plan: true });
|
|
428
425
|
await syncDevCommand({ plan: true });
|
|
@@ -493,7 +490,7 @@ befly sync:db --force
|
|
|
493
490
|
|
|
494
491
|
```typescript
|
|
495
492
|
// 自动清理以下缓存键
|
|
496
|
-
|
|
493
|
+
CacheKeys.tableColumns(tableName); // table:columns:{tableName}
|
|
497
494
|
```
|
|
498
495
|
|
|
499
496
|
### 4. 连接管理
|
|
@@ -573,8 +570,8 @@ A: 在配置文件中设置:
|
|
|
573
570
|
// befly.config.ts
|
|
574
571
|
export default {
|
|
575
572
|
dev: {
|
|
576
|
-
username:
|
|
577
|
-
password:
|
|
573
|
+
username: "dev",
|
|
574
|
+
password: "your_password"
|
|
578
575
|
}
|
|
579
576
|
};
|
|
580
577
|
```
|
|
@@ -95,7 +95,7 @@ interface FieldDefinition {
|
|
|
95
95
|
/** 字段标签/描述(必填) */
|
|
96
96
|
name: string;
|
|
97
97
|
/** 字段类型(必填) */
|
|
98
|
-
type:
|
|
98
|
+
type: "string" | "number" | "text" | "array_string" | "array_text";
|
|
99
99
|
/** 字段详细说明 */
|
|
100
100
|
detail?: string;
|
|
101
101
|
/** 最小值/最小长度 */
|