Skip to content

Commit 1bbdab7

Browse files
authored
refactor(demo): 修复 ECharts 表格图表功能并优化代码 (#1693)
* fix(demo): 修复 ECharts 表格图表功能并优化代码 - 修复 enableChart 被错误设置为对象而非布尔值的 bug - 简化配置逻辑,使用三元运算符替代 if-else - 统一插件加载逻辑,减少重复代码 - 添加详细的 JSDoc 注释和使用文档 - 添加快速开始指南和最佳实践建议 关键修复: - enableChart 必须是布尔值 true,不能是 ECharts 对象 - Table hook 使用严格相等检查 enableChart === true * docs: 更新流式渲染示例代码与滚动逻辑 * fix: 修复 addons 构建缺少环境变量替换导致运行时报错的问题 * fix(examples): 优化流式打印和插件加载体验 * refactor(examples): 移除流式聊天自动滚动逻辑
1 parent 8ca33f1 commit 1bbdab7

5 files changed

Lines changed: 773 additions & 249 deletions

File tree

.changeset/fix-addons-build-env.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'cherry-markdown': patch
3+
---
4+
5+
- fix: 修复 addons 构建缺少环境变量替换导致运行时报错的问题

examples/ai_chat_stream.html

Lines changed: 202 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!DOCTYPE html>
2-
<html lang="en">
2+
<html lang="zh-CN">
33

44
<head>
55
<meta charset="UTF-8">
@@ -137,58 +137,147 @@
137137
cursor: pointer;
138138
}
139139

140+
/* 插件选项 - 胶囊样式 */
140141
.plugin-options {
141142
width: 100%;
142143
max-width: var(--ai-max-width);
143-
margin: 0 auto 16px;
144-
padding: 16px;
145-
background: var(--ai-surface);
146-
border-radius: 8px;
147-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
144+
margin: 0 auto 12px;
145+
padding: 0;
146+
background: transparent;
147+
box-shadow: none;
148148
box-sizing: border-box;
149149
}
150150

151-
.plugin-options h3 {
152-
margin: 0 0 12px;
153-
font-size: 14px;
154-
color: #666;
151+
.plugin-title {
152+
font-size: 13px;
153+
font-weight: 600;
154+
color: #333;
155+
margin: 0 0 8px 0;
156+
display: flex;
157+
align-items: center;
158+
gap: 6px;
159+
}
160+
161+
.plugin-title-hint {
162+
font-size: 11px;
163+
font-weight: 400;
164+
color: #999;
155165
}
156166

157167
.plugin-list {
158168
display: flex;
159-
gap: 20px;
169+
gap: 8px;
160170
flex-wrap: wrap;
171+
align-items: center;
172+
}
173+
174+
.plugin-sep {
175+
width: 1px;
176+
height: 20px;
177+
background: var(--ai-muted);
178+
margin: 0 4px;
179+
}
180+
181+
.plugin-group-label {
182+
font-size: 12px;
183+
color: #999;
184+
margin-right: 2px;
185+
}
186+
187+
.plugin-or {
188+
font-size: 11px;
189+
color: #bbb;
190+
font-style: italic;
161191
}
162192

163193
.plugin-item {
164-
display: flex;
165-
align-items: center;
166-
gap: 8px;
194+
position: relative;
195+
cursor: pointer;
196+
user-select: none;
167197
}
168198

169199
.plugin-item input {
170-
width: 18px;
171-
height: 18px;
172-
cursor: pointer;
200+
position: absolute;
201+
opacity: 0;
202+
width: 0;
203+
height: 0;
173204
}
174205

175206
.plugin-item label {
176-
cursor: pointer;
177-
font-size: 14px;
207+
display: inline-flex;
208+
align-items: center;
209+
gap: 6px;
210+
padding: 6px 14px;
211+
border-radius: 20px;
212+
font-size: 13px;
213+
font-weight: 500;
214+
line-height: 1.4;
215+
border: 1px solid var(--ai-muted);
216+
background: var(--ai-surface);
217+
color: #666;
218+
transition: all 0.2s ease;
219+
white-space: nowrap;
178220
}
179221

180-
.plugin-item .plugin-status {
181-
font-size: 12px;
182-
color: #999;
183-
margin-left: 4px;
222+
.plugin-item input:checked+label {
223+
background: #e6f0ff;
224+
border-color: var(--ai-accent);
225+
color: var(--ai-accent);
184226
}
185227

186-
.plugin-item .plugin-status.loaded {
187-
color: #52c41a;
228+
.plugin-item input:disabled+label,
229+
.plugin-item input[disabled]+label {
230+
opacity: 0.5;
231+
pointer-events: none;
188232
}
189233

190-
.plugin-item .plugin-status.loading {
191-
color: #faad14;
234+
.plugin-item .status-dot {
235+
width: 7px;
236+
height: 7px;
237+
border-radius: 50%;
238+
background: transparent;
239+
transition: background 0.3s ease;
240+
flex-shrink: 0;
241+
}
242+
243+
.plugin-item .status-dot.loading {
244+
background: #faad14;
245+
animation: pulse-dot 1s infinite;
246+
}
247+
248+
.plugin-item .status-dot.loaded {
249+
background: #52c41a;
250+
}
251+
252+
@keyframes pulse-dot {
253+
0%, 100% { opacity: 1; }
254+
50% { opacity: 0.3; }
255+
}
256+
257+
/* 消息选择器 */
258+
.msg-picker {
259+
width: 100%;
260+
max-width: var(--ai-max-width);
261+
margin: 0 auto 12px;
262+
box-sizing: border-box;
263+
}
264+
265+
.msg-picker-label {
266+
font-size: 13px;
267+
color: #666;
268+
margin-bottom: 8px;
269+
}
270+
271+
.msg-picker-list {
272+
display: flex;
273+
flex-wrap: wrap;
274+
gap: 8px;
275+
}
276+
277+
.j-msg-pick-btn:disabled,
278+
.j-msg-pick-btn[disabled] {
279+
opacity: 0.5;
280+
cursor: not-allowed;
192281
}
193282

194283
.custom-input {
@@ -215,6 +304,51 @@
215304
min-height: 0;
216305
}
217306

307+
/* Toast 提示 */
308+
.toast-container {
309+
position: fixed;
310+
top: 16px;
311+
right: 16px;
312+
z-index: 9999;
313+
display: flex;
314+
flex-direction: column;
315+
gap: 8px;
316+
pointer-events: none;
317+
}
318+
319+
.toast {
320+
padding: 10px 16px;
321+
border-radius: 8px;
322+
font-size: 13px;
323+
line-height: 1.5;
324+
color: #fff;
325+
background: #333;
326+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
327+
opacity: 0;
328+
transform: translateX(20px);
329+
transition: opacity 0.3s ease, transform 0.3s ease;
330+
pointer-events: auto;
331+
max-width: 360px;
332+
word-break: break-word;
333+
}
334+
335+
.toast-visible {
336+
opacity: 1;
337+
transform: translateX(0);
338+
}
339+
340+
.toast-error {
341+
background: #ff4d4f;
342+
}
343+
344+
.toast-success {
345+
background: #52c41a;
346+
}
347+
348+
.toast-info {
349+
background: #1890ff;
350+
}
351+
218352
@media (max-width: 720px) {
219353
.ai-chat-wrapper {
220354
padding: 12px;
@@ -230,8 +364,12 @@
230364
}
231365

232366
.plugin-list {
233-
flex-direction: column;
234-
gap: 12px;
367+
gap: 6px;
368+
}
369+
370+
.plugin-item label {
371+
font-size: 12px;
372+
padding: 5px 10px;
235373
}
236374
}
237375
</style>
@@ -240,53 +378,68 @@
240378
</head>
241379

242380
<body>
381+
<!-- Toast 提示容器 -->
382+
<div class="toast-container j-toast-container"></div>
383+
243384
<div class="ai-chat-wrapper">
244385
<!-- 插件选项区 -->
245386
<div class="plugin-options">
246-
<h3>🔌 插件懒加载选项(勾选后懒加载对应插件)</h3>
387+
<div class="plugin-title">
388+
扩展插件 <span class="plugin-title-hint">勾选后点击下方消息按钮即可加载</span>
389+
</div>
247390
<div class="plugin-list">
248391
<div class="plugin-item">
249392
<input type="checkbox" id="plugin-mermaid" class="j-plugin-checkbox" data-plugin="mermaid">
250-
<label for="plugin-mermaid">Mermaid(流程图)</label>
251-
<span class="plugin-status j-plugin-status" data-plugin="mermaid"></span>
393+
<label for="plugin-mermaid">Mermaid<span class="status-dot j-plugin-status j-status-dot-mermaid"></span></label>
252394
</div>
395+
<span class="plugin-sep"></span>
396+
<div class="plugin-group-label">数学公式(二选一)</div>
253397
<div class="plugin-item">
254-
<input type="checkbox" id="plugin-katex" class="j-plugin-checkbox" data-plugin="katex" checked>
255-
<label for="plugin-katex">KaTeX(数学公式-轻量)</label>
256-
<span class="plugin-status j-plugin-status" data-plugin="katex"></span>
398+
<input type="checkbox" id="plugin-katex" class="j-plugin-checkbox" data-plugin="katex">
399+
<label for="plugin-katex">KaTeX<span class="status-dot j-plugin-status j-status-dot-katex"></span></label>
257400
</div>
401+
<div class="plugin-or">or</div>
258402
<div class="plugin-item">
259403
<input type="checkbox" id="plugin-mathjax" class="j-plugin-checkbox" data-plugin="mathjax">
260-
<label for="plugin-mathjax">MathJax(数学公式-完整)</label>
261-
<span class="plugin-status j-plugin-status" data-plugin="mathjax"></span>
404+
<label for="plugin-mathjax">MathJax<span class="status-dot j-plugin-status j-status-dot-mathjax"></span></label>
405+
</div>
406+
<span class="plugin-sep"></span>
407+
<div class="plugin-item">
408+
<input type="checkbox" id="plugin-echarts" class="j-plugin-checkbox" data-plugin="echarts">
409+
<label for="plugin-echarts">ECharts<span class="status-dot j-plugin-status j-status-dot-echarts"></span></label>
262410
</div>
263411
</div>
264412
</div>
265413

266-
<div class="dialog j-dialog" role="log" aria-live="polite"></div>
267-
268-
<!-- 消息模板(隐藏) -->
269-
<div class="one-msg j-one-msg" aria-hidden="true">
270-
<div class="avatar">AI</div>
271-
<div class="chat-one-msg"></div>
414+
<!-- 消息选择区 -->
415+
<div class="msg-picker">
416+
<div class="msg-picker-label">选择示例消息(点击后流式打印)</div>
417+
<div class="msg-picker-list j-msg-picker-list"></div>
272418
</div>
273419

274420
<!-- 控件区 -->
275421
<div class="controls">
276-
<button type="button" class="button j-button">
277-
获取消息(剩余<span class="j-button-tips"></span>条消息)
278-
</button>
279-
<button type="button" class="button secondary j-pause-button">
422+
<button type="button" class="button secondary j-pause-button" disabled>
280423
暂停流式
281424
</button>
282425
<label class="status">
283426
<input class="j-status-input status-input" type="checkbox" checked> 开启流式适配
284427
</label>
285428
</div>
286429

430+
<!-- 消息模板(隐藏) -->
431+
<div class="one-msg j-one-msg" aria-hidden="true">
432+
<div class="avatar">AI</div>
433+
<div class="chat-one-msg"></div>
434+
</div>
435+
436+
<!-- 渲染区 -->
437+
<div class="dialog j-dialog" role="log" aria-live="polite"></div>
438+
439+
<!-- 自定义输入区 -->
287440
<div class="custom-input">
288441
<textarea class="custom-textarea j-custom-textarea" placeholder="请输入您想要流式打印的Markdown内容..."></textarea>
289-
<div class="button custom-button j-custom-button">流式打印自定义内容</div>
442+
<button type="button" class="button custom-button j-custom-button">流式打印自定义内容</button>
290443
</div>
291444
</div>
292445

@@ -297,4 +450,4 @@ <h3>🔌 插件懒加载选项(勾选后懒加载对应插件)</h3>
297450
</script>
298451
</body>
299452

300-
</html>
453+
</html>

0 commit comments

Comments
 (0)