@lovrabet/cli 1.1.22 → 1.1.25
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/lib/add-page/input-page-router.js +1 -1
- package/lib/add-page/main.js +1 -1
- package/lib/add-page/select-page-template.js +1 -1
- package/lib/api/api-doc-ui.js +1 -1
- package/lib/api/api-doc.js +1 -1
- package/lib/api/api-pull-ui.js +1 -1
- package/lib/api/fetch-model-list.js +1 -1
- package/lib/api/generate-api-file.js +1 -1
- package/lib/api/main.js +1 -1
- package/lib/api/pull-silent.js +1 -1
- package/lib/app-menu/app-menu-sync-ui.js +1 -1
- package/lib/app-menu/create-menu.js +1 -1
- package/lib/app-menu/get-local-pages.js +1 -1
- package/lib/app-menu/get-online-menu-list.js +1 -1
- package/lib/app-menu/valid-url.js +1 -1
- package/lib/auth/auth-server-ui.js +1 -1
- package/lib/auth/auth-server.js +1 -1
- package/lib/auth/constant.js +1 -1
- package/lib/auth/get-cookie.js +1 -1
- package/lib/auth/is-session-valid.js +1 -1
- package/lib/auth/logout.js +1 -1
- package/lib/cli.js +1 -1
- package/lib/cmd/build-watch.js +1 -1
- package/lib/cmd/build.js +1 -1
- package/lib/cmd/logs.js +1 -1
- package/lib/cmd/preview.js +1 -1
- package/lib/cmd/start.js +1 -1
- package/lib/config/config-help.js +1 -1
- package/lib/config/main.js +1 -1
- package/lib/constant/domain.js +1 -1
- package/lib/constant/env.js +1 -1
- package/lib/create-app/enhanced-guided-create.js +1 -1
- package/lib/create-app/format-elapsed.js +1 -1
- package/lib/create-app/main.js +1 -1
- package/lib/create-app/task-finished.js +1 -1
- package/lib/create-app/task-loading.js +1 -1
- package/lib/create-app/task-running.js +1 -1
- package/lib/create-app/task-time.js +1 -1
- package/lib/create-app/use-copy-project-template.js +1 -1
- package/lib/create-app/use-format-code.js +1 -1
- package/lib/create-app/use-install-dependencies.js +1 -1
- package/lib/help.js +1 -1
- package/lib/init/main.js +1 -1
- package/lib/mcp/cursor.js +1 -1
- package/lib/mcp/main.js +1 -1
- package/lib/utils/config.js +1 -1
- package/lib/utils/copy-directory.js +1 -1
- package/lib/utils/http-client.js +1 -1
- package/lib/utils/logger.js +1 -1
- package/lib/utils/router-updater.js +1 -1
- package/lib/utils/sleep.js +1 -1
- package/lib/utils/template-replacer.js +1 -1
- package/package.json +1 -1
- package/templates/projects/sub-app-react-demo/package-lock.json +4 -4
- package/templates/projects/sub-app-react-demo/package.json +1 -1
- package/templates/rules/lovrabet_rules.mdc.tpl +181 -115
|
@@ -4,7 +4,7 @@ alwaysApply: false
|
|
|
4
4
|
---
|
|
5
5
|
# Lovrabet 开发生态 AI 助手指南
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 核心原则
|
|
8
8
|
|
|
9
9
|
你是一个专业的 Lovrabet 平台开发助手。你的目标是帮助开发者高效、正确地使用 Lovrabet SDK 和 MCP。
|
|
10
10
|
|
|
@@ -17,14 +17,14 @@ alwaysApply: false
|
|
|
17
17
|
5. **类型安全**:充分利用 TypeScript,避免运行时错误
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## SDK 使用规范
|
|
21
21
|
|
|
22
22
|
### 1. SDK 初始化
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
25
|
import { createClient } from '@lovrabet/sdk';
|
|
26
26
|
|
|
27
|
-
//
|
|
27
|
+
// 正确:使用 createClient 函数
|
|
28
28
|
const client = createClient({
|
|
29
29
|
appCode: '<appcode>',
|
|
30
30
|
accessKey: process.env.LOVRABET_ACCESS_KEY, // 服务端
|
|
@@ -38,13 +38,13 @@ const client = createClient({
|
|
|
38
38
|
},
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
//
|
|
41
|
+
// 错误:使用 new 关键字
|
|
42
42
|
const client = new LovrabetClient({ ... });
|
|
43
43
|
|
|
44
|
-
//
|
|
44
|
+
// 错误:使用不存在的 mode 参数
|
|
45
45
|
const client = createClient({ mode: 'webapi', ... });
|
|
46
46
|
|
|
47
|
-
//
|
|
47
|
+
// 错误:缺少必需的 models 配置
|
|
48
48
|
const client = createClient({ appCode: '<appcode>', accessKey: '<key>' });
|
|
49
49
|
```
|
|
50
50
|
|
|
@@ -55,16 +55,17 @@ const client = createClient({ appCode: '<appcode>', accessKey: '<key>' });
|
|
|
55
55
|
- SDK 返回:只返回 `data`字段的内容
|
|
56
56
|
|
|
57
57
|
**失败时**:抛出 `LovrabetError` 异常
|
|
58
|
-
- 异常对象包含:`{ message: string, status?: number, code?: string,
|
|
58
|
+
- 异常对象包含:`{ message: string, status?: number, code?: string, response?: any }`
|
|
59
|
+
- `response` 包含服务端完整响应数据
|
|
59
60
|
- 不会返回错误信息,而是抛出异常,需要使用 `try-catch` 包裹所有 SDK 调用
|
|
60
61
|
|
|
61
62
|
**关键提示**:
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
63
|
+
- 必须使用 `try-catch` 包裹所有 SDK 调用
|
|
64
|
+
- 成功时直接获取业务数据(如 `{ id: 123, name: "..." }`)
|
|
65
|
+
- 失败时捕获异常处理错误
|
|
65
66
|
|
|
66
67
|
```typescript
|
|
67
|
-
//
|
|
68
|
+
// 正确:完整的错误处理
|
|
68
69
|
try {
|
|
69
70
|
const user = await client.models.<modelName>.getOne(<id>);
|
|
70
71
|
console.log(user.name); // 直接使用返回的数据
|
|
@@ -73,65 +74,46 @@ try {
|
|
|
73
74
|
console.error('业务错误:', error.message);
|
|
74
75
|
console.error('错误代码:', error.code);
|
|
75
76
|
console.error('HTTP状态:', error.status);
|
|
77
|
+
console.error('服务端响应:', error.response); // 完整的服务端响应
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
|
|
79
|
-
//
|
|
81
|
+
// 错误:假设返回值包含 success 字段
|
|
80
82
|
const response = await client.models.<modelName>.getOne(<id>);
|
|
81
83
|
if (response.success) { ... } // 错误!成功时只返回 data 内容
|
|
82
84
|
```
|
|
83
85
|
|
|
84
86
|
### 3. 数据模型操作
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
**重要提示:强烈建议使用 `filter()` 而不是 `getList()`**
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
90
|
+
`filter()` 方法在 v1.1.22+ 已支持 **OpenAPI 和 WebAPI 两种模式**,强烈建议优先使用:
|
|
91
|
+
- 更强大的查询能力(支持复杂条件、范围查询、模糊匹配)
|
|
92
|
+
- 更好的性能(通过 `select` 参数只返回需要的字段)
|
|
93
|
+
- 更简洁的返回结构(直接返回 `{ tableData, total }`)
|
|
94
|
+
- 支持 11 种条件操作符和 `$and`/`$or` 逻辑组合
|
|
95
|
+
- 支持的操作符(11 种):
|
|
96
|
+
- $eq, $ne, $gte ($gteq), $lte ($lteq), $in, $contain, $startWith, $endWith
|
|
97
|
+
- 逻辑操作符:$and, $or(支持嵌套)
|
|
92
98
|
|
|
93
|
-
|
|
94
|
-
- 使用 Token/AccessKey 认证模式(不支持 filter)
|
|
95
|
-
- 需要 `tableColumns` 字段定义信息
|
|
96
|
-
|
|
97
|
-
#### 查询列表
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
// ⚠️ 不推荐:getList 功能有限,返回结构复杂
|
|
101
|
-
const response = await client.models.<modelName>.getList({
|
|
102
|
-
currentPage: 1,
|
|
103
|
-
pageSize: 20,
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
console.log(response.paging.totalCount); // 总数
|
|
107
|
-
console.log(response.tableData); // 数据列表
|
|
108
|
-
console.log(response.tableColumns); // 列定义
|
|
109
|
-
|
|
110
|
-
// ❌ 错误:使用 total 字段
|
|
111
|
-
console.log(response.total); // getList 没有 total 字段
|
|
112
|
-
|
|
113
|
-
// ✅ 正确:带排序
|
|
114
|
-
import { SortOrder } from '@lovrabet/sdk';
|
|
115
|
-
|
|
116
|
-
const sorted = await client.models.<modelName>.getList(
|
|
117
|
-
{ currentPage: 1, pageSize: 20 },
|
|
118
|
-
[{ <fieldName>: SortOrder.DESC }]
|
|
119
|
-
);
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
#### 高级过滤查询(v1.1.21+,仅 Cookie 模式,推荐使用)
|
|
99
|
+
#### 高级过滤查询(v1.1.22+,OpenAPI 和 WebAPI 都支持,强烈推荐!)
|
|
123
100
|
|
|
124
101
|
```typescript
|
|
125
|
-
//
|
|
102
|
+
// 强烈推荐:filter 功能强大,性能更好,两种模式都支持
|
|
126
103
|
const result = await client.models.<modelName>.filter({
|
|
127
104
|
where: {
|
|
128
105
|
$and: [
|
|
129
|
-
{
|
|
130
|
-
{
|
|
106
|
+
{ age: { $gte: 18, $lte: 45 } }, // 年龄区间
|
|
107
|
+
{ country: { $in: ['中国', '美国', '日本'] } }, // 国家在集合内
|
|
108
|
+
{ vip: { $ne: null } }, // VIP 字段非空
|
|
109
|
+
{ name: { $contain: 'hello' } }, // 名称模糊匹配
|
|
131
110
|
],
|
|
132
111
|
},
|
|
133
|
-
select: ['
|
|
134
|
-
orderBy: [
|
|
112
|
+
select: ['id', 'name', 'age', 'country'], // 注意:是 select,不是 fields
|
|
113
|
+
orderBy: [
|
|
114
|
+
{ lastLoginAt: SortOrder.DESC }, // 先按登录时间倒序
|
|
115
|
+
{ name: SortOrder.ASC }, // 再按名称升序
|
|
116
|
+
], // 注意:是 orderBy,不是 sortList
|
|
135
117
|
currentPage: 1,
|
|
136
118
|
pageSize: 20,
|
|
137
119
|
});
|
|
@@ -139,28 +121,87 @@ const result = await client.models.<modelName>.filter({
|
|
|
139
121
|
console.log(result.tableData); // 数据列表
|
|
140
122
|
console.log(result.total); // 总数
|
|
141
123
|
|
|
142
|
-
//
|
|
124
|
+
// 复杂嵌套条件
|
|
143
125
|
const result = await client.models.<modelName>.filter({
|
|
144
|
-
|
|
145
|
-
|
|
126
|
+
where: {
|
|
127
|
+
$and: [
|
|
128
|
+
{ age: { $gte: 18 } },
|
|
129
|
+
{
|
|
130
|
+
$or: [
|
|
131
|
+
{ country: { $eq: '中国' } },
|
|
132
|
+
{ country: { $eq: '美国' } }
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
146
137
|
});
|
|
147
|
-
|
|
148
|
-
// 支持的操作符:$eq, $ne, $gte, $lte, $in, $contain, $startWith, $endWith, $and, $or
|
|
149
138
|
```
|
|
150
139
|
|
|
151
140
|
#### SQL API(v1.1.19+)
|
|
152
141
|
|
|
142
|
+
**注意事项**:
|
|
143
|
+
|
|
144
|
+
1. **传入 SQL ID**:不是传入原始 SQL 语句,而是在 Lovrabet 后台登记后获得的 SQL ID(格式如 `fc8e7777-06e3847d`)
|
|
145
|
+
2. **SQL 登记**:去 Lovrabet 后台 → 自定义 SQL → 创建 SQL 并登记,获得唯一 ID
|
|
146
|
+
3. **参数传递**:SQL 支持参数化查询,通过第二个参数传入对象,对象的 key 对应 SQL 中的参数名
|
|
147
|
+
4. **检查执行状态**:必须检查 `data.execSuccess && data.execResult`,不要直接使用 `execResult`
|
|
148
|
+
|
|
149
|
+
**正确示例**:
|
|
150
|
+
|
|
153
151
|
```typescript
|
|
154
|
-
//
|
|
155
|
-
const data = await client.api.executeSql
|
|
152
|
+
// 基础查询(无参数)
|
|
153
|
+
const data = await client.api.executeSql('fc8e7777-06e3847d');
|
|
156
154
|
|
|
157
155
|
if (data.execSuccess && data.execResult) {
|
|
158
156
|
data.execResult.forEach(row => console.log(row));
|
|
159
157
|
}
|
|
160
158
|
|
|
161
|
-
//
|
|
162
|
-
const
|
|
163
|
-
|
|
159
|
+
// 参数化查询(推荐)
|
|
160
|
+
const data = await client.api.executeSql('fc8e7777-06e3847d', {
|
|
161
|
+
userId: '123', // SQL 中使用 #{userId}
|
|
162
|
+
startDate: '2025-01-01', // SQL 中使用 #{startDate}
|
|
163
|
+
endDate: '2025-12-31' // SQL 中使用 #{endDate}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (data.execSuccess && data.execResult) {
|
|
167
|
+
console.log('查询成功', data.execResult);
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### 用户列表 API(v1.1.19+)
|
|
172
|
+
|
|
173
|
+
**说明**:获取平台用户列表,内置 30 秒缓存。
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// 获取用户列表
|
|
177
|
+
const userList = await client.api.user.getList();
|
|
178
|
+
|
|
179
|
+
// 返回 User[] 数组
|
|
180
|
+
userList.forEach(user => {
|
|
181
|
+
console.log(user.code); // 用户代码
|
|
182
|
+
console.log(user.userName); // 用户名
|
|
183
|
+
console.log(user.nickName); // 昵称(可选)
|
|
184
|
+
console.log(user.mobile); // 手机号
|
|
185
|
+
console.log(user.email); // 邮箱(可选)
|
|
186
|
+
console.log(user.avatar); // 头像(可选)
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// 带类型提示
|
|
190
|
+
import type { User } from '@lovrabet/sdk';
|
|
191
|
+
|
|
192
|
+
const userList: User[] = await client.api.user.getList();
|
|
193
|
+
|
|
194
|
+
// 查找特定用户
|
|
195
|
+
const targetUser = userList.find(u => u.code === 'user123');
|
|
196
|
+
if (targetUser) {
|
|
197
|
+
console.log(targetUser.userName);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// 生成用户下拉选项
|
|
201
|
+
const userOptions = userList.map(u => ({
|
|
202
|
+
label: u.nickName || u.userName,
|
|
203
|
+
value: u.code
|
|
204
|
+
}));
|
|
164
205
|
```
|
|
165
206
|
|
|
166
207
|
#### 其他 CRUD 操作
|
|
@@ -185,28 +226,46 @@ const options = await client.models.<modelName>.getSelectOptions({
|
|
|
185
226
|
});
|
|
186
227
|
```
|
|
187
228
|
|
|
188
|
-
### 4.
|
|
229
|
+
### 4. 认证模式支持(v1.1.22+ 更新)
|
|
189
230
|
|
|
190
|
-
**
|
|
191
|
-
-
|
|
231
|
+
**OpenAPI 模式(accessKey/token)**:
|
|
232
|
+
- 支持:getList, getOne, create, update
|
|
233
|
+
- 支持:**filter**(v1.1.22+ 新增)
|
|
234
|
+
- 支持:executeSql
|
|
235
|
+
- 不支持:user.getList
|
|
236
|
+
- 不支持:delete(暂不支持)
|
|
237
|
+
- 不支持:getSelectOptions(暂不支持)
|
|
192
238
|
|
|
193
|
-
**Cookie
|
|
194
|
-
-
|
|
239
|
+
**WebAPI 模式(Cookie)**:
|
|
240
|
+
- 支持:getList, getOne, create, update
|
|
241
|
+
- 支持:filter
|
|
242
|
+
- 支持:delete
|
|
243
|
+
- 支持:getSelectOptions
|
|
244
|
+
- 支持:executeSql
|
|
245
|
+
- 支持:user.getList
|
|
195
246
|
|
|
196
247
|
```typescript
|
|
197
|
-
//
|
|
248
|
+
// 正确:v1.1.22+ OpenAPI 模式支持 filter
|
|
249
|
+
const client = createClient({ accessKey: '<key>', ... });
|
|
250
|
+
await client.models.<modelName>.filter({ ... }); // 可以使用
|
|
251
|
+
|
|
252
|
+
// 错误:OpenAPI 模式不支持 delete
|
|
198
253
|
const client = createClient({ token: '<token>', ... });
|
|
199
|
-
await client.models.<modelName>.
|
|
254
|
+
await client.models.<modelName>.delete('<id>'); // 会抛出错误
|
|
255
|
+
|
|
256
|
+
// 正确:使用 WebAPI 模式进行删除
|
|
257
|
+
const client = createClient({ appCode: '<appcode>', ... }); // 不提供认证信息,使用 Cookie
|
|
258
|
+
await client.models.<modelName>.delete('<id>'); // 可以使用
|
|
200
259
|
```
|
|
201
260
|
|
|
202
|
-
##
|
|
261
|
+
## MCP 使用规范
|
|
203
262
|
|
|
204
263
|
### 关键原则
|
|
205
264
|
|
|
206
265
|
**必须先获取数据集元数据,再编写代码!**
|
|
207
266
|
|
|
208
267
|
```typescript
|
|
209
|
-
//
|
|
268
|
+
// 正确流程
|
|
210
269
|
// 1. 获取数据集详情
|
|
211
270
|
const detail = await use_mcp_tool("get_dataset_detail", {
|
|
212
271
|
appcode: "<appcode>",
|
|
@@ -227,36 +286,36 @@ await client.models.<modelName>.create({
|
|
|
227
286
|
<field2>: <value2>, // 已确认字段存在
|
|
228
287
|
});
|
|
229
288
|
|
|
230
|
-
//
|
|
289
|
+
// 错误:跳过元数据获取
|
|
231
290
|
await client.models.<modelName>.create({
|
|
232
291
|
<field>: <value>, // 未确认字段是否存在
|
|
233
292
|
});
|
|
234
293
|
```
|
|
235
294
|
|
|
236
295
|
|
|
237
|
-
##
|
|
296
|
+
## 性能优化规则
|
|
238
297
|
|
|
239
298
|
### 1. 减少 API 调用和数据传输
|
|
240
299
|
|
|
241
300
|
```typescript
|
|
242
|
-
//
|
|
301
|
+
// 推荐:使用 filter + select 只返回需要的字段
|
|
243
302
|
const result = await client.models.<modelName>.filter({
|
|
244
303
|
where: { <field>: <value> },
|
|
245
304
|
select: ['<field1>', '<field2>', '<field3>'], // 只返回3个字段,减少数据传输
|
|
246
305
|
});
|
|
247
306
|
|
|
248
|
-
//
|
|
307
|
+
// 不推荐:getList 返回所有字段,浪费带宽
|
|
249
308
|
const response = await client.models.<modelName>.getList({
|
|
250
309
|
<field>: <value>,
|
|
251
310
|
pageSize: 20,
|
|
252
311
|
}); // 返回所有字段,无法筛选
|
|
253
312
|
|
|
254
|
-
//
|
|
313
|
+
// 批量操作,避免循环
|
|
255
314
|
const items = await Promise.all(
|
|
256
315
|
ids.map(id => client.models.<modelName>.getOne(id))
|
|
257
316
|
);
|
|
258
317
|
|
|
259
|
-
//
|
|
318
|
+
// 避免 N+1 问题
|
|
260
319
|
for (const id of ids) {
|
|
261
320
|
const item = await client.models.<modelName>.getOne(id); // 逐个等待
|
|
262
321
|
}
|
|
@@ -265,10 +324,10 @@ for (const id of ids) {
|
|
|
265
324
|
### 2. 缓存和防抖
|
|
266
325
|
|
|
267
326
|
```typescript
|
|
268
|
-
//
|
|
327
|
+
// 缓存不常变化的数据
|
|
269
328
|
const cache = new Map();
|
|
270
329
|
|
|
271
|
-
//
|
|
330
|
+
// 搜索使用防抖
|
|
272
331
|
import { debounce } from 'lodash';
|
|
273
332
|
const search = debounce(async (keyword) => {
|
|
274
333
|
const result = await client.models.<modelName>.filter({
|
|
@@ -279,12 +338,12 @@ const search = debounce(async (keyword) => {
|
|
|
279
338
|
```
|
|
280
339
|
|
|
281
340
|
|
|
282
|
-
##
|
|
341
|
+
## 错误处理规则
|
|
283
342
|
|
|
284
343
|
### 必须使用 try-catch
|
|
285
344
|
|
|
286
345
|
```typescript
|
|
287
|
-
//
|
|
346
|
+
// 正确:完整的错误处理
|
|
288
347
|
import { LovrabetError } from '@lovrabet/sdk';
|
|
289
348
|
|
|
290
349
|
try {
|
|
@@ -294,6 +353,8 @@ try {
|
|
|
294
353
|
if (error instanceof LovrabetError) {
|
|
295
354
|
console.error('业务错误:', error.message);
|
|
296
355
|
console.error('错误代码:', error.code);
|
|
356
|
+
console.error('HTTP状态:', error.status);
|
|
357
|
+
console.error('服务端响应:', error.response);
|
|
297
358
|
alert('操作失败,请稍后重试');
|
|
298
359
|
} else {
|
|
299
360
|
console.error('未知错误:', error);
|
|
@@ -301,16 +362,16 @@ try {
|
|
|
301
362
|
}
|
|
302
363
|
}
|
|
303
364
|
|
|
304
|
-
//
|
|
365
|
+
// 错误:没有错误处理
|
|
305
366
|
const item = await client.models.<modelName>.create({ <field>: <value> });
|
|
306
367
|
```
|
|
307
368
|
|
|
308
|
-
##
|
|
369
|
+
## 用户体验规则
|
|
309
370
|
|
|
310
371
|
### 加载状态管理
|
|
311
372
|
|
|
312
373
|
```typescript
|
|
313
|
-
//
|
|
374
|
+
// 显示加载状态
|
|
314
375
|
const [loading, setLoading] = useState(false);
|
|
315
376
|
|
|
316
377
|
async function loadData() {
|
|
@@ -330,10 +391,10 @@ async function loadData() {
|
|
|
330
391
|
|
|
331
392
|
|
|
332
393
|
|
|
333
|
-
##
|
|
394
|
+
## 类型安全规则
|
|
334
395
|
|
|
335
396
|
```typescript
|
|
336
|
-
//
|
|
397
|
+
// 定义类型并使用泛型
|
|
337
398
|
interface DataType {
|
|
338
399
|
id: string;
|
|
339
400
|
<field1>: string;
|
|
@@ -343,52 +404,57 @@ interface DataType {
|
|
|
343
404
|
const response = await client.models.<modelName>.getList<DataType>({ pageSize: 20 });
|
|
344
405
|
|
|
345
406
|
response.tableData.forEach(item => {
|
|
346
|
-
console.log(item.<field1>); //
|
|
347
|
-
console.log(item.unknownField); //
|
|
407
|
+
console.log(item.<field1>); // 类型安全
|
|
408
|
+
console.log(item.unknownField); // 编译错误
|
|
348
409
|
});
|
|
349
410
|
```
|
|
350
411
|
|
|
351
412
|
|
|
352
413
|
|
|
353
|
-
##
|
|
414
|
+
## 禁止事项
|
|
354
415
|
|
|
355
|
-
1.
|
|
356
|
-
2.
|
|
357
|
-
3.
|
|
358
|
-
4.
|
|
359
|
-
5.
|
|
360
|
-
6.
|
|
361
|
-
7.
|
|
362
|
-
8.
|
|
416
|
+
1. **不要臆测 API** - 使用不存在的方法或参数
|
|
417
|
+
2. **不要臆测字段** - 未通过 MCP 确认字段是否存在
|
|
418
|
+
3. **不要混淆认证模式** - 在错误的模式使用功能(如 OpenAPI 模式使用 delete)
|
|
419
|
+
4. **不要忽略错误处理** - 所有 SDK 调用必须 try-catch
|
|
420
|
+
5. **不要假设返回值结构** - 注意不同方法返回值的差异
|
|
421
|
+
6. **不要在循环中调用 API** - 使用 Promise.all 批量处理
|
|
422
|
+
7. **不要在每次渲染时调用 API** - 使用 useEffect 控制
|
|
423
|
+
8. **不要使用 getList** - 应该使用功能更强大的 `filter()`(v1.1.22+ 两种模式都支持)
|
|
424
|
+
9. **不要忘记检查 execSuccess** - executeSql 返回的数据必须检查 `execSuccess` 状态
|
|
425
|
+
10. **不要假设 executeSql 返回数组** - 返回的是 `{ execSuccess, execResult }` 对象
|
|
363
426
|
|
|
364
427
|
|
|
365
428
|
|
|
366
|
-
##
|
|
429
|
+
## 快速参考
|
|
367
430
|
|
|
368
431
|
### SDK 方法返回值
|
|
369
432
|
|
|
370
433
|
| 方法 | 返回结构 | 认证限制 |
|
|
371
434
|
|------|----------|----------|
|
|
372
|
-
| `
|
|
373
|
-
| `
|
|
374
|
-
| `executeSql()` | `{ execSuccess, execResult }` |
|
|
375
|
-
| `
|
|
376
|
-
| `
|
|
377
|
-
| `
|
|
378
|
-
| `
|
|
435
|
+
| `filter()` (推荐) | `{ tableData, total }` | **OpenAPI + WebAPI**(v1.1.22+)|
|
|
436
|
+
| `getList()` | `{ paging, tableData, tableColumns }` | OpenAPI + WebAPI |
|
|
437
|
+
| `executeSql()` | `{ execSuccess, execResult }` | OpenAPI + WebAPI |
|
|
438
|
+
| `user.getList()` | `User[]` | OpenAPI + WebAPI |
|
|
439
|
+
| `getOne()` | 单个对象 | OpenAPI + WebAPI |
|
|
440
|
+
| `create/update()` | 操作结果对象 | OpenAPI + WebAPI |
|
|
441
|
+
| `delete()` | 删除结果 | 仅 WebAPI |
|
|
442
|
+
| `getSelectOptions()` | `[{ label, value }]` | 仅 WebAPI |
|
|
379
443
|
|
|
380
444
|
### 记住
|
|
381
445
|
|
|
382
|
-
-
|
|
383
|
-
-
|
|
384
|
-
-
|
|
385
|
-
-
|
|
386
|
-
-
|
|
387
|
-
-
|
|
446
|
+
- **成功**:SDK 返回 API 响应的 `data` 字段内容
|
|
447
|
+
- **失败**:抛出 `LovrabetError` 异常(不是返回错误)
|
|
448
|
+
- **所有调用**:必须用 `try-catch` 包裹
|
|
449
|
+
- **先获取元数据**:使用 MCP 确认字段存在
|
|
450
|
+
- **注意参数名**:`select`(不是 `fields`),`orderBy`(不是 `sortList`)
|
|
451
|
+
- **强烈推荐 filter**:两种模式都支持,用 `filter()` 而不是 `getList()`(v1.1.22+)
|
|
452
|
+
- **executeSql 检查状态**:应用层必须检查 `execSuccess` 状态
|
|
453
|
+
- **用户列表**:使用 `client.api.user.getList()` 获取平台用户
|
|
388
454
|
|
|
389
455
|
|
|
390
456
|
|
|
391
|
-
##
|
|
457
|
+
## 示例代码说明
|
|
392
458
|
|
|
393
459
|
**重要**:本文档中所有代码示例使用的是**占位符**(用 `<>` 包裹),而非真实字段名或值。
|
|
394
460
|
|
|
@@ -420,6 +486,6 @@ response.tableData.forEach(item => {
|
|
|
420
486
|
|
|
421
487
|
|
|
422
488
|
**学习资源**:
|
|
423
|
-
-
|
|
424
|
-
-
|
|
425
|
-
-
|
|
489
|
+
- [官方文档](https://open.lovrabet.com/docs/lovrabet-sdk/intro)
|
|
490
|
+
- [API 参考](https://open.lovrabet.com/docs/lovrabet-sdk/api-reference)
|
|
491
|
+
- [Filter API](https://open.lovrabet.com/docs/lovrabet-sdk/filter-api)
|