产品地址:DevUI
使用说明:MateChat | MateChat - 轻松构建你的AI应用
引言
在数字化转型浪潮中,电商企业面临着用户咨询量激增、转化率提升困难、人工客服成本高昂等诸多挑战。如何在海量商品中精准匹配用户需求,如何在对话中自然地引导用户完成购买决策,成为电商平台亟需解决的核心问题。本文将基于华为MateChat对话组件和DevUI企业级前端解决方案,构建一个完整的智能导购助手系统,展示从用户咨询到订单转化的全链路设计与实现。
MateChat是华为云推出的GenAI对话组件库,致力于构建不同业务场景下高一致性的对话体验系统语言。它不仅提供了丰富的对话UI组件(消息气泡、输入框、快捷提示等),更重要的是匹配了各种工具/平台的原生业务场景和界面特征,提供更适合企业级应用的对话交互能力,打造流畅亲和、跨界一致、易学易用的用户体验,以及易接入、易维护、易扩展的开发体验。
编辑
DevUI则是面向企业中后台产品的开源前端解决方案,其设计价值观基于"高效、开放、可信、乐趣"四种自然与人文相结合的理念,旨在为设计师、前端开发者提供标准的设计体系。它提供了丰富的企业级组件库,满足各类落地场景,是一款真正开箱即用的企业级产品。两者结合,能够快速构建既符合企业设计规范,又具备优秀对话体验的智能应用。
编辑
本文将通过实际案例,展示如何利用这两大利器打造一个功能完善的智能导购助手,涵盖项目初始化、大模型接入、Markdown渲染优化、商品推荐卡片设计等核心环节,并深入探讨企业级场景下的知识库接入、性能优化、业务数据分析等关键问题。
一、项目初始化与环境搭建
1.1 通过Cl L 创建MateChat项目
咱们这里使用官方提供最新的MateChat的cli,直接执行下面命令就可以创建
npm create matechat@latest
这步需要输入创建的项目名称
编辑
出现 created successfully表示创建成功,下方提示咱们有新版本可用,可以执行npm install -g npm@11.6.3命令进行更新
编辑
执行npm install安装依赖
编辑
依赖安装完成后执行npm run dev运行项目
编辑
访问http://localhost:5173/vue-starter后成功进入主页
编辑
1.2 配置MateChat对话系统
在main.ts文件中引入MateChat和图标库样式,完成全局注册:
import { createApp } from 'vue';
import App from './App.vue';
import MateChat from '@matechat/core';
import '@devui-design/icons/icomoon/devui-icon.css';
createApp(App).use(MateChat).mount('#app');
编辑
这样配置后,MateChat的所有组件都可以在项目中直接使用,无需重复引入。图标库的全局引入也保证了图标能够正常显示。
二、接入大语言模型
2.1 安装OpenAI SDK
为了实现真正的智能对话,我们需要接入大语言模型。这里使用OpenAI兼容接口,以DeepSeek为例(也可以替换为其他兼容OpenAI接口的模型服务):
npm install openai
编辑
2.2 配置模型参数
在src/models/config.ts文件中做如下修改可启用真实模型进行对话
编辑
2.3 实现流式对话
配置完DeepSeek的API KEY之后咱们测试一下对话
编辑
三、Markdown渲染讲解
MateChat项目中已经引入了 @matechat/core 组件库,所以咱们可以直接使用Markdown组件
这一节主要实现Matechat的基本用法,主题切换,数学公式,Mermaid渲染,PlanUML渲染。
3.1 基本用法
目前MateChat项目中已经集成了MarkDown卡片,目前集成的位置在src/main.ts中,通过import MateChat from '@matechat/core'导入了整个MateChat组件库,使用.use(MateChat)全局注册了所有组件,包括McMarkdownCard
编辑
实际使用的位置:在src/view/chat-process/chat-process.vue中
编辑
在对话气泡中,McMarkdownCard组件用于渲染AI的回复内容:
- content属性:通过renderMessage(msg) 方法渲染消息内容,支持思考过程(think标签)
- theme属性:动态绑定主题themeStore.theme,支持明暗主题切换
- enableThink属性:启动思考模式显示功能
下面这段代码是渲染逻辑
3.2 主题切换
目前MateChat已经自主集成了主题切换功能
主题切换的核心原理是themeStrore.theme存储当前值(light或者dark),通过组件绑定:theme="themeStore.theme",切换时修改store值,所有组件自动响应
主题定义在src/constant/theme-data.ts下
编辑
主题状态在src/store/theme-store.ts下
编辑
主题映射在src/hooks/use-theme.ts下
编辑
应用到组件(src/view/chat-process/chat-process.vue)
编辑
3.3 数学公式
要集成数学公式首先安装 katex 依赖
katex是KaTeX数学公式渲染引擎
@mdit/plugin-katex是katex插件
npm install katex @mdit/plugin-katex
导入插件
import { katex } from '@mdit/plugin-katex';
编辑
配置插件
// 数学公式插件配置
const mdPlugins = ref([
{
plugin: katex,
opt: {},
},
]);
编辑
应用到组件中
编辑
导入KateX样式
<style scoped lang="scss">
@import "devui-theme/styles-var/devui-var.scss";
@import 'katex/dist/katex.min.css';
编辑
测试了一下数学公式的展示效果,也能够正常渲染。
编辑
3.4 Mermaid渲染
设置enableMermaid为true开启mermaid渲染。要确保已经安装了mermaid依赖
npm install mermaid
在 chat-process.vue 中添加了 enableMermaid 配置:
- :enableMermaid="true" - 启用 Mermaid 图表渲染
编辑
下面让咱们测试一下
请帮我画一个流程图:
```mermaid
graph LR
A[用户输入] --> B[AI处理]
B --> C[生成回复]
C --> D[显示结果]
```
渲染的效果没问题
编辑
3.5 PlanUML渲染
要支持PlanUML渲染,要先安装markdown-it-plantuml依赖
npm install markdown-it-plantuml
导入插件:
import PlantUml from 'markdown-it-plantuml';
添加到 mdPlugins 配置:
// Markdown 插件配置(数学公式 + PlantUML)
const mdPlugins = ref([
{
plugin: katex,
opt: {},
},
{
plugin: PlantUml,
opt: {
server: 'https://www.plantuml.com/plantuml', // PlantUML 服务器地址
},
},
]);
编辑
四、打造智能导购核心功能
整个系统的核心思路是:通过精心设计的 System Prompt 让 AI 扮演智能导购角色,按照约定的 JSON 格式返回商品数据,前端自动解析 JSON 并渲染成商品卡片。
具体流程分为三个关键步骤:
- 角色定义:通过 System Prompt 告诉 AI 它是专业导购"小智",需要理解用户需求并推荐商品
- 数据约定:规定 AI 返回格式为"文字说明 + JSON 商品数据",确保数据可解析
- 智能渲染:前端自动提取 JSON 数据,分离文字和商品信息,分别渲染成对话内容和商品卡片
如下是测试效果:
编辑
4.1 系统提示词设计 - AI 角色定义
文件位置:src/constant/system-prompt.ts
export const SHOPPING_ASSISTANT_SYSTEM_PROMPT = `你是一个专业的智能导购助手,名叫"小智"。你的任务是根据用户需求推荐合适的商品。
当推荐商品时,请按照以下格式返回:
1. 先用自然语言介绍推荐的商品和理由
2. 然后在回答末尾添加商品数据,格式如下:
```json
[
{
"name": "商品名称",
"price": 价格数字,
"image": "图片URL",
"desc": "简短描述(20字以内)"
}
]
注意:
- 每次推荐2-3个商品
- 价格要真实合理
- 图片必须使用以下格式之一:
- 笔记本电脑: images.unsplash.com/photo-14961…
- 手机: images.unsplash.com/photo-15117…
- 耳机: images.unsplash.com/photo-15057… ...(更多商品类型)
- 如果用户只是普通聊天(如问候、闲聊),不要推荐商品`;

**设计要点**:
1. **明确角色身份**:让 AI 知道自己是"小智",是专业导购
1. **规定返回格式**:详细说明 JSON 结构,确保可解析
1. **提供图片映射**:预设商品类型与图片 URL 的对应关系
1. **约束推荐数量**:控制在 2-3 个商品,避免信息过载
1. **场景判断**:区分购物需求和普通聊天,避免无意义推荐

编辑
### **4.2 商品数据解析工具 - JSON 提取核心逻辑**
这是系统的"大脑",负责从 AI 回复中智能提取商品数据。
**文件位置**:src/utils/product.ts
1. **正则匹配多种格式**:同时支持 ```json 和 ``` 两种代码块
1. **多重验证机制**:JSON 解析 + 数组类型检查 + 必需字段验证
1. **容错处理**:某个 JSON 块失败不影响其他块的解析
1. **内容分离**:保留文字说明,移除 JSON 数据,提升阅读体验
/**
-
从 AI 回复内容中提取商品 JSON 数据
-
@param content AI 返回的完整文本内容
-
@returns 解析出的商品列表,如果没有找到则返回空数组 */ export function extractProductsFromContent(content: string): ProductList { try { // 使用正则表达式匹配 JSON 代码块 // 支持
json 和两种格式 const jsonBlockRegex = /(?:json)?\s*\n?([\s\S]*?)\n?/g; const matches = content.matchAll(jsonBlockRegex);for (const match of matches) { const jsonStr = match[1].trim();
// 尝试解析 JSON try { const parsed = JSON.parse(jsonStr);
// 验证是否为商品数组 if (Array.isArray(parsed) && parsed.length > 0) { // 验证每个商品是否包含必需字段 const isValid = parsed.every( (item) => typeof item === 'object' && item !== null && 'name' in item && 'price' in item && 'image' in item && 'desc' in item ); if (isValid) { return parsed as ProductList; } }} catch (e) { // 当前 JSON 块解析失败,继续尝试下一个 continue; } }
return []; } catch (error) { console.error('Failed to extract products from content:', error); return []; } }
/**
- 从 AI 回复中移除商品 JSON 数据,只保留文本说明
*/
export function removeProductJsonFromContent(content: string): string {
return content.replace(/
(?:json)?\s*\n?[\s\S]*?\n?/g, '').trim(); }
/**
- 格式化价格显示
*/
export function formatPrice(price: number): string {
return
¥${price.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}; }


编辑
### **4.3 商品卡片组件 - 精美 UI 实现**
精心设计的商品卡片,提供出色的视觉体验和交互效果。
**文件位置**:src/view/product/product-card.vue
1. **悬停动效**:卡片上浮 + 图片放大,增强交互感
1. **图片容错**:加载失败自动显示占位图
1. **文字截断**:名称单行、描述两行,保持布局整洁
1. **价格突出**:红色加粗显示,吸引用户注意
1. **响应式设计**:适配移动端和桌面端
```
<template>
<div class="product-card">
<!-- 商品图片 -->
<div class="product-image-wrapper">
<img
:src="product.image"
:alt="product.name"
class="product-image"
@error="onImageError"
/>
</div>
<!-- 商品信息 -->
<div class="product-info">
<h3 class="product-name" :title="product.name">
{{ product.name }}
</h3>
<p class="product-desc">{{ product.desc }}</p>
<!-- 价格和操作 -->
<div class="product-footer">
<div class="product-price">{{ formatPrice(product.price) }}</div>
<div class="product-actions">
<d-button size="sm" variant="text" @click="onView">
<i class="icon-eye"></i>
</d-button>
<d-button size="sm" variant="solid" color="primary" @click="onBuy">
购买
</d-button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import type { IProduct } from '@/types/product-types';
import { formatPrice } from '@/utils/product';
interface Props {
product: IProduct;
}
const props = defineProps<Props>();
const emit = defineEmits<{
view: [product: IProduct];
buy: [product: IProduct];
}>();
const onImageError = (e: Event) => {
const target = e.target as HTMLImageElement;
target.src = 'https://via.placeholder.com/400x300?text=No+Image';
};
const onView = () => emit('view', props.product);
const onBuy = () => emit('buy', props.product);
</script>
<style scoped lang="scss">
.product-card {
display: flex;
flex-direction: column;
background: $devui-base-bg;
border: 1px solid $devui-dividing-line;
border-radius: $devui-border-radius;
overflow: hidden;
transition: all 0.3s ease;
&:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
transform: translateY(-2px);
}
.product-image-wrapper {
height: 200px;
overflow: hidden;
.product-image {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
&:hover .product-image {
transform: scale(1.05);
}
}
.product-info {
padding: 16px;
.product-name {
font-size: 16px;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.product-desc {
font-size: 14px;
color: #666;
line-height: 1.5;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.product-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 12px;
.product-price {
font-size: 20px;
font-weight: 700;
color: #ff4d4f;
}
}
}
}
</style>
```


编辑
## **五、总结与推荐**
本文基于**华为MateChat对话组件**和**DevUI企业级前端解决方案**,从零构建了一个功能完善的智能导购系统。通过精心设计的 System Prompt 让 AI 扮演智能导购角色,实现了从用户咨询到商品推荐的完整闭环。
**MateChat**作为华为云推出的企业级GenAI对话组件库,具有以下显著优势:
1. **开箱即用**:提供完整的对话UI组件(气泡、输入框、历史记录等),无需从零开发
1. **企业级品质**:经过华为内部大规模业务验证,稳定可靠
1. **高度可定制**:支持主题切换、打字机效果、Markdown渲染等丰富特性
1. **易于扩展**:插件化设计,轻松集成数学公式、Mermaid、PlantUML等增强功能
1. **跨框架支持**:提供Vue、React等多种版本,适配不同技术栈
1. **完善文档**:详细的使用指南和示例代码,降低学习成本
配合**DevUI的企业级组件库**,我们能够快速构建既符合企业设计规范,又具备出色对话体验的智能应用。本项目中的商品卡片、主题切换、响应式布局等功能,都得益于DevUI提供的标准化设计体系和组件支持。
**相关资源:**
- 产品地址:[DevUI](https://devui.design/home "DevUI")
<!---->
- 体验地址:[MateChat - 轻松构建你的AI应用](https://matechat.gitcode.com/ "MateChat - 轻松构建你的AI应用")
<!---->
- 使用说明:[MateChat | MateChat - 轻松构建你的AI应用](https://matechat.gitcode.com/use-guide/introduction.html "MateChat | MateChat - 轻松构建你的AI应用")
无论你是想构建智能客服、知识问答、还是本文的智能导购系统,MateChat都能为你提供坚实的技术基础。它不仅帮你节省大量UI开发时间,更重要的是提供了经过验证的对话交互范式和企业级的稳定性保障。
希望本文能为你的GenAI应用开发提供有价值的参考!如果觉得有帮助,欢迎Star支持,也期待看到更多基于MateChat构建的优秀应用!