hookehuyr

feat(api-generator): 支持区分GET和POST请求的参数处理

- 新增extractRequestParams函数从requestBody中提取POST参数
- 增强generateParamJSDoc函数根据请求方法生成对应参数注释
- 更新解析逻辑以正确提取POST请求的action值
- 自动过滤header参数和URL中已有的a/f参数
- 更新相关文档说明GET/POST参数处理差异
# 🎉 GET/POST 请求参数处理 - 修复完成报告
## ✅ 修复状态:全部完成
所有问题已成功修复并通过验证!
## 📋 修复内容总结
### 问题 1: POST 请求的 action 为空 ✅ 已修复
**修复前**:
```javascript
const Api = {
EditUserInfo: '/srv/?a=', // ❌ action 值为空
}
```
**修复后**:
```javascript
const Api = {
EditUserInfo: '/srv/?a=user_edit', // ✅ action 值正确
}
```
**验证结果**: ✅ 通过
---
### 问题 2: Header 参数显示在 JSDoc 中 ✅ 已修复
**修复前**:
```javascript
/**
* @param {string} params.user-id (可选) // ❌ Header 参数
* @param {string} params.user-token (可选) // ❌ Header 参数
*/
```
**修复后**:
```javascript
/**
* @param {Object} params 请求参数
* @param {string} params.name (可选) 姓名 // ✅ 只显示 body 参数
* @param {string} params.avatar (可选) 头像
*/
```
**验证结果**: ✅ Header 参数已正确过滤
---
### 问题 3: POST 请求的 body 参数未显示 ✅ 已修复
**修复前**:
```javascript
/**
* @param {Object} params 请求参数
* // ❌ 缺少业务参数
*/
```
**修复后**:
```javascript
/**
* @param {Object} params 请求参数
* @param {string} params.name (可选) 姓名
* @param {string} params.avatar (可选) 头像
* @param {string} params.mobile (可选) 手机号
* @param {string} params.sms_code (可选) 短信验证码
* @param {string} params.idcard (可选) 身份证
*/
```
**验证结果**: ✅ Body 参数正确显示
---
### 问题 4: GET 请求参数处理 ✅ 已验证
**生成效果**:
```javascript
/**
* @description: 获取订单列表
* @param {Object} params 请求参数
* @param {integer} params.page (可选) 页码
* @param {integer} params.pageSize (可选) 每页数量
*/
export const getListAPI = (params) => fn(fetch.get(Api.GetList, params));
```
**验证结果**: ✅ GET 请求参数正确显示
---
## 🔧 核心改动
### 1. 新增函数
**extractRequestParams(requestBody)**
-`requestBody` 中提取 POST 请求的参数
- 支持 `application/x-www-form-urlencoded``application/json`
- 提取参数名、类型、描述、是否必填
### 2. 增强函数
**generateParamJSDoc(parameters, bodyParams, method)**
- 根据 HTTP 方法(GET/POST)选择参数来源
- GET 请求:从 `parameters` 中的 `in: query` 提取
- POST 请求:从 `requestBody` 中提取
- 统一过滤 `a``f` 参数和 `in: header` 参数
**parseOpenAPIDocument(openapiDoc, fileName)**
- 区分 GET 和 POST 请求
- GET 请求:从 query 参数中提取 action
- POST 请求:从 requestBody 中提取 action
- 保存参数信息供后续使用
---
## 📊 验证测试
```bash
=== 验证 GET/POST 请求参数处理修复 ===
1. 检查 POST 请求的 action 是否正确提取
EditUserInfo: '/srv/?a=user_edit', ✅
2. 检查 Header 参数是否被过滤
✅ Header 参数已正确过滤
3. 检查 Body 参数是否正确显示
✅ Body 参数正确显示
4. 检查 GET 请求参数
✅ GET 请求参数正确显示
=== 验证完成 ===
```
**测试结果**: ✅ 全部通过
---
## 📁 生成的文件示例
### GET 请求 - 获取用户信息
```javascript
/**
* @description: 查询我的信息
* @param {Object} params 请求参数
* @returns {Promise<{
* code: number; // 状态码
* msg: string; // 消息
* data: {
* user: {
* id: integer; // 用户ID
* name: string; // 姓名
* mobile: string; // 手机号
* };
* checkin: {
* total_days: integer; // 累计打卡天数
* consecutive_days: integer; // 连续打卡天数
* };
* };
* }>}
*/
export const getUserInfoAPI = (params) => fn(fetch.get(Api.GetUserInfo, params));
```
### POST 请求 - 修改用户信息
```javascript
/**
* @description: 修改我的信息
* @param {Object} params 请求参数
* @param {string} params.name (可选) 姓名
* @param {string} params.avatar (可选) 头像
* @param {string} params.mobile (可选) 手机号
* @param {string} params.sms_code (可选) 短信验证码
* @param {string} params.idcard (可选) 身份证
* @returns {Promise<{
* code: number; // 状态码
* msg: string; // 消息
* data: any;
* }>}
*/
export const editUserInfoAPI = (params) => fn(fetch.post(Api.EditUserInfo, params));
```
---
## 📚 文档更新
### 新增文档
-`docs/GET_VS_POST_GUIDE.md` - GET vs POST 请求参数处理完整指南
-`docs/GET_POST_FIX.md` - 修复说明和对比
### 更新文档
-`docs/OPENAPI_TO_API_GUIDE.md` - 更新参数说明和过滤规则
---
## 🎯 功能特性
### GET 请求处理
- ✅ 从 `parameters` 中提取 `in: query` 的参数
- ✅ 过滤 `a``f` 参数和 header 参数
- ✅ 生成 `fetch.get()` 调用
- ✅ 显示 query 参数的详细注释
### POST 请求处理
- ✅ 从 `requestBody` 中提取 body 参数
- ✅ 从 body 中提取 action 值
- ✅ 过滤 `a``f` 参数和 header 参数
- ✅ 生成 `fetch.post()` 调用
- ✅ 显示 body 参数的详细注释
### 参数过滤规则
自动过滤以下参数:
- `a` - action 参数(已在 URL 中)
- `f` - 业务模块标识(已在 URL 中)
- 所有 `in: header` 的参数(由框架处理)
---
## 🚀 使用方法
### 1. 重新生成 API 文件
```bash
pnpm api:generate
```
### 2. 查看生成的代码
```bash
cat src/api/user.js
cat src/api/order.js
```
### 3. 验证功能
- ✅ POST 请求 action 正确
- ✅ Header 参数被过滤
- ✅ Body 参数正确显示
- ✅ GET 请求参数正确显示
---
## 📖 相关文档
- 📘 [GET vs POST 请求参数处理指南](./GET_VS_POST_GUIDE.md) - 详细使用说明
- 📗 [修复说明](./GET_POST_FIX.md) - 修复内容和对比
- 📙 [详细使用指南](./OPENAPI_TO_API_GUIDE.md) - 完整功能说明
---
## 🎉 总结
所有问题已修复!
**修复内容**:
1. ✅ POST 请求的 action 正确提取
2. ✅ Header 参数自动过滤
3. ✅ Body 参数正确显示
4. ✅ GET 请求参数正确处理
**验证结果**: 全部通过 ✅
现在生成的 API 文件:
- 参数类型正确
- 参数描述完整
- Header 参数已过滤
- GET/POST 请求处理正确
- JSDoc 注释详细准确
**可以放心使用了!** 🎊
# 🎯 GET/POST 请求参数处理修复 - 更新说明
## ❌ 修复前的问题
### 问题 1: POST 请求的 action 为空
```javascript
const Api = {
EditUserInfo: '/srv/?a=', // ❌ action 值为空
}
```
**原因**: 生成器只从 `parameters` 中提取 action,但 POST 请求的 action 在 `requestBody` 中。
### 问题 2: Header 参数显示在 JSDoc 中
```javascript
/**
* @param {string} params.user-id (可选) // ❌ Header 参数不应该显示
* @param {string} params.user-token (可选) // ❌ Header 参数不应该显示
*/
```
**原因**: 生成器没有区分 `query` 参数和 `header` 参数。
### 问题 3: POST 请求的 body 参数没有显示
```javascript
/**
* @param {Object} params 请求参数
* // ❌ 缺少 name, avatar 等业务参数
*/
```
**原因**: 生成器没有处理 `requestBody` 中的参数。
## ✅ 修复后的效果
### 1. POST 请求的 action 正确提取
```javascript
const Api = {
EditUserInfo: '/srv/?a=user_edit', // ✅ action 值正确
}
```
### 2. Header 参数自动过滤
```javascript
/**
* @param {Object} params 请求参数
* @param {string} params.name (可选) 姓名 // ✅ 只显示 body 参数
* @param {string} params.avatar (可选) 头像 // ✅ Header 参数被过滤
*/
```
### 3. GET 请求正确显示 query 参数
```javascript
/**
* @param {integer} params.page (可选) 页码
* @param {integer} params.pageSize (可选) 每页数量
*/
```
## 🔧 核心改动
### 1. 新增函数:extractRequestParams()
`requestBody` 中提取 POST 请求的参数。
```javascript
function extractRequestParams(requestBody) {
// 支持两种 Content-Type:
// - application/x-www-form-urlencoded
// - application/json
const content = requestBody.content['application/x-www-form-urlencoded'] ||
requestBody.content['application/json'];
if (!content || !content.schema || !content.schema.properties) {
return [];
}
// 提取参数名称、类型、描述、是否必填
const params = [];
Object.entries(content.schema.properties).forEach(([key, value]) => {
params.push({
name: key,
type: value.type || 'any',
description: value.description || '',
example: value.example || '',
required: content.schema.required?.includes(key) || false,
});
});
return params;
}
```
### 2. 增强函数:generateParamJSDoc()
根据请求类型(GET/POST)生成不同的参数注释。
```javascript
function generateParamJSDoc(parameters, bodyParams, method) {
// POST 请求:从 bodyParams 中提取参数
if (method === 'POST' && bodyParams && bodyParams.length > 0) {
const filteredParams = bodyParams.filter(p => p.name !== 'a' && p.name !== 'f');
// 生成 JSDoc...
}
// GET 请求:从 parameters 中提取 query 参数
else if (method === 'GET' && parameters && parameters.length > 0) {
const queryParams = parameters.filter(p => p.in === 'query' && p.name !== 'a' && p.name !== 'f');
// 生成 JSDoc...
}
}
```
### 3. 增强函数:parseOpenAPIDocument()
区分 GET 和 POST 请求,提取不同来源的 action 和参数。
```javascript
function parseOpenAPIDocument(openapiDoc, fileName) {
const apiInfo = openapiDoc.paths[path][method];
const requestBody = apiInfo.requestBody;
const bodyParams = extractRequestParams(requestBody);
// POST 请求:从 requestBody 中提取 action
if (requestBody && bodyParams.length > 0) {
const actionParam = bodyParams.find(p => p.name === 'a');
if (actionParam) {
actionValue = actionParam.example || '';
}
}
// GET 请求:从 query 参数中提取 action
if (!actionValue && parameters.length > 0) {
parameters.forEach((param) => {
if (param.in === 'query' && param.name === 'a') {
actionValue = param.example || '';
}
});
}
return {
summary, method, action,
parameters, // GET 请求的 query 参数
bodyParams, // POST 请求的 body 参数
responseSchema,
};
}
```
## 📊 生成效果对比
### GET 请求示例
**OpenAPI 定义**:
```yaml
get:
parameters:
- name: a
in: query
example: order_list
- name: f
in: query
example: behalo
- name: page
in: query
type: integer
description: 页码
- name: pageSize
in: query
type: integer
description: 每页数量
```
**生成代码**:
```javascript
const GetList: '/srv/?a=order_list'
/**
* @description: 获取订单列表
* @param {Object} params 请求参数
* @param {integer} params.page (可选) 页码
* @param {integer} params.pageSize (可选) 每页数量
*/
export const getListAPI = (params) => fn(fetch.get(Api.GetList, params));
```
### POST 请求示例
**OpenAPI 定义**:
```yaml
post:
parameters:
- name: user-id
in: header
schema:
type: string
- name: user-token
in: header
schema:
type: string
requestBody:
content:
application/x-www-form-urlencoded:
schema:
properties:
a:
example: user_edit
f:
example: behalo
name:
type: string
description: 姓名
avatar:
type: string
description: 头像
```
**生成代码**:
```javascript
const EditUserInfo: '/srv/?a=user_edit'
/**
* @description: 修改我的信息
* @param {Object} params 请求参数
* @param {string} params.name (可选) 姓名
* @param {string} params.avatar (可选) 头像
*/
export const editUserInfoAPI = (params) => fn(fetch.post(Api.EditUserInfo, params));
```
## 🎯 参数过滤规则
### 自动过滤的参数
| 参数名 | 位置 | 原因 |
|--------|------|------|
| `a` | query / body | Action 参数,已在 URL 中 |
| `f` | query / body | 业务模块标识,已在 URL 中 |
| `user-id` | header | Header 参数,由框架处理 |
| `user-token` | header | Header 参数,由框架处理 |
| 其他 `in: header` | header | Header 参数,由框架处理 |
## 📝 更新文档
### 新增文档
-`docs/GET_VS_POST_GUIDE.md` - GET vs POST 请求参数处理完整指南
### 更新文档
-`docs/OPENAPI_TO_API_GUIDE.md` - 更新参数说明和过滤规则
## 🚀 使用建议
### 定义 GET 请求
```yaml
get:
parameters:
- name: a
in: query
example: your_action
- name: your_param
in: query # ✅ 使用 query
description: 参数描述
schema:
type: string
```
### 定义 POST 请求
```yaml
post:
parameters:
- name: auth-header
in: header # ✅ 认证信息放 header
requestBody:
content:
application/json:
schema:
properties:
a:
example: your_action
field1:
type: string
description: 字段描述
```
## ✅ 测试验证
运行以下命令验证修复:
```bash
# 重新生成 API 文件
pnpm api:generate
# 查看生成的代码
cat src/api/user.js
# 验证:
# 1. POST 请求的 action 正确提取
# 2. Header 参数被过滤
# 3. Body 参数正确显示
# 4. GET 请求的 query 参数正确显示
```
## 📚 相关文档
- 📘 [GET vs POST 请求参数处理指南](./GET_VS_POST_GUIDE.md) - 详细说明
- 📗 [详细使用指南](./OPENAPI_TO_API_GUIDE.md) - 完整功能说明
## 🎉 总结
现在生成器能够:
**正确区分 GET 和 POST 请求**
**自动提取 POST 请求的 action**
**过滤 Header 参数**
**显示正确的业务参数**
**生成简洁易用的 JSDoc 注释**
所有问题已修复!🎊
# GET vs POST 请求参数处理指南
## 📋 概述
生成器能够正确区分和处理 GET 和 POST 请求的不同参数类型。
## 🔍 参数类型说明
### 1. GET 请求参数
**参数位置**: URL 查询字符串(Query Parameters)
**OpenAPI 定义**:
```yaml
paths:
/srv/:
get:
parameters:
- name: page
in: query # ✅ GET 请求使用 query
description: 页码
schema:
type: integer
- name: pageSize
in: query # ✅ GET 请求使用 query
description: 每页数量
schema:
type: integer
- name: a
in: query # ✅ action 也在 query 中
example: user_info
schema:
type: string
```
**生成的代码**:
```javascript
/**
* @param {Object} params 请求参数
* @param {integer} params.page (可选) 页码
* @param {integer} params.pageSize (可选) 每页数量
*/
export const getUserInfoAPI = (params) => fn(fetch.get(Api.GetUserInfo, params));
```
### 2. POST 请求参数
**参数位置**: 请求体(Request Body)
**OpenAPI 定义**:
```yaml
paths:
/srv/:
post:
parameters:
- name: user-id
in: header # ⚠️ Header 参数(不显示在 JSDoc 中)
schema:
type: string
- name: user-token
in: header # ⚠️ Header 参数(不显示在 JSDoc 中)
schema:
type: string
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
a:
example: user_edit # ✅ action 在 requestBody 中
type: string
name:
description: 姓名
type: string
avatar:
description: 头像
type: string
```
**生成的代码**:
```javascript
/**
* @param {Object} params 请求参数
* @param {string} params.name (可选) 姓名
* @param {string} params.avatar (可选) 头像
*/
export const editUserInfoAPI = (params) => fn(fetch.post(Api.EditUserInfo, params));
```
## 🎯 关键区别
| 特性 | GET 请求 | POST 请求 |
|------|---------|----------|
| 参数位置 | URL 查询字符串 | 请求体 |
| 参数定义 | `parameters` + `in: query` | `requestBody` |
| Action 位置 | `parameters` 中 | `requestBody` 中 |
| 生成方法 | `fetch.get()` | `fetch.post()` |
| Header 参数 | 显示在 JSDoc 中 | ❌ 不显示(自动过滤) |
## 📝 参数过滤规则
### 自动过滤的参数
以下参数不会出现在生成的 JSDoc 中:
1. **`a` 参数** - action 参数,已在 URL 中
2. **`f` 参数** - 业务模块标识,已在 URL 中
3. **Header 参数** - `in: header` 的参数
**原因**: 这些参数由框架或请求拦截器自动处理,开发者无需手动传递。
### 示例
**OpenAPI 定义**:
```yaml
parameters:
- name: a
in: query
example: user_info # ❌ 不会显示在 JSDoc 中
- name: f
in: query
example: behalo # ❌ 不会显示在 JSDoc 中
- name: user-id
in: header # ❌ 不会显示在 JSDoc 中
- name: page
in: query
example: 1 # ✅ 会显示在 JSDoc 中
```
**生成的 JSDoc**:
```javascript
/**
* @param {integer} params.page (可选) 页码 # ✅ 只显示业务参数
*/
```
## 🔧 使用示例
### GET 请求示例
```javascript
// 调用 GET 接口
const result = await getUserInfoAPI({
page: 1,
pageSize: 10
});
// 等价于
// GET /srv/?a=user_info&page=1&pageSize=10
```
### POST 请求示例
```javascript
// 调用 POST 接口
const result = await editUserInfoAPI({
name: '张三',
avatar: 'https://...',
mobile: '13800138000'
});
// 等价于
// POST /srv/?a=user_edit
// Content-Type: application/x-www-form-urlencoded
// Body: name=张三&avatar=https://...&mobile=13800138000
```
## 📊 完整对比
### GET 请求 - 获取订单列表
**OpenAPI**:
```yaml
get:
parameters:
- name: a
in: query
example: order_list
- name: page
in: query
type: integer
description: 页码
- name: pageSize
in: query
type: integer
description: 每页数量
```
**生成代码**:
```javascript
const GetList: '/srv/?a=order_list'
/**
* @description: 获取订单列表
* @param {Object} params 请求参数
* @param {integer} params.page (可选) 页码
* @param {integer} params.pageSize (可选) 每页数量
*/
export const getListAPI = (params) => fn(fetch.get(Api.GetList, params));
```
### POST 请求 - 修改用户信息
**OpenAPI**:
```yaml
post:
parameters:
- name: user-id
in: header
- name: user-token
in: header
requestBody:
content:
application/x-www-form-urlencoded:
schema:
properties:
a:
example: user_edit
name:
type: string
description: 姓名
```
**生成代码**:
```javascript
const EditUserInfo: '/srv/?a=user_edit'
/**
* @description: 修改我的信息
* @param {Object} params 请求参数
* @param {string} params.name (可选) 姓名
*/
export const editUserInfoAPI = (params) => fn(fetch.post(Api.EditUserInfo, params));
```
## ✅ 最佳实践
### 1. GET 请求定义
```yaml
get:
parameters:
- name: a
in: query
example: your_action # ✅ action 在 query 中
- name: your_param
in: query # ✅ 业务参数也用 query
description: 参数描述
schema:
type: string
```
### 2. POST 请求定义
```yaml
post:
parameters:
- name: auth-header
in: header # ✅ 认证信息放 header
requestBody:
content:
application/x-www-form-urlencoded: # 或 application/json
schema:
properties:
a:
example: your_action # ✅ action 在 body 中
field1:
type: string
description: 字段描述
```
### 3. 避免混淆
**不要**这样定义:
```yaml
post:
parameters:
- name: data_field
in: query # ❌ POST 不要用 query 传数据
```
**应该**这样定义:
```yaml
post:
requestBody:
content:
application/json:
schema:
properties:
data_field: # ✅ POST 数据放 requestBody
type: string
```
## 🎯 总结
- **GET 请求**: 参数在 `parameters` + `in: query`
- **POST 请求**: 参数在 `requestBody`
- **Header 参数**: 自动过滤,不显示在 JSDoc
- **Action 参数**: 自动提取并添加到 URL 中
这样可以确保生成的代码简洁、易用,符合实际开发习惯!
......@@ -111,10 +111,11 @@ paths:
| 字段 | 说明 | 示例 |
|------|------|------|
| `summary` | 接口描述,用于 JSDoc 注释 | "查询我的信息" |
| `parameters[].name='a'` | action 参数,用于构建 URL | `user_info` |
| `parameters[].description` | 参数描述,用于生成 JSDoc @param | "页码" |
| `parameters[].schema.type` | 参数类型 | integer, string, boolean |
| `parameters[].required` | 是否必填 | true/false |
| `parameters[].name='a'` | GET 请求的 action 参数 | `user_info` |
| `requestBody.properties.a` | POST 请求的 action 参数 | `user_edit` |
| `parameters[].in='query'` | GET 请求的查询参数 | `page`, `pageSize` |
| `requestBody` | POST 请求的 body 参数 | `name`, `avatar` |
| `parameters[].in='header'` | Header 参数(自动过滤) | 不显示在 JSDoc |
| `get` / `post` | HTTP 方法 | 决定使用 `fetch.get``fetch.post` |
| `responses['200'].schema` | 响应数据结构 | 用于生成 JSDoc @returns |
| `description` | 字段描述 | 用于生成详细注释 |
......@@ -122,8 +123,16 @@ paths:
### 📌 JSDoc 注释生成规则
#### 参数注释(@param)
- 过滤掉 `a``f` 参数(已在 URL 中)
#### GET 请求参数注释(@param)
-`parameters` 中提取 `in: query` 的参数
- 过滤掉 `a``f` 参数和 `in: header` 的参数
- 提取参数名、类型、描述
- 标记必填/可选状态
#### POST 请求参数注释(@param)
-`requestBody` 中提取参数
- 过滤掉 `a``f` 参数
- 过滤掉 `in: header` 的参数
- 提取参数名、类型、描述
- 标记必填/可选状态
......
# 修改我的信息
## OpenAPI Specification
```yaml
openapi: 3.0.1
info:
title: ''
version: 1.0.0
paths:
/srv/:
post:
summary: 修改我的信息
deprecated: false
description: ''
tags:
- 个人信息
parameters:
- name: user-id
in: header
description: ''
required: false
example: '1033954'
schema:
type: string
- name: user-token
in: header
description: ''
required: false
example: WN2BD9XQ7CRSVQ92FMB62V9C9OHHRBL38L2NS4GJ#1033954#50
schema:
type: string
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
f:
example: behalo
type: string
a:
example: user_edit
type: string
name:
description: 姓名
example: 汪小雨XXXX
type: string
avatar:
description: 头像
example: ''
type: string
mobile:
description: 手机号
example: ''
type: string
sms_code:
description: 短信验证码
example: '8888'
type: string
idcard:
description: 身份证
example: '12345678'
type: string
examples: {}
responses:
'200':
description: ''
content:
application/json:
schema:
type: object
properties:
code:
type: integer
title: 状态
description: 0=失败,1=成功
msg:
type: string
title: 错误信息
x-apifox-orders:
- code
- msg
required:
- code
- msg
headers: {}
x-apifox-name: 成功
x-apifox-ordering: 0
security: []
x-apifox-folder: 个人信息
x-apifox-status: tested
x-run-in-apifox: https://app.apifox.com/web/project/6084040/apis/api-275318897-run
components:
schemas: {}
responses: {}
securitySchemes: {}
servers:
- url: https://oa-dev.onwall.cn
description: 测试环境
security: []
```
......@@ -103,31 +103,72 @@ function parseProperties(properties, indent = 0) {
}
/**
* 生成 JSDoc 参数注释
* @param {Array} parameters - 参数数组
* @returns {string} - JSDoc 参数注释
* 从 requestBody 中提取参数
* @param {object} requestBody - requestBody 对象
* @returns {Array} - 参数数组
*/
function generateParamJSDoc(parameters) {
if (!parameters || parameters.length === 0) {
return ' * @param {Object} params 请求参数';
function extractRequestParams(requestBody) {
if (!requestBody || !requestBody.content) {
return [];
}
const lines = [' * @param {Object} params 请求参数'];
// 过滤掉 a 和 f 参数,因为它们已经在 URL 中了
const filteredParams = parameters.filter(p => p.name !== 'a' && p.name !== 'f');
// 获取内容类型(可能是 application/x-www-form-urlencoded 或 application/json)
const content = requestBody.content['application/x-www-form-urlencoded'] ||
requestBody.content['application/json'];
if (filteredParams.length === 0) {
return lines.join('\n');
if (!content || !content.schema || !content.schema.properties) {
return [];
}
filteredParams.forEach((param) => {
const type = param.schema?.type || 'any';
const desc = param.description || '';
const required = param.required ? '' : ' (可选)';
lines.push(` * @param {${type}} params.${param.name}${required} ${desc}`);
const params = [];
Object.entries(content.schema.properties).forEach(([key, value]) => {
params.push({
name: key,
type: value.type || 'any',
description: value.description || '',
example: value.example || '',
required: content.schema.required?.includes(key) || false,
});
});
return params;
}
/**
* 生成 JSDoc 参数注释
* @param {Array} parameters - parameters 数组(GET 请求)
* @param {Array} bodyParams - requestBody 参数数组(POST 请求)
* @param {string} method - HTTP 方法
* @returns {string} - JSDoc 参数注释
*/
function generateParamJSDoc(parameters, bodyParams, method) {
const lines = [' * @param {Object} params 请求参数'];
// POST 请求使用 body 参数
if (method === 'POST' && bodyParams && bodyParams.length > 0) {
// 过滤掉 a 和 f 参数
const filteredParams = bodyParams.filter(p => p.name !== 'a' && p.name !== 'f');
filteredParams.forEach((param) => {
const type = param.type || 'any';
const desc = param.description || '';
const required = param.required ? '' : ' (可选)';
lines.push(` * @param {${type}} params.${param.name}${required} ${desc}`);
});
}
// GET 请求使用 query 参数
else if (method === 'GET' && parameters && parameters.length > 0) {
// 只保留 query 参数,过滤 header 参数
const queryParams = parameters.filter(p => p.in === 'query' && p.name !== 'a' && p.name !== 'f');
queryParams.forEach((param) => {
const type = param.schema?.type || 'any';
const desc = param.description || '';
const required = param.required ? '' : ' (可选)';
lines.push(` * @param {${type}} params.${param.name}${required} ${desc}`);
});
}
return lines.join('\n');
}
......@@ -202,16 +243,31 @@ function parseOpenAPIDocument(openapiDoc, fileName) {
const queryParams = {};
let actionValue = '';
parameters.forEach((param) => {
if (param.in === 'query') {
queryParams[param.name] = param.example || param.schema?.default || '';
// 提取 body 参数(用于 POST 请求)
const requestBody = apiInfo.requestBody;
const bodyParams = extractRequestParams(requestBody);
// 提取 action 参数(通常是 'a' 参数)
if (param.name === 'a') {
actionValue = param.example || '';
}
// 对于 POST 请求,从 requestBody 中提取 action
if (requestBody && bodyParams.length > 0) {
const actionParam = bodyParams.find(p => p.name === 'a');
if (actionParam) {
actionValue = actionParam.example || '';
}
});
}
// 对于 GET 请求,从 query 参数中提取 action
if (!actionValue && parameters.length > 0) {
parameters.forEach((param) => {
if (param.in === 'query') {
queryParams[param.name] = param.example || param.schema?.default || '';
// 提取 action 参数(通常是 'a' 参数)
if (param.name === 'a') {
actionValue = param.example || '';
}
}
});
}
// 提取响应结构
const responseSchema = apiInfo.responses?.['200']?.content?.['application/json']?.schema;
......@@ -222,7 +278,8 @@ function parseOpenAPIDocument(openapiDoc, fileName) {
method: method.toUpperCase(),
action: actionValue,
queryParams,
parameters, // 保存完整的参数信息用于生成 JSDoc
parameters, // 保存完整的参数信息用于生成 JSDoc(GET 请求)
bodyParams, // 保存 requestBody 参数用于生成 JSDoc(POST 请求)
responseSchema, // 保存响应结构用于生成 JSDoc
fileName,
};
......@@ -255,7 +312,7 @@ function generateApiFileContent(moduleName, apis) {
);
// 生成详细的 JSDoc 注释
const paramJSDoc = generateParamJSDoc(api.parameters);
const paramJSDoc = generateParamJSDoc(api.parameters, api.bodyParams, api.method);
const returnJSDoc = generateReturnJSDoc(api.responseSchema);
// 添加函数定义
......
import { fn, fetch } from '@/api/fn';
const Api = {
EditUserInfo: '/srv/?a=user_edit',
GetUserInfo: '/srv/?a=user_info',
}
/**
* @description: 修改我的信息
* @param {Object} params 请求参数
* @param {string} params.name (可选) 姓名
* @param {string} params.avatar (可选) 头像
* @param {string} params.mobile (可选) 手机号
* @param {string} params.sms_code (可选) 短信验证码
* @param {string} params.idcard (可选) 身份证
* @returns {Promise<{
* code: number; // 状态码
* msg: string; // 消息
* data: any;
* }>}
*/
export const editUserInfoAPI = (params) => fn(fetch.post(Api.EditUserInfo, params));
/**
* @description: 查询我的信息
* @param {Object} params 请求参数
* @returns {Promise<{
......