完成页面统计图渲染
This commit is contained in:
@@ -10,11 +10,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"chart.js": "^4.4.8",
|
||||
"chartjs-adapter-moment": "^1.0.1",
|
||||
"echarts": "^5.6.0",
|
||||
"eventsource-client": "^1.1.3",
|
||||
"licia": "^1.46.0",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-container": "^4.0.0",
|
||||
"mermaid": "^11.4.1",
|
||||
"mermaid-it-markdown": "^1.0.8",
|
||||
"vue": "^3.5.13"
|
||||
|
||||
29
client/pnpm-lock.yaml
generated
29
client/pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ importers:
|
||||
chart.js:
|
||||
specifier: ^4.4.8
|
||||
version: 4.4.8
|
||||
chartjs-adapter-moment:
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1(chart.js@4.4.8)(moment@2.30.1)
|
||||
echarts:
|
||||
specifier: ^5.6.0
|
||||
version: 5.6.0
|
||||
@@ -23,9 +26,6 @@ importers:
|
||||
markdown-it:
|
||||
specifier: ^14.1.0
|
||||
version: 14.1.0
|
||||
markdown-it-container:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
mermaid:
|
||||
specifier: ^11.4.1
|
||||
version: 11.4.1
|
||||
@@ -758,6 +758,12 @@ packages:
|
||||
resolution: {integrity: sha512-IkGZlVpXP+83QpMm4uxEiGqSI7jFizwVtF3+n5Pc3k7sMO+tkd0qxh2OzLhenM0K80xtmAONWGBn082EiBQSDA==, tarball: https://registry.npmjs.org/chart.js/-/chart.js-4.4.8.tgz}
|
||||
engines: {pnpm: '>=8'}
|
||||
|
||||
chartjs-adapter-moment@1.0.1:
|
||||
resolution: {integrity: sha512-Uz+nTX/GxocuqXpGylxK19YG4R3OSVf8326D+HwSTsNw1LgzyIGRo+Qujwro1wy6X+soNSnfj5t2vZ+r6EaDmA==}
|
||||
peerDependencies:
|
||||
chart.js: '>=3.0.0'
|
||||
moment: ^2.10.2
|
||||
|
||||
chevrotain-allstar@0.3.1:
|
||||
resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==}
|
||||
peerDependencies:
|
||||
@@ -1047,7 +1053,7 @@ packages:
|
||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||
|
||||
eventsource-client@1.1.3:
|
||||
resolution: {integrity: sha512-6GJGePDMxin/6VH1Dex7RqnZRguweO1BVKhXpBYwKcQbVLOZPLfeDr9vYSb9ra88kjs0NpT8FaEDz5rExedDkg==, tarball: https://registry.npmjs.org/eventsource-client/-/eventsource-client-1.1.3.tgz}
|
||||
resolution: {integrity: sha512-6GJGePDMxin/6VH1Dex7RqnZRguweO1BVKhXpBYwKcQbVLOZPLfeDr9vYSb9ra88kjs0NpT8FaEDz5rExedDkg==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
eventsource-parser@3.0.0:
|
||||
@@ -1240,9 +1246,6 @@ packages:
|
||||
magic-string@0.30.17:
|
||||
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
||||
|
||||
markdown-it-container@4.0.0:
|
||||
resolution: {integrity: sha512-HaNccxUH0l7BNGYbFbjmGpf5aLHAMTinqRZQAEQbMr2cdD3z91Q6kIo1oUn1CQndkT03jat6ckrdRYuwwqLlQw==}
|
||||
|
||||
markdown-it@13.0.2:
|
||||
resolution: {integrity: sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==}
|
||||
hasBin: true
|
||||
@@ -1291,6 +1294,9 @@ packages:
|
||||
mlly@1.7.4:
|
||||
resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==}
|
||||
|
||||
moment@2.30.1:
|
||||
resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
|
||||
|
||||
mrmime@2.0.1:
|
||||
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -2363,6 +2369,11 @@ snapshots:
|
||||
dependencies:
|
||||
'@kurkle/color': 0.3.4
|
||||
|
||||
chartjs-adapter-moment@1.0.1(chart.js@4.4.8)(moment@2.30.1):
|
||||
dependencies:
|
||||
chart.js: 4.4.8
|
||||
moment: 2.30.1
|
||||
|
||||
chevrotain-allstar@0.3.1(chevrotain@11.0.3):
|
||||
dependencies:
|
||||
chevrotain: 11.0.3
|
||||
@@ -2865,8 +2876,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
||||
markdown-it-container@4.0.0: {}
|
||||
|
||||
markdown-it@13.0.2:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
@@ -2952,6 +2961,8 @@ snapshots:
|
||||
pkg-types: 1.3.1
|
||||
ufo: 1.5.4
|
||||
|
||||
moment@2.30.1: {}
|
||||
|
||||
mrmime@2.0.1: {}
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
@@ -1,9 +1,27 @@
|
||||
<script setup>
|
||||
import {onMounted, ref} from 'vue'
|
||||
import {onMounted, ref, toRaw} from 'vue'
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import MarkDownMermaidPlugin from 'mermaid-it-markdown'
|
||||
import {createEventSource} from 'eventsource-client'
|
||||
import * as echarts from 'echarts'
|
||||
import {CategoryScale, Chart, LinearScale, LineController, LineElement, PointElement, Title,} from 'chart.js'
|
||||
import 'chartjs-adapter-moment'
|
||||
import mermaid from 'mermaid'
|
||||
import {each, isEqual, isJson, nextTick} from 'licia'
|
||||
|
||||
Chart.register(
|
||||
LineController,
|
||||
LineElement,
|
||||
PointElement,
|
||||
LinearScale,
|
||||
Title,
|
||||
CategoryScale
|
||||
)
|
||||
|
||||
const chartsMap = ref({
|
||||
echarts: {},
|
||||
chartjs: {},
|
||||
mermaid: {},
|
||||
})
|
||||
// 初始化 markdown-it 实例
|
||||
const md = new MarkdownIt({
|
||||
html: true, // 启用 HTML 标签
|
||||
@@ -11,7 +29,33 @@ const md = new MarkdownIt({
|
||||
linkify: true, // 自动转换 URL 为链接
|
||||
typographer: true, // 启用一些语言中性的替换 + 引号美化
|
||||
})
|
||||
md.use(MarkDownMermaidPlugin)
|
||||
md.use(function (md) {
|
||||
md.renderer.rules.fence = function (tokens, idx, options, env, slf) {
|
||||
// console.log('tokens', tokens, tokens[idx].info)
|
||||
const content = tokens[idx].content
|
||||
// 此处判断是否为 echarts 代码块
|
||||
if (tokens[idx].info === 'echarts') {
|
||||
if (isJson(content)) {
|
||||
chartsMap.value.echarts[idx] = JSON.parse(content) //此处表示将内容存起来,存到当前页面的变量去
|
||||
}
|
||||
return `<div id="echarts-${idx}" style="width: 600px;height:400px;"></div>`
|
||||
} else if (tokens[idx].info === 'chartjs') {
|
||||
// 此处判断是否为 chartjs 代码块
|
||||
if (isJson(content)) {
|
||||
chartsMap.value.chartjs[idx] = JSON.parse(content)
|
||||
}
|
||||
return `<canvas id="chartjs-${idx}"></canvas>`
|
||||
} else if (tokens[idx].info === 'mermaid') {
|
||||
// 此处判断是否为 mermaidChart 代码块
|
||||
const code = content.trim()
|
||||
chartsMap.value.mermaid[idx] = code
|
||||
return `<div id="mermaid-${idx}">${code}</div>`
|
||||
} else {
|
||||
// 其他代码块
|
||||
return `<pre><code class='languge-${tokens[idx].info}'>${content}</code></pre>`
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const question = ref('')
|
||||
const answer = ref('')
|
||||
@@ -33,12 +77,25 @@ const showToast = ref(false)
|
||||
const toastMessage = ref('')
|
||||
const toastMessageType = ref('success')
|
||||
|
||||
const onEventSourceClose = (eventSource) => {
|
||||
console.log(answer.value)
|
||||
console.log(renderedAnswer.value)
|
||||
console.log(chartsMap.value)
|
||||
eventSource.close()
|
||||
renderCharts()
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!question.value.trim() || loading.value) return
|
||||
|
||||
loading.value = true
|
||||
answer.value = ''
|
||||
renderedAnswer.value = ''
|
||||
chartsMap.value = {
|
||||
echarts: {},
|
||||
chartjs: {},
|
||||
mermaid: {},
|
||||
}
|
||||
|
||||
try {
|
||||
const url = 'http://localhost:7891/chat/stream'
|
||||
@@ -59,18 +116,18 @@ const handleSubmit = async () => {
|
||||
url: url,
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
onDisconnect: () => {
|
||||
console.log(answer.value)
|
||||
console.log(renderedAnswer.value)
|
||||
eventSource.close()
|
||||
},
|
||||
})
|
||||
for await (const { data } of eventSource) {
|
||||
if (isEqual(data, '#CLOSE#')) {
|
||||
onEventSourceClose(eventSource)
|
||||
break
|
||||
}
|
||||
answer.value += data.replaceAll(/#\/#/g, '')
|
||||
renderedAnswer.value = md.render(answer.value)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('请求出错:', error)
|
||||
console.log(answer.value)
|
||||
answer.value = '抱歉,请求出现错误'
|
||||
renderedAnswer.value = answer.value
|
||||
showToastMessage('请求失败,请检查服务器连接', 'error')
|
||||
@@ -141,8 +198,25 @@ const handleCloseSettings = () => {
|
||||
showToastMessage('设置已保存', 'success')
|
||||
}
|
||||
|
||||
const renderCharts = () => {
|
||||
const map = toRaw(chartsMap.value)
|
||||
each(map.echarts, (value, key) => {
|
||||
echarts.init(document.getElementById(`echarts-${key}`)).setOption(value)
|
||||
})
|
||||
each(map.chartjs, (value, key) => {
|
||||
new Chart(document.getElementById(`chartjs-${key}`), value)
|
||||
})
|
||||
each(map.mermaid, (value, key) => {
|
||||
mermaid.initialize({ startOnLoad: true })
|
||||
mermaid.init(undefined, document.getElementById(`mermaid-${key}`))
|
||||
})
|
||||
}
|
||||
|
||||
// 在组件挂载时加载设置
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
renderCharts()
|
||||
})
|
||||
loadSettingsFromStorage()
|
||||
})
|
||||
</script>
|
||||
@@ -350,6 +424,10 @@ onMounted(() => {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.mermaid {
|
||||
font-family: 'Arial', sans-serif;
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
margin: 0;
|
||||
height: 100vh;
|
||||
|
||||
Reference in New Issue
Block a user