const fs = require('node:fs') const path = require('node:path') const projectRoot = path.resolve(__dirname, '..') const h5Root = path.join(projectRoot, 'dist', 'build', 'h5') const faviconSource = path.join(projectRoot, 'public', 'favicon.svg') const faviconTarget = path.join(h5Root, 'favicon.svg') if (!fs.existsSync(h5Root)) { throw new Error(`H5 build output not found: ${h5Root}`) } const copyDirectory = (source, target) => { fs.mkdirSync(target, { recursive: true }) for (const entry of fs.readdirSync(source, { withFileTypes: true })) { const sourcePath = path.join(source, entry.name) const targetPath = path.join(target, entry.name) if (entry.isDirectory()) { copyDirectory(sourcePath, targetPath) continue } if (entry.isFile()) { fs.copyFileSync(sourcePath, targetPath) } } } const copyStaticSubtree = (subtree) => { const sourceDir = path.join(projectRoot, 'static', subtree) const targetDir = path.join(h5Root, 'static', subtree) if (!fs.existsSync(sourceDir)) { throw new Error(`Static assets not found: ${sourceDir}`) } fs.rmSync(targetDir, { recursive: true, force: true }) copyDirectory(sourceDir, targetDir) console.log(`Copied ${subtree} assets to ${path.relative(projectRoot, targetDir)}`) } const copyPublicStaticSubtree = (subtree) => { const sourceDir = path.join(projectRoot, 'public', 'static', subtree) const targetDir = path.join(h5Root, 'static', subtree) if (!fs.existsSync(sourceDir)) { throw new Error(`Public static assets not found: ${sourceDir}`) } fs.rmSync(targetDir, { recursive: true, force: true }) copyDirectory(sourceDir, targetDir) console.log(`Copied public static ${subtree} assets to ${path.relative(projectRoot, targetDir)}`) } const copyStaticFile = (fileName) => { const sourceFile = path.join(projectRoot, 'static', fileName) const targetFile = path.join(h5Root, 'static', fileName) if (!fs.existsSync(sourceFile)) { throw new Error(`Static file not found: ${sourceFile}`) } fs.mkdirSync(path.dirname(targetFile), { recursive: true }) fs.copyFileSync(sourceFile, targetFile) console.log(`Copied ${fileName} to ${path.relative(projectRoot, targetFile)}`) } const rewriteCopiedGuideDataUrls = () => { const guideDataDir = path.join(h5Root, 'static', 'guide-data') const replacements = [ ['http://1.92.206.90:9000/museum-assets', '/museum-assets'], ['http://1.92.206.90:9000/tts-audio', '/tts-audio'], ['https://guide.whaoyue.com/museum-assets', '/museum-assets'], ['https://guide.whaoyue.com/tts-audio', '/tts-audio'], ['https://guide.whaoyue.com/app-api', '/app-api'], ['"sourceHost": "1.92.206.90:5237"', '"sourceHost": ""'] ] for (const entry of fs.readdirSync(guideDataDir, { withFileTypes: true })) { if (!entry.isFile() || !entry.name.endsWith('.json')) continue const filePath = path.join(guideDataDir, entry.name) let text = fs.readFileSync(filePath, 'utf8') const original = text for (const [from, to] of replacements) { text = text.split(from).join(to) } if (text !== original) { fs.writeFileSync(filePath, text, 'utf8') console.log(`Rewrote guide-data URLs in ${path.relative(projectRoot, filePath)}`) } } } copyStaticSubtree('nav-assets') copyStaticSubtree('guide-data') rewriteCopiedGuideDataUrls() copyStaticSubtree('guide') copyStaticSubtree('icons') // 讲解业务单元封面由 H5 运行时按 /static/explain/... 动态加载。 copyStaticSubtree('explain') copyStaticSubtree('sgs-map-sdk') copyStaticSubtree('three') copyStaticFile('exhibit-placeholder.jpg') copyStaticFile('hall-placeholder.jpg') copyPublicStaticSubtree('Fonts') if (fs.existsSync(faviconSource)) { fs.copyFileSync(faviconSource, faviconTarget) }