From db7a14329f7fc5d397841116ca37132d05011a13 Mon Sep 17 00:00:00 2001
From: lyf <2514544224@qq.com>
Date: Fri, 3 Jul 2026 02:31:27 +0800
Subject: [PATCH] =?UTF-8?q?=E4=B8=BA=E8=AE=B2=E8=A7=A3=E4=B8=9A=E5=8A=A1?=
=?UTF-8?q?=E5=8D=95=E5=85=83=E6=8E=A5=E5=85=A5=E9=A2=84=E8=A7=88=E5=B0=81?=
=?UTF-8?q?=E9=9D=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
scripts/copy-h5-nav-assets.cjs | 2 +
scripts/generate-explain-unit-previews.cjs | 173 ++++++++++++++++++
src/components/explain/ExplainHallSelect.vue | 45 +++--
src/data/adapters/guideDataAdapter.ts | 4 +
src/domain/museum.ts | 1 +
src/pages/explain/list.vue | 1 +
src/pages/index/index.vue | 1 +
src/utils/explainUnitPreviews.ts | 46 +++++
.../unit-previews/2060939176503275521.svg | 27 +++
.../unit-previews/2060939176637493249.svg | 27 +++
.../unit-previews/2060939176767516674.svg | 28 +++
.../unit-previews/2060939176897540098.svg | 27 +++
.../unit-previews/2060939177027563521.svg | 27 +++
.../unit-previews/7467940240901013505.svg | 28 +++
.../unit-previews/7467940240901013506.svg | 28 +++
.../unit-previews/7467940240901013507.svg | 27 +++
.../unit-previews/7467940240901013508.svg | 27 +++
.../unit-previews/7467940240901013509.svg | 27 +++
.../unit-previews/7467940240901013510.svg | 27 +++
.../unit-previews/7467940240901013511.svg | 27 +++
.../unit-previews/7467940240901013512.svg | 27 +++
.../unit-previews/7467940240901013513.svg | 28 +++
.../unit-previews/7467940240901013514.svg | 28 +++
.../unit-previews/7467940240901013515.svg | 28 +++
.../unit-previews/7467940240901013516.svg | 28 +++
.../unit-previews/7467940240901013517.svg | 28 +++
.../unit-previews/7467940240901013518.svg | 29 +++
.../unit-previews/7467940240901013519.svg | 29 +++
.../unit-previews/7467940240901013520.svg | 29 +++
.../unit-previews/7467940240901013521.svg | 29 +++
.../unit-previews/7467940240901013522.svg | 29 +++
.../unit-previews/7467940240901013523.svg | 28 +++
.../unit-previews/7467940240901013524.svg | 28 +++
.../unit-previews/7467940240901013525.svg | 28 +++
.../unit-previews/7467940240901013526.svg | 28 +++
.../unit-previews/7467940240901013527.svg | 28 +++
.../unit-previews/7467940240901013528.svg | 28 +++
.../unit-previews/7467940240901013529.svg | 28 +++
.../unit-previews/7467940240901013530.svg | 27 +++
.../unit-previews/7467940240901013531.svg | 27 +++
.../unit-previews/7467940240901013532.svg | 28 +++
.../unit-previews/7467940240901013533.svg | 27 +++
.../unit-previews/7467940240901013534.svg | 27 +++
static/explain/unit-previews/default.svg | 27 +++
44 files changed, 1254 insertions(+), 17 deletions(-)
create mode 100644 scripts/generate-explain-unit-previews.cjs
create mode 100644 src/utils/explainUnitPreviews.ts
create mode 100644 static/explain/unit-previews/2060939176503275521.svg
create mode 100644 static/explain/unit-previews/2060939176637493249.svg
create mode 100644 static/explain/unit-previews/2060939176767516674.svg
create mode 100644 static/explain/unit-previews/2060939176897540098.svg
create mode 100644 static/explain/unit-previews/2060939177027563521.svg
create mode 100644 static/explain/unit-previews/7467940240901013505.svg
create mode 100644 static/explain/unit-previews/7467940240901013506.svg
create mode 100644 static/explain/unit-previews/7467940240901013507.svg
create mode 100644 static/explain/unit-previews/7467940240901013508.svg
create mode 100644 static/explain/unit-previews/7467940240901013509.svg
create mode 100644 static/explain/unit-previews/7467940240901013510.svg
create mode 100644 static/explain/unit-previews/7467940240901013511.svg
create mode 100644 static/explain/unit-previews/7467940240901013512.svg
create mode 100644 static/explain/unit-previews/7467940240901013513.svg
create mode 100644 static/explain/unit-previews/7467940240901013514.svg
create mode 100644 static/explain/unit-previews/7467940240901013515.svg
create mode 100644 static/explain/unit-previews/7467940240901013516.svg
create mode 100644 static/explain/unit-previews/7467940240901013517.svg
create mode 100644 static/explain/unit-previews/7467940240901013518.svg
create mode 100644 static/explain/unit-previews/7467940240901013519.svg
create mode 100644 static/explain/unit-previews/7467940240901013520.svg
create mode 100644 static/explain/unit-previews/7467940240901013521.svg
create mode 100644 static/explain/unit-previews/7467940240901013522.svg
create mode 100644 static/explain/unit-previews/7467940240901013523.svg
create mode 100644 static/explain/unit-previews/7467940240901013524.svg
create mode 100644 static/explain/unit-previews/7467940240901013525.svg
create mode 100644 static/explain/unit-previews/7467940240901013526.svg
create mode 100644 static/explain/unit-previews/7467940240901013527.svg
create mode 100644 static/explain/unit-previews/7467940240901013528.svg
create mode 100644 static/explain/unit-previews/7467940240901013529.svg
create mode 100644 static/explain/unit-previews/7467940240901013530.svg
create mode 100644 static/explain/unit-previews/7467940240901013531.svg
create mode 100644 static/explain/unit-previews/7467940240901013532.svg
create mode 100644 static/explain/unit-previews/7467940240901013533.svg
create mode 100644 static/explain/unit-previews/7467940240901013534.svg
create mode 100644 static/explain/unit-previews/default.svg
diff --git a/scripts/copy-h5-nav-assets.cjs b/scripts/copy-h5-nav-assets.cjs
index 58b076e..f8c5dc4 100644
--- a/scripts/copy-h5-nav-assets.cjs
+++ b/scripts/copy-h5-nav-assets.cjs
@@ -70,6 +70,8 @@ const copyStaticFile = (fileName) => {
copyStaticSubtree('nav-assets')
copyStaticSubtree('guide-data')
copyStaticSubtree('icons')
+// 讲解业务单元封面由 H5 运行时按 /static/explain/... 动态加载。
+copyStaticSubtree('explain')
copyStaticSubtree('sgs-map-sdk')
copyStaticSubtree('three')
copyStaticFile('exhibit-placeholder.jpg')
diff --git a/scripts/generate-explain-unit-previews.cjs b/scripts/generate-explain-unit-previews.cjs
new file mode 100644
index 0000000..b4b5aca
--- /dev/null
+++ b/scripts/generate-explain-unit-previews.cjs
@@ -0,0 +1,173 @@
+const fs = require('fs')
+const path = require('path')
+
+const projectRoot = path.resolve(__dirname, '..')
+const outputDir = path.join(projectRoot, 'static', 'explain', 'unit-previews')
+
+// 业务单元来自当前 H5 讲解页实际渲染的一级 outline,生成结果需与映射表同步。
+const units = [
+ { id: '7467940240901013508', hall: '地球厅', name: '第一单元:宜居地球', theme: 'earth' },
+ { id: '7467940240901013509', hall: '地球厅', name: '第二单元:地史探源', theme: 'geology' },
+ { id: '7467940240901013510', hall: '地球厅', name: '第三单元:华夏山水', theme: 'landscape' },
+ { id: '7467940240901013511', hall: '地球厅', name: '第四单元:矿产资源——大地的馈赠', theme: 'mineral' },
+ { id: '7467940240901013512', hall: '地球厅', name: '专题区:地心穿越+自然灾害', theme: 'disaster' },
+ { id: '7467940240901013530', hall: '家园厅', name: '序厅', theme: 'home' },
+ { id: '7467940240901013531', hall: '家园厅', name: '第一单元:天地共鉴', theme: 'home' },
+ { id: '7467940240901013532', hall: '家园厅', name: '第二单元:万物共生', theme: 'ecology' },
+ { id: '7467940240901013533', hall: '家园厅', name: '第三单元:家园共筑', theme: 'home' },
+ { id: '7467940240901013534', hall: '家园厅', name: '尾厅', theme: 'home' },
+ { id: '7467940240901013513', hall: '恐龙厅', name: '第一单元:初识恐龙', theme: 'dinosaur' },
+ { id: '7467940240901013514', hall: '恐龙厅', name: '第二单元:恐龙解密', theme: 'dinosaur' },
+ { id: '7467940240901013515', hall: '恐龙厅', name: '第三单元:恐龙时代', theme: 'dinosaur' },
+ { id: '7467940240901013516', hall: '恐龙厅', name: '第四单元:粤赣育龙', theme: 'dinosaur' },
+ { id: '7467940240901013517', hall: '恐龙厅', name: '第五单元:终结与新生', theme: 'dinosaur' },
+ { id: '2060939176503275521', hall: '人类厅', name: '第一单元:什么是灵长类', theme: 'human' },
+ { id: '2060939176637493249', hall: '人类厅', name: '第二单元:猿与猴', theme: 'human' },
+ { id: '2060939176767516674', hall: '人类厅', name: '第三单元:丛林远足', theme: 'forest' },
+ { id: '2060939176897540098', hall: '人类厅', name: '第四单元:与巨兽同行', theme: 'human' },
+ { id: '2060939177027563521', hall: '人类厅', name: '第五单元:从燧石到硅基', theme: 'human' },
+ { id: '7467940240901013523', hall: '生态厅', name: '前言', theme: 'ecology' },
+ { id: '7467940240901013524', hall: '生态厅', name: '第二单元:各得其所——世界动物地理区系', theme: 'ecology' },
+ { id: '7467940240901013525', hall: '生态厅', name: '第三单元:地球之窗——全球主要生态系统景观', theme: 'ecology' },
+ { id: '7467940240901013526', hall: '生物厅', name: '序篇:生物的命名与分类', theme: 'biology' },
+ { id: '7467940240901013527', hall: '生物厅', name: '第二单元:中国南方保护动物', theme: 'biology' },
+ { id: '7467940240901013528', hall: '生物厅', name: '第三单元:生物基础知识', theme: 'biology' },
+ { id: '7467940240901013529', hall: '生物厅', name: '第四单元:生物大观', theme: 'biology' },
+ { id: '7467940240901013518', hall: '演化厅', name: '第零单元:基于博物学的进化思想', theme: 'evolution' },
+ { id: '7467940240901013519', hall: '演化厅', name: '第一单元:经典进化学说——影响世界的理论', theme: 'evolution' },
+ { id: '7467940240901013520', hall: '演化厅', name: '第二单元:遗传与变异——演化的内在驱动力', theme: 'evolution' },
+ { id: '7467940240901013521', hall: '演化厅', name: '第三单元:演化方向的选择——适应', theme: 'evolution' },
+ { id: '7467940240901013522', hall: '演化厅', name: '第四单元:三十八亿年的创造——从单细胞到智慧生命', theme: 'evolution' },
+ { id: '7467940240901013505', hall: '宇宙厅', name: '第一单元:仰望苍穹——人类对宇宙认识的历程', theme: 'cosmos' },
+ { id: '7467940240901013506', hall: '宇宙厅', name: '第二单元:拾级而观——等级宇宙结构', theme: 'cosmos' },
+ { id: '7467940240901013507', hall: '宇宙厅', name: '第三单元:采石知天——行星科学与深空探测', theme: 'meteorite' }
+]
+
+const themes = {
+ earth: ['#d7e9d2', '#fbf6d8', '#2f6f5f', '#8eac50'],
+ geology: ['#ebe1d3', '#bfd5dc', '#674c3b', '#c08c45'],
+ landscape: ['#dcefd7', '#f4efd0', '#265d4e', '#92b65a'],
+ mineral: ['#e8e1d4', '#f1f4df', '#4b4f5a', '#c2a95b'],
+ disaster: ['#eee0d1', '#d7e3e0', '#5b3d35', '#d69d45'],
+ home: ['#edf2df', '#f5f2d7', '#334c45', '#b2bf47'],
+ ecology: ['#dbeedb', '#f4f2d1', '#2a5a49', '#87a946'],
+ dinosaur: ['#e7e0cd', '#dce8d5', '#4d4932', '#9a7844'],
+ human: ['#e8e0d7', '#eef0d6', '#4b3f36', '#b8884b'],
+ forest: ['#d9eddc', '#eff3d2', '#2f5f43', '#76a159'],
+ biology: ['#dff0df', '#eef4d4', '#2f604b', '#7bb36c'],
+ evolution: ['#e6e6d8', '#dbe9df', '#3f5147', '#9ea34a'],
+ cosmos: ['#dce5ef', '#f2f1d4', '#26354e', '#7b8bb7'],
+ meteorite: ['#dedfe5', '#f4efd5', '#343746', '#b19b56'],
+ fallback: ['#e8eadf', '#f7f5df', '#3f4d43', '#a8b64c']
+}
+
+const escapeXml = (value) => String(value)
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+
+const shortTitle = (name) => name
+ .replace(/^第[一二三四五六七八九十零]+单元[::]?/, '')
+ .replace(/^专题区[::]?/, '')
+ .replace(/^序篇[::]?/, '')
+ .replace(/[——+].*$/, '')
+ .trim()
+
+const motif = (theme, accent, dark) => {
+ if (theme === 'cosmos') {
+ return `
+
+
+
+
+ `
+ }
+ if (theme === 'meteorite' || theme === 'mineral' || theme === 'geology') {
+ return `
+
+
+
+ `
+ }
+ if (theme === 'dinosaur') {
+ return `
+
+
+
+
+ `
+ }
+ if (theme === 'human') {
+ return `
+
+
+
+ `
+ }
+ if (theme === 'biology' || theme === 'ecology' || theme === 'forest') {
+ return `
+
+
+
+
+ `
+ }
+ if (theme === 'evolution') {
+ return `
+
+
+
+
+
+ `
+ }
+ return `
+
+
+
+ `
+}
+
+const svgFor = ({ id, hall, name, theme }) => {
+ const [start, end, dark, accent] = themes[theme] || themes.fallback
+ const title = shortTitle(name) || name
+
+ return `
+`
+}
+
+fs.mkdirSync(outputDir, { recursive: true })
+units.forEach((unit) => {
+ fs.writeFileSync(path.join(outputDir, `${unit.id}.svg`), svgFor(unit), 'utf8')
+})
+fs.writeFileSync(path.join(outputDir, 'default.svg'), svgFor({
+ id: 'default',
+ hall: '讲解',
+ name: '自然博物馆导览',
+ theme: 'fallback'
+}), 'utf8')
+
+console.log(`Generated ${units.length + 1} explain unit preview SVG files in ${path.relative(projectRoot, outputDir)}`)
diff --git a/src/components/explain/ExplainHallSelect.vue b/src/components/explain/ExplainHallSelect.vue
index 0e60936..7568b06 100644
--- a/src/components/explain/ExplainHallSelect.vue
+++ b/src/components/explain/ExplainHallSelect.vue
@@ -62,9 +62,12 @@
class="hall-card unit-card"
@tap="handleBusinessUnitClick(unit.id)"
>
-
- {{ unit.name.slice(0, 1) || '讲' }}
-
+
{{ unit.name }}
@@ -122,7 +125,10 @@