init: 初始化 AssetX 项目仓库

包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、
antdesign(管理后台)、landingpage(营销落地页)、
数据库 SQL 和配置文件。
This commit is contained in:
2026-03-27 11:26:43 +00:00
commit 2ee4553b71
634 changed files with 988255 additions and 0 deletions

View File

@@ -0,0 +1,163 @@
#!/usr/bin/env node
/**
* 颜色验证脚本
*
* 检查组件文件中是否还有硬编码的十六进制颜色值
* 用法: node scripts/validate-colors.js
*/
const fs = require('fs');
const path = require('path');
// 硬编码颜色的正则模式
const hardcodedColorPatterns = [
// Tailwind 类名中的十六进制颜色: bg-[#hex], text-[#hex], border-[#hex]
/(bg|text|border|from|to|via)-\[#[0-9a-fA-F]{3,8}\]/g,
// 内联样式中的十六进制颜色
/(?:background|color|border)(?:Color)?:\s*['"]?#[0-9a-fA-F]{3,8}/g,
// 对象样式中的十六进制颜色
/['"](?:background|color|border)(?:Color)?['"]\s*:\s*['"]#[0-9a-fA-F]{3,8}/g,
];
// 允许的例外情况(特殊设计需求)
const allowedExceptions = [
// rgba/hsla 透明度值(毛玻璃效果等)
/rgba?\(/,
/hsla?\(/,
// 渐变色gradient-to-br from-green-400 to-emerald-500 等非硬编码)
// 注意:这里不排除硬编码的渐变,会被上面的模式捕获
];
// 需要检查的目录
const componentsDir = path.join(__dirname, '../components');
// 收集结果
const results = {
files: [],
totalViolations: 0,
};
/**
* 检查单个文件
*/
function checkFile(filePath) {
const content = fs.readFileSync(filePath, 'utf-8');
const violations = [];
// 按行分析
const lines = content.split('\n');
lines.forEach((line, index) => {
hardcodedColorPatterns.forEach(pattern => {
const matches = line.match(pattern);
if (matches) {
// 检查是否是允许的例外
const isException = allowedExceptions.some(exceptionPattern =>
exceptionPattern.test(line)
);
if (!isException) {
matches.forEach(match => {
violations.push({
line: index + 1,
content: line.trim(),
match: match,
});
});
}
}
});
});
if (violations.length > 0) {
results.files.push({
path: path.relative(process.cwd(), filePath),
violations: violations,
count: violations.length,
});
results.totalViolations += violations.length;
}
return violations.length === 0;
}
/**
* 递归扫描目录
*/
function scanDirectory(dir) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
entries.forEach(entry => {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
scanDirectory(fullPath);
} else if (entry.isFile() && /\.(tsx|ts|jsx|js)$/.test(entry.name)) {
checkFile(fullPath);
}
});
}
/**
* 打印结果
*/
function printResults() {
console.log('\n='.repeat(80));
console.log('🎨 设计系统颜色验证报告');
console.log('='.repeat(80));
console.log();
if (results.totalViolations === 0) {
console.log('✅ 太棒了!没有发现硬编码颜色值。');
console.log();
console.log('所有组件都已成功迁移到设计系统!');
} else {
console.log(`⚠️ 发现 ${results.totalViolations} 处硬编码颜色值,分布在 ${results.files.length} 个文件中:`);
console.log();
results.files.forEach(file => {
console.log(`📄 ${file.path} (${file.count} 处问题)`);
console.log('─'.repeat(80));
// 按行号分组相同的问题
const lineMap = new Map();
file.violations.forEach(v => {
if (!lineMap.has(v.line)) {
lineMap.set(v.line, []);
}
lineMap.get(v.line).push(v.match);
});
lineMap.forEach((matches, lineNum) => {
const firstViolation = file.violations.find(v => v.line === lineNum);
console.log(`${lineNum}: ${firstViolation.content.substring(0, 100)}${firstViolation.content.length > 100 ? '...' : ''}`);
matches.forEach(match => {
console.log(`${match}`);
});
});
console.log();
});
console.log('='.repeat(80));
console.log('💡 建议:');
console.log(' • 将硬编码颜色替换为设计系统的 token (如 text-text-primary, bg-bg-base 等)');
console.log(' • 检查是否有特殊设计需求需要保留硬编码');
console.log(' • 参考 /styles/design-system.css 中定义的颜色变量');
}
console.log('='.repeat(80));
console.log();
// 退出码
process.exit(results.totalViolations > 0 ? 1 : 0);
}
// 执行扫描
console.log('🔍 正在扫描组件文件...');
scanDirectory(componentsDir);
printResults();