Initial commit: reorganized source tree

- backend/: 13 Maven modules (cw-elevator-application, cloudwalk-cloud, intelligent-cwoscomponent, ninca-crk, etc.)
- frontend/: 4 Vue projects (elevator-front, cwos-portal, alarm-front, front_acs) + decompiled + scripts
- scripts/: build, test-env, tools (Docker Compose, service templates, API parity)
- docs/: AGENTS.md, superpowers specs, architecture docs
- .gitignore: standard Java/Maven exclusions

Moved from legacy maven-*/ root layout to backend/ organized structure.
This commit is contained in:
hpd840321
2026-05-09 09:00:12 +08:00
commit 7b2bd307f1
7260 changed files with 612980 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
#!/usr/bin/env node
/**
* API 调用提取器
* 从格式化后的 JS 中提取 HTTP 请求模式,输出 API 清单 JSON
*
* 用法: node extract-api-calls.js <formatted-dir> <output.json>
*/
const fs = require('fs');
const path = require('path');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
function extractApiCalls(inputDir, outputFile) {
const apiCalls = [];
const files = fs.readdirSync(inputDir).filter(f => f.endsWith('.formatted.js'));
for (const file of files) {
const code = fs.readFileSync(path.join(inputDir, file), 'utf-8');
try {
const ast = parser.parse(code, {
sourceType: 'script',
plugins: ['jsx', 'typescript', 'classProperties', 'dynamicImport'],
errorRecovery: true,
});
traverse(ast, {
// Match: axios.get('/api/xxx'), axios.post('/api/xxx', data)
CallExpression(nodePath) {
const node = nodePath.node;
const callee = node.callee;
if (
callee.type === 'MemberExpression' &&
callee.object.type === 'Identifier' &&
(callee.object.name === 'axios' || callee.object.name === 'http')
) {
const method = callee.property.name;
if (['get', 'post', 'put', 'delete', 'patch'].includes(method)) {
const url = node.arguments[0];
if (url && url.type === 'StringLiteral') {
apiCalls.push({
file: file,
method: method.toUpperCase(),
url: url.value,
hasBody: method !== 'get' && node.arguments.length > 1,
});
}
}
}
// this.$http.get|post
if (
callee.type === 'MemberExpression' &&
callee.object.type === 'MemberExpression' &&
callee.object.property.name === '$http'
) {
const method = callee.property.name;
const url = node.arguments[0];
if (url && url.type === 'StringLiteral') {
apiCalls.push({
file: file,
method: method.toUpperCase(),
url: url.value,
via: '$http',
});
}
}
},
// Match string constants containing API paths
StringLiteral(nodePath) {
const value = nodePath.node.value;
if (typeof value === 'string' && value.startsWith('/api/') && value.length > 5) {
const parent = nodePath.parent;
if (parent.type === 'CallExpression') return;
apiCalls.push({
file: file,
method: 'REFERENCE',
url: value,
});
}
},
});
} catch (e) {
console.error(`解析失败: ${file}${e.message}`);
}
}
// Deduplicate + sort
const unique = {};
apiCalls.forEach(call => {
const key = `${call.method} ${call.url}`;
if (!unique[key]) {
unique[key] = call;
}
});
const result = Object.values(unique).sort((a, b) => a.url.localeCompare(b.url));
fs.writeFileSync(outputFile, JSON.stringify(result, null, 2));
console.log(`提取完成: ${result.length} 个 API 端点 → ${outputFile}`);
// Also generate Markdown report
const mdPath = outputFile.replace('.json', '.md');
let md = '# API 端点清单\n\n';
md += `| Method | URL | 来源文件 |\n`;
md += `|--------|-----|----------|\n`;
result.forEach(call => {
md += '| ' + call.method + ' | `' + call.url + '` | ' + call.file + ' |\n';
});
fs.writeFileSync(mdPath, md);
console.log(`Markdown 清单: ${mdPath}`);
}
const args = process.argv.slice(2);
if (args.length < 2) {
console.log('用法: node extract-api-calls.js <formatted-dir> <output.json>');
process.exit(1);
}
extractApiCalls(args[0], args[1]);