|
@@ -27,10 +27,18 @@ const resize = () => {
|
|
|
|
|
|
|
|
// 初始挂载和内容变化都触发 resize
|
|
// 初始挂载和内容变化都触发 resize
|
|
|
onMounted(() => nextTick(resize))
|
|
onMounted(() => nextTick(resize))
|
|
|
-const messages = ref([
|
|
|
|
|
|
|
+
|
|
|
|
|
+interface MessageItem {
|
|
|
|
|
+ type: 'robot' | 'user'
|
|
|
|
|
+ content: string
|
|
|
|
|
+ feedback?: 'good' | 'noGood' | '' // 反馈结果
|
|
|
|
|
+ isShowFeedback?: boolean // 是否展示反馈样式
|
|
|
|
|
+ isAnswer?: boolean // 是否为用户问题的答案,是则才能展示反馈组件
|
|
|
|
|
+}
|
|
|
|
|
+const messages = ref<MessageItem[]>([
|
|
|
{
|
|
{
|
|
|
type: 'robot',
|
|
type: 'robot',
|
|
|
- content: 'Hello! How can I assist you today?'
|
|
|
|
|
|
|
+ content: 'You can click on Frequently Asked Questions above or type your own question'
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
type: 'user',
|
|
type: 'user',
|
|
@@ -38,7 +46,9 @@ const messages = ref([
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
type: 'robot',
|
|
type: 'robot',
|
|
|
- allowComments: true,
|
|
|
|
|
|
|
+ feedback: '',
|
|
|
|
|
+ isShowFeedback: true,
|
|
|
|
|
+ isAnswer: true,
|
|
|
content: 'Can you help me with my shipment?'
|
|
content: 'Can you help me with my shipment?'
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
@@ -122,8 +132,14 @@ const handleClose = () => {
|
|
|
progressInterval.value && clearInterval(progressInterval.value)
|
|
progressInterval.value && clearInterval(progressInterval.value)
|
|
|
emit('close')
|
|
emit('close')
|
|
|
}
|
|
}
|
|
|
-// 评论icon
|
|
|
|
|
-const reviewStatus = ref()
|
|
|
|
|
|
|
+
|
|
|
|
|
+// 关闭反馈意见
|
|
|
|
|
+const handleCloseFeedback = (msg) => {
|
|
|
|
|
+ msg.isFeedback = true
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ msg.isShowFeedback = false
|
|
|
|
|
+ }, 3000)
|
|
|
|
|
+}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
<template>
|
|
@@ -157,6 +173,8 @@ const reviewStatus = ref()
|
|
|
]"
|
|
]"
|
|
|
v-for="(msg, index) in messages"
|
|
v-for="(msg, index) in messages"
|
|
|
:key="index"
|
|
:key="index"
|
|
|
|
|
+ @mouseenter="msg.isShowFeedback = true"
|
|
|
|
|
+ @mouseleave="msg.isShowFeedback = false"
|
|
|
>
|
|
>
|
|
|
<!-- 请求失败后的提示icon -->
|
|
<!-- 请求失败后的提示icon -->
|
|
|
<span
|
|
<span
|
|
@@ -172,34 +190,33 @@ const reviewStatus = ref()
|
|
|
alt=""
|
|
alt=""
|
|
|
/>
|
|
/>
|
|
|
{{ msg.content }}
|
|
{{ msg.content }}
|
|
|
- <div class="review" v-if="msg.allowComments">
|
|
|
|
|
|
|
+ <div class="review" v-if="msg.isShowFeedback && msg.isAnswer">
|
|
|
<div class="review-icon">
|
|
<div class="review-icon">
|
|
|
<el-button
|
|
<el-button
|
|
|
- v-if="reviewStatus !== 'good'"
|
|
|
|
|
|
|
+ v-if="msg.feedback !== 'good'"
|
|
|
class="el-button--text"
|
|
class="el-button--text"
|
|
|
- @click="reviewStatus = 'good'"
|
|
|
|
|
|
|
+ @click="msg.feedback = 'good'"
|
|
|
>
|
|
>
|
|
|
<span class="font_family icon-icon_good_b"></span>
|
|
<span class="font_family icon-icon_good_b"></span>
|
|
|
</el-button>
|
|
</el-button>
|
|
|
- <div v-if="reviewStatus === 'good'" style="width: 33px; text-align: center">
|
|
|
|
|
- <span class="font_family icon-icon_good__filled_b"></span>
|
|
|
|
|
|
|
+ <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>
|
|
</div>
|
|
|
<el-button
|
|
<el-button
|
|
|
- v-if="reviewStatus !== 'noGood'"
|
|
|
|
|
|
|
+ v-if="msg.feedback !== 'noGood'"
|
|
|
class="el-button--text"
|
|
class="el-button--text"
|
|
|
- @click="reviewStatus = 'noGood'"
|
|
|
|
|
|
|
+ @click="msg.feedback = 'noGood'"
|
|
|
>
|
|
>
|
|
|
<span class="font_family icon-icon_notgood_b"></span>
|
|
<span class="font_family icon-icon_notgood_b"></span>
|
|
|
</el-button>
|
|
</el-button>
|
|
|
- <div v-if="reviewStatus === 'noGood'" style="width: 33px; text-align: center">
|
|
|
|
|
- <span class="font_family icon-icon_notgood__filled_b"></span>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="review-input-card">
|
|
|
|
|
- <span class="font_family icon-icon_reject_b"></span>
|
|
|
|
|
- <div class="review-input">
|
|
|
|
|
- <AutoResizeTextarea v-model="userQuestion" />
|
|
|
|
|
- <el-button class="el-button--dark" size="small">Submit</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>
|
|
|
</div>
|
|
</div>
|
|
@@ -230,6 +247,7 @@ const reviewStatus = ref()
|
|
|
<div class="footer-input" :class="[isFooterInputFocus ? 'focus-style' : '']">
|
|
<div class="footer-input" :class="[isFooterInputFocus ? 'focus-style' : '']">
|
|
|
<AutoResizeTextarea
|
|
<AutoResizeTextarea
|
|
|
v-model="userQuestion"
|
|
v-model="userQuestion"
|
|
|
|
|
+ :placeholder="'Type your question here...'"
|
|
|
@focus="isFooterInputFocus = true"
|
|
@focus="isFooterInputFocus = true"
|
|
|
@blur="isFooterInputFocus = false"
|
|
@blur="isFooterInputFocus = false"
|
|
|
/>
|
|
/>
|
|
@@ -299,11 +317,19 @@ const reviewStatus = ref()
|
|
|
margin-bottom: 7px;
|
|
margin-bottom: 7px;
|
|
|
border-radius: 12px;
|
|
border-radius: 12px;
|
|
|
.review {
|
|
.review {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ bottom: -24px;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 50px;
|
|
|
margin-top: 10px;
|
|
margin-top: 10px;
|
|
|
|
|
+ padding-left: 30px;
|
|
|
|
|
+ padding-top: 30px;
|
|
|
|
|
+
|
|
|
.review-icon {
|
|
.review-icon {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- gap: 6px;
|
|
|
|
|
|
|
+ gap: 10px;
|
|
|
}
|
|
}
|
|
|
button.el-button + .el-button {
|
|
button.el-button + .el-button {
|
|
|
margin-left: 0px;
|
|
margin-left: 0px;
|
|
@@ -316,12 +342,14 @@ const reviewStatus = ref()
|
|
|
box-shadow: 1px 1px 12px 0px rgba(0, 0, 0, 0.05);
|
|
box-shadow: 1px 1px 12px 0px rgba(0, 0, 0, 0.05);
|
|
|
border-radius: 6px;
|
|
border-radius: 6px;
|
|
|
}
|
|
}
|
|
|
- .review-input {
|
|
|
|
|
- padding: 8px;
|
|
|
|
|
- border: 1px solid var(--color-border);
|
|
|
|
|
- border-radius: 6px;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+
|
|
|
.el-button--text {
|
|
.el-button--text {
|
|
|
|
|
+ height: 16px;
|
|
|
|
|
+ width: 16px;
|
|
|
|
|
+ span {
|
|
|
|
|
+ color: var(--color-neutral-2);
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ }
|
|
|
&:hover {
|
|
&:hover {
|
|
|
span {
|
|
span {
|
|
|
color: var(--color-theme);
|
|
color: var(--color-theme);
|