Files
ebiz-base-ai/src/views/AI/components/message.vue
陈昱达 9769036058 style(AI): 优化聊天组件样式并添加全局样式类
- 在 chat.vue 中添加 .input-icon 和 .wh25 全局样式类
- 在 message.vue 中添加 .wh15 全局样式类
- 调整 sticky.vue 中工具箱模块的宽度
2025-06-11 13:21:49 +08:00

235 lines
5.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<section>
<div v-for="(message, index) in messagesList" :key="index" class="message-item">
<!--用户消息-->
<div v-if="message.type === 'user'" class="user-message mb10">
<p>{{ message.text }}</p>
</div>
<!--机器人消息-->
<div v-else-if="message.type === 'bot'" class="bot-message mb10">
<span v-if="message.isThink" style="width: 100%">
<!-- loading-->
<span class="speakLoadingToast pv10">
<van-loading type="spinner" color="#2e5ca9" size="20px" v-if="!message.text" />
<span class="loading-text">{{ message.text ? '思考完成' : '思考中...' }}</span>
<van-icon name="arrow-up" :class="message.showThink ? 'rate360' : 'rate180'" @click="showThink(message)" v-if="message.think" />
</span>
<!--开启思考-->
<p v-html="md.render(message.think)" v-if="message.think && message.showThink" class="thinkText" />
</span>
<div style="width: 100%">
<p v-html="md.render(message.text)" v-if="message.text"></p>
<span class="speakLoadingToast pv10" v-else-if="!message.text && !thinkOk && !message.isThink">
<van-loading type="spinner" color="#2e5ca9" size="20px" v-if="!message.text" />
</span>
<div class="text-right fs12 mb5 mr10" style="font-size: 10px; color: #f6aa21">此内容由AI生成</div>
</div>
</div>
<!--百宝箱-->
<div v-else class="mb10">
<treasure-box :item="message" @setProductName="setProductName"></treasure-box>
</div>
<!-- 新增点赞和踩按钮 -->
<div class="reaction-buttons mb10" v-if="message.type !== 'user'">
<button @click="handleReaction(message, 'like')" class="like">
<svg-icon :icon-class="message.isLike ? 'fillLike' : 'like'" class-name="chat-icon"></svg-icon> 有用
</button>
<button @click="handleReaction(message, 'dislike')" class="dislike">
<svg-icon :icon-class="message.isDisLike ? 'fillDislike' : 'dislike'" class-name="wh15"></svg-icon>无用
</button>
</div>
</div>
</section>
</template>
<script>
// icon
import { Icon } from 'vant'
import TreasureBox from '@/views/AI/components/treasureBox.vue'
import MarkdownIt from 'markdown-it'
import markdownItKatex from 'markdown-it-katex'
const md = new MarkdownIt({
html: true,
linkify: true,
typographer: true,
}).use(markdownItKatex)
export default {
name: 'message',
components: { TreasureBox, [Icon.name]: Icon },
props: {
messagesList: {
type: Array,
default: () => [],
},
thinkOk: {
type: Boolean,
default: false,
},
isDeep: {
type: Boolean,
default: false,
},
},
data() {
return {
md,
}
},
methods: {
setProductName(e) {
this.$emit('setProductName', e)
},
showThink(message) {
this.$set(message, 'showThink', !message.showThink)
console.log(message.showThink)
},
// 处理点赞和踩的逻辑
handleReaction(message, type) {
if (type === 'like') {
this.$set(message, 'isLike', !message.isLike)
this.$set(message, 'isDisLike', false)
} else if (type === 'dislike') {
this.$set(message, 'isDisLike', !message.isDisLike)
this.$set(message, 'isLike', false)
}
// 触发父组件的更新事件
this.$emit('update-message', { ...message })
},
},
}
</script>
<style scoped lang="scss">
// 主题颜色定义
$primary-color: #2e5ca9; // 修复了 SCSS 变量的定义方式
$primary-text-color: #f6aa21; // 修复了 SCSS 变量的定义方式
$primary-trans-color: rgba(135, 162, 208, 0.5); // 使用rgba定义颜色透明度为0.8
.wh15 {
width: 15px;
height: 15px;
}
.message-item {
all: initial;
margin-bottom: 10px;
width: 100%;
font-size: unset;
.user-message,
.bot-message {
display: flex;
align-items: center;
img {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 10px;
}
p {
background-color: $primary-color;
color: #fff;
border-radius: 5px;
padding: 10px;
//max-width: 70%;
//max-width: 80%;
}
}
.user-message {
justify-content: end;
max-width: 80%;
margin-left: 20%;
}
.bot-message {
justify-content: start;
background-color: #fff;
border-radius: 5px;
max-width: calc(80% + 20px);
display: flex;
flex-wrap: wrap;
line-height: 20px;
.bot-avatar {
margin-left: 10px;
margin-right: 0;
}
.thinkText {
color: $primary-trans-color;
padding-top: 0;
}
.speakLoadingToast {
display: flex;
align-items: center;
gap: 10px;
color: $primary-text-color;
margin-left: 10px;
.loading-text {
color: $primary-trans-color;
}
}
p {
background-color: #fff;
padding: 10px 10px 2px 10px;
color: $primary-color;
}
}
// 新增样式:点赞和踩按钮
.reaction-buttons {
display: flex;
gap: 10px;
margin-top: 5px;
button {
display: flex;
align-items: center;
background: #fff;
border: none;
cursor: pointer;
font-size: 11px;
padding: 2px 3px;
border-radius: 5px;
color: $primary-color;
}
.dislike {
color: $primary-text-color;
}
}
}
.rate360 {
animation-duration: 0.5s;
animation-fill-mode: both;
animation-name: rate360;
}
.rate180 {
animation-duration: 0.5s;
animation-fill-mode: both;
animation-name: rate180;
}
@keyframes rate360 {
0% {
transform: rotate(180deg);
}
100% {
transform: rotate(0deg);
}
}
@keyframes rate180 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
</style>