docs: 重组文档结构并清理 API 文件
主要变更: - 将文档从 docs/ 根目录移动到子目录(guides/, reports/, decisions/) - 删除旧的 src/api/index.js 和 src/api/order.js 文件 - 添加 Apifox 测试脚本(debug, endpoints, export) - 更新 Claude Code 设置以支持新的文档结构 文档结构优化: - docs/guides/ - 操作指南和集成指南 - docs/reports/ - 技术报告和问题分析 - docs/decisions/ - 技术决策记录 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Showing
17 changed files
with
528 additions
and
57 deletions
| ... | @@ -55,7 +55,10 @@ | ... | @@ -55,7 +55,10 @@ |
| 55 | "Bash(pnpm dev:weapp:*)", | 55 | "Bash(pnpm dev:weapp:*)", |
| 56 | "Bash(tee:*)", | 56 | "Bash(tee:*)", |
| 57 | "Bash(node:*)", | 57 | "Bash(node:*)", |
| 58 | - "Bash(~/.claude/bin/check-changelog.sh:*)" | 58 | + "Bash(~/.claude/bin/check-changelog.sh:*)", |
| 59 | + "Bash(pnpm api:generate:*)", | ||
| 60 | + "Bash(do if [ -d \"/Users/huyirui/program/itomix/git/manulife-weapp/docs/$dir\" ])", | ||
| 61 | + "Bash(then echo \"=== $dir/ ===\" ls -1 /Users/huyirui/program/itomix/git/manulife-weapp/docs/$dir/*.md)" | ||
| 59 | ] | 62 | ] |
| 60 | } | 63 | } |
| 61 | } | 64 | } | ... | ... |
docs/DOCS_STRUCTURE.md
0 → 100644
| 1 | +# Docs 目录结构说明 | ||
| 2 | + | ||
| 3 | +## 📁 目录结构 | ||
| 4 | + | ||
| 5 | +``` | ||
| 6 | +docs/ | ||
| 7 | +├── README.md # 文档总索引(保留在顶层) | ||
| 8 | +├── CHANGELOG.md # 变更日志(保留在顶层) | ||
| 9 | +├── lessons-learned.md # 经验教训总结(保留在顶层) | ||
| 10 | +│ | ||
| 11 | +├── PreDocs/ # 前期项目文档 | ||
| 12 | +│ └── 臻奇智荟圈小程序项目需求20260123a.docx | ||
| 13 | +│ | ||
| 14 | +├── decisions/ # 技术决策记录 | ||
| 15 | +│ └── decisions.md | ||
| 16 | +│ | ||
| 17 | +├── plan/ # 开发计划 | ||
| 18 | +│ ├── 项目开发计划.md | ||
| 19 | +│ ├── 前端开发计划.md | ||
| 20 | +│ └── 前端开发计划-调整版.md | ||
| 21 | +│ | ||
| 22 | +├── guides/ # 指南文档 | ||
| 23 | +│ ├── START_HERE.md # 新人入门指南 | ||
| 24 | +│ ├── API_USAGE_EXAMPLES.md # API 使用示例 | ||
| 25 | +│ ├── API_DIFF_GUIDE.md # API 差异指南 | ||
| 26 | +│ ├── GET_VS_POST_GUIDE.md # GET vs POST 指南 | ||
| 27 | +│ ├── OPENAPI_TO_API_GUIDE.md # OpenAPI 转 API 指南 | ||
| 28 | +│ ├── JSDOC_GENERATION_GUIDE.md # JSDoc 生成指南 | ||
| 29 | +│ ├── apifox-integration-guide.md # Apifox 集成指南 | ||
| 30 | +│ ├── changelog-check-guide.md # CHANGELOG 检查指南 | ||
| 31 | +│ └── 腾讯元宝AI接入说明.md # 腾讯元宝 AI 接入说明 | ||
| 32 | +│ | ||
| 33 | +├── reports/ # 问题修复与实施报告 | ||
| 34 | +│ ├── COMPLETION_REPORT.md # 完成报告 | ||
| 35 | +│ ├── FINAL_FIX_REPORT.md # 最终修复报告 | ||
| 36 | +│ ├── IMPLEMENTATION_SUMMARY.md # 实施总结 | ||
| 37 | +│ ├── GET_POST_FIX.md # GET/POST 修复 | ||
| 38 | +│ ├── RENAME_TEST_REPORT.md # 重命名测试报告 | ||
| 39 | +│ ├── apifox-setup-summary.md # Apifox 设置总结 | ||
| 40 | +│ ├── changelog-check-report-20260201.md # CHANGELOG 检查报告 | ||
| 41 | +│ ├── changes-summary.md # 变更总结 | ||
| 42 | +│ ├── DOCUMENT_ICONS_UPDATE.md # 文档图标更新 | ||
| 43 | +│ ├── search-fix-summary.md # 搜索修复总结 | ||
| 44 | +│ └── search-problems-analysis.md # 搜索问题分析 | ||
| 45 | +│ | ||
| 46 | +├── design/ # UI/UX 设计文档 | ||
| 47 | +│ └── manulife-V1/ | ||
| 48 | +│ ├── done/ # 已完成的设计稿 | ||
| 49 | +│ │ ├── 首页/ | ||
| 50 | +│ │ ├── 入职相关/ | ||
| 51 | +│ │ ├── 签单相关/ | ||
| 52 | +│ │ ├── 资料知识库/ | ||
| 53 | +│ │ ├── 资料列表/ | ||
| 54 | +│ │ ├── 产品详情/ | ||
| 55 | +│ │ ├── 计划书/ | ||
| 56 | +│ │ ├── 我的/ | ||
| 57 | +│ │ ├── 我的收藏/ | ||
| 58 | +│ │ ├── 修改头像/ | ||
| 59 | +│ │ ├── 意见反馈/ | ||
| 60 | +│ │ └── 帮助中心/ | ||
| 61 | +│ └── 录入计划书/ | ||
| 62 | +│ ├── 方案A/ | ||
| 63 | +│ └── 方案B/ | ||
| 64 | +│ | ||
| 65 | +└── mcp/ # MCP 相关文档 | ||
| 66 | + ├── MCP_配置测试指南.md | ||
| 67 | + └── 如何切换到独立Apifox项目.md | ||
| 68 | +``` | ||
| 69 | + | ||
| 70 | +## 📝 文档说明 | ||
| 71 | + | ||
| 72 | +### 顶层文档(核心文档) | ||
| 73 | + | ||
| 74 | +| 文件 | 说明 | | ||
| 75 | +|------|------| | ||
| 76 | +| `README.md` | 文档总索引,快速了解项目文档结构 | | ||
| 77 | +| `CHANGELOG.md` | 项目变更日志,记录所有功能、修复和优化 | | ||
| 78 | +| `lessons-learned.md` | 开发经验教训,包含最佳实践和常见陷阱 | | ||
| 79 | + | ||
| 80 | +### decisions/ - 技术决策记录 | ||
| 81 | + | ||
| 82 | +记录项目中的重要技术决策和设计权衡。 | ||
| 83 | + | ||
| 84 | +### plan/ - 开发计划 | ||
| 85 | + | ||
| 86 | +存放各种开发计划文档,包括整体计划和调整版计划。 | ||
| 87 | + | ||
| 88 | +### guides/ - 指南文档 | ||
| 89 | + | ||
| 90 | +开发过程中使用的各种指南文档,帮助开发者快速上手。 | ||
| 91 | + | ||
| 92 | +### reports/ - 问题修复与实施报告 | ||
| 93 | + | ||
| 94 | +记录问题修复过程、实施总结和测试报告。 | ||
| 95 | + | ||
| 96 | +### design/ - UI/UX 设计文档 | ||
| 97 | + | ||
| 98 | +存放 UI/UX 设计稿和生成的代码。 | ||
| 99 | + | ||
| 100 | +### mcp/ - MCP 相关文档 | ||
| 101 | + | ||
| 102 | +MCP (Model Context Protocol) 相关配置和测试指南。 | ||
| 103 | + | ||
| 104 | +## 🔍 快速查找 | ||
| 105 | + | ||
| 106 | +- **我是新开发者,想快速上手** → 阅读 `guides/START_HERE.md` | ||
| 107 | +- **我想了解项目的历史变更** → 查看 `CHANGELOG.md` | ||
| 108 | +- **我遇到了开发问题** → 查看 `lessons-learned.md` 和 `reports/` | ||
| 109 | +- **我需要添加新功能** → 先查看 `decisions/` 了解技术决策 | ||
| 110 | +- **我需要修改 UI** → 查看 `design/` 中的设计稿 | ||
| 111 | + | ||
| 112 | +--- | ||
| 113 | + | ||
| 114 | +**整理日期**: 2026-02-02 |
File moved
scripts/debug-apifox-response.js
0 → 100644
| 1 | +#!/usr/bin/env node | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * Apifox API 响应调试工具 | ||
| 5 | + * | ||
| 6 | + * 功能:输出完整的 API 响应,帮助诊断问题 | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | +const fs = require('fs'); | ||
| 10 | +const path = require('path'); | ||
| 11 | +const https = require('https'); | ||
| 12 | + | ||
| 13 | +// 加载配置 | ||
| 14 | +function loadConfig() { | ||
| 15 | + const envPath = path.join(__dirname, '../.env.apifox'); | ||
| 16 | + const env = fs.readFileSync(envPath, 'utf-8'); | ||
| 17 | + const config = {}; | ||
| 18 | + | ||
| 19 | + env.split('\n').forEach(line => { | ||
| 20 | + const [key, ...valueParts] = line.split('='); | ||
| 21 | + const value = valueParts.join('='); | ||
| 22 | + if (key && !key.startsWith('#') && value) { | ||
| 23 | + config[key.trim()] = value.trim(); | ||
| 24 | + } | ||
| 25 | + }); | ||
| 26 | + | ||
| 27 | + return config; | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +// 发送 HTTPS 请求 | ||
| 31 | +function httpsRequest(options) { | ||
| 32 | + return new Promise((resolve, reject) => { | ||
| 33 | + console.log(`📡 请求 URL: https://${options.hostname}${options.path}`); | ||
| 34 | + console.log(`📋 请求头:`, JSON.stringify(options.headers, null, 2)); | ||
| 35 | + | ||
| 36 | + const req = https.request(options, (res) => { | ||
| 37 | + console.log(`\n📊 响应状态码: ${res.statusCode}`); | ||
| 38 | + console.log(`📋 响应头:`, JSON.stringify(res.headers, null, 2)); | ||
| 39 | + | ||
| 40 | + const chunks = []; | ||
| 41 | + | ||
| 42 | + res.on('data', chunk => { | ||
| 43 | + chunks.push(chunk); | ||
| 44 | + }); | ||
| 45 | + | ||
| 46 | + res.on('end', () => { | ||
| 47 | + const raw = Buffer.concat(chunks).toString('utf8').trim(); | ||
| 48 | + | ||
| 49 | + if (!raw) { | ||
| 50 | + console.log('⚠️ 响应体为空'); | ||
| 51 | + resolve({ raw: null, statusCode: res.statusCode }); | ||
| 52 | + return; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + console.log(`\n📦 响应体长度: ${raw.length} 字符`); | ||
| 56 | + console.log(`📄 响应体内容:`); | ||
| 57 | + console.log('---开始---'); | ||
| 58 | + console.log(raw); | ||
| 59 | + console.log('---结束---\n'); | ||
| 60 | + | ||
| 61 | + try { | ||
| 62 | + const json = JSON.parse(raw.replace(/^\uFEFF/, '')); | ||
| 63 | + resolve(json); | ||
| 64 | + } catch (err) { | ||
| 65 | + console.error(`❌ JSON 解析失败: ${err.message}`); | ||
| 66 | + resolve({ raw, parseError: err.message }); | ||
| 67 | + } | ||
| 68 | + }); | ||
| 69 | + }); | ||
| 70 | + | ||
| 71 | + req.on('error', (err) => { | ||
| 72 | + console.error(`❌ 请求失败: ${err.message}`); | ||
| 73 | + reject(err); | ||
| 74 | + }); | ||
| 75 | + | ||
| 76 | + req.end(); | ||
| 77 | + }); | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +// 主函数 | ||
| 81 | +async function main() { | ||
| 82 | + console.log('🔍 Apifox API 响应调试工具\n'); | ||
| 83 | + | ||
| 84 | + const config = loadConfig(); | ||
| 85 | + | ||
| 86 | + // 测试获取接口列表 | ||
| 87 | + console.log('========================================'); | ||
| 88 | + console.log('测试: 获取接口列表'); | ||
| 89 | + console.log('========================================\n'); | ||
| 90 | + | ||
| 91 | + const options = { | ||
| 92 | + hostname: 'api.apifox.com', | ||
| 93 | + path: `/api/v1/projects/${config.VITE_APIFOX_PROJECT_ID}/apis?pageSize=10`, | ||
| 94 | + method: 'GET', | ||
| 95 | + headers: { | ||
| 96 | + 'Authorization': `Bearer ${config.VITE_APIFOX_TOKEN}`, | ||
| 97 | + 'Content-Type': 'application/json' | ||
| 98 | + } | ||
| 99 | + }; | ||
| 100 | + | ||
| 101 | + try { | ||
| 102 | + const response = await httpsRequest(options); | ||
| 103 | + | ||
| 104 | + console.log('========================================'); | ||
| 105 | + console.log('解析结果'); | ||
| 106 | + console.log('========================================\n'); | ||
| 107 | + | ||
| 108 | + if (response.parseError) { | ||
| 109 | + console.log(`❌ 无法解析 JSON`); | ||
| 110 | + console.log(`原始响应:`, response.raw); | ||
| 111 | + } else { | ||
| 112 | + console.log(`✅ JSON 解析成功`); | ||
| 113 | + console.log(`响应类型: ${typeof response}`); | ||
| 114 | + console.log(`响应键:`, Object.keys(response)); | ||
| 115 | + console.log(`\ndata 类型: ${typeof response.data}`); | ||
| 116 | + console.log(`data 是数组: ${Array.isArray(response.data)}`); | ||
| 117 | + console.log(`data 长度: ${response.data?.length || 0}`); | ||
| 118 | + console.log(`total: ${response.total}`); | ||
| 119 | + | ||
| 120 | + if (response.data && response.data.length > 0) { | ||
| 121 | + console.log(`\n第一个接口示例:`); | ||
| 122 | + console.log(JSON.stringify(response.data[0], null, 2)); | ||
| 123 | + } | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + } catch (err) { | ||
| 127 | + console.error(`\n❌ 请求失败: ${err.message}`); | ||
| 128 | + } | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +main(); |
scripts/test-apifox-endpoints.js
0 → 100644
| 1 | +#!/usr/bin/env node | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * 测试不同的 Apifox API 端点 | ||
| 5 | + */ | ||
| 6 | + | ||
| 7 | +const fs = require('fs'); | ||
| 8 | +const path = require('path'); | ||
| 9 | +const https = require('https'); | ||
| 10 | + | ||
| 11 | +// 加载配置 | ||
| 12 | +function loadConfig() { | ||
| 13 | + const envPath = path.join(__dirname, '../.env.apifox'); | ||
| 14 | + const env = fs.readFileSync(envPath, 'utf-8'); | ||
| 15 | + const config = {}; | ||
| 16 | + | ||
| 17 | + env.split('\n').forEach(line => { | ||
| 18 | + const [key, ...valueParts] = line.split('='); | ||
| 19 | + const value = valueParts.join('='); | ||
| 20 | + if (key && !key.startsWith('#') && value) { | ||
| 21 | + config[key.trim()] = value.trim(); | ||
| 22 | + } | ||
| 23 | + }); | ||
| 24 | + | ||
| 25 | + return config; | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +// 发送 HTTPS 请求 | ||
| 29 | +function httpsRequest(options) { | ||
| 30 | + return new Promise((resolve, reject) => { | ||
| 31 | + const req = https.request(options, (res) => { | ||
| 32 | + const chunks = []; | ||
| 33 | + | ||
| 34 | + res.on('data', chunk => { | ||
| 35 | + chunks.push(chunk); | ||
| 36 | + }); | ||
| 37 | + | ||
| 38 | + res.on('end', () => { | ||
| 39 | + const raw = Buffer.concat(chunks).toString('utf8').trim(); | ||
| 40 | + | ||
| 41 | + if (!raw) { | ||
| 42 | + resolve({ statusCode: res.statusCode, data: null, headers: res.headers }); | ||
| 43 | + return; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + try { | ||
| 47 | + const json = JSON.parse(raw.replace(/^\uFEFF/, '')); | ||
| 48 | + resolve({ statusCode: res.statusCode, data: json, headers: res.headers }); | ||
| 49 | + } catch (err) { | ||
| 50 | + resolve({ statusCode: res.statusCode, raw, parseError: err.message, headers: res.headers }); | ||
| 51 | + } | ||
| 52 | + }); | ||
| 53 | + }); | ||
| 54 | + | ||
| 55 | + req.on('error', reject); | ||
| 56 | + req.end(); | ||
| 57 | + }); | ||
| 58 | +} | ||
| 59 | + | ||
| 60 | +// 测试端点 | ||
| 61 | +async function testEndpoint(config, endpointPath, description) { | ||
| 62 | + console.log(`\n测试: ${description}`); | ||
| 63 | + console.log(`端点: ${endpointPath}`); | ||
| 64 | + | ||
| 65 | + const options = { | ||
| 66 | + hostname: 'api.apifox.com', | ||
| 67 | + path: endpointPath, | ||
| 68 | + method: 'GET', | ||
| 69 | + headers: { | ||
| 70 | + 'Authorization': `Bearer ${config.VITE_APIFOX_TOKEN}`, | ||
| 71 | + 'Content-Type': 'application/json' | ||
| 72 | + } | ||
| 73 | + }; | ||
| 74 | + | ||
| 75 | + try { | ||
| 76 | + const response = await httpsRequest(options); | ||
| 77 | + | ||
| 78 | + console.log(`状态码: ${response.statusCode}`); | ||
| 79 | + console.log(`Content-Type: ${response.headers['content-type']}`); | ||
| 80 | + console.log(`Content-Length: ${response.headers['content-length']}`); | ||
| 81 | + | ||
| 82 | + if (response.parseError) { | ||
| 83 | + console.log(`❌ JSON 解析失败: ${response.parseError}`); | ||
| 84 | + console.log(`原始响应 (前 200 字符): ${response.raw?.substring(0, 200)}`); | ||
| 85 | + } else if (response.data) { | ||
| 86 | + console.log(`✅ 成功`); | ||
| 87 | + | ||
| 88 | + // 显示响应结构 | ||
| 89 | + if (Array.isArray(response.data)) { | ||
| 90 | + console.log(` - data 是数组,长度: ${response.data.length}`); | ||
| 91 | + } else if (typeof response.data === 'object') { | ||
| 92 | + console.log(` - data 是对象,键: ${Object.keys(response.data).join(', ')}`); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + // 如果有接口数据,显示第一个 | ||
| 96 | + if (Array.isArray(response.data) && response.data.length > 0) { | ||
| 97 | + console.log(` - 第一个接口:`, JSON.stringify(response.data[0]).substring(0, 150)); | ||
| 98 | + } | ||
| 99 | + } else { | ||
| 100 | + console.log(`⚠️ 响应为空`); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + return response.statusCode === 200 && response.data && (Array.isArray(response.data) ? response.data.length > 0 : true); | ||
| 104 | + } catch (err) { | ||
| 105 | + console.log(`❌ 请求失败: ${err.message}`); | ||
| 106 | + return false; | ||
| 107 | + } | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +// 主函数 | ||
| 111 | +async function main() { | ||
| 112 | + const config = loadConfig(); | ||
| 113 | + const projectId = config.VITE_APIFOX_PROJECT_ID; | ||
| 114 | + | ||
| 115 | + console.log('='.repeat(60)); | ||
| 116 | + console.log('测试不同的 Apifox API 端点'); | ||
| 117 | + console.log('='.repeat(60)); | ||
| 118 | + | ||
| 119 | + // 尝试不同的端点 | ||
| 120 | + const endpoints = [ | ||
| 121 | + { path: `/api/v1/projects/${projectId}/apis?pageSize=10`, desc: '当前使用的端点 (/apis)' }, | ||
| 122 | + { path: `/api/v1/projects/${projectId}/interfaces?pageSize=10`, desc: '尝试 /interfaces' }, | ||
| 123 | + { path: `/v1/projects/${projectId}/apis?pageSize=10`, desc: '不带 /api 前缀' }, | ||
| 124 | + { path: `/api/v1/projects/${projectId}/api-lists?pageSize=10`, desc: '尝试 /api-lists' }, | ||
| 125 | + { path: `/api/v1/projects/${projectId}/endpoints?pageSize=10`, desc: '尝试 /endpoints' }, | ||
| 126 | + ]; | ||
| 127 | + | ||
| 128 | + let successCount = 0; | ||
| 129 | + | ||
| 130 | + for (const endpoint of endpoints) { | ||
| 131 | + const success = await testEndpoint(config, endpoint.path, endpoint.desc); | ||
| 132 | + if (success) successCount++; | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + console.log('\n' + '='.repeat(60)); | ||
| 136 | + console.log(`测试完成!成功: ${successCount}/${endpoints.length}`); | ||
| 137 | + console.log('='.repeat(60)); | ||
| 138 | +} | ||
| 139 | + | ||
| 140 | +main(); |
scripts/test-apifox-export.js
0 → 100644
| 1 | +#!/usr/bin/env node | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * 测试 Apifox 导出 API | ||
| 5 | + */ | ||
| 6 | + | ||
| 7 | +const fs = require('fs'); | ||
| 8 | +const path = require('path'); | ||
| 9 | +const https = require('https'); | ||
| 10 | + | ||
| 11 | +// 加载配置 | ||
| 12 | +function loadConfig() { | ||
| 13 | + const envPath = path.join(__dirname, '../.env.apifox'); | ||
| 14 | + const env = fs.readFileSync(envPath, 'utf-8'); | ||
| 15 | + const config = {}; | ||
| 16 | + | ||
| 17 | + env.split('\n').forEach(line => { | ||
| 18 | + const [key, ...valueParts] = line.split('='); | ||
| 19 | + const value = valueParts.join('='); | ||
| 20 | + if (key && !key.startsWith('#') && value) { | ||
| 21 | + config[key.trim()] = value.trim(); | ||
| 22 | + } | ||
| 23 | + }); | ||
| 24 | + | ||
| 25 | + return config; | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +// 发送 HTTPS 请求 | ||
| 29 | +function httpsRequest(options) { | ||
| 30 | + return new Promise((resolve, reject) => { | ||
| 31 | + const req = https.request(options, (res) => { | ||
| 32 | + const chunks = []; | ||
| 33 | + | ||
| 34 | + res.on('data', chunk => { | ||
| 35 | + chunks.push(chunk); | ||
| 36 | + }); | ||
| 37 | + | ||
| 38 | + res.on('end', () => { | ||
| 39 | + const raw = Buffer.concat(chunks).toString('utf8').trim(); | ||
| 40 | + | ||
| 41 | + if (!raw) { | ||
| 42 | + resolve({ statusCode: res.statusCode, data: null, headers: res.headers }); | ||
| 43 | + return; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + try { | ||
| 47 | + const json = JSON.parse(raw.replace(/^\uFEFF/, '')); | ||
| 48 | + resolve({ statusCode: res.statusCode, data: json, headers: res.headers }); | ||
| 49 | + } catch (err) { | ||
| 50 | + resolve({ statusCode: res.statusCode, raw, headers: res.headers }); | ||
| 51 | + } | ||
| 52 | + }); | ||
| 53 | + }); | ||
| 54 | + | ||
| 55 | + req.on('error', reject); | ||
| 56 | + req.end(); | ||
| 57 | + }); | ||
| 58 | +} | ||
| 59 | + | ||
| 60 | +// 主函数 | ||
| 61 | +async function main() { | ||
| 62 | + const config = loadConfig(); | ||
| 63 | + const projectId = config.VITE_APIFOX_PROJECT_ID; | ||
| 64 | + | ||
| 65 | + console.log('='.repeat(60)); | ||
| 66 | + console.log('测试 Apifox 导出 API'); | ||
| 67 | + console.log('='.repeat(60)); | ||
| 68 | + | ||
| 69 | + // 尝试导出 OpenAPI 格式 | ||
| 70 | + const exportEndpoints = [ | ||
| 71 | + { path: `/api/v1/projects/${projectId}/export-openapi`, desc: '导出 OpenAPI' }, | ||
| 72 | + { path: `/api/v1/projects/${projectId}/export-openapi/3.0.0`, desc: '导出 OpenAPI 3.0' }, | ||
| 73 | + { path: `/api/v1/projects/${projectId}/export-openapi/3.0.0/json`, desc: '导出 OpenAPI 3.0 JSON' }, | ||
| 74 | + ]; | ||
| 75 | + | ||
| 76 | + for (const endpoint of exportEndpoints) { | ||
| 77 | + console.log(`\n测试: ${endpoint.desc}`); | ||
| 78 | + console.log(`端点: ${endpoint.path}`); | ||
| 79 | + | ||
| 80 | + const options = { | ||
| 81 | + hostname: 'api.apifox.com', | ||
| 82 | + path: endpoint.path, | ||
| 83 | + method: 'GET', | ||
| 84 | + headers: { | ||
| 85 | + 'Authorization': `Bearer ${config.VITE_APIFOX_TOKEN}`, | ||
| 86 | + 'Content-Type': 'application/json', | ||
| 87 | + 'X-Apifox-Version': '2024-06-14' // 尝试添加版本头 | ||
| 88 | + } | ||
| 89 | + }; | ||
| 90 | + | ||
| 91 | + try { | ||
| 92 | + const response = await httpsRequest(options); | ||
| 93 | + | ||
| 94 | + console.log(`状态码: ${response.statusCode}`); | ||
| 95 | + console.log(`Content-Type: ${response.headers['content-type']}`); | ||
| 96 | + console.log(`Content-Length: ${response.headers['content-length']}`); | ||
| 97 | + | ||
| 98 | + if (response.statusCode === 200 && response.raw) { | ||
| 99 | + console.log(`✅ 成功获取数据 (${response.raw.length} 字符)`); | ||
| 100 | + | ||
| 101 | + // 尝试解析为 JSON | ||
| 102 | + try { | ||
| 103 | + const json = JSON.parse(response.raw); | ||
| 104 | + console.log(` - JSON 解析成功`); | ||
| 105 | + console.log(` - 顶层键: ${Object.keys(json).join(', ')}`); | ||
| 106 | + | ||
| 107 | + // 检查是否有接口数据 | ||
| 108 | + if (json.paths) { | ||
| 109 | + const pathCount = Object.keys(json.paths).length; | ||
| 110 | + console.log(` - OpenAPI paths 数量: ${pathCount}`); | ||
| 111 | + | ||
| 112 | + if (pathCount > 0) { | ||
| 113 | + console.log(` ✓ 找到接口数据!`); | ||
| 114 | + // 保存到文件 | ||
| 115 | + const outputPath = path.join(__dirname, `../test-openapi-${Date.now()}.json`); | ||
| 116 | + fs.writeFileSync(outputPath, JSON.stringify(json, null, 2), 'utf-8'); | ||
| 117 | + console.log(` - 已保存到: ${outputPath}`); | ||
| 118 | + return; // 找到数据就退出 | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + } catch (err) { | ||
| 122 | + console.log(` - JSON 解析失败,可能是其他格式`); | ||
| 123 | + } | ||
| 124 | + } else if (response.data) { | ||
| 125 | + console.log(`✅ 响应包含 data 字段`); | ||
| 126 | + console.log(` - data 键: ${Object.keys(response.data).join(', ')}`); | ||
| 127 | + } else { | ||
| 128 | + console.log(`⚠️ 响应为空`); | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + } catch (err) { | ||
| 132 | + console.log(`❌ 请求失败: ${err.message}`); | ||
| 133 | + } | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + console.log('\n' + '='.repeat(60)); | ||
| 137 | +} | ||
| 138 | + | ||
| 139 | +main(); |
src/api/index.js
deleted
100644 → 0
src/api/order.js
deleted
100644 → 0
| 1 | -import { fn, fetch } from '@/api/fn'; | ||
| 2 | - | ||
| 3 | -const Api = { | ||
| 4 | - GetDetail: '/srv/?a=order_detail', | ||
| 5 | - GetList: '/srv/?a=order_list', | ||
| 6 | -} | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * @description: 获取订单详情 | ||
| 10 | - * @param {Object} params 请求参数 | ||
| 11 | - * @param {integer} params.id 订单ID | ||
| 12 | - * @returns {Promise<{ | ||
| 13 | - * code: number; // 状态码 | ||
| 14 | - * msg: string; // 消息 | ||
| 15 | - * data: { | ||
| 16 | - * order: { | ||
| 17 | - * id: integer; // 订单ID | ||
| 18 | - * order_no: string; // 订单号 | ||
| 19 | - * total_amount: number; // 订单总金额 | ||
| 20 | - * status: string; // 订单状态 | ||
| 21 | - * items: array; // 订单商品列表 | ||
| 22 | - * }; | ||
| 23 | - * }; | ||
| 24 | - * }>} | ||
| 25 | - */ | ||
| 26 | -export const getDetailAPI = (params) => fn(fetch.get(Api.GetDetail, params)); | ||
| 27 | - | ||
| 28 | -/** | ||
| 29 | - * @description: 获取订单列表 | ||
| 30 | - * @param {Object} params 请求参数 | ||
| 31 | - * @param {integer} params.page (可选) 页码 | ||
| 32 | - * @param {integer} params.pageSize (可选) 每页数量 | ||
| 33 | - * @returns {Promise<{ | ||
| 34 | - * code: number; // 状态码 | ||
| 35 | - * msg: string; // 消息 | ||
| 36 | - * data: { | ||
| 37 | - * list: Array<{ | ||
| 38 | - * id: integer; // 订单ID | ||
| 39 | - * order_no: string; // 订单号 | ||
| 40 | - * status: string; // 订单状态 | ||
| 41 | - * total_amount: number; // 订单金额 | ||
| 42 | - * }>; | ||
| 43 | - * }; | ||
| 44 | - * }>} | ||
| 45 | - */ | ||
| 46 | -export const getListAPI = (params) => fn(fetch.get(Api.GetList, params)); |
-
Please register or login to post a comment