|
|
|
@ -2,7 +2,7 @@
|
|
|
|
<view class="chat">
|
|
|
|
<view class="chat">
|
|
|
|
<view v-for="(m,index) in messages" :key="m.id" :id="'msg-' + m.id" :class="['msg', m.role]">
|
|
|
|
<view v-for="(m,index) in messages" :key="m.id" :id="'msg-' + m.id" :class="['msg', m.role]">
|
|
|
|
<view v-if="m.role === 'user'" class="bubble user-bubble">
|
|
|
|
<view v-if="m.role === 'user'" class="bubble user-bubble">
|
|
|
|
<text v-if="m.inputType === 'text'">{{ m.content }}</text>
|
|
|
|
<text v-if="m.inputType === 'text'" @longpress.prevent="loadTool($event,m)" >{{ m.content }}</text>
|
|
|
|
<view class="text-voice" v-if="m.inputType === 'voice'" @tap="playVoice(m)">
|
|
|
|
<view class="text-voice" v-if="m.inputType === 'voice'" @tap="playVoice(m)">
|
|
|
|
<text>{{ m.duration }}</text>
|
|
|
|
<text>{{ m.duration }}</text>
|
|
|
|
<image class="voice-play" src="@/static/voice-play.png" mode="widthFix"></image>
|
|
|
|
<image class="voice-play" src="@/static/voice-play.png" mode="widthFix"></image>
|
|
|
|
@ -42,15 +42,43 @@
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<view class="text-tool" :class="{'show': showTool}" :style="textToolStyle" v-if="isOpenTextTool">
|
|
|
|
|
|
|
|
<view class="tool-item" v-for="(item, index) in textToolList" :key="item.id"
|
|
|
|
|
|
|
|
:style="{animationDelay: index * 0.05 + 's'}" @tap="selectTextTool(item.id)">
|
|
|
|
|
|
|
|
<image class="img" :src="item.imageUrl" mode="widthFix"></image>
|
|
|
|
|
|
|
|
<text class="text">{{item.text}}</text>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<view class="mark-layer" v-if="isOpenTextTool" @touchstart="closeTool"></view>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<uni-popup ref="popup" type="bottom" class="popup" @change="changeShow">
|
|
|
|
|
|
|
|
<view class="feedback">
|
|
|
|
|
|
|
|
<view class="top">
|
|
|
|
|
|
|
|
<view class="title">反馈</view>
|
|
|
|
|
|
|
|
<view class="close" @tap="closeFeedback">×</view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<view class="quick-ask">
|
|
|
|
|
|
|
|
<view :class="['ask',item.id === askActive ? 'active' : '']" v-for="item in quickAskList"
|
|
|
|
|
|
|
|
:key="item.id" @tap="selectAsk(item.id)">{{item.label}}</view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<view>
|
|
|
|
|
|
|
|
<textarea class="textarea" placeholder="我们想知道你对此回答不满意的原因,你认为更好的回答是什么?"></textarea>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<button type="primary" style="font-size: 16px;" @tap="submitFeedback">提交</button>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
</uni-popup>
|
|
|
|
|
|
|
|
|
|
|
|
<uni-popup ref="popup" type="bottom" class="popup" @change="changeShow">
|
|
|
|
|
|
|
|
|
|
|
|
<uni-popup ref="popup" type="bottom" class="popup" @change="changeShow">
|
|
|
|
<view class="feedback">
|
|
|
|
<view class="feedback">
|
|
|
|
<view class="top">
|
|
|
|
<view class="top">
|
|
|
|
<view class="title">反馈</view>
|
|
|
|
<view class="title">反馈</view>
|
|
|
|
<view class="close" @tap="closeFeedback">×</view>
|
|
|
|
<view class="close" @tap="closeFeedback">×</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
<view class="quick-ask">
|
|
|
|
<view class="quick-ask">
|
|
|
|
<view :class="['ask',item.id === askActive ? 'active' : '']" v-for="item in quickAskList" :key="item.id" @tap="selectAsk(item.id)">{{item.label}}</view>
|
|
|
|
<view :class="['ask',item.id === askActive ? 'active' : '']" v-for="item in quickAskList"
|
|
|
|
|
|
|
|
:key="item.id" @tap="selectAsk(item.id)">{{item.label}}</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
<view>
|
|
|
|
<view>
|
|
|
|
<textarea class="textarea" placeholder="我们想知道你对此回答不满意的原因,你认为更好的回答是什么?"></textarea>
|
|
|
|
<textarea class="textarea" placeholder="我们想知道你对此回答不满意的原因,你认为更好的回答是什么?"></textarea>
|
|
|
|
@ -62,6 +90,7 @@
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
<script>
|
|
|
|
|
|
|
|
import {copyText} from '@/utils/utils.js'
|
|
|
|
export default {
|
|
|
|
export default {
|
|
|
|
props: {
|
|
|
|
props: {
|
|
|
|
messages: {
|
|
|
|
messages: {
|
|
|
|
@ -72,43 +101,103 @@
|
|
|
|
},
|
|
|
|
},
|
|
|
|
isReplying: {
|
|
|
|
isReplying: {
|
|
|
|
type: Boolean,
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
default: false,
|
|
|
|
|
|
|
|
textTool: []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
upvoteImage: require('@/static/upvote.png'),
|
|
|
|
upvoteImage: require('@/static/upvote.png'),
|
|
|
|
upvoteHighLightImage: require('@/static/upvote-highlight.png'),
|
|
|
|
upvoteHighLightImage: require('@/static/upvote-highlight.png'),
|
|
|
|
|
|
|
|
textToolList : [{
|
|
|
|
|
|
|
|
id : 1,
|
|
|
|
|
|
|
|
text : '复制',
|
|
|
|
|
|
|
|
imageUrl : require('@/static/copy.png')
|
|
|
|
|
|
|
|
},{
|
|
|
|
|
|
|
|
id : 2,
|
|
|
|
|
|
|
|
text : '修改',
|
|
|
|
|
|
|
|
imageUrl : require('@/static/edit.png')
|
|
|
|
|
|
|
|
}],
|
|
|
|
isHighLight: false,
|
|
|
|
isHighLight: false,
|
|
|
|
upvoteIndex: null,
|
|
|
|
upvoteIndex: null,
|
|
|
|
quickAskList : [
|
|
|
|
quickAskList: [{
|
|
|
|
{
|
|
|
|
id: 1,
|
|
|
|
id : 1,
|
|
|
|
label: '数据不准确'
|
|
|
|
label : '虚假信息'
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
id : 2,
|
|
|
|
id: 2,
|
|
|
|
label : '没有帮助'
|
|
|
|
label: '没有帮助'
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
id : 3,
|
|
|
|
id: 3,
|
|
|
|
label : '其他'
|
|
|
|
label: '其他'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
|
|
|
],
|
|
|
|
askActive : null
|
|
|
|
askActive: null,
|
|
|
|
|
|
|
|
textToolStyle : {},
|
|
|
|
|
|
|
|
isOpenTextTool : false,
|
|
|
|
|
|
|
|
showTool: false,
|
|
|
|
|
|
|
|
screenWidth : 0,
|
|
|
|
|
|
|
|
selectText : ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
mounted () {
|
|
|
|
|
|
|
|
this.screenWidth = uni.getSystemInfoSync().screenWidth;
|
|
|
|
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
methods: {
|
|
|
|
|
|
|
|
selectTextTool(id){
|
|
|
|
|
|
|
|
switch(id){
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
|
|
copyText(this.selectText)
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
|
|
this.$emit('changeInputText',this.selectText)
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.closeTool();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
closeTool(){
|
|
|
|
|
|
|
|
this.showTool = false;
|
|
|
|
|
|
|
|
this.isOpenTextTool = false;
|
|
|
|
|
|
|
|
this.$emit('changeShow', false)
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
loadTool($event, m) {
|
|
|
|
|
|
|
|
this.selectText = m.content;
|
|
|
|
|
|
|
|
uni.createSelectorQuery().select(`#msg-${m.id}`).boundingClientRect((rect) => {
|
|
|
|
|
|
|
|
let height = rect.height || 0;
|
|
|
|
|
|
|
|
if($event.touches[0].pageX > (this.screenWidth / 2)){
|
|
|
|
|
|
|
|
this.textToolStyle = {
|
|
|
|
|
|
|
|
top : $event.target.offsetTop + height - 10 + 'px',
|
|
|
|
|
|
|
|
right : this.screenWidth - Math.ceil($event.touches[0].pageX) + 'px'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
this.textToolStyle = {
|
|
|
|
|
|
|
|
top : $event.target.offsetTop + height - 10 + 'px',
|
|
|
|
|
|
|
|
left : Math.ceil($event.touches[0].pageX) + 'px'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.isOpenTextTool = true;
|
|
|
|
|
|
|
|
this.$emit('changeShow', true);
|
|
|
|
|
|
|
|
// 确保DOM更新后再触发动画
|
|
|
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
|
|
|
this.showTool = true;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}).exec();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
changeShow(e) {
|
|
|
|
changeShow(e) {
|
|
|
|
this.$emit('changeShow',e.show)
|
|
|
|
this.$emit('changeShow', e.show)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
selectAsk(id){
|
|
|
|
selectAsk(id) {
|
|
|
|
this.askActive = id;
|
|
|
|
this.askActive = id;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
continueCreate() {
|
|
|
|
continueCreate() {
|
|
|
|
this.$emit('continueCreate')
|
|
|
|
this.$emit('continueCreate')
|
|
|
|
},
|
|
|
|
},
|
|
|
|
refresh() {
|
|
|
|
refresh() {
|
|
|
|
|
|
|
|
this.isHighLight = false;
|
|
|
|
|
|
|
|
this.upvoteIndex = null;
|
|
|
|
this.$emit('refresh')
|
|
|
|
this.$emit('refresh')
|
|
|
|
},
|
|
|
|
},
|
|
|
|
upvote() {
|
|
|
|
upvote() {
|
|
|
|
@ -132,12 +221,12 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!this.isHighLight) {
|
|
|
|
if (!this.isHighLight) {
|
|
|
|
this.$refs.popup.open();
|
|
|
|
this.$refs.popup.open();
|
|
|
|
}else{
|
|
|
|
} else {
|
|
|
|
this.isHighLight = !this.isHighLight;
|
|
|
|
this.isHighLight = !this.isHighLight;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.upvoteIndex = 1;
|
|
|
|
this.upvoteIndex = 1;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
submitFeedback(){
|
|
|
|
submitFeedback() {
|
|
|
|
this.$refs.popup.close();
|
|
|
|
this.$refs.popup.close();
|
|
|
|
this.isHighLight = true;
|
|
|
|
this.isHighLight = true;
|
|
|
|
uni.showToast({
|
|
|
|
uni.showToast({
|
|
|
|
@ -146,7 +235,7 @@
|
|
|
|
duration: 1500
|
|
|
|
duration: 1500
|
|
|
|
})
|
|
|
|
})
|
|
|
|
},
|
|
|
|
},
|
|
|
|
closeFeedback(){
|
|
|
|
closeFeedback() {
|
|
|
|
this.$refs.popup.close();
|
|
|
|
this.$refs.popup.close();
|
|
|
|
this.isHighLight = false;
|
|
|
|
this.isHighLight = false;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
@ -182,6 +271,7 @@
|
|
|
|
<style scoped lang="scss">
|
|
|
|
<style scoped lang="scss">
|
|
|
|
.chat {
|
|
|
|
.chat {
|
|
|
|
margin: 6px 0 12px;
|
|
|
|
margin: 6px 0 12px;
|
|
|
|
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.msg {
|
|
|
|
.msg {
|
|
|
|
@ -316,6 +406,58 @@
|
|
|
|
margin-left: 5px;
|
|
|
|
margin-left: 5px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.text-tool {
|
|
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
|
|
z-index: 10000;
|
|
|
|
|
|
|
|
color: #000;
|
|
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
|
|
box-shadow: 0 0 1px 1px #e4e4e4;
|
|
|
|
|
|
|
|
opacity: 0;
|
|
|
|
|
|
|
|
transform: translateY(-10px) scale(0.9);
|
|
|
|
|
|
|
|
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.show {
|
|
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
|
|
transform: translateY(0) scale(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.tool-item{
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
width: 160px;
|
|
|
|
|
|
|
|
padding: 10px;
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
border-bottom: 1px solid #ddd;
|
|
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
|
|
opacity: 0;
|
|
|
|
|
|
|
|
transform: translateX(-10px);
|
|
|
|
|
|
|
|
animation: slideInItem 0.3s ease forwards;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.tool-item:last-child{
|
|
|
|
|
|
|
|
border-bottom: 0px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.img{
|
|
|
|
|
|
|
|
width: 16px;
|
|
|
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@keyframes slideInItem {
|
|
|
|
|
|
|
|
from {
|
|
|
|
|
|
|
|
opacity: 0;
|
|
|
|
|
|
|
|
transform: translateX(-10px);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
to {
|
|
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
|
|
transform: translateX(0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.popup {
|
|
|
|
.popup {
|
|
|
|
z-index: 99999;
|
|
|
|
z-index: 99999;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -325,6 +467,7 @@
|
|
|
|
padding: 0 20px;
|
|
|
|
padding: 0 20px;
|
|
|
|
border-radius: 10px 10px 0 0;
|
|
|
|
border-radius: 10px 10px 0 0;
|
|
|
|
padding-bottom: 20px;
|
|
|
|
padding-bottom: 20px;
|
|
|
|
|
|
|
|
|
|
|
|
.top {
|
|
|
|
.top {
|
|
|
|
position: relative;
|
|
|
|
position: relative;
|
|
|
|
text-align: center;
|
|
|
|
text-align: center;
|
|
|
|
@ -349,18 +492,19 @@
|
|
|
|
font-size: 18px;
|
|
|
|
font-size: 18px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.quick-ask{
|
|
|
|
.quick-ask {
|
|
|
|
display: flex;
|
|
|
|
display: flex;
|
|
|
|
.ask{
|
|
|
|
|
|
|
|
|
|
|
|
.ask {
|
|
|
|
padding: 5px 15px;
|
|
|
|
padding: 5px 15px;
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
border-radius: 10px;
|
|
|
|
border-radius: 10px;
|
|
|
|
margin-right: 10px;
|
|
|
|
margin-right: 10px;
|
|
|
|
font-size: 14px;
|
|
|
|
font-size: 14px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.active{
|
|
|
|
.active {
|
|
|
|
background-color: #007AFF;
|
|
|
|
background-color: #007AFF;
|
|
|
|
color: #fff;
|
|
|
|
color: #fff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -378,4 +522,16 @@
|
|
|
|
font-size: 14px;
|
|
|
|
font-size: 14px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.mark-layer{
|
|
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
|
|
width: 100vw;
|
|
|
|
|
|
|
|
height: 100vh;
|
|
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
|
|
right: 0;
|
|
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
|
|
z-index: 9999;
|
|
|
|
|
|
|
|
opacity: 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</style>
|