Files
ONE-OS/axhub-make/scripts/review-all.js
王冕 a27e3b8e43 feat: sync full workspace including web modules, docs, and configurations to Gitea
Optimized the root .gitignore to exclude virtual environments, node modules,
and temp folders to ensure clean and lightweight version tracking.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 18:12:25 +08:00

239 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* 批量检查所有组件和页面
*/
import http from 'http';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const HOST = 'localhost';
const PORT = 51720;
function reviewCode(targetPath) {
return new Promise((resolve, reject) => {
const postData = JSON.stringify({ path: targetPath });
const options = {
hostname: HOST,
port: PORT,
path: '/api/code-review',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData)
},
timeout: 5000
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
const result = JSON.parse(data);
resolve(result);
} catch (error) {
reject(new Error(`解析响应失败: ${error.message}`));
}
});
});
req.on('error', (error) => {
reject(error);
});
req.on('timeout', () => {
req.destroy();
reject(new Error('请求超时'));
});
req.write(postData);
req.end();
});
}
function getAllComponents() {
const srcDir = path.resolve(__dirname, '../src');
const components = [];
// 扫描 prototypes
const pagesDir = path.join(srcDir, 'prototypes');
if (fs.existsSync(pagesDir)) {
const prototypes = fs.readdirSync(pagesDir, { withFileTypes: true });
prototypes.forEach(page => {
if (page.isDirectory()) {
const indexPath = path.join(pagesDir, page.name, 'index.tsx');
if (fs.existsSync(indexPath)) {
components.push({
type: 'page',
name: page.name,
path: `prototypes/${page.name}`
});
}
}
});
}
// 扫描 components
const elementsDir = path.join(srcDir, 'components');
if (fs.existsSync(elementsDir)) {
const components = fs.readdirSync(elementsDir, { withFileTypes: true });
components.forEach(element => {
if (element.isDirectory()) {
const indexPath = path.join(elementsDir, element.name, 'index.tsx');
if (fs.existsSync(indexPath)) {
components.push({
type: 'element',
name: element.name,
path: `components/${element.name}`
});
}
}
});
}
return components;
}
function formatIssue(issue, indent = ' ') {
const icon = issue.type === 'error' ? '❌' : '⚠️';
let output = `${indent}${icon} [${issue.rule}] ${issue.message}`;
if (issue.suggestion) {
output += `\n${indent} 💡 ${issue.suggestion}`;
}
return output;
}
async function main() {
console.log('\n🔍 扫描项目中的所有组件和页面...\n');
const components = getAllComponents();
if (components.length === 0) {
console.log('❌ 未找到任何组件或页面\n');
process.exit(1);
}
console.log(`找到 ${components.length} 个组件/页面\n`);
console.log('='.repeat(70));
let totalChecked = 0;
let totalPassed = 0;
let totalErrors = 0;
let totalWarnings = 0;
const failedComponents = [];
for (const component of components) {
totalChecked++;
const displayName = `${component.type === 'page' ? '📄' : '🧩'} ${component.name}`;
try {
const result = await reviewCode(component.path);
if (result.error) {
console.log(`\n${displayName}`);
console.log(` ❌ 检查失败: ${result.error}`);
continue;
}
const errors = result.issues.filter(i => i.type === 'error');
const warnings = result.issues.filter(i => i.type === 'warning');
totalErrors += errors.length;
totalWarnings += warnings.length;
if (result.passed) {
totalPassed++;
console.log(`\n${displayName}`);
console.log(` ✅ 通过`);
} else {
failedComponents.push({
component,
result
});
console.log(`\n${displayName}`);
console.log(` ❌ 未通过 (${errors.length} 错误, ${warnings.length} 警告)`);
// 只显示错误,不显示警告(简化输出)
if (errors.length > 0) {
errors.forEach(issue => {
console.log(formatIssue(issue));
});
}
}
} catch (error) {
console.log(`\n${displayName}`);
console.log(` ❌ 检查失败: ${error.message}`);
}
}
// 总结
console.log('\n' + '='.repeat(70));
console.log('\n📊 检查总结:\n');
console.log(` 总计: ${totalChecked} 个组件/页面`);
console.log(` 通过: ${totalPassed} 个 ✅`);
console.log(` 失败: ${totalChecked - totalPassed} 个 ❌`);
console.log(` 错误: ${totalErrors}`);
console.log(` 警告: ${totalWarnings}`);
if (failedComponents.length > 0) {
console.log('\n⚠ 需要修复的组件:\n');
failedComponents.forEach(({ component }) => {
console.log(` - ${component.path}`);
});
}
console.log('\n' + '='.repeat(70) + '\n');
if (totalPassed === totalChecked) {
console.log('✅ 所有组件都符合规范!\n');
} else {
console.log('⚠️ 部分组件需要修复,请查看上面的详细信息。\n');
console.log('💡 使用以下命令查看单个组件的详细问题:');
console.log(' node scripts/code-review.js <path>\n');
process.exit(1);
}
}
// 检查服务器
function checkServer() {
return new Promise((resolve) => {
const req = http.get(`http://${HOST}:${PORT}/api/version`, (res) => {
resolve(true);
});
req.on('error', () => {
resolve(false);
});
req.setTimeout(2000, () => {
req.destroy();
resolve(false);
});
});
}
(async () => {
const serverRunning = await checkServer();
if (!serverRunning) {
console.error('\n❌ 错误:开发服务器未运行');
console.log('\n请先启动开发服务器');
console.log(' npm run dev\n');
process.exit(1);
}
await main();
})();