在上一篇文章里,咱们热热闹闹地聊了 AI 产品的交互实现。今天,就继续带大家探索 Markdown 内容解析,以及超酷炫的可视化展示,这可都是开发 AI 对话页面的 "秘密武器"!
Markdown内容解析
在解析 Markdown
信息之前,得先唠唠 AI 交互时的思考过程。这部分内容得按原有格式展示,直接用<pre>
标签就行。而处理 Markdown
信息,就得请出 MarkdownIt
这个 "得力助手" 啦!话不多说,上代码:
php
import MarkdownIt from "markdown-it";
// import emoji from "markdown-it-emoji";
import deflist from "markdown-it-deflist";
import abbr from "markdown-it-abbr";
import footnote from "markdown-it-footnote";
import ins from "markdown-it-ins";
import mark from "markdown-it-mark";
import taskLists from "markdown-it-task-lists";
import container from "markdown-it-container";
import toc from "markdown-it-toc-done-right";
// import mermaid from "@DatatracCorporation/markdown-it-mermaid";
import MarkdownItAnchor from "markdown-it-anchor";
export const useMarkDown = () => {
var config = {
html: true,
xhtmlOut: true,
breaks: true,
langPrefix: "lang-",
linkify: false,
typographer: true,
quotes: """''",
};
let markdownIt = new MarkdownIt(config);
markdownIt.renderer.rules.hr = function () {
return '';
};
// 自定义表格开始标签的渲染规则
markdownIt.renderer.rules.table_open = function (tokens, idx, options, env, self) {
// 在表格开始标签前添加带有指定 class 的 div 开始标签
let result = '<div class="custom-table-wrapper">';
result += '<table';
if (tokens[idx].attrPush) {
tokens[idx].attrPush(['class', 'custom-table']);
}
result += self.renderAttrs(tokens[idx]);
result += '>';
return result;
};
// 自定义表格结束标签的渲染规则
markdownIt.renderer.rules.table_close = function (tokens, idx, options, env, self) {
let result = '</table>';
// 在表格结束标签后添加 div 结束标签
result += '</div>';
return result;
};
// 自定义 th 开始标签的渲染规则
markdownIt.renderer.rules.th_open = function (tokens, idx, options, env, self) {
return '<th><div class="custom-cell-wrapper">';
};
// 自定义 th 结束标签的渲染规则
markdownIt.renderer.rules.th_close = function (tokens, idx, options, env, self) {
return '</div></th>';
};
// 自定义 td 开始标签的渲染规则
markdownIt.renderer.rules.td_open = function (tokens, idx, options, env, self) {
return '<td><div class="custom-cell-wrapper">';
};
// 自定义 td 结束标签的渲染规则
markdownIt.renderer.rules.td_close = function (tokens, idx, options, env, self) {
return '</div></td>';
};
markdownIt
// .use(emoji)
.use(deflist)
.use(abbr)
.use(MarkdownItAnchor)
.use(footnote)
.use(ins)
.use(mark)
.use(taskLists)
.use(container)
.use(container, "hljs-left")
.use(container, "hljs-center")
.use(container, "hljs-right")
.use(toc)
// .use(mermaid);
return {
markdownIt
}
}
用 MarkdownIt
的时候,你完全可以根据自己的想法,通过markdownIt.renderer.rules
对某些标签进行 "改造",让它更贴合你的需求!
可视化内容解析
和 Markdown 内容相比,可视化内容的处理就简单多啦!直接有请 echarts 这个 "可视化小能手" 闪亮登场!代码如下
javascript
/*
* @Author: Robin LEI
* @Date: 2025-03-24 09:06:17
* @LastEditTime: 2025-04-03 11:38:59
* @FilePath: \uniapp\插件模板\前端页面模板\uniapp-ai-mobile\src\utils\echart.ts
*/
import * as echarts from 'echarts/core';
import {
BarChart,
LineChart,
PieChart
} from 'echarts/charts';
import {
TitleComponent,
TooltipComponent,
GridComponent,
// 数据集组件
DatasetComponent,
// 内置数据转换器组件 (filter, sort)
TransformComponent,
ToolboxComponent,
DataZoomComponent
} from 'echarts/components';
import { LabelLayout, UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
// 注册必须的组件
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent,
TransformComponent,
BarChart,
LineChart,
PieChart,
LabelLayout,
UniversalTransition,
CanvasRenderer,
ToolboxComponent,
DataZoomComponent
]);
export default echarts;
yaml
const initChartFunc = (content: any, domName: string, chatType: string = "bar") => {
let chartDom: any = document.querySelector(`#${domName}`);
if (chartDom) {
const chart = echarts.init(chartDom);
arrDom.push(chart);
const xAxisKey = content?.visualization?.data?.xAxis[0];
const yAxisKey = content?.visualization?.data?.yAxis[0];
let option = {};
if (chatType === "line" || chatType === "bar") {
let xAxisData: any = [];
let yAxisData: any = [];
content?.sqlData.data.forEach((item) => {
xAxisData.push(item[xAxisKey]);
yAxisData.push(initNumFunc(item[yAxisKey]));
});
option = {
title: {
text: "",
},
tooltip: {
trigger: "axis",
formatter: "{b0}: {c0}",
},
toolbox: {
show: false,
},
grid: {
left: "12%",
},
xAxis: {
nameTextStyle: {
fontSize: 14,
color: "#999",
},
type: "category",
data: xAxisData,
show: true,
name: xAxisKey,
nameLocation: "middle",
nameGap: 30,
axisLabel: {
fontSize: 14,
color: "#999",
},
},
yAxis: {
show: true,
nameTextStyle: {
fontSize: 14,
color: "#999",
},
type: "value",
name: yAxisKey,
axisTick: {
inside: true,
},
scale: true,
axisLabel: {
fontSize: 14,
color: "#999",
formatter: function (value, index) {
if (value >= 10000 && value < 10000000) {
value = value / 10000 + "万";
} else if (value >= 10000000) {
value = value / 10000000 + "千万";
}
return value;
},
},
},
series: [
{
data: yAxisData,
type: chatType,
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgb(158,144,255)", // 0% 处的颜色
},
{
offset: 1,
color: "rgb(136,85,255)", // 100% 处的颜色
},
],
global: false, // 缺省为 false
},
},
},
],
dataZoom: {
start: 0,
end: 100, // 初始显示范围的结束百分比
type: "inside",
zoomLock: false,
},
};
} else {
const seriesData = content?.sqlData.data.map((item) => {
return {
name: item[xAxisKey],
value: initNumFunc(item[yAxisKey]),
};
});
option = {
title: {
text: "",
},
tooltip: {
trigger: "item",
},
toolbox: {
show: true,
},
xAxis: {
show: false,
},
yAxis: {
show: false,
},
label: {
formatter: "{b}\n{c}",
lineHeight: 15,
fontSize: 14,
color: "#999",
},
series: [
{
type: "pie",
radius: "50%",
data: seriesData,
},
],
};
}
chart.setOption(option);
}
};
到这儿,一个超基础的 AI 对话交互内容渲染就大功告成啦!要是你觉得这些代码超有趣,想实际跑一跑,直接从 GitHub 上下载代码就行:github.com/xknk/uniapp... 。要是觉得这个项目还挺不错,别忘了给个 Star,这对我来说可是超级大的鼓励!希望这篇文章能成为你开发 AI 对话页面的 "神助攻",也欢迎各位技术大佬在评论区畅所欲言,一起交流讨论!