@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.
Files changed (56) hide show
  1. package/lib/add-page/input-page-router.js +1 -1
  2. package/lib/add-page/main.js +1 -1
  3. package/lib/add-page/select-page-template.js +1 -1
  4. package/lib/api/api-doc-ui.js +1 -1
  5. package/lib/api/api-doc.js +1 -1
  6. package/lib/api/api-pull-ui.js +1 -1
  7. package/lib/api/fetch-model-list.js +1 -1
  8. package/lib/api/generate-api-file.js +1 -1
  9. package/lib/api/main.js +1 -1
  10. package/lib/api/pull-silent.js +1 -1
  11. package/lib/app-menu/app-menu-sync-ui.js +1 -1
  12. package/lib/app-menu/create-menu.js +1 -1
  13. package/lib/app-menu/get-local-pages.js +1 -1
  14. package/lib/app-menu/get-online-menu-list.js +1 -1
  15. package/lib/app-menu/valid-url.js +1 -1
  16. package/lib/auth/auth-server-ui.js +1 -1
  17. package/lib/auth/auth-server.js +1 -1
  18. package/lib/auth/constant.js +1 -1
  19. package/lib/auth/get-cookie.js +1 -1
  20. package/lib/auth/is-session-valid.js +1 -1
  21. package/lib/auth/logout.js +1 -1
  22. package/lib/cli.js +1 -1
  23. package/lib/cmd/build-watch.js +1 -1
  24. package/lib/cmd/build.js +1 -1
  25. package/lib/cmd/logs.js +1 -1
  26. package/lib/cmd/preview.js +1 -1
  27. package/lib/cmd/start.js +1 -1
  28. package/lib/config/config-help.js +1 -1
  29. package/lib/config/main.js +1 -1
  30. package/lib/constant/domain.js +1 -1
  31. package/lib/constant/env.js +1 -1
  32. package/lib/create-app/enhanced-guided-create.js +1 -1
  33. package/lib/create-app/format-elapsed.js +1 -1
  34. package/lib/create-app/main.js +1 -1
  35. package/lib/create-app/task-finished.js +1 -1
  36. package/lib/create-app/task-loading.js +1 -1
  37. package/lib/create-app/task-running.js +1 -1
  38. package/lib/create-app/task-time.js +1 -1
  39. package/lib/create-app/use-copy-project-template.js +1 -1
  40. package/lib/create-app/use-format-code.js +1 -1
  41. package/lib/create-app/use-install-dependencies.js +1 -1
  42. package/lib/help.js +1 -1
  43. package/lib/init/main.js +1 -1
  44. package/lib/mcp/cursor.js +1 -1
  45. package/lib/mcp/main.js +1 -1
  46. package/lib/utils/config.js +1 -1
  47. package/lib/utils/copy-directory.js +1 -1
  48. package/lib/utils/http-client.js +1 -1
  49. package/lib/utils/logger.js +1 -1
  50. package/lib/utils/router-updater.js +1 -1
  51. package/lib/utils/sleep.js +1 -1
  52. package/lib/utils/template-replacer.js +1 -1
  53. package/package.json +1 -1
  54. package/templates/projects/sub-app-react-demo/package-lock.json +4 -4
  55. package/templates/projects/sub-app-react-demo/package.json +1 -1
  56. 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
- ## 📚 SDK 使用规范
20
+ ## SDK 使用规范
21
21
 
22
22
  ### 1. SDK 初始化
23
23
 
24
24
  ```typescript
25
25
  import { createClient } from '@lovrabet/sdk';
26
26
 
27
- // 正确:使用 createClient 函数
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
- // 错误:使用 new 关键字
41
+ // 错误:使用 new 关键字
42
42
  const client = new LovrabetClient({ ... });
43
43
 
44
- // 错误:使用不存在的 mode 参数
44
+ // 错误:使用不存在的 mode 参数
45
45
  const client = createClient({ mode: 'webapi', ... });
46
46
 
47
- // 错误:缺少必需的 models 配置
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, data?: any }`
58
+ - 异常对象包含:`{ message: string, status?: number, code?: string, response?: any }`
59
+ - `response` 包含服务端完整响应数据
59
60
  - 不会返回错误信息,而是抛出异常,需要使用 `try-catch` 包裹所有 SDK 调用
60
61
 
61
62
  **关键提示**:
62
- - 必须使用 `try-catch` 包裹所有 SDK 调用
63
- - 成功时直接获取业务数据(如 `{ id: 123, name: "..." }`)
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
- // 错误:假设返回值包含 success 字段
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
- **⚠️ 重要提示:优先使用 `filter()` 而不是 `getList()`**
88
+ **重要提示:强烈建议使用 `filter()` 而不是 `getList()`**
87
89
 
88
- 在 Cookie 认证模式下,应该优先使用 `filter()` 方法,因为它提供:
89
- - 更强大的查询能力(支持复杂条件、范围查询、模糊匹配)
90
- - 更好的性能(通过 `select` 参数只返回需要的字段)
91
- - 更简洁的返回结构(直接返回 `{ tableData, total }`)
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
- 只在以下情况使用 `getList()`:
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
- // ✅ 推荐:filter 功能强大,性能更好
102
+ // 强烈推荐:filter 功能强大,性能更好,两种模式都支持
126
103
  const result = await client.models.<modelName>.filter({
127
104
  where: {
128
105
  $and: [
129
- { <fieldName>: { $gte: 18, $lte: 35 } },
130
- { <fieldName>: { $in: ['<value1>', '<value2>'] } },
106
+ { age: { $gte: 18, $lte: 45 } }, // 年龄区间
107
+ { country: { $in: ['中国', '美国', '日本'] } }, // 国家在集合内
108
+ { vip: { $ne: null } }, // VIP 字段非空
109
+ { name: { $contain: 'hello' } }, // 名称模糊匹配
131
110
  ],
132
111
  },
133
- select: ['<field1>', '<field2>', '<field3>'], // 注意:是 select,不是 fields
134
- orderBy: [{ <fieldName>: SortOrder.DESC }], // 注意:是 orderBy,不是 sortList
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
- fields: ['<field1>', '<field2>'], // 错误!应该是 select
145
- sortList: [{ ... }], // 错误!应该是 orderBy
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
- // ✅ 正确:executeSql 返回 { execSuccess, execResult }
155
- const data = await client.api.executeSql<MyType>(<sql-code>);
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 results = await client.api.executeSql(<sql-code>);
163
- results.forEach(...); // 错误!返回的是对象,不是数组
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
- **Token/AccessKey 模式**:
191
- - getList, getOne, create, update, executeSql
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
- - delete, filter, getSelectOptions
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
- // 错误:在 Token 模式使用 filter
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>.filter({ ... }); // 会失败
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
- ## 🔧 MCP 使用规范
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
- // 推荐:使用 filter + select 只返回需要的字段
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
- // ⚠️ 不推荐:getList 返回所有字段,浪费带宽
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
- // 避免 N+1 问题
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. **不要臆测 API** - 使用不存在的方法或参数
356
- 2. **不要臆测字段** - 未通过 MCP 确认字段是否存在
357
- 3. **不要混淆认证模式** - 在错误的模式使用功能
358
- 4. **不要忽略错误处理** - 所有 SDK 调用必须 try-catch
359
- 5. **不要假设返回值结构** - 注意不同方法返回值的差异
360
- 6. **不要在循环中调用 API** - 使用 Promise.all 批量处理
361
- 7. **不要在每次渲染时调用 API** - 使用 useEffect 控制
362
- 8. **不要在 Cookie 模式下使用 getList** - 应该使用功能更强大的 filter
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
- | `getList()` | `{ paging, tableData, tableColumns }` | 所有模式 |
373
- | `filter()` | `{ tableData, total }` | Cookie |
374
- | `executeSql()` | `{ execSuccess, execResult }` | 所有模式 |
375
- | `getOne()` | 单个对象 | 所有模式 |
376
- | `create/update()` | 操作结果对象 | 所有模式 |
377
- | `delete()` | 删除结果 | Cookie |
378
- | `getSelectOptions()` | `[{ label, value }]` | 仅 Cookie |
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
- - **成功**:SDK 返回 API 响应的 `data` 字段内容
383
- - **失败**:抛出 `LovrabetError` 异常(不是返回错误)
384
- - **所有调用**:必须用 `try-catch` 包裹
385
- - **先获取元数据**:使用 MCP 确认字段存在
386
- - **注意参数名**:`select`(不是 `fields`),`orderBy`(不是 `sortList`)
387
- - **优先使用 filter**:Cookie 模式下用 `filter()` 而不是 `getList()`
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
- - 📖 [官方文档](https://open.lovrabet.com/docs/lovrabet-sdk/intro)
424
- - 📋 [API 参考](https://open.lovrabet.com/docs/lovrabet-sdk/api-reference)
425
- - 🔍 [Filter API](https://open.lovrabet.com/docs/lovrabet-sdk/filter-api)
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)