befly 3.10.0 → 3.10.1
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 +10 -13
- package/docs/README.md +17 -11
- package/docs/api/api.md +15 -1
- package/docs/guide/quickstart.md +19 -5
- package/docs/infra/redis.md +23 -11
- package/docs/quickstart.md +5 -335
- package/docs/reference/addon.md +0 -15
- package/docs/reference/config.md +1 -1
- package/docs/reference/logger.md +3 -3
- package/docs/reference/sync.md +99 -73
- package/docs/reference/table.md +1 -1
- package/package.json +3 -3
- package/docs/cipher.md +0 -582
- package/docs/database.md +0 -1176
package/README.md
CHANGED
|
@@ -220,7 +220,7 @@ export const beflyConfig = {
|
|
|
220
220
|
redis: {
|
|
221
221
|
host: "127.0.0.1",
|
|
222
222
|
port: 6379,
|
|
223
|
-
prefix: "befly
|
|
223
|
+
prefix: "befly"
|
|
224
224
|
},
|
|
225
225
|
|
|
226
226
|
// CORS 跨域配置
|
|
@@ -238,6 +238,8 @@ export const beflyConfig = {
|
|
|
238
238
|
};
|
|
239
239
|
```
|
|
240
240
|
|
|
241
|
+
> 注意:`redis.prefix` 不要包含 `:`(系统会自动拼接分隔符)。
|
|
242
|
+
|
|
241
243
|
### 数据库连接
|
|
242
244
|
|
|
243
245
|
通常你不需要手动连接(框架启动期会完成连接并注入插件实例)。
|
|
@@ -263,7 +265,7 @@ await Connect.connectRedis({
|
|
|
263
265
|
host: "127.0.0.1",
|
|
264
266
|
port: 6379,
|
|
265
267
|
db: 0,
|
|
266
|
-
prefix: "befly
|
|
268
|
+
prefix: "befly"
|
|
267
269
|
});
|
|
268
270
|
|
|
269
271
|
// 或:同时连接 SQL 和 Redis
|
|
@@ -281,7 +283,7 @@ await Connect.connect({
|
|
|
281
283
|
host: "127.0.0.1",
|
|
282
284
|
port: 6379,
|
|
283
285
|
db: 0,
|
|
284
|
-
prefix: "befly
|
|
286
|
+
prefix: "befly"
|
|
285
287
|
}
|
|
286
288
|
});
|
|
287
289
|
|
|
@@ -294,19 +296,14 @@ console.log(status.redis.connected); // true/false
|
|
|
294
296
|
await Connect.disconnect();
|
|
295
297
|
```
|
|
296
298
|
|
|
297
|
-
###
|
|
298
|
-
|
|
299
|
-
如果你的项目之前使用 `app.config.ts`,请按以下步骤迁移:
|
|
299
|
+
### 配置文件(当前约定)
|
|
300
300
|
|
|
301
|
-
|
|
302
|
-
2. **更新导出名**:`config` → `beflyConfig`
|
|
301
|
+
配置文件名为 `befly.config.ts`,导出名为 `beflyConfig`:
|
|
303
302
|
|
|
304
303
|
```typescript
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
// 新写法
|
|
309
|
-
export const beflyConfig = { ... };
|
|
304
|
+
export const beflyConfig = {
|
|
305
|
+
// ...
|
|
306
|
+
};
|
|
310
307
|
```
|
|
311
308
|
|
|
312
309
|
## 📖 文档
|
package/docs/README.md
CHANGED
|
@@ -2,18 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
> Befly 是基于 Bun 的高性能 API 框架
|
|
4
4
|
|
|
5
|
+
## 文档原则
|
|
6
|
+
|
|
7
|
+
- 文档只描述**当前实现**:不提供迁移指引、不保留兼容说明、不出现“已迁移/跳转页/占位页”。
|
|
8
|
+
- 如文档与代码行为不一致:**以代码为准**,应直接修正文档。
|
|
9
|
+
- 规则以“可执行/可验证”为标准:给出明确约束(例如 pathname-only、严格校验规则),避免含糊表述。
|
|
10
|
+
|
|
5
11
|
## 快速开始
|
|
6
12
|
|
|
7
13
|
- [Quickstart 快速入门](./guide/quickstart.md) - 5 分钟搭建第一个 API 服务
|
|
8
14
|
|
|
9
15
|
## 核心概念
|
|
10
16
|
|
|
11
|
-
| 文档 | 说明
|
|
12
|
-
| ---------------------------------------- |
|
|
13
|
-
| [API 开发](./api/api.md) | API
|
|
14
|
-
| [Table 表结构](./reference/table.md) | JSON 表定义格式、字段类型
|
|
15
|
-
| [Database 数据库](./plugins/database.md) | CRUD 操作、事务、批量操作
|
|
16
|
-
| [Config 配置](./reference/config.md) | 配置文件、环境分离
|
|
17
|
+
| 文档 | 说明 |
|
|
18
|
+
| ---------------------------------------- | --------------------------------------------------------------------- |
|
|
19
|
+
| [API 开发](./api/api.md) | API 定义、字段验证、权限控制([强约束清单](./api/api.md#强约束清单)) |
|
|
20
|
+
| [Table 表结构](./reference/table.md) | JSON 表定义格式、字段类型 |
|
|
21
|
+
| [Database 数据库](./plugins/database.md) | CRUD 操作、事务、批量操作 |
|
|
22
|
+
| [Config 配置](./reference/config.md) | 配置文件、环境分离 |
|
|
17
23
|
|
|
18
24
|
## 扩展开发
|
|
19
25
|
|
|
@@ -41,9 +47,9 @@
|
|
|
41
47
|
|
|
42
48
|
## 命令工具
|
|
43
49
|
|
|
44
|
-
| 文档 | 说明
|
|
45
|
-
| -------------------------------- |
|
|
46
|
-
| [Sync 同步](./reference/sync.md) | 数据库、API
|
|
50
|
+
| 文档 | 说明 |
|
|
51
|
+
| -------------------------------- | --------------------------------------------------------------------- |
|
|
52
|
+
| [Sync 同步](./reference/sync.md) | 数据库、API、菜单同步([强约束清单](./reference/sync.md#强约束清单)) |
|
|
47
53
|
|
|
48
54
|
## 实战示例
|
|
49
55
|
|
|
@@ -57,7 +63,7 @@
|
|
|
57
63
|
|
|
58
64
|
### 开发篇
|
|
59
65
|
|
|
60
|
-
2. **[API](./api/api.md)** - API
|
|
66
|
+
2. **[API](./api/api.md)** - API 路由定义、字段验证、权限控制、响应格式([强约束清单](./api/api.md#强约束清单))
|
|
61
67
|
3. **[Table](./reference/table.md)** - 表定义格式、字段类型、系统字段、命名规范
|
|
62
68
|
4. **[Database](./plugins/database.md)** - 数据库连接、CRUD 操作、事务处理、批量操作
|
|
63
69
|
5. **[Config](./reference/config.md)** - 配置文件结构、环境分离、运行时配置
|
|
@@ -77,7 +83,7 @@
|
|
|
77
83
|
|
|
78
84
|
### 运维篇
|
|
79
85
|
|
|
80
|
-
13. **[Sync](./reference/sync.md)** - syncTable、
|
|
86
|
+
13. **[Sync](./reference/sync.md)** - syncTable、syncApi、syncMenu、syncDev、syncCache([强约束清单](./reference/sync.md#强约束清单))
|
|
81
87
|
|
|
82
88
|
## 常用链接
|
|
83
89
|
|
package/docs/api/api.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
- [目录](#目录)
|
|
9
9
|
- [概述](#概述)
|
|
10
10
|
- [核心特性](#核心特性)
|
|
11
|
+
- [强约束清单](#强约束清单)
|
|
11
12
|
- [目录结构](#目录结构-1)
|
|
12
13
|
- [项目 API](#项目-api)
|
|
13
14
|
- [Addon API](#addon-api)
|
|
@@ -78,6 +79,15 @@ Befly 框架的 API 系统是一套基于约定优于配置的接口开发体系
|
|
|
78
79
|
|
|
79
80
|
---
|
|
80
81
|
|
|
82
|
+
## 强约束清单
|
|
83
|
+
|
|
84
|
+
- **权限/路由匹配只看 pathname**:系统内部用于路由匹配与权限判断的值均为 `url.pathname`(例如 `/api/user/login`),与 method 无关。
|
|
85
|
+
- **禁止写法**:禁止把权限或路由路径写成 `POST/api/...` 或 `POST /api/...`(这些只是一种“请求行展示写法”,不能进入任何存储/配置/权限集合)。
|
|
86
|
+
- **routePath 必须严格合法**:必须以 `/api/` 开头、不得包含空格、不得出现 `/api//`。
|
|
87
|
+
- **同一路径多方法共用权限**:同一个 pathname(例如 `/api/user/login`)即使同时注册 GET/POST,也共用同一套权限集合。
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
81
91
|
## 目录结构
|
|
82
92
|
|
|
83
93
|
### 项目 API
|
|
@@ -139,7 +149,7 @@ export default {
|
|
|
139
149
|
fields: {}, // 字段定义(验证规则)
|
|
140
150
|
required: [], // 必填字段列表
|
|
141
151
|
rawBody: false // 是否保留原始请求体
|
|
142
|
-
//
|
|
152
|
+
// 缓存/限流:当前实现为 Hook 能力(见 hook 文档/配置),不再挂载在接口定义上
|
|
143
153
|
} as ApiRoute;
|
|
144
154
|
```
|
|
145
155
|
|
|
@@ -1276,6 +1286,8 @@ if (!ctx.user?.id) {
|
|
|
1276
1286
|
| `addonAdmin/apis/auth/login.ts` | `POST /api/addon/addonAdmin/auth/login` |
|
|
1277
1287
|
| `addonAdmin/apis/admin/list.ts` | `POST /api/addon/addonAdmin/admin/list` |
|
|
1278
1288
|
|
|
1289
|
+
> 注意:上表中的 `POST /api/...` 是“请求行示意”。系统内部生成并存储的 `ctx.route` / 数据库 `routePath` / 角色权限 `role.apis` / Redis 权限缓存都只使用 `url.pathname`(例如 `/api/user/login`),与 method 无关;权限数据禁止写成 `POST /api/...` 或 `POST/api/...`。
|
|
1290
|
+
|
|
1279
1291
|
### 多方法注册
|
|
1280
1292
|
|
|
1281
1293
|
当 `method: 'GET,POST'` 时,会同时注册两个路由:
|
|
@@ -1283,6 +1295,8 @@ if (!ctx.user?.id) {
|
|
|
1283
1295
|
- `GET /api/user/search`
|
|
1284
1296
|
- `POST /api/user/search`
|
|
1285
1297
|
|
|
1298
|
+
> 权限校验只看 pathname:如果同一个 pathname 同时注册了多个 method,它们共享同一套权限(以 `/api/user/search` 作为权限值)。
|
|
1299
|
+
|
|
1286
1300
|
---
|
|
1287
1301
|
|
|
1288
1302
|
## BeflyContext 对象
|
package/docs/guide/quickstart.md
CHANGED
|
@@ -121,6 +121,8 @@ export default {
|
|
|
121
121
|
| `apis/user/register.ts` | `POST /api/user/register` |
|
|
122
122
|
| `apis/article/list.ts` | `POST /api/article/list` |
|
|
123
123
|
|
|
124
|
+
> 注意:上面的写法是“HTTP 请求方法 + url.pathname”。系统内部生成并存储的 `routePath`、角色权限 `role.apis` 以及 Redis 权限缓存都只使用 `url.pathname`(例如 `/api/user/login`),与 method 无关,且禁止写成 `POST/api/...` 或 `POST /api/...`。
|
|
125
|
+
|
|
124
126
|
---
|
|
125
127
|
|
|
126
128
|
## 配置数据库
|
|
@@ -135,7 +137,7 @@ export default {
|
|
|
135
137
|
"type": "mysql",
|
|
136
138
|
"host": "127.0.0.1",
|
|
137
139
|
"port": 3306,
|
|
138
|
-
"
|
|
140
|
+
"username": "root",
|
|
139
141
|
"password": "your_password",
|
|
140
142
|
"database": "my_api"
|
|
141
143
|
},
|
|
@@ -213,19 +215,31 @@ CREATE DATABASE my_api CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
|
213
215
|
服务启动时会在**主进程**自动执行同步流程:
|
|
214
216
|
|
|
215
217
|
1. `syncTable()`:同步表结构
|
|
216
|
-
2. `
|
|
218
|
+
2. `syncApi()`:同步接口定义
|
|
219
|
+
3. `syncMenu()`:同步菜单定义
|
|
220
|
+
4. `syncDev()`:同步开发账户/开发角色
|
|
221
|
+
5. `syncCache()`:缓存同步收尾(cacheApis + cacheMenus + rebuildRoleApiPermissions)
|
|
217
222
|
|
|
218
223
|
如需手动触发,可在代码中调用(一般不建议在请求路径中调用):
|
|
219
224
|
|
|
220
225
|
```typescript
|
|
221
|
-
import { syncData } from "../sync/syncData.js";
|
|
222
226
|
import { syncTable } from "../sync/syncTable.js";
|
|
227
|
+
import { syncApi } from "../sync/syncApi.js";
|
|
228
|
+
import { syncMenu } from "../sync/syncMenu.js";
|
|
229
|
+
import { syncDev } from "../sync/syncDev.js";
|
|
230
|
+
import { syncCache } from "../sync/syncCache.js";
|
|
231
|
+
import { checkMenu } from "../checks/checkMenu.js";
|
|
223
232
|
import { scanSources } from "../utils/scanSources.js";
|
|
224
233
|
|
|
225
|
-
// ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.config)
|
|
234
|
+
// ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.cache / ctx.config)
|
|
226
235
|
const sources = await scanSources();
|
|
236
|
+
const checkedMenus = await checkMenu(sources.addons, { disableMenus: ctx.config.disableMenus || [] });
|
|
237
|
+
|
|
227
238
|
await syncTable(ctx, sources.tables);
|
|
228
|
-
await
|
|
239
|
+
await syncApi(ctx, sources.apis as any);
|
|
240
|
+
await syncMenu(ctx, checkedMenus);
|
|
241
|
+
await syncDev(ctx, { devEmail: ctx.config.devEmail, devPassword: ctx.config.devPassword });
|
|
242
|
+
await syncCache(ctx);
|
|
229
243
|
```
|
|
230
244
|
|
|
231
245
|
### 验证同步结果
|
package/docs/infra/redis.md
CHANGED
|
@@ -220,9 +220,11 @@ const count = await befly.redis.expireBatch([
|
|
|
220
220
|
### saddBatch - 批量添加 Set 成员
|
|
221
221
|
|
|
222
222
|
```typescript
|
|
223
|
+
import { CacheKeys } from "befly/lib/cacheKeys";
|
|
224
|
+
|
|
223
225
|
const count = await befly.redis.saddBatch([
|
|
224
|
-
{ key: "
|
|
225
|
-
{ key: "
|
|
226
|
+
{ key: CacheKeys.roleApis("admin"), members: ["/api/user"] },
|
|
227
|
+
{ key: CacheKeys.roleApis("editor"), members: ["/api/article"] }
|
|
226
228
|
]);
|
|
227
229
|
// 返回: 成功添加的总成员数量
|
|
228
230
|
```
|
|
@@ -230,9 +232,11 @@ const count = await befly.redis.saddBatch([
|
|
|
230
232
|
### sismemberBatch - 批量检查 Set 成员
|
|
231
233
|
|
|
232
234
|
```typescript
|
|
235
|
+
import { CacheKeys } from "befly/lib/cacheKeys";
|
|
236
|
+
|
|
233
237
|
const results = await befly.redis.sismemberBatch([
|
|
234
|
-
{ key: "
|
|
235
|
-
{ key: "
|
|
238
|
+
{ key: CacheKeys.roleApis("admin"), member: "/api/user" },
|
|
239
|
+
{ key: CacheKeys.roleApis("admin"), member: "/api/user/delete" }
|
|
236
240
|
]);
|
|
237
241
|
// 返回: [true, false]
|
|
238
242
|
```
|
|
@@ -285,11 +289,11 @@ const id = await befly.db.insData({
|
|
|
285
289
|
import { CacheKeys } from "befly/lib/cacheKeys";
|
|
286
290
|
|
|
287
291
|
// 获取键名
|
|
288
|
-
const
|
|
289
|
-
const
|
|
290
|
-
const
|
|
291
|
-
const
|
|
292
|
-
const
|
|
292
|
+
const apisAllKey = CacheKeys.apisAll(); // 'befly:apis:all'
|
|
293
|
+
const menusAllKey = CacheKeys.menusAll(); // 'befly:menus:all'
|
|
294
|
+
const adminRoleInfoKey = CacheKeys.roleInfo("admin"); // 'befly:role:info:admin'
|
|
295
|
+
const adminRoleApisKey = CacheKeys.roleApis("admin"); // 'befly:role:apis:admin'
|
|
296
|
+
const userTableColumnsKey = CacheKeys.tableColumns("user"); // 'befly:table:columns:user'
|
|
293
297
|
```
|
|
294
298
|
|
|
295
299
|
### 键名前缀
|
|
@@ -304,7 +308,12 @@ Redis 插件支持配置全局前缀,避免键名冲突:
|
|
|
304
308
|
}
|
|
305
309
|
```
|
|
306
310
|
|
|
307
|
-
|
|
311
|
+
所有键会自动添加前缀,最终写入 Redis 的 key 形如:`myapp:<key>`。
|
|
312
|
+
|
|
313
|
+
- 例如:你调用 `befly.redis.getString("user:1")`,实际访问的是 `myapp:user:1`
|
|
314
|
+
- 例如:你调用 `befly.redis.sismember(CacheKeys.roleApis("admin"), "/api/user")`,实际访问的是 `myapp:befly:role:apis:admin`
|
|
315
|
+
|
|
316
|
+
> 注意:`redis.prefix` **不允许包含** `:`,因为 RedisHelper 会自动拼接分隔符 `:`。
|
|
308
317
|
|
|
309
318
|
---
|
|
310
319
|
|
|
@@ -313,6 +322,8 @@ Redis 插件支持配置全局前缀,避免键名冲突:
|
|
|
313
322
|
### 场景1:表结构缓存
|
|
314
323
|
|
|
315
324
|
DbHelper 自动缓存表字段信息,避免重复查询数据库。
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
316
327
|
// 计数 + 过期:常用于限流/风控
|
|
317
328
|
// 更推荐:直接使用 Befly Core 内置的 rateLimit hook(通过 configs 配置即可)
|
|
318
329
|
|
|
@@ -323,8 +334,9 @@ const key = `ratelimit:${ctx.ip}:${ctx.route}`;
|
|
|
323
334
|
const count = await befly.redis.incrWithExpire(key, windowSeconds);
|
|
324
335
|
|
|
325
336
|
if (count > limit) {
|
|
326
|
-
return befly.tool.No("请求过于频繁");
|
|
337
|
+
return befly.tool.No("请求过于频繁");
|
|
327
338
|
}
|
|
339
|
+
```
|
|
328
340
|
|
|
329
341
|
### 场景2:接口权限缓存
|
|
330
342
|
|
package/docs/quickstart.md
CHANGED
|
@@ -1,338 +1,8 @@
|
|
|
1
|
-
# Quickstart
|
|
1
|
+
# Quickstart 快速入门(已迁移)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
为避免重复内容长期漂移,本 Quickstart 已迁移到权威入口:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- `packages/core/docs/guide/quickstart.md`
|
|
6
|
+
- 在线阅读:[`./guide/quickstart.md`](./guide/quickstart.md)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
- [项目结构](#项目结构)
|
|
9
|
-
- [第一个 API](#第一个-api)
|
|
10
|
-
- [配置数据库](#配置数据库)
|
|
11
|
-
- [定义表结构](#定义表结构)
|
|
12
|
-
- [同步数据库](#同步数据库)
|
|
13
|
-
- [启动服务](#启动服务)
|
|
14
|
-
- [下一步](#下一步)
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## 环境准备
|
|
19
|
-
|
|
20
|
-
### 必需软件
|
|
21
|
-
|
|
22
|
-
| 软件 | 版本要求 | 说明 |
|
|
23
|
-
| ----- | -------- | ----------------- |
|
|
24
|
-
| Bun | >= 1.0 | JavaScript 运行时 |
|
|
25
|
-
| MySQL | >= 8.0 | 数据库 |
|
|
26
|
-
| Redis | >= 6.0 | 缓存(可选) |
|
|
27
|
-
|
|
28
|
-
### 安装 Bun
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
# Windows (PowerShell)
|
|
32
|
-
powershell -c "irm bun.sh/install.ps1 | iex"
|
|
33
|
-
|
|
34
|
-
# macOS / Linux
|
|
35
|
-
curl -fsSL https://bun.sh/install | bash
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### 创建项目
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
# 克隆模板项目
|
|
42
|
-
git clone https://github.com/chenbimo/befly-tpl.git my-api
|
|
43
|
-
cd my-api
|
|
44
|
-
|
|
45
|
-
# 安装依赖
|
|
46
|
-
bun install
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## 项目结构
|
|
52
|
-
|
|
53
|
-
```
|
|
54
|
-
my-api/
|
|
55
|
-
├── apis/ # API 接口目录
|
|
56
|
-
│ └── user/
|
|
57
|
-
│ └── login.ts # 用户登录接口
|
|
58
|
-
├── tables/ # 表定义目录
|
|
59
|
-
│ └── user.json # 用户表定义
|
|
60
|
-
├── configs/ # 配置文件目录
|
|
61
|
-
│ ├── befly.common.json # 公共配置
|
|
62
|
-
│ ├── befly.development.json # 开发环境配置
|
|
63
|
-
│ └── befly.production.json # 生产环境配置
|
|
64
|
-
├── main.ts # 入口文件
|
|
65
|
-
└── package.json
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## 第一个 API
|
|
71
|
-
|
|
72
|
-
### 创建 API 文件
|
|
73
|
-
|
|
74
|
-
在 `apis/user/` 目录下创建 `login.ts`:
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
import type { ApiRoute } from "befly/types/api";
|
|
78
|
-
|
|
79
|
-
export default {
|
|
80
|
-
name: "用户登录",
|
|
81
|
-
method: "POST",
|
|
82
|
-
auth: false, // 不需要登录
|
|
83
|
-
fields: {
|
|
84
|
-
email: { name: "邮箱", type: "string", min: 5, max: 100, regexp: "@email" },
|
|
85
|
-
password: { name: "密码", type: "string", min: 6, max: 100 }
|
|
86
|
-
},
|
|
87
|
-
required: ["email", "password"],
|
|
88
|
-
handler: async (befly, ctx) => {
|
|
89
|
-
// 查询用户
|
|
90
|
-
const user = await befly.db.getDetail({
|
|
91
|
-
table: "user",
|
|
92
|
-
columns: ["id", "email", "password", "nickname"],
|
|
93
|
-
where: { email: ctx.body.email }
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
if (!user?.id) {
|
|
97
|
-
return No("用户不存在");
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// 验证密码
|
|
101
|
-
const isValid = await befly.cipher.verifyPassword(ctx.body.password, user.password);
|
|
102
|
-
if (!isValid) {
|
|
103
|
-
return No("密码错误");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// 签发令牌
|
|
107
|
-
const token = befly.jwt.sign({ userId: user.id });
|
|
108
|
-
|
|
109
|
-
return Yes("登录成功", { token: token, user: { id: user.id, nickname: user.nickname } });
|
|
110
|
-
}
|
|
111
|
-
} as ApiRoute;
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### API 路由规则
|
|
115
|
-
|
|
116
|
-
文件路径自动转换为路由:
|
|
117
|
-
|
|
118
|
-
| 文件路径 | 路由路径 |
|
|
119
|
-
| ----------------------- | ------------------------- |
|
|
120
|
-
| `apis/user/login.ts` | `POST /api/user/login` |
|
|
121
|
-
| `apis/user/register.ts` | `POST /api/user/register` |
|
|
122
|
-
| `apis/article/list.ts` | `POST /api/article/list` |
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
## 配置数据库
|
|
127
|
-
|
|
128
|
-
### 编辑配置文件
|
|
129
|
-
|
|
130
|
-
修改 `configs/befly.development.json`:
|
|
131
|
-
|
|
132
|
-
```json
|
|
133
|
-
{
|
|
134
|
-
"db": {
|
|
135
|
-
"type": "mysql",
|
|
136
|
-
"host": "127.0.0.1",
|
|
137
|
-
"port": 3306,
|
|
138
|
-
"user": "root",
|
|
139
|
-
"password": "your_password",
|
|
140
|
-
"database": "my_api"
|
|
141
|
-
},
|
|
142
|
-
"redis": {
|
|
143
|
-
"host": "127.0.0.1",
|
|
144
|
-
"port": 6379,
|
|
145
|
-
"password": ""
|
|
146
|
-
},
|
|
147
|
-
"auth": {
|
|
148
|
-
"secret": "your-jwt-secret-change-in-production",
|
|
149
|
-
"expiresIn": "7d"
|
|
150
|
-
},
|
|
151
|
-
"logger": {
|
|
152
|
-
"debug": 1,
|
|
153
|
-
"console": 1
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### 创建数据库
|
|
159
|
-
|
|
160
|
-
```sql
|
|
161
|
-
CREATE DATABASE my_api CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
## 定义表结构
|
|
167
|
-
|
|
168
|
-
### 创建表定义文件
|
|
169
|
-
|
|
170
|
-
在 `tables/` 目录下创建 `user.json`:
|
|
171
|
-
|
|
172
|
-
```json
|
|
173
|
-
{
|
|
174
|
-
"email": "邮箱|string|5|100||true|^[\\w.-]+@[\\w.-]+\\.[a-zA-Z]{2,}$",
|
|
175
|
-
"password": "密码|string|6|100||true",
|
|
176
|
-
"nickname": "昵称|string|2|50|用户",
|
|
177
|
-
"avatar": "头像|string|0|500",
|
|
178
|
-
"phone": "手机号|string|0|20"
|
|
179
|
-
}
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### 字段定义格式
|
|
183
|
-
|
|
184
|
-
格式:`"字段标签|类型|最小|最大|默认|必填|正则"`
|
|
185
|
-
|
|
186
|
-
| 位置 | 说明 | 示例 |
|
|
187
|
-
| ---- | ----------- | --------------------- |
|
|
188
|
-
| 1 | 字段标签 | `邮箱` |
|
|
189
|
-
| 2 | 数据类型 | `string` / `number` |
|
|
190
|
-
| 3 | 最小值/长度 | `5` |
|
|
191
|
-
| 4 | 最大值/长度 | `100` |
|
|
192
|
-
| 5 | 默认值 | `用户` |
|
|
193
|
-
| 6 | 是否必填 | `true` / `false` |
|
|
194
|
-
| 7 | 正则验证 | `@email` 或自定义正则 |
|
|
195
|
-
|
|
196
|
-
### 自动字段
|
|
197
|
-
|
|
198
|
-
每个表自动添加:
|
|
199
|
-
|
|
200
|
-
| 字段 | 类型 | 说明 |
|
|
201
|
-
| ------------ | ------- | ------------------------------- |
|
|
202
|
-
| `id` | BIGINT | 主键,自增 |
|
|
203
|
-
| `created_at` | BIGINT | 创建时间戳 |
|
|
204
|
-
| `updated_at` | BIGINT | 更新时间戳 |
|
|
205
|
-
| `state` | TINYINT | 状态(1=正常,0=禁用,-1=删除) |
|
|
206
|
-
|
|
207
|
-
---
|
|
208
|
-
|
|
209
|
-
## 同步数据库
|
|
210
|
-
|
|
211
|
-
### 自动同步
|
|
212
|
-
|
|
213
|
-
服务启动时会在**主进程**自动执行同步流程:
|
|
214
|
-
|
|
215
|
-
1. `syncTable()`:同步表结构
|
|
216
|
-
2. `syncData()`:固定顺序执行 `syncApi` → `syncMenu` → `syncDev`
|
|
217
|
-
|
|
218
|
-
如需手动触发,可在代码中调用(一般不建议在请求路径中调用):
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
import { syncData } from "../sync/syncData.js";
|
|
222
|
-
import { syncTable } from "../sync/syncTable.js";
|
|
223
|
-
import { scanSources } from "../utils/scanSources.js";
|
|
224
|
-
|
|
225
|
-
// ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.config)
|
|
226
|
-
const sources = await scanSources();
|
|
227
|
-
await syncTable(ctx, sources.tables);
|
|
228
|
-
await syncData();
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### 验证同步结果
|
|
232
|
-
|
|
233
|
-
```bash
|
|
234
|
-
# 查看数据库
|
|
235
|
-
mysql -u root -p my_api -e "SHOW TABLES;"
|
|
236
|
-
|
|
237
|
-
# 应该看到:
|
|
238
|
-
# +------------------+
|
|
239
|
-
# | Tables_in_my_api |
|
|
240
|
-
# +------------------+
|
|
241
|
-
# | user |
|
|
242
|
-
# +------------------+
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
---
|
|
246
|
-
|
|
247
|
-
## 启动服务
|
|
248
|
-
|
|
249
|
-
### 开发模式
|
|
250
|
-
|
|
251
|
-
```bash
|
|
252
|
-
bun run dev
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
服务启动后:
|
|
256
|
-
|
|
257
|
-
```
|
|
258
|
-
🚀 Befly 服务已启动
|
|
259
|
-
📍 http://localhost:3000
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
### 测试 API
|
|
263
|
-
|
|
264
|
-
```bash
|
|
265
|
-
# 测试登录接口
|
|
266
|
-
curl -X POST http://localhost:3000/api/user/login \
|
|
267
|
-
-H "Content-Type: application/json" \
|
|
268
|
-
-d '{"email":"test@example.com","password":"123456"}'
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
响应示例:
|
|
272
|
-
|
|
273
|
-
```json
|
|
274
|
-
{
|
|
275
|
-
"code": 0,
|
|
276
|
-
"msg": "登录成功",
|
|
277
|
-
"data": {
|
|
278
|
-
"token": "eyJhbGciOiJIUzI1NiIs...",
|
|
279
|
-
"user": {
|
|
280
|
-
"id": 1,
|
|
281
|
-
"nickname": "用户"
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
## 下一步
|
|
290
|
-
|
|
291
|
-
### 学习更多
|
|
292
|
-
|
|
293
|
-
| 主题 | 文档 | 说明 |
|
|
294
|
-
| ---------- | ------------------------------------ | -------------------- |
|
|
295
|
-
| API 开发 | [api.md](./api/api.md) | API 定义、字段、权限 |
|
|
296
|
-
| 表结构 | [table.md](./table.md) | 表定义格式详解 |
|
|
297
|
-
| 数据库操作 | [database.md](./plugins/database.md) | CRUD 操作 |
|
|
298
|
-
| 配置系统 | [config.md](./config.md) | 配置文件说明 |
|
|
299
|
-
| 插件开发 | [plugin.md](./plugins/plugin.md) | 自定义插件 |
|
|
300
|
-
| Hook 开发 | [hook.md](./hooks/hook.md) | 请求处理钩子 |
|
|
301
|
-
| 验证系统 | [validator.md](./validator.md) | 参数验证 |
|
|
302
|
-
| 日志系统 | [logger.md](./logger.md) | 日志配置 |
|
|
303
|
-
| 加密工具 | [cipher.md](./plugins/cipher.md) | 加密与 JWT |
|
|
304
|
-
| 同步命令 | [sync.md](./sync.md) | 数据库同步 |
|
|
305
|
-
|
|
306
|
-
### 常用命令
|
|
307
|
-
|
|
308
|
-
```bash
|
|
309
|
-
# 开发
|
|
310
|
-
bun run dev # 启动开发服务
|
|
311
|
-
|
|
312
|
-
# 生产
|
|
313
|
-
bun run build # 构建
|
|
314
|
-
bun run start # 启动生产服务
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
### 项目示例
|
|
318
|
-
|
|
319
|
-
```
|
|
320
|
-
apis/
|
|
321
|
-
├── user/
|
|
322
|
-
│ ├── login.ts # 登录
|
|
323
|
-
│ ├── register.ts # 注册
|
|
324
|
-
│ ├── info.ts # 获取信息
|
|
325
|
-
│ └── update.ts # 更新信息
|
|
326
|
-
├── article/
|
|
327
|
-
│ ├── list.ts # 文章列表
|
|
328
|
-
│ ├── detail.ts # 文章详情
|
|
329
|
-
│ ├── create.ts # 创建文章
|
|
330
|
-
│ └── delete.ts # 删除文章
|
|
331
|
-
└── common/
|
|
332
|
-
└── upload.ts # 文件上传
|
|
333
|
-
|
|
334
|
-
tables/
|
|
335
|
-
├── user.json # 用户表
|
|
336
|
-
├── article.json # 文章表
|
|
337
|
-
└── category.json # 分类表
|
|
338
|
-
```
|
|
8
|
+
如你从旧链接跳转到这里,请以 `guide/quickstart.md` 的内容为准(配置字段、同步流程、权限 pathname 规则等都以当前实现为准)。
|
package/docs/reference/addon.md
CHANGED
|
@@ -465,21 +465,6 @@ A: 在配置文件中设置:
|
|
|
465
465
|
}
|
|
466
466
|
```
|
|
467
467
|
|
|
468
|
-
### Q: Addon 的表如何迁移?
|
|
469
|
-
|
|
470
|
-
A: 服务启动时(主进程)会自动执行 `syncTable()`,会同步项目与所有 Addon 的表定义。
|
|
471
|
-
|
|
472
|
-
如需手动触发:
|
|
473
|
-
|
|
474
|
-
```typescript
|
|
475
|
-
import { syncTable } from "../../sync/syncTable.js";
|
|
476
|
-
import { scanSources } from "../../utils/scanSources.js";
|
|
477
|
-
|
|
478
|
-
// ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.config)
|
|
479
|
-
const sources = await scanSources();
|
|
480
|
-
await syncTable(ctx, sources.tables);
|
|
481
|
-
```
|
|
482
|
-
|
|
483
468
|
### Q: 如何在 Addon 中访问项目配置?
|
|
484
469
|
|
|
485
470
|
A: 通过 `befly.config` 访问:
|