--- author: Peanut created_at: 2026-04-07 purpose: 定义小程序"创造未来"页面剧本卡片的 Markdown 渲染方案 --- # 小程序剧本卡片 Markdown 渲染设计 ## 问题背景 小程序"创造未来"页面(ScriptView.vue)中,剧本卡片当前以纯文本形式显示内容: - 摘要区域:`{{ getScriptSummary(script) }}` - 完整内容:存储在 `script.plotJson.fullContent` 中 但后端返回的剧本数据是 **Markdown 格式**: ```markdown ### 人物小传 花生米曾有过光芒闪耀的"破土而出"时刻... ### 戏剧驱动力 - 主人公当下最想要的一件具体的东西是:成为武林高手。 - 为了得到它,他必须承受或放弃的是:原本正常的生活节奏... #### 第一场:抉择 - **时间**:日 - **地点**:花生米家中 - **人物**:花生米 花生米(自言自语):"成为武林高手,这听起来多带劲啊..." ``` 当前纯文本显示导致: - 标题与普通文本无法区分 - 列表项没有项目符号 - 粗体等格式丢失 - 阅读体验差 ## 设计方案 ### 架构概述 ``` ┌─────────────────────────────────────────────────────────────┐ │ ScriptView.vue │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 剧本卡片 (script-card) │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │ 标题 / persona │ │ │ │ │ ├─────────────────────────────────────────────┤ │ │ │ │ │ 摘要区域 (Markdown 渲染 - 前 200 字符) │ │ │ │ │ │ ### 人物小传 │ │ │ │ │ │ 花生米曾有过光芒闪耀的... │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ [路径映射 →] (点击跳转详情页) │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ▼ 点击卡片 ┌─────────────────────────────────────────────────────────────┐ │ ScriptDetailView.vue (新增) │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 返回 剧本标题 │ │ │ ├─────────────────────────────────────────────────────┤ │ │ │ │ │ │ │ 完整 Markdown 内容渲染 │ │ │ │ ### 人物小传 │ │ │ │ 花生米曾有过... │ │ │ │ ### 戏剧驱动力 │ │ │ │ - 主人公当下最想要... │ │ │ │ #### 第一场:抉择 │ │ │ │ - **时间**:日 │ │ │ │ ... │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ### 组件复用 **已有组件**:[`mini-program/src/components/Markdown.vue`](mini-program/src/components/Markdown.vue) 当前支持的 Markdown 格式: - ✅ 分割线 `---` - ✅ 四级标题 `#### ` - ✅ 列表项 `* ` / `- ` - ✅ 普通段落 **需要扩展支持**: - ❌ 三级标题 `### ` - ❌ 粗体 `**text**` ### 文件结构 ``` mini-program/src/ ├── components/ │ └── Markdown.vue # 扩展现有组件 ├── pages/main/ │ ├── ScriptView.vue # 修改:卡片摘要使用 Markdown │ └── ScriptDetailView.vue # 新增:剧本详情页 └── services/ └── epicScript.js # 现有服务,无需修改 ``` ## 实施细节 ### 1. Markdown 组件扩展 **文件**:`mini-program/src/components/Markdown.vue` **新增解析规则**: ```javascript // 三级标题 ### const h3Match = trimmed.match(/^###\s+(.+)/) if (h3Match) { blocks.push({ type: 'h3', content: h3Match[1] }) continue } // 粗体 **text** (在段落内容中处理) // 由于小程序不支持富文本内的 HTML,粗体需要特殊处理 // 方案:将包含粗体的段落拆分为多个文本段 ``` **模板新增**: ```vue {{ block.content }} ``` **样式**: ```css .markdown-h3 { display: block; font-size: 30rpx; font-weight: 600; color: rgba(243, 232, 255, 0.95); margin: 20rpx 0 12rpx 0; line-height: 1.4; } ``` ### 2. ScriptView.vue 修改 **修改点 1**:导入 Markdown 组件 ```javascript import Markdown from '../../components/Markdown.vue' ``` **修改点 2**:摘要区域使用 Markdown 渲染 ```vue {{ getScriptSummary(script) }} ``` **修改点 3**:添加点击跳转 ```vue ``` **修改点 4**:跳转方法 ```javascript const viewScriptDetail = (script) => { uni.navigateTo({ url: `/pages/main/ScriptDetailView?id=${script.id}` }) } ``` ### 3. ScriptDetailView.vue 新建 **文件**:`mini-program/src/pages/main/ScriptDetailView.vue` **核心结构**: ```vue ``` ### 4. 摘要提取逻辑 **当前逻辑**: ```javascript const getScriptSummary = (script) => { const text = script.summary || script.content || '' return text.replace(/\s+/g, ' ').trim() } ``` **修改后**: ```javascript const getScriptSummary = (script) => { // 优先使用 summary 字段 if (script.summary) { return script.summary } // 从 fullContent 提取前 200 字符 const fullContent = script.plotJson?.fullContent || '' if (fullContent) { // 提取内容,去掉 Markdown 符号 return fullContent .split('\n') .filter(line => line.trim()) .slice(0, 5) // 取前 5 行 .join('\n') .slice(0, 200) + '...' } return '暂无摘要' } ``` ## 验收标准 - [x] Markdown 组件支持三级标题 `###` - [x] Markdown 组件支持粗体 `**text**`(如无法完美支持,降级为普通文本) - [x] ScriptView.vue 卡片摘要使用 Markdown 渲染 - [x] 点击卡片可跳转到详情页查看完整内容 - [x] 详情页正确渲染完整 Markdown 格式 - [x] 样式与现有设计保持一致 ## 注意事项 ### 1. 粗体支持限制 微信小程序的 `` 组件不支持富文本内的局部样式。 **解决方案**: - 方案 A:使用正则将 `**text**` 拆分为多个 `` 组件(复杂) - 方案 B:降级处理,粗体标记移除但保留文字(简单) **推荐**:先实现方案 B,如效果不佳再考虑方案 A。 ### 2. 长内容加载 剧本完整内容可能较长(2000+ 字符),详情页使用 `` 确保可滚动浏览。 ### 3. 数据获取 - 剧本数据已通过 `store.fetchScripts()` 加载到 store - 详情页从 store 根据 ID 获取,无需额外 API 调用 ## 参考文档 - [uni-app 页面跳转](https://uniapp.dcloud.net.cn/api/router.html) - [uni-app scroll-view](https://uniapp.dcloud.net.cn/component/scroll-view.html) - 已有 Markdown 组件:`mini-program/src/components/Markdown.vue`