|
@@ -1,32 +1,23 @@
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import AutoResizeTextarea from './components/AutoResizeTextarea.vue'
|
|
import AutoResizeTextarea from './components/AutoResizeTextarea.vue'
|
|
|
-const modalSize = ref('large')
|
|
|
|
|
|
|
+import userBubbleLight from './image/userBubbleLight.png'
|
|
|
|
|
+import userBubbleDark from './image/userBubbleDark.png'
|
|
|
|
|
+import robotBubbleLight from './image/robotBubbleLight.png'
|
|
|
|
|
+import robotBubbleDark from './image/robotBubbleDark.png'
|
|
|
|
|
+import { useThemeStore } from '@/stores/modules/theme'
|
|
|
|
|
|
|
|
|
|
+const themeStore = useThemeStore()
|
|
|
|
|
+const modalSize = ref('large')
|
|
|
const userQuestion = ref()
|
|
const userQuestion = ref()
|
|
|
|
|
|
|
|
const isFooterInputFocus = ref(false)
|
|
const isFooterInputFocus = ref(false)
|
|
|
-const textareaRef = ref(null)
|
|
|
|
|
-// 实现自适应高度(最多 4 行)
|
|
|
|
|
-const resize = () => {
|
|
|
|
|
- const el = textareaRef.value
|
|
|
|
|
- if (!el) return
|
|
|
|
|
-
|
|
|
|
|
- el.style.height = 'auto' // 先清空旧高度
|
|
|
|
|
- const scrollHeight = el.scrollHeight
|
|
|
|
|
-
|
|
|
|
|
- const maxHeight = 100 // 四行时高度
|
|
|
|
|
-
|
|
|
|
|
- if (scrollHeight <= maxHeight) {
|
|
|
|
|
- el.style.overflowY = 'hidden'
|
|
|
|
|
- el.style.height = scrollHeight + 'px'
|
|
|
|
|
- } else {
|
|
|
|
|
- el.style.overflowY = 'auto'
|
|
|
|
|
- el.style.height = maxHeight + 'px'
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
-// 初始挂载和内容变化都触发 resize
|
|
|
|
|
-onMounted(() => nextTick(resize))
|
|
|
|
|
|
|
+const userBubbleImg = computed(() => {
|
|
|
|
|
+ return themeStore.theme === 'light' ? userBubbleLight : userBubbleDark
|
|
|
|
|
+})
|
|
|
|
|
+const robotBubbleImg = computed(() => {
|
|
|
|
|
+ return themeStore.theme === 'light' ? robotBubbleLight : robotBubbleDark
|
|
|
|
|
+})
|
|
|
|
|
|
|
|
interface MessageItem {
|
|
interface MessageItem {
|
|
|
type: 'robot' | 'user'
|
|
type: 'robot' | 'user'
|
|
@@ -47,7 +38,7 @@ const messages = ref<MessageItem[]>([
|
|
|
{
|
|
{
|
|
|
type: 'robot',
|
|
type: 'robot',
|
|
|
feedback: '',
|
|
feedback: '',
|
|
|
- isShowFeedback: true,
|
|
|
|
|
|
|
+ isShowFeedback: false,
|
|
|
isAnswer: true,
|
|
isAnswer: true,
|
|
|
content: 'Can you help me with my shipment?'
|
|
content: 'Can you help me with my shipment?'
|
|
|
},
|
|
},
|
|
@@ -73,12 +64,12 @@ const progressStatus = {
|
|
|
const progressInterval = ref()
|
|
const progressInterval = ref()
|
|
|
const handleSend = () => {
|
|
const handleSend = () => {
|
|
|
if (!userQuestion.value) return
|
|
if (!userQuestion.value) return
|
|
|
|
|
+
|
|
|
messages.value.push({
|
|
messages.value.push({
|
|
|
type: 'user',
|
|
type: 'user',
|
|
|
content: userQuestion.value
|
|
content: userQuestion.value
|
|
|
})
|
|
})
|
|
|
userQuestion.value = ''
|
|
userQuestion.value = ''
|
|
|
- textareaRef.value.style.height = '29px' // 重置高度
|
|
|
|
|
queryTime.value = 0
|
|
queryTime.value = 0
|
|
|
messages.value.push({
|
|
messages.value.push({
|
|
|
type: 'robot',
|
|
type: 'robot',
|
|
@@ -132,14 +123,6 @@ const handleClose = () => {
|
|
|
progressInterval.value && clearInterval(progressInterval.value)
|
|
progressInterval.value && clearInterval(progressInterval.value)
|
|
|
emit('close')
|
|
emit('close')
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-// 关闭反馈意见
|
|
|
|
|
-const handleCloseFeedback = (msg) => {
|
|
|
|
|
- msg.isFeedback = true
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- msg.isShowFeedback = false
|
|
|
|
|
- }, 3000)
|
|
|
|
|
-}
|
|
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
<template>
|
|
@@ -191,48 +174,36 @@ const handleCloseFeedback = (msg) => {
|
|
|
/>
|
|
/>
|
|
|
{{ msg.content }}
|
|
{{ msg.content }}
|
|
|
<div class="review" v-if="msg.isShowFeedback && msg.isAnswer">
|
|
<div class="review" v-if="msg.isShowFeedback && msg.isAnswer">
|
|
|
- <div class="review-icon">
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-if="msg.feedback !== 'good'"
|
|
|
|
|
- class="el-button--text"
|
|
|
|
|
- @click="msg.feedback = 'good'"
|
|
|
|
|
- >
|
|
|
|
|
- <span class="font_family icon-icon_good_b"></span>
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <div v-if="msg.feedback === 'good'" style="width: 16px; text-align: center">
|
|
|
|
|
- <span
|
|
|
|
|
- style="color: var(--color-theme); font-size: 14px"
|
|
|
|
|
- class="font_family icon-icon_good__filled_b"
|
|
|
|
|
- ></span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-if="msg.feedback !== 'noGood'"
|
|
|
|
|
- class="el-button--text"
|
|
|
|
|
- @click="msg.feedback = 'noGood'"
|
|
|
|
|
- >
|
|
|
|
|
- <span class="font_family icon-icon_notgood_b"></span>
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <div v-if="msg.feedback === 'noGood'" style="width: 16px; text-align: center">
|
|
|
|
|
- <span
|
|
|
|
|
- style="color: var(--color-theme); font-size: 14px"
|
|
|
|
|
- class="font_family icon-icon_notgood__filled_b"
|
|
|
|
|
- ></span>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ v-if="msg.feedback !== 'good'"
|
|
|
|
|
+ class="el-button--text"
|
|
|
|
|
+ @click="msg.feedback = 'good'"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span class="font_family icon-icon_good_b"></span>
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <div v-if="msg.feedback === 'good'" style="width: 16px; text-align: center">
|
|
|
|
|
+ <span
|
|
|
|
|
+ style="color: var(--color-theme); font-size: 14px"
|
|
|
|
|
+ class="font_family icon-icon_good__filled_b"
|
|
|
|
|
+ ></span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ v-if="msg.feedback !== 'noGood'"
|
|
|
|
|
+ class="el-button--text"
|
|
|
|
|
+ @click="msg.feedback = 'noGood'"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span class="font_family icon-icon_notgood_b"></span>
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <div v-if="msg.feedback === 'noGood'" style="width: 16px; text-align: center">
|
|
|
|
|
+ <span
|
|
|
|
|
+ style="color: var(--color-theme); font-size: 14px"
|
|
|
|
|
+ class="font_family icon-icon_notgood__filled_b"
|
|
|
|
|
+ ></span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <img
|
|
|
|
|
- class="robot-bubble-img"
|
|
|
|
|
- v-if="msg.type === 'robot'"
|
|
|
|
|
- src="./image/robotBubbleLight.png"
|
|
|
|
|
- alt=""
|
|
|
|
|
- />
|
|
|
|
|
- <img
|
|
|
|
|
- class="user-bubble-img"
|
|
|
|
|
- v-else-if="msg.type === 'user'"
|
|
|
|
|
- src="./image/userBubbleLight.png"
|
|
|
|
|
- alt=""
|
|
|
|
|
- />
|
|
|
|
|
|
|
+ <img class="robot-bubble-img" v-if="msg.type === 'robot'" :src="robotBubbleImg" alt="" />
|
|
|
|
|
+ <img class="user-bubble-img" v-else-if="msg.type === 'user'" :src="userBubbleImg" alt="" />
|
|
|
<!-- 暂停回答 icon -->
|
|
<!-- 暂停回答 icon -->
|
|
|
<div
|
|
<div
|
|
|
class="pause-btn"
|
|
class="pause-btn"
|
|
@@ -272,12 +243,18 @@ const handleCloseFeedback = (msg) => {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
border-radius: 12px;
|
|
border-radius: 12px;
|
|
|
|
|
+ border: 1px solid var(--color-border);
|
|
|
box-shadow: 4px 4px 32px 0px rgba(0, 0, 0, 0.2);
|
|
box-shadow: 4px 4px 32px 0px rgba(0, 0, 0, 0.2);
|
|
|
- background-color: #fff;
|
|
|
|
|
|
|
+ background-color: var(--color-dialog-body-bg);
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
.top-section {
|
|
.top-section {
|
|
|
height: 150px;
|
|
height: 150px;
|
|
|
- background: linear-gradient(to bottom, #eaecff 10%, #eaecff 10%, #fefdff 100%);
|
|
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ to bottom,
|
|
|
|
|
+ var(--color-ai-chat-header-bg-gradient-begin) 10%,
|
|
|
|
|
+ var(--color-ai-chat-header-bg-gradient-begin) 10%,
|
|
|
|
|
+ var(--color-ai-chat-header-bg-gradient-end) 100%
|
|
|
|
|
+ );
|
|
|
.header {
|
|
.header {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
@@ -316,21 +293,20 @@ const handleCloseFeedback = (msg) => {
|
|
|
padding: 11px 8px;
|
|
padding: 11px 8px;
|
|
|
margin-bottom: 7px;
|
|
margin-bottom: 7px;
|
|
|
border-radius: 12px;
|
|
border-radius: 12px;
|
|
|
|
|
+ background-color: var(--scoring-bg-color);
|
|
|
.review {
|
|
.review {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
bottom: -24px;
|
|
bottom: -24px;
|
|
|
left: 0;
|
|
left: 0;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 13px;
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
- height: 50px;
|
|
|
|
|
|
|
+ height: 30px;
|
|
|
margin-top: 10px;
|
|
margin-top: 10px;
|
|
|
padding-left: 30px;
|
|
padding-left: 30px;
|
|
|
- padding-top: 30px;
|
|
|
|
|
|
|
+ padding-top: 10px;
|
|
|
|
|
|
|
|
- .review-icon {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- gap: 10px;
|
|
|
|
|
- }
|
|
|
|
|
button.el-button + .el-button {
|
|
button.el-button + .el-button {
|
|
|
margin-left: 0px;
|
|
margin-left: 0px;
|
|
|
}
|
|
}
|
|
@@ -375,7 +351,7 @@ const handleCloseFeedback = (msg) => {
|
|
|
height: 16px;
|
|
height: 16px;
|
|
|
width: 16px;
|
|
width: 16px;
|
|
|
border-radius: 50%;
|
|
border-radius: 50%;
|
|
|
- background-color: #fff1e6;
|
|
|
|
|
|
|
+ background-color: var(--color-customize-column-right-section-bg);
|
|
|
.dot {
|
|
.dot {
|
|
|
height: 5px;
|
|
height: 5px;
|
|
|
width: 5px;
|
|
width: 5px;
|
|
@@ -388,7 +364,7 @@ const handleCloseFeedback = (msg) => {
|
|
|
color: #b5b9bf;
|
|
color: #b5b9bf;
|
|
|
}
|
|
}
|
|
|
.robot-bubble {
|
|
.robot-bubble {
|
|
|
- background: #f2f4f7;
|
|
|
|
|
|
|
+ background: var(--scoring-bg-color);
|
|
|
align-self: flex-start;
|
|
align-self: flex-start;
|
|
|
.robot-bubble-img {
|
|
.robot-bubble-img {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
@@ -398,7 +374,11 @@ const handleCloseFeedback = (msg) => {
|
|
|
}
|
|
}
|
|
|
.user-bubble {
|
|
.user-bubble {
|
|
|
align-self: flex-end;
|
|
align-self: flex-end;
|
|
|
- background: linear-gradient(to right, #ffede6, #f2f4f7);
|
|
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ to right,
|
|
|
|
|
+ var(--color-ai-user-bubble-bg-gradient-begin),
|
|
|
|
|
+ var(--color-ai-user-bubble-bg-gradient-end)
|
|
|
|
|
+ );
|
|
|
.user-bubble-img {
|
|
.user-bubble-img {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
right: 0;
|
|
right: 0;
|
|
@@ -413,7 +393,7 @@ const handleCloseFeedback = (msg) => {
|
|
|
padding: 4px 12px;
|
|
padding: 4px 12px;
|
|
|
padding-right: 4px;
|
|
padding-right: 4px;
|
|
|
margin: 12px 16px;
|
|
margin: 12px 16px;
|
|
|
- border: 1px solid #eaebed;
|
|
|
|
|
|
|
+ border: 1px solid var(--input-border);
|
|
|
border-radius: 20px;
|
|
border-radius: 20px;
|
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
|
.input-icon {
|
|
.input-icon {
|
|
@@ -438,10 +418,11 @@ const handleCloseFeedback = (msg) => {
|
|
|
background-color: #d56200;
|
|
background-color: #d56200;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ &.focus-style {
|
|
|
|
|
+ border: 1px solid var(--color-theme);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- .focus-style {
|
|
|
|
|
- border-color: var(--color-theme);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+
|
|
|
// .input-area {
|
|
// .input-area {
|
|
|
// width: 100%;
|
|
// width: 100%;
|
|
|
// font-size: 14px;
|
|
// font-size: 14px;
|