listpage_cli 0.0.299 → 0.0.300
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/package.json +1 -1
- package/templates/backend-template/package.json.tmpl +1 -1
- package/templates/frontend-template/package.json.tmpl +2 -2
- package/templates/skills-template/listpage-http/SKILL.md +1 -0
- package/templates/skills-template/listpage-http/api.md +5 -3
- package/templates/skills-template/listpage-http/examples.md +95 -5
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"react": "^19.2.0",
|
|
14
14
|
"react-dom": "^19.2.0",
|
|
15
|
-
"listpage-next": "~0.0.
|
|
15
|
+
"listpage-next": "~0.0.300",
|
|
16
16
|
"react-router-dom": ">=6.0.0",
|
|
17
17
|
"@ant-design/v5-patch-for-react-19": "~1.0.3",
|
|
18
18
|
"ahooks": "^3.9.5",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"styled-components": "^6.1.19",
|
|
24
24
|
"mobx": "~6.15.0",
|
|
25
25
|
"@ant-design/icons": "~6.0.2",
|
|
26
|
-
"listpage-components": "~0.0.
|
|
26
|
+
"listpage-components": "~0.0.300",
|
|
27
27
|
"lucide-react": "~0.575.0"
|
|
28
28
|
"mobx-react-lite": "~4.1.1"
|
|
29
29
|
},
|
|
@@ -60,6 +60,7 @@ Task Progress:
|
|
|
60
60
|
|
|
61
61
|
## 命名与模块约定
|
|
62
62
|
|
|
63
|
+
- **文件命名**:统一使用短横线间隔(kebab-case),例如:`request-config.ts`、`user-profile.ts`、`order-detail.ts`。
|
|
63
64
|
- **模块名**:`requestConfig` 中一级 key 建议与模块文件名一致,如 `user`、`order`。
|
|
64
65
|
- **方法名**:使用动词短语小驼峰,如 `login`、`list`、`detail`、`create`、`update`、`remove`。
|
|
65
66
|
- **类型命名**:
|
|
@@ -41,7 +41,8 @@ export function defineEndpoint<Req, Res>(
|
|
|
41
41
|
|
|
42
42
|
用途:
|
|
43
43
|
|
|
44
|
-
- 声明接口的 HTTP 方法、路径、是否 SSE
|
|
44
|
+
- 声明接口的 HTTP 方法、路径、是否 SSE、是否需要鉴权,以及数据模式(`mode`)。
|
|
45
|
+
- 当 `mode === "upload"` 时,请求体参数会被视为普通对象,并在内部自动转换为 `FormData` 进行 `multipart/form-data` 上传。
|
|
45
46
|
- 绑定请求泛型 `Req` 与响应泛型 `Res`,后续通过 `ApiClient` 自动推导。
|
|
46
47
|
|
|
47
48
|
### ClientOptions
|
|
@@ -78,7 +79,7 @@ export interface ClientOptions {
|
|
|
78
79
|
|
|
79
80
|
```ts
|
|
80
81
|
export interface RequestOptions {
|
|
81
|
-
timeout?: number; //
|
|
82
|
+
timeout?: number; // 单次调用超时(传 0 表示显式关闭超时)
|
|
82
83
|
headers?: Record<string, string>;
|
|
83
84
|
cache?: {
|
|
84
85
|
key?: string;
|
|
@@ -89,7 +90,8 @@ export interface RequestOptions {
|
|
|
89
90
|
|
|
90
91
|
说明:
|
|
91
92
|
|
|
92
|
-
-
|
|
93
|
+
- 若未显式配置 `timeout`,则不启用超时逻辑(不会使用 `ClientOptions.defaultTimeout`)。
|
|
94
|
+
- 若在接口级或调用级将 `timeout` 显式设置为 `0`,则表示**本次请求不使用超时逻辑**,并覆盖掉任何默认超时。
|
|
93
95
|
- 若不配 `cache`,则该次请求不走缓存逻辑。
|
|
94
96
|
|
|
95
97
|
### ApiClient<Cfg>
|
|
@@ -46,7 +46,47 @@ export type RequestConfig = typeof requestConfig;
|
|
|
46
46
|
|
|
47
47
|
---
|
|
48
48
|
|
|
49
|
-
## 3.
|
|
49
|
+
## 3. 无参数接口示例(`Req = void`)
|
|
50
|
+
|
|
51
|
+
对于完全没有请求体的接口,推荐将 `Req` 定义为 `void`,并在调用时传 `undefined` 作为第一个参数:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
// src/api/system.ts
|
|
55
|
+
export type ReqPing = void;
|
|
56
|
+
|
|
57
|
+
export interface ResPing {
|
|
58
|
+
ok: boolean;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// src/api/request-config.ts 片段
|
|
64
|
+
import { defineEndpoint } from "listpage-http";
|
|
65
|
+
import type { ReqPing, ResPing } from "./system";
|
|
66
|
+
|
|
67
|
+
export const requestConfig = {
|
|
68
|
+
system: {
|
|
69
|
+
ping: defineEndpoint<ReqPing, ResPing>({
|
|
70
|
+
method: "GET",
|
|
71
|
+
path: "/system/ping",
|
|
72
|
+
}),
|
|
73
|
+
},
|
|
74
|
+
} as const;
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
// service 调用:显式传入 undefined 表示没有请求体
|
|
79
|
+
import api from "@/api";
|
|
80
|
+
import type { ResPing } from "@/api/system";
|
|
81
|
+
|
|
82
|
+
export async function ping(): Promise<ResPing> {
|
|
83
|
+
return api.system.ping(undefined, { timeout: 3_000 });
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 4. 创建并导出 client(`src/api/index.ts`)
|
|
50
90
|
|
|
51
91
|
```ts
|
|
52
92
|
import { createApiClient } from "listpage-http";
|
|
@@ -73,7 +113,7 @@ export default api;
|
|
|
73
113
|
|
|
74
114
|
---
|
|
75
115
|
|
|
76
|
-
##
|
|
116
|
+
## 5. 在 service 中调用(推荐,不直接在组件里写细节)
|
|
77
117
|
|
|
78
118
|
```ts
|
|
79
119
|
// src/services/auth.ts
|
|
@@ -90,7 +130,7 @@ export async function login(values: ReqLogin): Promise<ResLogin> {
|
|
|
90
130
|
|
|
91
131
|
---
|
|
92
132
|
|
|
93
|
-
##
|
|
133
|
+
## 6. 在组件中使用
|
|
94
134
|
|
|
95
135
|
接口报错已由 api 层(`onError`)统一处理,业务层**不需要**对 `api` 调用再包 try/catch 来弹错误提示。
|
|
96
136
|
|
|
@@ -117,7 +157,7 @@ export function LoginForm() {
|
|
|
117
157
|
|
|
118
158
|
---
|
|
119
159
|
|
|
120
|
-
##
|
|
160
|
+
## 7. SSE 示例(可选)
|
|
121
161
|
|
|
122
162
|
```ts
|
|
123
163
|
// 在 request-config 中配置 SSE 接口
|
|
@@ -159,7 +199,57 @@ async function startSse(id: string) {
|
|
|
159
199
|
|
|
160
200
|
---
|
|
161
201
|
|
|
162
|
-
##
|
|
202
|
+
## 8. 文件上传示例(`mode: "upload"`,内部自动 FormData)
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
// src/api/file.ts
|
|
206
|
+
export interface ReqUploadFile {
|
|
207
|
+
file: File;
|
|
208
|
+
bizType: string;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface ResUploadFile {
|
|
212
|
+
url: string;
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
// src/api/request-config.ts 片段
|
|
218
|
+
import { defineEndpoint } from "listpage-http";
|
|
219
|
+
import type { ReqUploadFile, ResUploadFile } from "./file";
|
|
220
|
+
|
|
221
|
+
export const requestConfig = {
|
|
222
|
+
file: {
|
|
223
|
+
upload: defineEndpoint<ReqUploadFile, ResUploadFile>({
|
|
224
|
+
method: "POST",
|
|
225
|
+
path: "/file/upload",
|
|
226
|
+
mode: "upload", // 关键:内部会将 ReqUploadFile 转成 FormData
|
|
227
|
+
}),
|
|
228
|
+
},
|
|
229
|
+
} as const;
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
// service 调用
|
|
234
|
+
import api from "@/api";
|
|
235
|
+
import type { ReqUploadFile, ResUploadFile } from "@/api/file";
|
|
236
|
+
|
|
237
|
+
export async function uploadFile(params: ReqUploadFile): Promise<ResUploadFile> {
|
|
238
|
+
return api.file.upload(params);
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
说明:
|
|
243
|
+
|
|
244
|
+
- 当某个接口配置 `mode: "upload"` 时,`listpage-http` 会将第二个参数(`params`)视为普通对象:
|
|
245
|
+
- 普通字段:`formData.append(key, value)`。
|
|
246
|
+
- 数组字段:对每一项执行一次 `append`。
|
|
247
|
+
- `null` / `undefined` 字段会被跳过,不会被序列化为 `"null"` 或 `"undefined"`。
|
|
248
|
+
- Content-Type 由浏览器在提交 `FormData` 时自动携带带 boundary 的 `multipart/form-data`,如需覆盖可在 headers 中显式传入。
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 9. 新增接口 Checklist
|
|
163
253
|
|
|
164
254
|
1. 在对应模块类型文件(如 `src/api/order.ts`)中添加 `ReqOrderList` / `ResOrderList` 等类型。
|
|
165
255
|
2. 在 `src/api/request-config.ts` 中为该模块新增一个 `defineEndpoint`(例如 `order.list`)。
|