|
|
@@ -1,7 +1,8 @@
|
|
|
<script setup lang="ts">
|
|
|
+import AutoResizeTextarea from './components/AutoResizeTextarea.vue'
|
|
|
const modalSize = ref('large')
|
|
|
|
|
|
-const inputVModel = ref()
|
|
|
+const userQuestion = ref()
|
|
|
|
|
|
const isFooterInputFocus = ref(false)
|
|
|
const textareaRef = ref(null)
|
|
|
@@ -37,6 +38,7 @@ const messages = ref([
|
|
|
},
|
|
|
{
|
|
|
type: 'robot',
|
|
|
+ allowComments: true,
|
|
|
content: 'Can you help me with my shipment?'
|
|
|
},
|
|
|
{
|
|
|
@@ -60,12 +62,12 @@ const progressStatus = {
|
|
|
|
|
|
const progressInterval = ref()
|
|
|
const handleSend = () => {
|
|
|
- if (!inputVModel.value) return
|
|
|
+ if (!userQuestion.value) return
|
|
|
messages.value.push({
|
|
|
type: 'user',
|
|
|
- content: inputVModel.value
|
|
|
+ content: userQuestion.value
|
|
|
})
|
|
|
- inputVModel.value = ''
|
|
|
+ userQuestion.value = ''
|
|
|
textareaRef.value.style.height = '29px' // 重置高度
|
|
|
queryTime.value = 0
|
|
|
messages.value.push({
|
|
|
@@ -120,6 +122,8 @@ const handleClose = () => {
|
|
|
progressInterval.value && clearInterval(progressInterval.value)
|
|
|
emit('close')
|
|
|
}
|
|
|
+// 评论icon
|
|
|
+const reviewStatus = ref()
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
@@ -168,6 +172,38 @@ const handleClose = () => {
|
|
|
alt=""
|
|
|
/>
|
|
|
{{ msg.content }}
|
|
|
+ <div class="review" v-if="msg.allowComments">
|
|
|
+ <div class="review-icon">
|
|
|
+ <el-button
|
|
|
+ v-if="reviewStatus !== 'good'"
|
|
|
+ class="el-button--text"
|
|
|
+ @click="reviewStatus = 'good'"
|
|
|
+ >
|
|
|
+ <span class="font_family icon-icon_good_b"></span>
|
|
|
+ </el-button>
|
|
|
+ <div v-if="reviewStatus === 'good'" style="width: 33px; text-align: center">
|
|
|
+ <span class="font_family icon-icon_good__filled_b"></span>
|
|
|
+ </div>
|
|
|
+ <el-button
|
|
|
+ v-if="reviewStatus !== 'noGood'"
|
|
|
+ class="el-button--text"
|
|
|
+ @click="reviewStatus = 'noGood'"
|
|
|
+ >
|
|
|
+ <span class="font_family icon-icon_notgood_b"></span>
|
|
|
+ </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>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
<img
|
|
|
class="robot-bubble-img"
|
|
|
v-if="msg.type === 'robot'"
|
|
|
@@ -192,19 +228,14 @@ const handleClose = () => {
|
|
|
</div>
|
|
|
|
|
|
<div class="footer-input" :class="[isFooterInputFocus ? 'focus-style' : '']">
|
|
|
- <textarea
|
|
|
- ref="textareaRef"
|
|
|
- v-model="inputVModel"
|
|
|
- class="input-area"
|
|
|
- rows="1"
|
|
|
- placeholder="Type your question here..."
|
|
|
- @input="resize"
|
|
|
+ <AutoResizeTextarea
|
|
|
+ v-model="userQuestion"
|
|
|
@focus="isFooterInputFocus = true"
|
|
|
@blur="isFooterInputFocus = false"
|
|
|
/>
|
|
|
<div
|
|
|
class="input-icon"
|
|
|
- :class="[inputVModel ? 'input-style' : 'disable']"
|
|
|
+ :class="[userQuestion ? 'input-style' : 'disable']"
|
|
|
@click="handleSend"
|
|
|
>
|
|
|
<span class="font_family icon-icon_send_b"></span>
|
|
|
@@ -260,12 +291,44 @@ const handleClose = () => {
|
|
|
gap: 16px;
|
|
|
margin-top: 81px;
|
|
|
padding: 0 16px;
|
|
|
+ overflow: auto;
|
|
|
.message-item {
|
|
|
position: relative;
|
|
|
display: inline-block;
|
|
|
padding: 11px 8px;
|
|
|
margin-bottom: 7px;
|
|
|
border-radius: 12px;
|
|
|
+ .review {
|
|
|
+ margin-top: 10px;
|
|
|
+ .review-icon {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+ }
|
|
|
+ button.el-button + .el-button {
|
|
|
+ margin-left: 0px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .review-input-card {
|
|
|
+ margin-top: 6px;
|
|
|
+ padding: 8px;
|
|
|
+ text-align: right;
|
|
|
+ box-shadow: 1px 1px 12px 0px rgba(0, 0, 0, 0.05);
|
|
|
+ border-radius: 6px;
|
|
|
+ }
|
|
|
+ .review-input {
|
|
|
+ padding: 8px;
|
|
|
+ border: 1px solid var(--color-border);
|
|
|
+ border-radius: 6px;
|
|
|
+ }
|
|
|
+ .el-button--text {
|
|
|
+ &:hover {
|
|
|
+ span {
|
|
|
+ color: var(--color-theme);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
.loading-img {
|
|
|
width: 16px;
|
|
|
height: 16px;
|
|
|
@@ -351,25 +414,25 @@ const handleClose = () => {
|
|
|
.focus-style {
|
|
|
border-color: var(--color-theme);
|
|
|
}
|
|
|
- .input-area {
|
|
|
- width: 100%;
|
|
|
- font-size: 14px;
|
|
|
- line-height: 21px;
|
|
|
- padding: 4px;
|
|
|
- resize: none;
|
|
|
- overflow-y: hidden; // 默认不显示滚动条
|
|
|
- height: 40px; // 初始高度(1 行)
|
|
|
- max-height: 100px; // 最多 4 行
|
|
|
- box-sizing: border-box;
|
|
|
- border: none;
|
|
|
- outline-color: #fff;
|
|
|
- border-radius: 8px;
|
|
|
- transition: height 0.1s ease;
|
|
|
- &::placeholder {
|
|
|
- color: #b5b9bf;
|
|
|
- opacity: 1;
|
|
|
- }
|
|
|
- }
|
|
|
+ // .input-area {
|
|
|
+ // width: 100%;
|
|
|
+ // font-size: 14px;
|
|
|
+ // line-height: 21px;
|
|
|
+ // padding: 4px;
|
|
|
+ // resize: none;
|
|
|
+ // overflow-y: hidden; // 默认不显示滚动条
|
|
|
+ // height: 40px; // 初始高度(1 行)
|
|
|
+ // max-height: 100px; // 最多 4 行
|
|
|
+ // box-sizing: border-box;
|
|
|
+ // border: none;
|
|
|
+ // outline-color: #fff;
|
|
|
+ // border-radius: 8px;
|
|
|
+ // transition: height 0.1s ease;
|
|
|
+ // &::placeholder {
|
|
|
+ // color: #b5b9bf;
|
|
|
+ // opacity: 1;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
@keyframes loading-rotate {
|
|
|
0% {
|
|
|
transform: rotate(0deg);
|