提交 59178dbf 编写于 作者: I InsCode

Auto Commit

上级 3e9e786e
# Vue 3 + Vite # MateChatTemplate
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more. ## 🌈项目简介
本项目是基于MateChat与Devui的Vue3项目模板,由Inscode 提供 AI 接口,旨在帮助开发者快速上手体验MateChat并搭建属于自己的AI助手。
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support). 了解更多请访问MateChat网站:[MateChat](https://matechat.gitcode.com)
## 🖥️开始体验
### 开放MateChat入口:
在Header.vue的\<template>标签中,放开MateChat入口的注释,
页面刷新后就能看到MateChat的入口。
本项目提供了两个不同的MateChat模板,它们的区别在于完成度不同
### 极简搭建
默认场景:简单的对话功能,没有接入模型,只有一个最基本的聊天助手的框架。大家可以在这里尝试组合MateChat的不同组件,搭建具有个人风格的AI应用.
### 完整搭建
如果您不满足于极简场景,我们还提供了完整的搭建。您只需要在Page.vue文件,将\<template>标签中的\<SimpleDemo />注释掉,放开\<Demo />的注释,即可看到完整的场景。
Demo在SimpleDemo的基础上,加入了MateChat的其他组件,并接入Inscode的AI模型,提供完整的聊天助手场景。
### 尝试问答:
- 帮我写一个简单的Vue3欢迎组件
- 帮我写一个Vue3组件,并使用echarts
- 帮我写一个Vue3组件,并使用echarts,内容为一个折线图,横轴为时间,纵轴为温度,数据为[1,2,3,4,5,6,7,8,9,10], 标题为“温度变化”
大模型回答后,可以点击下方的"切换为卡片"按钮,切换为卡片模式,并拖动卡片去替换页面上原有的卡片。
### 添砖加瓦:
在Demo.vue文件中\<McIntroduction>标签的下方, 放开\<Prompt>组件的注释,为欢迎页添加一行提示词。
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="./src/assets/devui-logo.svg" /> <link rel="icon" type="image/svg+xml" href="./src/assets/devui-logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DevUI Admin</title> <title>DevUI Admin</title>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script> <script src="https://unpkg.com/browse/echarts@5.6.0"></script>
</head> </head>
<body> <body>
<div id="app" style="height: 100%;"></div> <div id="app" style="height: 100%;"></div>
......
@import 'devui-theme/styles-var/devui-var.scss'; @use 'devui-theme/styles-var/devui-var.scss' as *;
.content-card { .content-card {
margin: 8px; margin: 8px;
......
...@@ -264,6 +264,6 @@ export default defineComponent({ ...@@ -264,6 +264,6 @@ export default defineComponent({
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import './Content.scss'; @use './Content.scss' as *;
</style> </style>
\ No newline at end of file
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
@import 'devui-theme/styles-var/devui-var.scss'; @use 'devui-theme/styles-var/devui-var.scss' as *;
.da-footer { .da-footer {
font-size: 12px; font-size: 12px;
......
...@@ -3,11 +3,10 @@ ...@@ -3,11 +3,10 @@
<div class="left-nav"> <div class="left-nav">
</div> </div>
<div class="right-nav"> <div class="right-nav">
<d-search id="search" v-model="search" icon-position="left" size="sm" :no-border="true"></d-search> <d-search id="search" style="margin-right: 8px;" v-model="search" icon-position="left" size="sm" :no-border="true"></d-search>
<d-button class="nav-drop-btn" icon="icon-project-nav" variant="text"></d-button>
<div class="theme"> <div class="theme">
<!-- MateChat抽屉 --> <!-- MateChat入口 -->
<img :class="['opt', {'active': props.drawerOpen}]" @click="openDrawer()" src="../assets/logo.svg"> <!-- <img :class="['opt', {'active': props.drawerOpen}]" @click="openDrawer()" src="../assets/logo.svg"> -->
<div class="opt"> <div class="opt">
<d-icon name="dark" color="var(--devui-text)" @click="changeTheme()"> <d-icon name="dark" color="var(--devui-text)" @click="changeTheme()">
<template #suffix> <template #suffix>
...@@ -31,7 +30,7 @@ ...@@ -31,7 +30,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { HtmlHTMLAttributes, onMounted, ref, defineProps } from 'vue'; import { onMounted, ref } from 'vue';
import { themeServiceInstance } from '../main'; import { themeServiceInstance } from '../main';
import { infinityTheme, galaxyTheme } from 'devui-theme'; import { infinityTheme, galaxyTheme } from 'devui-theme';
...@@ -63,7 +62,7 @@ onMounted(() => { ...@@ -63,7 +62,7 @@ onMounted(() => {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import 'devui-theme/styles-var/devui-var.scss'; @use 'devui-theme/styles-var/devui-var.scss' as *;
.header { .header {
z-index: 20; z-index: 20;
display: flex; display: flex;
...@@ -93,10 +92,6 @@ onMounted(() => { ...@@ -93,10 +92,6 @@ onMounted(() => {
display: flex; display: flex;
align-items: center; align-items: center;
.nav-drop-btn {
display: none;
}
.nav-list { .nav-list {
margin-right: 24px; margin-right: 24px;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<div v-if="startChat" ref="conversationRef" class="conversation-area"> <div v-if="startChat" ref="conversationRef" class="conversation-area">
<template v-for="(msg, idx) in messages" :key="idx"> <template v-for="(msg, idx) in messages" :key="idx">
<McBubble v-if="msg.from === 'user'" :content="msg.content" :align="'right'" :avatarConfig="msg.avatarConfig"></McBubble> <McBubble v-if="msg.from === 'user'" :content="msg.content" :align="'right'" :avatarConfig="msg.avatarConfig"></McBubble>
<McBubble v-else :loading="msg.loading ?? false" :avatarPosition="msg.avatarPosition" :avatarConfig="msg.avatarConfig"> <McBubble v-else :loading="msg.loading" :avatarPosition="msg.avatarPosition" :avatarConfig="msg.avatarConfig">
<RenderMarkdown v-if="msg.type === 'common'" :content="msg.content"></RenderMarkdown> <RenderMarkdown v-if="msg.type === 'common'" :content="msg.content"></RenderMarkdown>
<div :id="'demoChart'+idx" <div :id="'demoChart'+idx"
draggable="true" draggable="true"
...@@ -46,28 +46,16 @@ ...@@ -46,28 +46,16 @@
]" ]"
></McIntroduction> ></McIntroduction>
<!-- <McPrompt :list="introPrompt.list" :direction="'horizontal'" class="intro-prompt" @itemClick="onItemClick($event)"></McPrompt> --> <!-- <McPrompt :list="introPrompt.list" :direction="'horizontal'" class="intro-prompt" @itemClick="onItemClick($event)"></McPrompt> -->
<div class="guess-question">
<div class="guess-title">
<div>猜你想问</div>
<div>
<i class="icon-recover"></i>
<span>换一批</span>
</div>
</div>
<div class="guess-content">
<span v-for="(item, index) in guessQuestions" :key="index" @click="onItemClick(item)">{{ item.label }}</span>
</div>
</div>
</div> </div>
<div class="new-convo-button"> <div class="new-convo-button">
<div v-if="startChat" class="prompt-list"> <div v-if="startChat" class="prompt-list">
<!-- <McPrompt <McPrompt
class="simple-prompt" class="simple-prompt"
style="flex: 1" style="flex: 1"
:list="simplePrompt" :list="simplePrompt"
:direction="'horizontal'" :direction="'horizontal'"
@itemClick="onItemClick($event)" @itemClick="onItemClick($event)"
></McPrompt> --> ></McPrompt>
</div> </div>
<div v-else class="agent-knowledge"> <div v-else class="agent-knowledge">
<d-dropdown :position="['top']" @toggle="(val) => (isAgentOpen = val)"> <d-dropdown :position="['top']" @toggle="(val) => (isAgentOpen = val)">
...@@ -131,10 +119,10 @@ ...@@ -131,10 +119,10 @@
const conversationRef = ref(); const conversationRef = ref();
const isAgentOpen = ref(false); const isAgentOpen = ref(false);
const agentList = ref([ const agentList = ref([
{ label: 'MateChat', value: 'matechat', active: true }, { label: 'MateChat', value: 'matechat' },
{ label: 'InsCode', value: 'inscode' }, { label: 'InsCode', value: 'inscode', active: true },
]); ]);
const selectedAgent = ref(agentList.value[0]); const selectedAgent = ref(agentList.value[1]);
const aiModelAvatar = { const aiModelAvatar = {
imgSrc: "/src/assets/logo.svg", imgSrc: "/src/assets/logo.svg",
width: 32, width: 32,
...@@ -208,6 +196,7 @@ ...@@ -208,6 +196,7 @@
}; };
const getMockAnswer = (answer, type) => { const getMockAnswer = (answer, type) => {
console.log('getmock')
const aiAnswer = { const aiAnswer = {
from: 'ai-model', from: 'ai-model',
content: answer, content: answer,
...@@ -219,6 +208,12 @@ ...@@ -219,6 +208,12 @@
messages.value.push(aiAnswer); messages.value.push(aiAnswer);
setTimeout(() => { setTimeout(() => {
messages.value.at(-1).loading = false; messages.value.at(-1).loading = false;
nextTick(() => {
conversationRef.value?.scrollTo({
top: conversationRef.value.scrollHeight,
behavior: 'smooth',
});
});
}, 1000); }, 1000);
} }
...@@ -389,7 +384,6 @@ ...@@ -389,7 +384,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
.conversation-area, .conversation-area,
.welcome-page { .welcome-page {
flex: 1; flex: 1;
......
...@@ -3,12 +3,9 @@ ...@@ -3,12 +3,9 @@
</template> </template>
<script setup> <script setup>
import { createApp, defineProps, watch, onBeforeUnmount } from "vue"; import { createApp, watch, onBeforeUnmount } from "vue";
import { loadModule } from 'vue3-sfc-loader' import { loadModule } from 'vue3-sfc-loader'
import * as echarts from 'echarts' import * as echarts from 'echarts'
const processComponentString = (str) => {
return str.replace(/import.*from.*['"]echarts['"];?\n?/g, '');
};
const props = defineProps({ const props = defineProps({
...@@ -22,9 +19,15 @@ const props = defineProps({ ...@@ -22,9 +19,15 @@ const props = defineProps({
} }
}) })
let currentApp = null; let currentApp = null;
let currentStyle = null; let currentStyle = null;
const processComponentString = (str) => {
return str.replace(/import.*from.*['"]echarts['"];?\n?/g, '');
};
onBeforeUnmount(() => { onBeforeUnmount(() => {
if (currentApp) { if (currentApp) {
currentApp.unmount(); currentApp.unmount();
......
...@@ -26,9 +26,9 @@ ...@@ -26,9 +26,9 @@
</d-layout> </d-layout>
<d-drawer v-model="visible" position="right" style="padding: 20px; width: 650px" :show-overlay="false" :close-on-click-overlay="false"> <d-drawer v-model="visible" position="right" style="padding: 20px; width: 650px" :show-overlay="false" :close-on-click-overlay="false">
<keep-alive> <keep-alive>
<Demo @closeDrawer="visible = false" @chartStrChange="chartStrChange($event)"/> <!-- <Demo @closeDrawer="visible = false" @chartStrChange="chartStrChange($event)"/> -->
</keep-alive> </keep-alive>
<!-- <SimpleDemo @closeDrawer="visible = false"/> --> <SimpleDemo @closeDrawer="visible = false"/>
</d-drawer> </d-drawer>
</template> </template>
...@@ -171,7 +171,7 @@ export default defineComponent({ ...@@ -171,7 +171,7 @@ export default defineComponent({
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import 'devui-theme/styles-var/devui-var.scss'; @use 'devui-theme/styles-var/devui-var.scss' as *;
.floating-card { .floating-card {
position: fixed; position: fixed;
......
@import 'devui-theme/styles-var/devui-var.scss'; @use 'devui-theme/styles-var/devui-var.scss' as *;
body { body {
height: 100%; height: 100%;
min-height: 100vh; min-height: 100vh;
......
...@@ -18,4 +18,11 @@ export default defineConfig({ ...@@ -18,4 +18,11 @@ export default defineConfig({
} }
}, },
assetsInclude: ['**/*.md'], assetsInclude: ['**/*.md'],
css: {
preprocessorOptions: {
scss: {
quietDeps: true,
}
}
}
}) })
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册