From e295922209fb87c6dcd68ea1560fd16c3e6d808c Mon Sep 17 00:00:00 2001 From: dongyukun <1208714201@qq.com> Date: 星期五, 27 六月 2025 09:36:51 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/feature/ai' --- src/views/ai/mindmap/index/components/Right.vue | 60 ++++++++++++++++++++++++++---------------------------------- 1 files changed, 26 insertions(+), 34 deletions(-) diff --git a/src/views/ai/mindmap/index/components/Right.vue b/src/views/ai/mindmap/index/components/Right.vue index 0550650..b1d04de 100644 --- a/src/views/ai/mindmap/index/components/Right.vue +++ b/src/views/ai/mindmap/index/components/Right.vue @@ -4,7 +4,7 @@ <h3 class="m-0 px-7 shrink-0 flex items-center justify-between"> <span>思维导图预览</span> <!-- 展示在右上角 --> - <el-button type="primary" v-show="isEnd" @click="downloadImage" size="small"> + <el-button v-show="isEnd" size="small" type="primary" @click="downloadImage"> <template #icon> <Icon icon="ph:copy-bold" /> </template> @@ -19,33 +19,33 @@ <div class="flex flex-col items-center justify-center" v-html="html"></div> </div> - <div ref="mindmapRef" class="wh-full"> - <svg ref="svgRef" class="w-full" :style="{ height: `${contentAreaHeight}px` }" /> + <div ref="mindMapRef" class="wh-full"> + <svg ref="svgRef" :style="{ height: `${contentAreaHeight}px` }" class="w-full" /> <div ref="toolBarRef" class="absolute bottom-[10px] right-5"></div> </div> </div> </el-card> </template> -<script setup lang="ts"> +<script lang="ts" setup> import { Markmap } from 'markmap-view' import { Transformer } from 'markmap-lib' import { Toolbar } from 'markmap-toolbar' import markdownit from 'markdown-it' +import download from '@/utils/download' const md = markdownit() const message = useMessage() // 消息弹窗 -// TODO @hhero:mindmap 改成 mindMap 更精准哈 const props = defineProps<{ - mindmapResult: string // 生成结果 TODO @hhero 改成 generatedContent 会不会好点 + generatedContent: string // 生成结果 isEnd: boolean // 是否结束 isGenerating: boolean // 是否正在生成 isStart: boolean // 开始状态,开始时需要清除 html }>() -const contentRef = ref<HTMLDivElement>() // 右侧出来header以下的区域 +const contentRef = ref<HTMLDivElement>() // 右侧出来 header 以下的区域 const mdContainerRef = ref<HTMLDivElement>() // markdown 的容器,用来滚动到底下的 -const mindmapRef = ref<HTMLDivElement>() // 思维导图的容器 +const mindMapRef = ref<HTMLDivElement>() // 思维导图的容器 const svgRef = ref<SVGElement>() // 思维导图的渲染 svg const toolBarRef = ref<HTMLDivElement>() // 思维导图右下角的工具栏,缩放等 const html = ref('') // 生成过程中的文本 @@ -66,15 +66,16 @@ } }) -watch(props, ({ mindmapResult, isGenerating, isEnd, isStart }) => { +watch(props, ({ generatedContent, isGenerating, isEnd, isStart }) => { // 开始生成的时候清空一下 markdown 的内容 if (isStart) { html.value = '' } // 生成内容的时候使用 markdown 来渲染 if (isGenerating) { - html.value = md.render(mindmapResult) + html.value = md.render(generatedContent) } + // 生成结束时更新思维导图 if (isEnd) { update() } @@ -83,7 +84,7 @@ /** 更新思维导图的展示 */ const update = () => { try { - const { root } = transformer.transform(processContent(props.mindmapResult)) + const { root } = transformer.transform(processContent(props.generatedContent)) markMap?.setData(root) markMap?.fit() } catch (e) { @@ -105,32 +106,19 @@ return arr.join('\n') } -/** 下载图片 */ -// TODO @hhhero:可以抽到 download 这个里面,src/utils/download.ts 么?复用 image 方法? -// download SVG to png file +/** 下载图片:download SVG to png file */ const downloadImage = () => { - const svgElement = mindmapRef.value + const svgElement = mindMapRef.value // 将 SVG 渲染到图片对象 const serializer = new XMLSerializer() - const source = - '<?xml version="1.0" standalone="no"?>\r\n' + serializer.serializeToString(svgRef.value!) - const image = new Image() - image.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(source) - - // 将图片对象渲染 - const canvas = document.createElement('canvas') - canvas.width = svgElement?.offsetWidth || 0 - canvas.height = svgElement?.offsetHeight || 0 - let context = canvas.getContext('2d') - context?.clearRect(0, 0, canvas.width, canvas.height) - - image.onload = function () { - context?.drawImage(image, 0, 0) - const a = document.createElement('a') - a.download = 'mindmap.png' - a.href = canvas.toDataURL(`image/png`) - a.click() - } + const source = `<?xml version="1.0" standalone="no"?>\r\n${serializer.serializeToString(svgRef.value!)}` + const base64Url = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(source)}` + download.image({ + url: base64Url, + canvasWidth: svgElement?.offsetWidth, + canvasHeight: svgElement?.offsetHeight, + drawWithImageSize: false + }) } defineExpose({ @@ -149,6 +137,7 @@ height: 0; } } + .my-card { display: flex; flex-direction: column; @@ -161,13 +150,16 @@ @extend .hide-scroll-bar; } } + // markmap的tool样式覆盖 :deep(.markmap) { width: 100%; } + :deep(.mm-toolbar-brand) { display: none; } + :deep(.mm-toolbar) { display: flex; flex-direction: row; -- Gitblit v1.9.3