You need to sign in or sign up before continuing.
GET_POST_FIX.md 7.52 KB

🎯 GET/POST 请求参数处理修复 - 更新说明

❌ 修复前的问题

问题 1: POST 请求的 action 为空

const Api = {
  EditUserInfo: '/srv/?a=',  // ❌ action 值为空
}

原因: 生成器只从 parameters 中提取 action,但 POST 请求的 action 在 requestBody 中。

问题 2: Header 参数显示在 JSDoc 中

/**
 * @param {string} params.user-id (可选)    // ❌ Header 参数不应该显示
 * @param {string} params.user-token (可选) // ❌ Header 参数不应该显示
 */

原因: 生成器没有区分 query 参数和 header 参数。

问题 3: POST 请求的 body 参数没有显示

/**
 * @param {Object} params 请求参数
 * // ❌ 缺少 name, avatar 等业务参数
 */

原因: 生成器没有处理 requestBody 中的参数。

✅ 修复后的效果

1. POST 请求的 action 正确提取

const Api = {
  EditUserInfo: '/srv/?a=user_edit',  // ✅ action 值正确
}

2. Header 参数自动过滤

/**
 * @param {Object} params 请求参数
 * @param {string} params.name (可选) 姓名    // ✅ 只显示 body 参数
 * @param {string} params.avatar (可选) 头像  // ✅ Header 参数被过滤
 */

3. GET 请求正确显示 query 参数

/**
 * @param {integer} params.page (可选) 页码
 * @param {integer} params.pageSize (可选) 每页数量
 */

🔧 核心改动

1. 新增函数:extractRequestParams()

requestBody 中提取 POST 请求的参数。

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)生成不同的参数注释。

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 和参数。

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 定义:

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: 每页数量

生成代码:

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 定义:

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: 头像

生成代码:

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 请求

get:
  parameters:
    - name: a
      in: query
      example: your_action

    - name: your_param
      in: query               # ✅ 使用 query
      description: 参数描述
      schema:
        type: string

定义 POST 请求

post:
  parameters:
    - name: auth-header
      in: header              # ✅ 认证信息放 header

  requestBody:
    content:
      application/json:
        schema:
          properties:
            a:
              example: your_action
            field1:
              type: string
              description: 字段描述

✅ 测试验证

运行以下命令验证修复:

# 重新生成 API 文件
pnpm api:generate

# 查看生成的代码
cat src/api/user.js

# 验证:
# 1. POST 请求的 action 正确提取
# 2. Header 参数被过滤
# 3. Body 参数正确显示
# 4. GET 请求的 query 参数正确显示

📚 相关文档

🎉 总结

现在生成器能够:

正确区分 GET 和 POST 请求自动提取 POST 请求的 action过滤 Header 参数显示正确的业务参数生成简洁易用的 JSDoc 注释

所有问题已修复!🎊