diff --git a/scripts/generate-overview.js b/scripts/generate-overview.js deleted file mode 100644 index 007b4e5..0000000 --- a/scripts/generate-overview.js +++ /dev/null @@ -1,508 +0,0 @@ -/** - * 全平台原型完成情况汇总页生成脚本 - * - * 用法:node scripts/generate-overview.js [输出目录] - * 默认输出到:C:\Users\lenovo\Desktop\数字味道\蚁熊SAAS项目\产品\已完成\全平台 - * - * 由 git post-merge hook 在 git pull 后自动触发 - */ - -const fs = require('fs'); -const path = require('path'); - -// ===== 配置 ===== -const PROJECT_ROOT = path.resolve(__dirname, '..'); -const INDEX_HTML = path.join(PROJECT_ROOT, 'index.html'); -const OUTPUT_DIR = process.argv[2] || 'C:\\Users\\lenovo\\Desktop\\数字味道\\蚁熊SAAS项目\\产品\\已完成\\全平台'; - -// ===== 从 index.html 提取 SITE_MAP 数据 ===== -function extractSiteMap(html) { - // 找到 const SITE_MAP = [ 开始的位置 - const startMarker = 'const SITE_MAP = ['; - const startIdx = html.indexOf(startMarker); - if (startIdx === -1) throw new Error('未找到 SITE_MAP 定义'); - - // 从 SITE_MAP 开始,数括号匹配找到结束的 ]; - let depth = 0; - let inString = false; - let stringChar = ''; - let i = startIdx + startMarker.length - 1; // -1 因为 [ 已经包含在 marker 中 - - for (; i < html.length; i++) { - const ch = html[i]; - if (inString) { - if (ch === '\\') { i++; continue; } - if (ch === stringChar) { inString = false; } - continue; - } - if (ch === '"' || ch === "'" || ch === '`') { - inString = true; - stringChar = ch; - continue; - } - if (ch === '[' || ch === '{') { depth++; } - else if (ch === ']' || ch === '}') { - depth--; - if (depth === 0) { - // 找到了闭合的 ] - const jsCode = html.substring(startIdx + startMarker.indexOf('['), i + 1); - // 处理 JS 中的尾逗号(JSON 不允许) - const cleanedCode = jsCode - .replace(/,(\s*[}\]])/g, '$1') // 移除尾逗号 - .replace(/\/\*[\s\S]*?\*\//g, '') // 移除块注释 - .replace(/\/\/.*$/gm, ''); // 移除行注释 - try { - return eval('(' + cleanedCode + ')'); - } catch (e) { - throw new Error('SITE_MAP 解析失败: ' + e.message); - } - } - } - } - throw new Error('SITE_MAP 未正确闭合'); -} - -// ===== 提取 ICONS SVG 定义 ===== -function extractIcons(html) { - const match = html.match(/const ICONS = (\{[\s\S]*?\n\};)/); - if (!match) return {}; - try { - const cleaned = match[1].replace(/,(\s*\})/g, '$1'); - return eval('(' + cleaned + ')'); - } catch (e) { - return {}; - } -} - -// ===== 计算模块状态 ===== -function getModuleStatus(mod) { - const hasPages = mod.pages && mod.pages.length > 0; - if (!hasPages) return { status: 'pending', label: '待设计', cls: 'pending' }; - if (mod.done) return { status: 'done', label: '已完成', cls: 'done' }; - return { status: 'wip', label: '设计中', cls: 'wip' }; -} - -// ===== 统计各端数据 ===== -function buildTabStats(tab) { - if (tab.roles) { - // 健康应急 APP 特殊结构:roles + shared - const roleModules = []; - tab.roles.forEach(role => { - role.modules.forEach(mod => { - const st = getModuleStatus(mod); - roleModules.push({ - name: role.role + ' - ' + mod.name, - dir: mod.dir, - pages: mod.pages || [], - pageCount: (mod.pages || []).length, - status: st.status, - statusLabel: st.label, - statusCls: st.cls, - prd: mod.prd || null - }); - }); - }); - if (tab.shared) { - tab.shared.forEach(mod => { - const st = getModuleStatus(mod); - roleModules.push({ - name: '共享 - ' + mod.name, - dir: mod.dir, - pages: mod.pages || [], - pageCount: (mod.pages || []).length, - status: st.status, - statusLabel: st.label, - statusCls: st.cls, - prd: null - }); - }); - } - return { - id: tab.id, - label: tab.label, - modules: roleModules, - totalPages: roleModules.reduce((s, m) => s + m.pageCount, 0), - doneModules: roleModules.filter(m => m.status === 'done').length, - wipModules: roleModules.filter(m => m.status === 'wip').length, - pendingModules: roleModules.filter(m => m.status === 'pending').length, - totalModules: roleModules.length - }; - } - - // 标准结构:modules[] - const modules = (tab.modules || []).map(mod => { - const st = getModuleStatus(mod); - return { - name: mod.name, - dir: mod.dir, - pages: mod.pages || [], - pageCount: (mod.pages || []).length, - status: st.status, - statusLabel: st.label, - statusCls: st.cls, - prd: mod.prd || null, - entry: mod.entry || 'index.html' - }; - }); - - return { - id: tab.id, - label: tab.label, - modules, - totalPages: modules.reduce((s, m) => s + m.pageCount, 0), - doneModules: modules.filter(m => m.status === 'done').length, - wipModules: modules.filter(m => m.status === 'wip').length, - pendingModules: modules.filter(m => m.status === 'pending').length, - totalModules: modules.length - }; -} - -// ===== 生成 HTML ===== -function generateHTML(tabStats, generatedAt) { - const grandTotalPages = tabStats.reduce((s, t) => s + t.totalPages, 0); - const grandTotalModules = tabStats.reduce((s, t) => s + t.totalModules, 0); - const grandDoneModules = tabStats.reduce((s, t) => s + t.doneModules, 0); - - const platformColors = { - 'web-admin': '#69b1ff', - 'employee-app': '#95de64', - 'emergency-app': '#ffc069', - 'other-terminals': '#b37feb' - }; - - const platformIcons = { - 'web-admin': '💻', - 'employee-app': '📱', - 'emergency-app': '🎥', - 'other-terminals': '🌐' - }; - - const platformLabels = { - 'web-admin': 'Web 管理端', - 'employee-app': '员工端 APP', - 'emergency-app': '健康应急 APP', - 'other-terminals': '其他终端' - }; - - function renderModuleCard(mod) { - const statusConfig = { - done: { cls: 'card--done', badge: '已完成', badgeCls: 'badge--done' }, - wip: { cls: 'card--wip', badge: '设计中', badgeCls: 'badge--wip' }, - pending: { cls: 'card--pending', badge: '待设计', badgeCls: 'badge--pending' } - }; - const sc = statusConfig[mod.status]; - const pageLabel = mod.pageCount > 0 ? `${mod.pageCount} 页` : '暂无页面'; - const prdLink = mod.prd ? `PRD` : ''; - - return ` -
自动生成于 ${generatedAt} | 数据来源:git pull 后最新 SITE_MAP
-