789 lines
22 KiB
JavaScript
789 lines
22 KiB
JavaScript
/**
|
|
* V1.0全项目盘点脚本
|
|
* 自动扫描全项目代码库,生成盘点报告
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// 配置
|
|
const CONFIG = {
|
|
projectRoot: path.join(__dirname, '../..'),
|
|
outputDir: path.join(__dirname, 'reports'),
|
|
};
|
|
|
|
// V1.0必须实现清单
|
|
const V10_MUST_HAVE = [
|
|
{
|
|
id: 'MH-001',
|
|
name: 'Entity【知识实体表】',
|
|
description: '包含entity_id、name、definition、description、metadata等字段',
|
|
checkType: 'database',
|
|
checkPattern: 'CREATE TABLE IF NOT EXISTS entities',
|
|
},
|
|
{
|
|
id: 'MH-002',
|
|
name: 'DirectedRelationship【有向实体关系表】',
|
|
description: '包含rel_id、source_entity_id、relation_type、target_entity_id等字段',
|
|
checkType: 'database',
|
|
checkPattern: 'CREATE TABLE IF NOT EXISTS directed_relationships',
|
|
},
|
|
{
|
|
id: 'MH-003',
|
|
name: 'Content【内容基础表】',
|
|
description: '包含content_id、title、body、content_type、publish_status等字段',
|
|
checkType: 'database',
|
|
checkPattern: 'CREATE TABLE IF NOT EXISTS contents',
|
|
},
|
|
{
|
|
id: 'MH-004',
|
|
name: 'Page【页面扩展表】',
|
|
description: '包含page_id、slug、template、seo_title等字段',
|
|
checkType: 'database',
|
|
checkPattern: 'CREATE TABLE IF NOT EXISTS pages',
|
|
},
|
|
{
|
|
id: 'MH-005',
|
|
name: 'Article【文章扩展表】',
|
|
description: '包含article_id、category、tags、cover_image、author等字段',
|
|
checkType: 'database',
|
|
checkPattern: 'CREATE TABLE IF NOT EXISTS articles',
|
|
},
|
|
{
|
|
id: 'MH-006',
|
|
name: 'Case【案例扩展表】',
|
|
description: '包含case_id、client_name、industry、challenge、solution、result等字段',
|
|
checkType: 'database',
|
|
checkPattern: 'CREATE TABLE IF NOT EXISTS cases',
|
|
},
|
|
{
|
|
id: 'MH-007',
|
|
name: 'FAQ【常见问题扩展表】',
|
|
description: '包含faq_id、question、answer、sort_order等字段',
|
|
checkType: 'database',
|
|
checkPattern: 'CREATE TABLE IF NOT EXISTS faqs',
|
|
},
|
|
{
|
|
id: 'MH-008',
|
|
name: 'Capability【能力扩展表】',
|
|
description: '包含capability_id、capability_type、features、use_cases等字段',
|
|
checkType: 'database',
|
|
checkPattern: 'CREATE TABLE IF NOT EXISTS capabilities',
|
|
},
|
|
{
|
|
id: 'MH-009',
|
|
name: 'Service【服务扩展表】',
|
|
description: '包含service_id、service_type、pricing_model、delivery_method等字段',
|
|
checkType: 'database',
|
|
checkPattern: 'CREATE TABLE IF NOT EXISTS services',
|
|
},
|
|
{
|
|
id: 'MH-010',
|
|
name: 'EntityContentJoin【实体-内容关联表】',
|
|
description: '包含join_id、entity_id、content_id、join_note等字段',
|
|
checkType: 'database',
|
|
checkPattern: 'CREATE TABLE IF NOT EXISTS entity_content_joins',
|
|
},
|
|
{
|
|
id: 'MH-011',
|
|
name: 'Entity管理CRUD',
|
|
description: '新增、编辑、停用实体,entity_id生成后不可修改',
|
|
checkType: 'api',
|
|
checkPattern: '/api/entities',
|
|
},
|
|
{
|
|
id: 'MH-012',
|
|
name: 'DirectedRelationship管理CRUD',
|
|
description: '新增、编辑、停用关系,禁止自动生成反向数据库记录',
|
|
checkType: 'api',
|
|
checkPattern: '/api/relationships',
|
|
},
|
|
{
|
|
id: 'MH-013',
|
|
name: '内容管理CRUD',
|
|
description: 'Page/Article/Case/FAQ/Capability/Service全部CRUD',
|
|
checkType: 'api',
|
|
checkPattern: '/api/contents',
|
|
},
|
|
{
|
|
id: 'MH-014',
|
|
name: '内容生命周期流转',
|
|
description: 'draft ↔ review → published → unpublished → historical',
|
|
checkType: 'api',
|
|
checkPattern: '/transition',
|
|
},
|
|
{
|
|
id: 'MH-015',
|
|
name: '权威等级L1-L7',
|
|
description: '可编辑存储',
|
|
checkType: 'database',
|
|
checkPattern: 'authority_level',
|
|
},
|
|
{
|
|
id: 'MH-016',
|
|
name: '版本留存',
|
|
description: '进入historical状态保留历史版本,不物理删除',
|
|
checkType: 'api',
|
|
checkPattern: '/history',
|
|
},
|
|
{
|
|
id: 'MH-017',
|
|
name: '公开输出接口',
|
|
description: '对外数据接口只返回status=published的内容',
|
|
checkType: 'api',
|
|
checkPattern: '/api/public',
|
|
},
|
|
{
|
|
id: 'MH-018',
|
|
name: 'JSON-LD结构化数据生成',
|
|
description: '系统自动生成JSON-LD结构化数据',
|
|
checkType: 'api',
|
|
checkPattern: '/api/jsonld',
|
|
},
|
|
{
|
|
id: 'MH-019',
|
|
name: '首页',
|
|
description: '路由: /,展示阿美巴认知体系',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-020',
|
|
name: '阿美巴页面',
|
|
description: '路由: /about,展示阿美巴定位、使命',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/about/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-021',
|
|
name: '企业进化页面',
|
|
description: '路由: /evolution,展示企业进化定义',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/evolution/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-022',
|
|
name: '进化方法页面',
|
|
description: '路由: /evolution/method,展示方法论',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/evolution/method/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-023',
|
|
name: '四大价值页面',
|
|
description: '路由: /value,展示四大价值',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/value/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-024',
|
|
name: '价值创造页面',
|
|
description: '路由: /value/creation,展示价值创造',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/value/creation/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-025',
|
|
name: '价值传递页面',
|
|
description: '路由: /value/transfer,展示价值传递',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/value/transfer/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-026',
|
|
name: '价值交付页面',
|
|
description: '路由: /value/delivery,展示价值交付',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/value/delivery/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-027',
|
|
name: '价值支持页面',
|
|
description: '路由: /value/support,展示价值支持',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/value/support/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-028',
|
|
name: 'A/M-B总览页面',
|
|
description: '路由: /amb,展示三态模型',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/amb/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-029',
|
|
name: 'A态页面',
|
|
description: '路由: /amb/a,展示A态定义',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/amb/a/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-030',
|
|
name: 'M态页面',
|
|
description: '路由: /amb/m,展示M态定义',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/amb/m/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-031',
|
|
name: 'B态页面',
|
|
description: '路由: /amb/b,展示B态定义',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/amb/b/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-032',
|
|
name: '能力地图页面',
|
|
description: '路由: /capabilities,展示能力体系',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/capabilities/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-033',
|
|
name: '案例页面',
|
|
description: '路由: /cases,展示案例列表',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/cases/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-034',
|
|
name: '知识中心页面',
|
|
description: '路由: /knowledge,展示知识体系',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/knowledge/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-035',
|
|
name: '概念页面',
|
|
description: '路由: /concepts,展示概念列表',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/concepts/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-036',
|
|
name: 'FAQ页面',
|
|
description: '路由: /faq,展示常见问题',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/faq/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-037',
|
|
name: '企业需求与能力匹配页面',
|
|
description: '路由: /match,展示匹配结构',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/match/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-038',
|
|
name: '联系我们页面',
|
|
description: '路由: /contact,展示联系方式',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/contact/page.tsx',
|
|
},
|
|
{
|
|
id: 'MH-039',
|
|
name: 'sitemap.xml生成',
|
|
description: '自动生成sitemap.xml',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/sitemap.ts',
|
|
},
|
|
{
|
|
id: 'MH-040',
|
|
name: 'robots.txt生成',
|
|
description: '自动生成robots.txt',
|
|
checkType: 'frontend',
|
|
checkPattern: 'src/app/robots.ts',
|
|
},
|
|
{
|
|
id: 'MH-041',
|
|
name: 'SEO元数据',
|
|
description: 'title/description/canonical/Open Graph/Twitter Card',
|
|
checkType: 'frontend',
|
|
checkPattern: 'generateSEO',
|
|
},
|
|
{
|
|
id: 'MH-042',
|
|
name: '面包屑导航',
|
|
description: 'BreadcrumbList Schema',
|
|
checkType: 'frontend',
|
|
checkPattern: 'generateBreadcrumbSchema',
|
|
},
|
|
{
|
|
id: 'MH-043',
|
|
name: '结构化数据',
|
|
description: 'Organization/Article/FAQPage/Service Schema',
|
|
checkType: 'frontend',
|
|
checkPattern: 'JsonLd',
|
|
},
|
|
{
|
|
id: 'MH-044',
|
|
name: '单元测试',
|
|
description: 'Entity/Content/DirectedRelationship/EntityContentJoin模型测试',
|
|
checkType: 'test',
|
|
checkPattern: '.test.js',
|
|
},
|
|
{
|
|
id: 'MH-045',
|
|
name: 'AI认知测试集',
|
|
description: '实体认知用例、十问认知用例',
|
|
checkType: 'test',
|
|
checkPattern: 'ai_cognitive_testset.md',
|
|
},
|
|
{
|
|
id: 'MH-046',
|
|
name: '模拟抓取校验脚本',
|
|
description: '遍历sitemap、校验页面质量',
|
|
checkType: 'test',
|
|
checkPattern: 'crawler.js',
|
|
},
|
|
{
|
|
id: 'MH-047',
|
|
name: '内容边界隔离校验脚本',
|
|
description: '校验非published内容不可见',
|
|
checkType: 'test',
|
|
checkPattern: 'content_filter.js',
|
|
},
|
|
{
|
|
id: 'MH-048',
|
|
name: '十问认知基线校验模块',
|
|
description: '校验网站内容与标准答案一致性',
|
|
checkType: 'test',
|
|
checkPattern: 'ten_questions.js',
|
|
},
|
|
{
|
|
id: 'MH-049',
|
|
name: 'V1.0全项目盘点脚本',
|
|
description: '扫描代码、核查禁止项',
|
|
checkType: 'test',
|
|
checkPattern: 'project_audit.js',
|
|
},
|
|
{
|
|
id: 'MH-050',
|
|
name: '交付回执文档',
|
|
description: '数据表清单、关键接口清单、单元测试要点',
|
|
checkType: 'document',
|
|
checkPattern: 'DELIVERY_RECEIPT.md',
|
|
},
|
|
];
|
|
|
|
// V1.0明确不做清单
|
|
const V10_DONT_DO = [
|
|
{
|
|
id: 'DD-001',
|
|
name: 'AI聊天机器人',
|
|
description: '不得开发AI聊天机器人功能',
|
|
checkPattern: ['chatbot', 'chat-bot', 'ai-chat', '聊天机器人'],
|
|
},
|
|
{
|
|
id: 'DD-002',
|
|
name: '在线诊断',
|
|
description: '不得开发在线诊断功能',
|
|
checkPattern: ['diagnosis', 'diagnostic', '在线诊断', '诊断工具'],
|
|
},
|
|
{
|
|
id: 'DD-003',
|
|
name: '自动评分',
|
|
description: '不得开发自动评分功能',
|
|
checkPattern: ['auto-score', '自动评分', '评分系统'],
|
|
},
|
|
{
|
|
id: 'DD-004',
|
|
name: 'AIO对接',
|
|
description: '不得预埋AIO对接接口',
|
|
checkPattern: ['aio', 'AIO', '企客通'],
|
|
},
|
|
{
|
|
id: 'DD-005',
|
|
name: 'CRM对接',
|
|
description: '不得预埋CRM对接接口',
|
|
checkPattern: ['crm', 'CRM', '客户关系管理'],
|
|
},
|
|
{
|
|
id: 'DD-006',
|
|
name: '商城功能',
|
|
description: '不得开发商城功能',
|
|
checkPattern: ['shop', '商城', '电商', 'payment', '支付'],
|
|
},
|
|
{
|
|
id: 'DD-007',
|
|
name: '自动获客',
|
|
description: '不得开发自动获客功能',
|
|
checkPattern: ['lead-generation', '自动获客', '获客系统'],
|
|
},
|
|
{
|
|
id: 'DD-008',
|
|
name: '第三方大模型API',
|
|
description: '不得对接第三方大模型API',
|
|
checkPattern: ['openai', 'gpt', 'claude', 'gemini', '大模型API'],
|
|
},
|
|
{
|
|
id: 'DD-009',
|
|
name: 'AI Agent能力',
|
|
description: '不得开发AI Agent能力',
|
|
checkPattern: ['agent', 'AI Agent', '智能代理'],
|
|
},
|
|
{
|
|
id: 'DD-010',
|
|
name: '浮夸科技视觉',
|
|
description: '不得使用机器人、粒子、科技蓝、3D、光效等元素',
|
|
checkPattern: ['particle', 'robot', '3d', 'glow', '科技蓝'],
|
|
},
|
|
];
|
|
|
|
/**
|
|
* 扫描文件内容
|
|
*/
|
|
function scanFileContent(filePath, patterns) {
|
|
const results = [];
|
|
|
|
try {
|
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
const lines = content.split('\n');
|
|
|
|
patterns.forEach((pattern) => {
|
|
const regex = new RegExp(pattern, 'gi');
|
|
lines.forEach((line, index) => {
|
|
if (regex.test(line)) {
|
|
results.push({
|
|
file: filePath,
|
|
line: index + 1,
|
|
content: line.trim(),
|
|
pattern: pattern,
|
|
});
|
|
}
|
|
});
|
|
});
|
|
} catch (error) {
|
|
// 忽略读取错误
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* 扫描目录
|
|
*/
|
|
function scanDirectory(dir, patterns) {
|
|
const results = [];
|
|
|
|
try {
|
|
const items = fs.readdirSync(dir);
|
|
|
|
items.forEach((item) => {
|
|
const fullPath = path.join(dir, item);
|
|
const stat = fs.statSync(fullPath);
|
|
|
|
if (stat.isDirectory()) {
|
|
// 跳过node_modules和.next目录
|
|
if (item === 'node_modules' || item === '.next' || item === 'data') {
|
|
return;
|
|
}
|
|
results.push(...scanDirectory(fullPath, patterns));
|
|
} else if (stat.isFile()) {
|
|
// 只扫描代码文件
|
|
const ext = path.extname(item);
|
|
if (['.js', '.ts', '.tsx', '.jsx', '.json', '.md'].includes(ext)) {
|
|
results.push(...scanFileContent(fullPath, patterns));
|
|
}
|
|
}
|
|
});
|
|
} catch (error) {
|
|
// 忽略读取错误
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* 检查文件是否存在
|
|
*/
|
|
function checkFileExists(filePath) {
|
|
return fs.existsSync(filePath);
|
|
}
|
|
|
|
/**
|
|
* 检查目录是否存在
|
|
*/
|
|
function checkDirectoryExists(dirPath) {
|
|
return fs.existsSync(dirPath);
|
|
}
|
|
|
|
/**
|
|
* 盘点V1.0必须实现项
|
|
*/
|
|
function auditMustHave() {
|
|
console.log('\n=== 盘点V1.0必须实现项 ===');
|
|
|
|
const results = [];
|
|
|
|
V10_MUST_HAVE.forEach((item) => {
|
|
let found = false;
|
|
let details = '';
|
|
|
|
switch (item.checkType) {
|
|
case 'database':
|
|
// 检查数据库迁移文件
|
|
const migrateFile = path.join(CONFIG.projectRoot, 'src/database/migrate.js');
|
|
if (checkFileExists(migrateFile)) {
|
|
const scanResults = scanFileContent(migrateFile, [item.checkPattern]);
|
|
found = scanResults.length > 0;
|
|
details = found ? `在migrate.js中找到` : '未在migrate.js中找到';
|
|
} else {
|
|
details = 'migrate.js文件不存在';
|
|
}
|
|
break;
|
|
|
|
case 'api':
|
|
// 检查API路由文件
|
|
const routesDir = path.join(CONFIG.projectRoot, 'src/routes');
|
|
if (checkDirectoryExists(routesDir)) {
|
|
const scanResults = scanDirectory(routesDir, [item.checkPattern]);
|
|
found = scanResults.length > 0;
|
|
details = found ? `在路由文件中找到` : '未在路由文件中找到';
|
|
} else {
|
|
details = 'routes目录不存在';
|
|
}
|
|
break;
|
|
|
|
case 'frontend':
|
|
// 检查前端文件
|
|
const frontendDir = path.join(CONFIG.projectRoot, 'frontend');
|
|
if (checkDirectoryExists(frontendDir)) {
|
|
const scanResults = scanDirectory(frontendDir, [item.checkPattern]);
|
|
found = scanResults.length > 0;
|
|
details = found ? `在前端文件中找到` : '未在前端文件中找到';
|
|
} else {
|
|
details = 'frontend目录不存在';
|
|
}
|
|
break;
|
|
|
|
case 'test':
|
|
// 检查测试文件
|
|
const testsDir = path.join(CONFIG.projectRoot, 'tests');
|
|
if (checkDirectoryExists(testsDir)) {
|
|
const scanResults = scanDirectory(testsDir, [item.checkPattern]);
|
|
found = scanResults.length > 0;
|
|
details = found ? `在测试文件中找到` : '未在测试文件中找到';
|
|
} else {
|
|
details = 'tests目录不存在';
|
|
}
|
|
break;
|
|
|
|
case 'document':
|
|
// 检查文档
|
|
const docPath = path.join(CONFIG.projectRoot, item.checkPattern);
|
|
found = checkFileExists(docPath);
|
|
details = found ? '文档存在' : '文档不存在';
|
|
break;
|
|
}
|
|
|
|
results.push({
|
|
...item,
|
|
status: found ? 'completed' : 'missing',
|
|
details: details,
|
|
});
|
|
|
|
console.log(`${found ? '✅' : '❌'} ${item.id}: ${item.name} - ${details}`);
|
|
});
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* 盘点V1.0明确不做项
|
|
*/
|
|
function auditDontDo() {
|
|
console.log('\n=== 盘点V1.0明确不做项 ===');
|
|
|
|
const results = [];
|
|
|
|
V10_DONT_DO.forEach((item) => {
|
|
const scanResults = scanDirectory(CONFIG.projectRoot, item.checkPattern);
|
|
const found = scanResults.length > 0;
|
|
|
|
results.push({
|
|
...item,
|
|
status: found ? 'violation' : 'compliant',
|
|
details: found ? `发现${scanResults.length}处违规` : '未发现违规',
|
|
violations: found ? scanResults.slice(0, 5) : [], // 只保留前5个
|
|
});
|
|
|
|
console.log(`${found ? '❌' : '✅'} ${item.id}: ${item.name} - ${found ? '发现违规' : '合规'}`);
|
|
});
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* 生成盘点报告
|
|
*/
|
|
function generateReport(mustHaveResults, dontDoResults) {
|
|
// 创建报告目录
|
|
if (!fs.existsSync(CONFIG.outputDir)) {
|
|
fs.mkdirSync(CONFIG.outputDir, { recursive: true });
|
|
}
|
|
|
|
const reportPath = path.join(CONFIG.outputDir, 'project_audit_report.json');
|
|
|
|
// 统计
|
|
const summary = {
|
|
totalTime: new Date().toISOString(),
|
|
mustHave: {
|
|
total: mustHaveResults.length,
|
|
completed: mustHaveResults.filter((r) => r.status === 'completed').length,
|
|
missing: mustHaveResults.filter((r) => r.status === 'missing').length,
|
|
completionRate: 0,
|
|
},
|
|
dontDo: {
|
|
total: dontDoResults.length,
|
|
compliant: dontDoResults.filter((r) => r.status === 'compliant').length,
|
|
violation: dontDoResults.filter((r) => r.status === 'violation').length,
|
|
complianceRate: 0,
|
|
},
|
|
};
|
|
|
|
summary.mustHave.completionRate = summary.mustHave.total > 0
|
|
? ((summary.mustHave.completed / summary.mustHave.total) * 100).toFixed(2) + '%'
|
|
: '0%';
|
|
|
|
summary.dontDo.complianceRate = summary.dontDo.total > 0
|
|
? ((summary.dontDo.compliant / summary.dontDo.total) * 100).toFixed(2) + '%'
|
|
: '0%';
|
|
|
|
const reportContent = {
|
|
summary: summary,
|
|
mustHave: mustHaveResults,
|
|
dontDo: dontDoResults,
|
|
};
|
|
|
|
fs.writeFileSync(reportPath, JSON.stringify(reportContent, null, 2));
|
|
|
|
// 生成可读报告
|
|
const readableReportPath = path.join(CONFIG.outputDir, 'project_audit_report.md');
|
|
let readableReport = `# V1.0全项目盘点报告
|
|
|
|
生成时间: ${new Date().toISOString()}
|
|
|
|
## 摘要
|
|
|
|
### V1.0必须实现项
|
|
- 总数: ${summary.mustHave.total}
|
|
- 已完成: ${summary.mustHave.completed}
|
|
- 缺失: ${summary.mustHave.missing}
|
|
- 完成率: ${summary.mustHave.completionRate}
|
|
|
|
### V1.0明确不做项
|
|
- 总数: ${summary.dontDo.total}
|
|
- 合规: ${summary.dontDo.compliant}
|
|
- 违规: ${summary.dontDo.violation}
|
|
- 合规率: ${summary.dontDo.complianceRate}
|
|
|
|
## V1.0必须实现项详情
|
|
|
|
`;
|
|
|
|
mustHaveResults.forEach((item) => {
|
|
const statusIcon = item.status === 'completed' ? '✅' : '❌';
|
|
readableReport += `### ${statusIcon} ${item.id}: ${item.name}
|
|
|
|
- 描述: ${item.description}
|
|
- 状态: ${item.status === 'completed' ? '已完成' : '缺失'}
|
|
- 详情: ${item.details}
|
|
|
|
`;
|
|
});
|
|
|
|
readableReport += `## V1.0明确不做项详情
|
|
|
|
`;
|
|
|
|
dontDoResults.forEach((item) => {
|
|
const statusIcon = item.status === 'compliant' ? '✅' : '❌';
|
|
readableReport += `### ${statusIcon} ${item.id}: ${item.name}
|
|
|
|
- 描述: ${item.description}
|
|
- 状态: ${item.status === 'compliant' ? '合规' : '违规'}
|
|
- 详情: ${item.details}
|
|
`;
|
|
|
|
if (item.violations && item.violations.length > 0) {
|
|
readableReport += `- 违规详情:
|
|
`;
|
|
item.violations.forEach((violation) => {
|
|
readableReport += ` - ${violation.file}:${violation.line} - ${violation.content}
|
|
`;
|
|
});
|
|
}
|
|
|
|
readableReport += '\n';
|
|
});
|
|
|
|
readableReport += `## 结论
|
|
|
|
`;
|
|
|
|
if (summary.mustHave.missing === 0 && summary.dontDo.violation === 0) {
|
|
readableReport += '✅ V1.0所有必须实现项已完成,所有明确不做项合规\n';
|
|
} else {
|
|
if (summary.mustHave.missing > 0) {
|
|
readableReport += `❌ V1.0有${summary.mustHave.missing}项必须实现项缺失\n`;
|
|
}
|
|
if (summary.dontDo.violation > 0) {
|
|
readableReport += `❌ V1.0有${summary.dontDo.violation}项明确不做项违规\n`;
|
|
}
|
|
}
|
|
|
|
fs.writeFileSync(readableReportPath, readableReport);
|
|
|
|
console.log(`报告已生成:`);
|
|
console.log(` - JSON报告: ${reportPath}`);
|
|
console.log(` - 可读报告: ${readableReportPath}`);
|
|
}
|
|
|
|
/**
|
|
* 主函数
|
|
*/
|
|
function main() {
|
|
console.log('开始V1.0全项目盘点...');
|
|
console.log(`项目根目录: ${CONFIG.projectRoot}`);
|
|
|
|
// 盘点必须实现项
|
|
const mustHaveResults = auditMustHave();
|
|
|
|
// 盘点明确不做项
|
|
const dontDoResults = auditDontDo();
|
|
|
|
// 生成报告
|
|
console.log('\n正在生成报告...');
|
|
generateReport(mustHaveResults, dontDoResults);
|
|
|
|
// 统计结果
|
|
const mustHaveCompleted = mustHaveResults.filter((r) => r.status === 'completed').length;
|
|
const mustHaveMissing = mustHaveResults.filter((r) => r.status === 'missing').length;
|
|
const dontDoCompliant = dontDoResults.filter((r) => r.status === 'compliant').length;
|
|
const dontDoViolation = dontDoResults.filter((r) => r.status === 'violation').length;
|
|
|
|
console.log('\n盘点完成!');
|
|
console.log(`必须实现项: ${mustHaveCompleted}/${mustHaveResults.length} 完成`);
|
|
console.log(`明确不做项: ${dontDoCompliant}/${dontDoResults.length} 合规`);
|
|
|
|
// 返回结果
|
|
return {
|
|
mustHave: mustHaveResults,
|
|
dontDo: dontDoResults,
|
|
};
|
|
}
|
|
|
|
// 如果直接运行此脚本
|
|
if (require.main === module) {
|
|
main();
|
|
}
|
|
|
|
module.exports = {
|
|
main,
|
|
auditMustHave,
|
|
auditDontDo,
|
|
V10_MUST_HAVE,
|
|
V10_DONT_DO,
|
|
CONFIG,
|
|
}; |