const fs = require('fs') const path = require('path') const root = path.resolve(__dirname, '..') const sourceRoot = path.join(root, 'src') const outputRoot = path.join(root, 'work') function walk(dir) { const files = [] for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { const full = path.join(dir, entry.name) if (entry.isDirectory()) files.push(...walk(full)) else if (/\.(vue|js)$/i.test(entry.name)) files.push(full) } return files } function csv(value) { const text = String(value == null ? '' : value) return `"${text.replace(/"/g, '""')}"` } const files = walk(sourceRoot) const records = new Map() let totalCreateDataCalls = 0 let literalCreateDataCalls = 0 let dynamicCreateDataCalls = 0 let b1Get = 0 let b1Post = 0 let b1Patch = 0 let tmGet = 0 let tmPost = 0 let tmPatch = 0 for (const file of files) { const source = fs.readFileSync(file, 'utf8') const relative = path.relative(root, file).replace(/\\/g, '/') const createDataCount = (source.match(/\bCreateData\s*\(/g) || []).length totalCreateDataCalls += createDataCount const literalPattern = /\bCreateData\s*\(\s*(['"])(.*?)\1\s*,\s*(['"])(.*?)\3/gms let match let fileLiteralCount = 0 while ((match = literalPattern.exec(source)) !== null) { const type = match[2] const procedure = match[4] literalCreateDataCalls++ fileLiteralCount++ if (!records.has(procedure)) records.set(procedure, { procedure, calls: 0, types: new Set(), files: new Set() }) const record = records.get(procedure) record.calls++ record.types.add(type) record.files.add(relative) } dynamicCreateDataCalls += Math.max(0, createDataCount - fileLiteralCount) const increment = (pattern, counter) => { const count = (source.match(pattern) || []).length return counter + count } b1Get = increment(/\bgetB1\s*\(/g, b1Get) b1Post = increment(/\bpostB1\s*\(/g, b1Post) b1Patch = increment(/\bpatchB1\s*\(/g, b1Patch) tmGet = increment(/\bgettm\s*\(/g, tmGet) tmPost = increment(/\bposttm\s*\(/g, tmPost) tmPatch = increment(/\bpatchtm\s*\(/g, tmPatch) } const procedureRows = [...records.values()] .sort((a, b) => a.procedure.localeCompare(b.procedure, 'zh-CN')) .map(row => [row.procedure, row.calls, [...row.types].sort().join('|'), [...row.files].sort().join('|')]) const procedureCsv = [ ['Procedure', 'CallCount', 'CreateDataTypes', 'SourceFiles'], ...procedureRows ].map(row => row.map(csv).join(',')).join('\n') + '\n' fs.writeFileSync(path.join(outputRoot, 'frontend_procedure_call_inventory_20260725.csv'), procedureCsv, 'utf8') const summary = { sourceFiles: files.length, vueFiles: files.filter(file => file.endsWith('.vue')).length, jsFiles: files.filter(file => file.endsWith('.js')).length, totalCreateDataCalls, literalCreateDataCalls, dynamicCreateDataCalls, uniqueLiteralProcedures: procedureRows.length, b1: { get: b1Get, post: b1Post, patch: b1Patch }, tm: { get: tmGet, post: tmPost, patch: tmPatch } } fs.writeFileSync(path.join(outputRoot, 'frontend_function_scan_summary_20260725.json'), JSON.stringify(summary, null, 2) + '\n', 'utf8') console.log(JSON.stringify(summary))