mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-21 02:36:39 +08:00
feat: support markmap svg export and download as png image
This commit is contained in:
parent
6807f7e88a
commit
dacdd6fe74
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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">
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user