feat: support markmap svg export and download as png image

This commit is contained in:
RockYang 2024-04-22 14:20:51 +08:00
parent 6807f7e88a
commit dacdd6fe74
5 changed files with 67 additions and 11 deletions

View File

@ -67,8 +67,18 @@
.right-box { .right-box {
width 100% width 100%
h2 { .top-bar {
color #ffffff display flex
justify-content space-between
align-items center
h2 {
color #ffffff
}
.el-button {
margin-right 20px
}
} }
.markdown { .markdown {

View File

@ -378,7 +378,12 @@ const initData = () => {
httpGet(`/api/role/list`).then((res) => { httpGet(`/api/role/list`).then((res) => {
roles.value = res.data; roles.value = res.data;
console.log() console.log()
roleId.value = parseInt(router.currentRoute.value.params["role_id"]) ?? roles.value[0]['id']; if (router.currentRoute.value.params.role_id) {
roleId.value = parseInt(router.currentRoute.value.params["role_id"])
} else {
roleId.value = roles.value[0]['id']
}
newChat(); newChat();
}).catch((e) => { }).catch((e) => {
ElMessage.error('获取聊天角色失败: ' + e.messages) ElMessage.error('获取聊天角色失败: ' + e.messages)

View File

@ -135,9 +135,10 @@ onMounted(() => {
} }
.content { .content {
width: 100%; width: 100%
height: 100vh; height: 100vh
box-sizing: border-box; box-sizing: border-box
background-color #282c34
} }
} }

View File

@ -70,11 +70,20 @@
</div> </div>
<div class="right-box"> <div class="right-box">
<h2>思维导图</h2> <div class="top-bar">
<h2>思维导图</h2>
<el-button @click="downloadImage" type="primary">
<el-icon>
<Download/>
</el-icon>
<span>下载图片</span>
</el-button>
</div>
<div class="markdown" v-if="loading"> <div class="markdown" v-if="loading">
<div v-html="html"></div> <div v-html="html"></div>
</div> </div>
<div class="body" v-show="!loading"> <div class="body" id="markmap" v-show="!loading">
<svg ref="svgRef" :style="{ height: rightBoxHeight + 'px' }"/> <svg ref="svgRef" :style="{ height: rightBoxHeight + 'px' }"/>
</div> </div>
</div><!-- end task list box --> </div><!-- end task list box -->
@ -95,6 +104,7 @@ import {Transformer} from 'markmap-lib';
import {checkSession} from "@/action/session"; import {checkSession} from "@/action/session";
import {httpGet} from "@/utils/http"; import {httpGet} from "@/utils/http";
import {ElMessage} from "element-plus"; import {ElMessage} from "element-plus";
import {Download} from "@element-plus/icons-vue";
const leftBoxHeight = ref(window.innerHeight - 105) const leftBoxHeight = ref(window.innerHeight - 105)
const rightBoxHeight = ref(window.innerHeight - 85) const rightBoxHeight = ref(window.innerHeight - 85)
@ -287,6 +297,32 @@ const changeModel = () => {
} }
} }
// download SVG to png file
const downloadImage = () => {
const svgElement = document.getElementById("markmap");
// 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
canvas.height = svgElement.offsetHeight
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 = "geek-ai-xmind.png"
a.href = canvas.toDataURL(`image/png`)
a.click()
}
}
</script> </script>
<style lang="stylus"> <style lang="stylus">

View File

@ -19,7 +19,12 @@
</div> </div>
<el-row v-if="items.length > 0"> <el-row v-if="items.length > 0">
<el-table :data="items" :row-key="row => row.id" table-layout="auto" border> <el-table :data="items" :row-key="row => row.id" table-layout="auto" border
style="--el-table-border-color:#373C47;
--el-table-tr-bg-color:#2D323B;
--el-table-row-hover-bg-color:#373C47;
--el-table-header-bg-color:#474E5C;
--el-table-text-color:#d1d1d1">
<el-table-column prop="username" label="用户"/> <el-table-column prop="username" label="用户"/>
<el-table-column prop="model" label="模型"/> <el-table-column prop="model" label="模型"/>
<el-table-column prop="type" label="类型"> <el-table-column prop="type" label="类型">
@ -119,8 +124,7 @@ const fetchData = () => {
<style lang="stylus" scoped> <style lang="stylus" scoped>
.power-log { .power-log {
background-color #ffffff color #ffffff
.inner { .inner {
padding 0 20px 20px 20px padding 0 20px 20px 20px