jinbi-utils 1.0.21 → 1.0.23
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/dist/chunk-optimizer.cjs +703 -0
- package/dist/index.esm.js +3085 -0
- package/dist/index.esm.min.js +15 -0
- package/dist/index.umd.js +3198 -0
- package/dist/index.umd.min.js +16 -0
- package/package.json +36 -3
- package/.babelrc +0 -19
- package/.cz-config.js +0 -55
- package/.dockerignore +0 -3
- package/.editorconfig +0 -12
- package/.eslintignore +0 -8
- package/.eslintrc.js +0 -54
- package/.versionrc.json +0 -9
- package/CHUNK_OPTIMIZER_USAGE.md +0 -132
- package/Dockerfile +0 -3
- package/QUICK_RELEASE.md +0 -85
- package/RELEASE_GUIDE.md +0 -243
- package/api-extractor.json +0 -15
- package/commitlint.config.js +0 -3
- package/jest.config.js +0 -15
- package/rollup.config.chunk-optimizer.js +0 -32
- package/rollup.config.js +0 -73
- package/src/array/index.ts +0 -85
- package/src/build/chunk-optimizer/ARCHITECTURE.md +0 -347
- package/src/build/chunk-optimizer/QUICK_START.md +0 -370
- package/src/build/chunk-optimizer/README.md +0 -240
- package/src/build/chunk-optimizer/core/chunk-generator.ts +0 -166
- package/src/build/chunk-optimizer/core/classifier.ts +0 -148
- package/src/build/chunk-optimizer/core/dependency-reader.ts +0 -138
- package/src/build/chunk-optimizer/examples/basic-usage.ts +0 -234
- package/src/build/chunk-optimizer/index.ts +0 -166
- package/src/build/chunk-optimizer/rules/common-rules.ts +0 -131
- package/src/build/chunk-optimizer/rules/framework-rules.ts +0 -93
- package/src/build/chunk-optimizer/rules/index.ts +0 -27
- package/src/build/chunk-optimizer/test.ts +0 -94
- package/src/build/chunk-optimizer/types.ts +0 -128
- package/src/color/index.ts +0 -58
- package/src/common/index.ts +0 -353
- package/src/constant/common.constant.ts +0 -13
- package/src/date/index.ts +0 -143
- package/src/dom/index.ts +0 -198
- package/src/file/index.ts +0 -319
- package/src/http/apiBuilder/README.md +0 -648
- package/src/http/apiBuilder/api-builder.ts +0 -502
- package/src/http/apiBuilder/example.ts +0 -243
- package/src/http/apiBuilder/index.ts +0 -1
- package/src/http/apiBuilder//345/277/253/351/200/237/345/217/202/350/200/203.md +0 -199
- package/src/http/http.ts +0 -79
- package/src/http/httpEnums.ts +0 -61
- package/src/iam/index.ts +0 -46
- package/src/index.ts +0 -20
- package/src/middleware/requestLogger.middware.ts +0 -371
- package/src/middleware/requestLoggerUnified.ts +0 -371
- package/src/number/index.ts +0 -362
- package/src/object/index.ts +0 -54
- package/src/print/index.ts +0 -102
- package/src/string/index.ts +0 -189
- package/src/utils/curl.ts +0 -108
- package/src/validate/index.ts +0 -100
- package/src/websocket/emitter.ts +0 -39
- package/src/websocket/index.ts +0 -6
- package/src/websocket/manager.ts +0 -151
- package/src/websocket/pinia-store.ts +0 -91
- package/src/websocket/service.ts +0 -34
- package/src/websocket/types.ts +0 -45
- package/test/common/index.test.ts +0 -19
- package/test/date/index.test.ts +0 -107
- package/test/file/index.test.ts +0 -104
- package/test/number/index.test.ts +0 -108
- package/test/object/index.test.ts +0 -20
- package/test/string/index.test.ts +0 -82
- package/tsconfig.json +0 -39
- package/typedoc.json +0 -12
|
@@ -1,648 +0,0 @@
|
|
|
1
|
-
# API Builder (TypeScript)
|
|
2
|
-
|
|
3
|
-
快速组装后端 JSON 格式请求参数的工具库。
|
|
4
|
-
|
|
5
|
-
## ✨ 特性
|
|
6
|
-
|
|
7
|
-
- TypeScript 编写,完整类型支持
|
|
8
|
-
- ESM 模块
|
|
9
|
-
- Knex 风格链式调用
|
|
10
|
-
- 支持查询、新增、更新操作
|
|
11
|
-
|
|
12
|
-
## 📦 安装
|
|
13
|
-
|
|
14
|
-
复制 `api-builder.ts` 到你的项目:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
cp api-builder-ts/api-builder.ts src/utils/
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## 🚀 快速开始
|
|
21
|
-
|
|
22
|
-
### 1. 准备 field_catalog(可选)
|
|
23
|
-
|
|
24
|
-
从 API 文档中复制 `field_catalog`(后端提供的字段元数据):
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
const fieldCatalog = {
|
|
28
|
-
"sfs_cart.user_id": {
|
|
29
|
-
type: "number",
|
|
30
|
-
label: "用户ID",
|
|
31
|
-
allowed_field: "user_id",
|
|
32
|
-
nullable: false,
|
|
33
|
-
dict_field: false
|
|
34
|
-
},
|
|
35
|
-
"sfs_cart.goods_id": {
|
|
36
|
-
type: "number",
|
|
37
|
-
label: "商品ID",
|
|
38
|
-
allowed_field: "goods_id",
|
|
39
|
-
nullable: false,
|
|
40
|
-
dict_field: false
|
|
41
|
-
}
|
|
42
|
-
// ... 其他字段
|
|
43
|
-
};
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
**注意:** `field_catalog` 是可选的。如果后端不需要这个字段,可以不传。
|
|
47
|
-
|
|
48
|
-
### 2. 实例化 ApiBuilder
|
|
49
|
-
|
|
50
|
-
```typescript
|
|
51
|
-
import ApiBuilder from './utils/api-builder';
|
|
52
|
-
|
|
53
|
-
// 方式 1:传入 fieldCatalog(生成的参数包含 field_catalog)
|
|
54
|
-
const cartApi = new ApiBuilder(fieldCatalog);
|
|
55
|
-
|
|
56
|
-
// 方式 2:不传 fieldCatalog(生成的参数不包含 field_catalog)
|
|
57
|
-
const simpleApi = new ApiBuilder();
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### 3. 开始使用
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
// 查询
|
|
64
|
-
const params = cartApi.query()
|
|
65
|
-
.where('user_id', 10086)
|
|
66
|
-
.where('is_deleted', 0)
|
|
67
|
-
.orderBy('created_time', 'desc')
|
|
68
|
-
.limit(20)
|
|
69
|
-
.build();
|
|
70
|
-
|
|
71
|
-
// 发送请求
|
|
72
|
-
const response = await axios.post('/api/cart/query', params);
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
**生成的参数示例:**
|
|
76
|
-
|
|
77
|
-
```json
|
|
78
|
-
// 传入 fieldCatalog
|
|
79
|
-
{
|
|
80
|
-
"filters": { "logic": "and", "filters": [...] },
|
|
81
|
-
"order_by": [...],
|
|
82
|
-
"limit": 20,
|
|
83
|
-
"offset": 0,
|
|
84
|
-
"field_catalog": { ... } // 包含 field_catalog
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// 不传 fieldCatalog
|
|
88
|
-
{
|
|
89
|
-
"filters": { "logic": "and", "filters": [...] },
|
|
90
|
-
"order_by": [...],
|
|
91
|
-
"limit": 20,
|
|
92
|
-
"offset": 0
|
|
93
|
-
// 不包含 field_catalog
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## 📚 完整 API 文档
|
|
98
|
-
|
|
99
|
-
### QueryBuilder - 查询构建器
|
|
100
|
-
|
|
101
|
-
#### 基础 WHERE 条件
|
|
102
|
-
|
|
103
|
-
```typescript
|
|
104
|
-
// 两参数形式(默认 = 操作符)
|
|
105
|
-
.where('user_id', 10086)
|
|
106
|
-
|
|
107
|
-
// 三参数形式(指定操作符)
|
|
108
|
-
.where('age', '>', 18)
|
|
109
|
-
.where('price', '>=', 100)
|
|
110
|
-
.where('status', '!=', 0)
|
|
111
|
-
|
|
112
|
-
// 对象形式(多个 AND 条件)
|
|
113
|
-
.where({ user_id: 10086, is_deleted: 0, status: 1 })
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
#### OR 条件
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
// OR WHERE
|
|
120
|
-
.where('status', 1)
|
|
121
|
-
.orWhere('status', 2)
|
|
122
|
-
.orWhere('status', 3)
|
|
123
|
-
|
|
124
|
-
// 对象形式
|
|
125
|
-
.orWhere({ status: 1, type: 'A' })
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
#### IN / NOT IN
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
// WHERE IN
|
|
132
|
-
.whereIn('status', [1, 2, 3])
|
|
133
|
-
|
|
134
|
-
// WHERE NOT IN
|
|
135
|
-
.whereNotIn('status', [0, -1])
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
#### LIKE 查询
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
// WHERE LIKE
|
|
142
|
-
.whereLike('goods_name', '%手机%')
|
|
143
|
-
.whereLike('title', '苹果%') // 以"苹果"开头
|
|
144
|
-
.whereLike('description', '%优惠') // 以"优惠"结尾
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
#### NULL 查询
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
// WHERE NULL
|
|
151
|
-
.whereNull('deleted_at')
|
|
152
|
-
|
|
153
|
-
// WHERE NOT NULL
|
|
154
|
-
.whereNotNull('goods_price')
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
#### BETWEEN
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
// WHERE BETWEEN
|
|
161
|
-
.whereBetween('price', 100, 500)
|
|
162
|
-
.whereBetween('created_time', '2024-01-01', '2024-12-31')
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
#### 排序
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
// 升序(默认)
|
|
169
|
-
.orderBy('created_time')
|
|
170
|
-
|
|
171
|
-
// 降序
|
|
172
|
-
.orderBy('created_time', 'desc')
|
|
173
|
-
|
|
174
|
-
// 多个排序
|
|
175
|
-
.orderBy('status', 'asc')
|
|
176
|
-
.orderBy('created_time', 'desc')
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
#### 分页
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
// 方式 1:limit + offset
|
|
183
|
-
.limit(20)
|
|
184
|
-
.offset(0)
|
|
185
|
-
|
|
186
|
-
// 方式 2:paginate(便捷方法)
|
|
187
|
-
.paginate(20, 0)
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
#### 完整示例
|
|
191
|
-
|
|
192
|
-
``typescript
|
|
193
|
-
const params = cartApi.query()
|
|
194
|
-
.where('user_id', 10086)
|
|
195
|
-
.whereIn('status', [1, 2, 3])
|
|
196
|
-
.whereLike('goods_name', '%手机%')
|
|
197
|
-
.whereNotNull('goods_price')
|
|
198
|
-
.whereBetween('price', 100, 1000)
|
|
199
|
-
.orderBy('created_time', 'desc')
|
|
200
|
-
.limit(20)
|
|
201
|
-
.offset(0)
|
|
202
|
-
.build();
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
#### 嵌套过滤条件
|
|
206
|
-
|
|
207
|
-
对于复杂的查询需求,可以使用嵌套过滤条件来构建更复杂的逻辑结构:
|
|
208
|
-
|
|
209
|
-
```typescript
|
|
210
|
-
// 使用 whereNested 方法添加嵌套条件
|
|
211
|
-
const params = cartApi.query()
|
|
212
|
-
.where('orderStatus', 'in', [1, 2])
|
|
213
|
-
.where('createdBy', '=', 2511261629388069)
|
|
214
|
-
.whereNested({
|
|
215
|
-
logic: 'or',
|
|
216
|
-
filters: [
|
|
217
|
-
{ field: 'orderId', op: 'like', value: 'wwu' },
|
|
218
|
-
{ field: 'goodNameGroup', op: 'like', value: 'wwu' },
|
|
219
|
-
{ field: 'recipientName', op: 'like', value: 'wwu' },
|
|
220
|
-
{ field: 'recipientPhone', op: 'like', value: 'wwu' }
|
|
221
|
-
]
|
|
222
|
-
})
|
|
223
|
-
.build();
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
嵌套过滤条件允许构建如下结构的复杂查询:
|
|
227
|
-
|
|
228
|
-
```
|
|
229
|
-
{
|
|
230
|
-
"filters": {
|
|
231
|
-
"logic": "and",
|
|
232
|
-
"filters": [
|
|
233
|
-
{
|
|
234
|
-
"field": "orderStatus",
|
|
235
|
-
"op": "in",
|
|
236
|
-
"value": [1, 2]
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
"field": "createdBy",
|
|
240
|
-
"op": "=",
|
|
241
|
-
"value": 2511261629388069
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
"logic": "or",
|
|
245
|
-
"filters": [
|
|
246
|
-
{
|
|
247
|
-
"field": "orderId",
|
|
248
|
-
"op": "like",
|
|
249
|
-
"value": "wwu"
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
"field": "goodNameGroup",
|
|
253
|
-
"op": "like",
|
|
254
|
-
"value": "wwu"
|
|
255
|
-
},
|
|
256
|
-
{
|
|
257
|
-
"field": "recipientName",
|
|
258
|
-
"op": "like",
|
|
259
|
-
"value": "wwu"
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
"field": "recipientPhone",
|
|
263
|
-
"op": "like",
|
|
264
|
-
"value": "wwu"
|
|
265
|
-
}
|
|
266
|
-
]
|
|
267
|
-
}
|
|
268
|
-
]
|
|
269
|
-
},
|
|
270
|
-
"order_by": [],
|
|
271
|
-
"limit": 100,
|
|
272
|
-
"offset": 0
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
#### 链式嵌套构建器
|
|
277
|
-
|
|
278
|
-
为了更方便地构建多层嵌套条件,我们提供了链式嵌套构建器:
|
|
279
|
-
|
|
280
|
-
```typescript
|
|
281
|
-
// 使用 group 方法创建嵌套组并链式构建条件
|
|
282
|
-
const params = cartApi.query()
|
|
283
|
-
.where('status', 'in', [1, 2, 3])
|
|
284
|
-
.group('or')
|
|
285
|
-
.where('category', '=', 'electronics')
|
|
286
|
-
.group('and')
|
|
287
|
-
.where('price', '>=', 100)
|
|
288
|
-
.group('or')
|
|
289
|
-
.where('brand', 'like', 'Apple')
|
|
290
|
-
.where('brand', 'like', 'Samsung')
|
|
291
|
-
.endGroup() // 结束第三层嵌套
|
|
292
|
-
.endGroup() // 结束第二层嵌套
|
|
293
|
-
.endGroup() // 结束第一层嵌套
|
|
294
|
-
.orderBy('createdTime', 'desc')
|
|
295
|
-
.limit(20)
|
|
296
|
-
.build();
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
这种方式可以构建任意深度的嵌套结构,让复杂查询的构建更加直观和易于维护。
|
|
300
|
-
|
|
301
|
-
更复杂的嵌套示例:
|
|
302
|
-
|
|
303
|
-
``typescript
|
|
304
|
-
const params = cartApi.query()
|
|
305
|
-
.where('userId', '=', 12345)
|
|
306
|
-
.group('or')
|
|
307
|
-
.where('orderType', 'in', ['online', 'offline'])
|
|
308
|
-
.group('and')
|
|
309
|
-
.where('amount', '>', 1000)
|
|
310
|
-
.group('or')
|
|
311
|
-
.where('region', '=', 'north')
|
|
312
|
-
.group('and')
|
|
313
|
-
.where('discount', '>', 0.1)
|
|
314
|
-
.where('vipLevel', '>=', 3)
|
|
315
|
-
.endGroup() // 结束第四层嵌套
|
|
316
|
-
.endGroup() // 结束第三层嵌套
|
|
317
|
-
.endGroup() // 结束第二层嵌套
|
|
318
|
-
.endGroup() // 结束第一层嵌套
|
|
319
|
-
.orderBy('createTime', 'desc')
|
|
320
|
-
.limit(50)
|
|
321
|
-
.build();
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
### InsertBuilder - 新增构建器
|
|
325
|
-
|
|
326
|
-
#### 单条新增
|
|
327
|
-
|
|
328
|
-
```typescript
|
|
329
|
-
const params = cartApi.insert()
|
|
330
|
-
.add({
|
|
331
|
-
cart_id: 19,
|
|
332
|
-
user_id: 10086,
|
|
333
|
-
store_id: 2001,
|
|
334
|
-
goods_id: 30005,
|
|
335
|
-
quantity: 6,
|
|
336
|
-
goods_price: 50,
|
|
337
|
-
selected: 1
|
|
338
|
-
})
|
|
339
|
-
.build();
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
#### 批量新增
|
|
343
|
-
|
|
344
|
-
```typescript
|
|
345
|
-
const params = cartApi.insert()
|
|
346
|
-
.addBatch([
|
|
347
|
-
{ user_id: 10086, goods_id: 30005, quantity: 6 },
|
|
348
|
-
{ user_id: 10086, goods_id: 30006, quantity: 1 },
|
|
349
|
-
{ user_id: 10086, goods_id: 30007, quantity: 3 }
|
|
350
|
-
])
|
|
351
|
-
.build();
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
### UpdateBuilder - 更新构建器
|
|
355
|
-
|
|
356
|
-
#### 单条更新
|
|
357
|
-
|
|
358
|
-
```typescript
|
|
359
|
-
// 对象形式
|
|
360
|
-
const params = cartApi.update()
|
|
361
|
-
.set({ selected: 1 })
|
|
362
|
-
.where({ id: 1 })
|
|
363
|
-
.build();
|
|
364
|
-
|
|
365
|
-
// 键值对形式
|
|
366
|
-
const params = cartApi.update()
|
|
367
|
-
.set({ quantity: 5 })
|
|
368
|
-
.where('id', 1)
|
|
369
|
-
.build();
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
#### 多个条件
|
|
373
|
-
|
|
374
|
-
```typescript
|
|
375
|
-
const params = cartApi.update()
|
|
376
|
-
.set({ selected: 1 })
|
|
377
|
-
.where('user_id', 10086)
|
|
378
|
-
.where('goods_id', 30005)
|
|
379
|
-
.build();
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
#### 批量更新
|
|
383
|
-
|
|
384
|
-
```typescript
|
|
385
|
-
const params = cartApi.update()
|
|
386
|
-
.set({ selected: 0 })
|
|
387
|
-
.where({ id: 1 })
|
|
388
|
-
.and() // 开始下一个更新操作
|
|
389
|
-
.set({ is_deleted: 1 })
|
|
390
|
-
.where({ id: 2 })
|
|
391
|
-
.and()
|
|
392
|
-
.set({ quantity: 10 })
|
|
393
|
-
.where({ id: 3 })
|
|
394
|
-
.build();
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
## 💡 实际应用示例
|
|
398
|
-
|
|
399
|
-
### 购物车服务类
|
|
400
|
-
|
|
401
|
-
``typescript
|
|
402
|
-
import ApiBuilder from './utils/api-builder';
|
|
403
|
-
import axios from 'axios';
|
|
404
|
-
|
|
405
|
-
const CART_CATALOG = { /* field_catalog */ };
|
|
406
|
-
|
|
407
|
-
class CartService {
|
|
408
|
-
private static api = new ApiBuilder(CART_CATALOG);
|
|
409
|
-
|
|
410
|
-
// 查询用户购物车
|
|
411
|
-
static async getCart(userId: number, page = 1, pageSize = 20) {
|
|
412
|
-
const params = this.api.query()
|
|
413
|
-
.where('user_id', userId)
|
|
414
|
-
.where('is_deleted', 0)
|
|
415
|
-
.orderBy('created_time', 'desc')
|
|
416
|
-
.limit(pageSize)
|
|
417
|
-
.offset((page - 1) * pageSize)
|
|
418
|
-
.build();
|
|
419
|
-
|
|
420
|
-
return axios.post('/api/sfs/cart/query/goods', params);
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
// 搜索商品
|
|
424
|
-
static async searchGoods(keyword: string) {
|
|
425
|
-
const params = this.api.query()
|
|
426
|
-
.whereLike('goods_name', `%${keyword}%`)
|
|
427
|
-
.where('is_deleted', 0)
|
|
428
|
-
.whereNotNull('goods_price')
|
|
429
|
-
.orderBy('created_time', 'desc')
|
|
430
|
-
.limit(50)
|
|
431
|
-
.build();
|
|
432
|
-
|
|
433
|
-
return axios.post('/api/sfs/cart/query/goods', params);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// 查询选中的商品
|
|
437
|
-
static async getSelectedItems(userId: number) {
|
|
438
|
-
const params = this.api.query()
|
|
439
|
-
.where({ user_id: userId, selected: 1, is_deleted: 0 })
|
|
440
|
-
.orderBy('created_time', 'desc')
|
|
441
|
-
.build();
|
|
442
|
-
|
|
443
|
-
return axios.post('/api/sfs/cart/query/goods', params);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
// 查询特定状态的商品
|
|
447
|
-
static async getByStatus(userId: number, statuses: number[]) {
|
|
448
|
-
const params = this.api.query()
|
|
449
|
-
.where('user_id', userId)
|
|
450
|
-
.whereIn('status', statuses)
|
|
451
|
-
.where('is_deleted', 0)
|
|
452
|
-
.limit(100)
|
|
453
|
-
.build();
|
|
454
|
-
|
|
455
|
-
return axios.post('/api/sfs/cart/query/goods', params);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
// 价格区间查询
|
|
459
|
-
static async getByPriceRange(userId: number, min: number, max: number) {
|
|
460
|
-
const params = this.api.query()
|
|
461
|
-
.where('user_id', userId)
|
|
462
|
-
.whereBetween('goods_price', min, max)
|
|
463
|
-
.where('is_deleted', 0)
|
|
464
|
-
.limit(100)
|
|
465
|
-
.build();
|
|
466
|
-
|
|
467
|
-
return axios.post('/api/sfs/cart/query/goods', params);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// 添加到购物车
|
|
471
|
-
static async addToCart(item: {
|
|
472
|
-
cart_id: number;
|
|
473
|
-
user_id: number;
|
|
474
|
-
store_id: number;
|
|
475
|
-
goods_id: number;
|
|
476
|
-
quantity: number;
|
|
477
|
-
goods_price: number;
|
|
478
|
-
}) {
|
|
479
|
-
const params = this.api.insert()
|
|
480
|
-
.add({ ...item, selected: 1 })
|
|
481
|
-
.build();
|
|
482
|
-
|
|
483
|
-
return axios.post('/api/sfs/cart/add', params);
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// 批量添加
|
|
487
|
-
static async addBatch(items: any[]) {
|
|
488
|
-
const params = this.api.insert()
|
|
489
|
-
.addBatch(items)
|
|
490
|
-
.build();
|
|
491
|
-
|
|
492
|
-
return axios.post('/api/sfs/cart/add', params);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
// 选中商品
|
|
496
|
-
static async selectItem(itemId: number) {
|
|
497
|
-
const params = this.api.update()
|
|
498
|
-
.set({ selected: 1 })
|
|
499
|
-
.where({ id: itemId })
|
|
500
|
-
.build();
|
|
501
|
-
|
|
502
|
-
return axios.post('/api/sfs/cart/update', params);
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
// 更新数量
|
|
506
|
-
static async updateQuantity(itemId: number, quantity: number) {
|
|
507
|
-
const params = this.api.update()
|
|
508
|
-
.set({ quantity })
|
|
509
|
-
.where({ id: itemId })
|
|
510
|
-
.build();
|
|
511
|
-
|
|
512
|
-
return axios.post('/api/sfs/cart/update', params);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
// 删除商品(逻辑删除)
|
|
516
|
-
static async deleteItem(itemId: number) {
|
|
517
|
-
const params = this.api.update()
|
|
518
|
-
.set({ is_deleted: 1 })
|
|
519
|
-
.where({ id: itemId })
|
|
520
|
-
.build();
|
|
521
|
-
|
|
522
|
-
return axios.post('/api/sfs/cart/update', params);
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// 批量删除
|
|
526
|
-
static async deleteBatch(itemIds: number[]) {
|
|
527
|
-
const builder = this.api.update();
|
|
528
|
-
|
|
529
|
-
itemIds.forEach((id, index) => {
|
|
530
|
-
if (index > 0) builder.and();
|
|
531
|
-
builder.set({ is_deleted: 1 }).where({ id });
|
|
532
|
-
});
|
|
533
|
-
|
|
534
|
-
return axios.post('/api/sfs/cart/update', builder.build());
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
// 使用示例
|
|
539
|
-
const cart = await CartService.getCart(10086, 1, 20);
|
|
540
|
-
const searchResults = await CartService.searchGoods('手机');
|
|
541
|
-
await CartService.selectItem(123);
|
|
542
|
-
await CartService.deleteItem(456);
|
|
543
|
-
```
|
|
544
|
-
|
|
545
|
-
## 🎯 使用技巧
|
|
546
|
-
|
|
547
|
-
### 1. fieldCatalog 可选
|
|
548
|
-
|
|
549
|
-
如果后端不需要 `field_catalog` 字段,可以不传:
|
|
550
|
-
|
|
551
|
-
```typescript
|
|
552
|
-
// 不传 fieldCatalog
|
|
553
|
-
const api = new ApiBuilder();
|
|
554
|
-
|
|
555
|
-
const params = api.query()
|
|
556
|
-
.where('user_id', 10086)
|
|
557
|
-
.limit(20)
|
|
558
|
-
.build();
|
|
559
|
-
|
|
560
|
-
// 生成的参数不包含 field_catalog
|
|
561
|
-
// { filters: {...}, order_by: [], limit: 20, offset: 0 }
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
### 2. 为不同的表创建不同的实例
|
|
565
|
-
|
|
566
|
-
```typescript
|
|
567
|
-
const cartApi = new ApiBuilder(CART_CATALOG);
|
|
568
|
-
const orderApi = new ApiBuilder(ORDER_CATALOG);
|
|
569
|
-
const userApi = new ApiBuilder(USER_CATALOG);
|
|
570
|
-
|
|
571
|
-
// 或者不传 fieldCatalog
|
|
572
|
-
const simpleApi = new ApiBuilder();
|
|
573
|
-
```
|
|
574
|
-
|
|
575
|
-
### 3. 在服务类中使用
|
|
576
|
-
|
|
577
|
-
```typescript
|
|
578
|
-
class CartService {
|
|
579
|
-
private static api = new ApiBuilder(); // 不传 fieldCatalog
|
|
580
|
-
|
|
581
|
-
static getCart(userId: number) {
|
|
582
|
-
return this.api
|
|
583
|
-
.query()
|
|
584
|
-
.where("user_id", userId)
|
|
585
|
-
.where("is_deleted", 0)
|
|
586
|
-
.limit(20)
|
|
587
|
-
.build();
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
static addToCart(item: any) {
|
|
591
|
-
return this.api.insert().add(item).build();
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
static updateItem(itemId: number, data: any) {
|
|
595
|
-
return this.api.update().set(data).where({ id: itemId }).build();
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
### 4. 组合查询条件
|
|
601
|
-
|
|
602
|
-
``typescript
|
|
603
|
-
// 根据条件动态构建查询
|
|
604
|
-
const builder = cartApi.query().where('user_id', userId);
|
|
605
|
-
|
|
606
|
-
if (keyword) {
|
|
607
|
-
builder.whereLike('goods_name', `%${keyword}%`);
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
if (minPrice) {
|
|
611
|
-
builder.where('goods_price', '>=', minPrice);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
if (maxPrice) {
|
|
615
|
-
builder.where('goods_price', '<=', maxPrice);
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
const params = builder.limit(20).build();
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
## 🔄 向后兼容
|
|
622
|
-
|
|
623
|
-
旧的静态方法仍然支持:
|
|
624
|
-
|
|
625
|
-
``typescript
|
|
626
|
-
// 旧用法
|
|
627
|
-
ApiBuilder.query(fieldCatalog).where('user_id', '=', 10086).build();
|
|
628
|
-
ApiBuilder.insert(fieldCatalog).add({...}).build();
|
|
629
|
-
ApiBuilder.update(fieldCatalog).set({...}).where({...}).build();
|
|
630
|
-
|
|
631
|
-
// 新用法(推荐)
|
|
632
|
-
const api = new ApiBuilder(fieldCatalog);
|
|
633
|
-
api.query().where('user_id', 10086).build();
|
|
634
|
-
api.insert().add({...}).build();
|
|
635
|
-
api.update().set({...}).where({...}).build();
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
## 💪 优势
|
|
639
|
-
|
|
640
|
-
1. **代码简洁** - 实例化一次,多次使用
|
|
641
|
-
2. **类型安全** - TypeScript 完整类型支持
|
|
642
|
-
3. **易于上手** - 类似 Knex.js 的语法
|
|
643
|
-
4. **灵活强大** - 支持各种查询条件
|
|
644
|
-
5. **向后兼容** - 不破坏现有代码
|
|
645
|
-
|
|
646
|
-
## 🎉 开始使用
|
|
647
|
-
|
|
648
|
-
复制 `api-builder.ts` 到你的项目,开始享受简洁的 API 构建体验!
|