Merge branch 'test_dispaly' of https://git.code.tencent.com/lian-cbtc/jl-client into test_dispaly
This commit is contained in:
commit
3a7babb483
@ -116,7 +116,8 @@ const socket = {
|
|||||||
nextStationName: '',
|
nextStationName: '',
|
||||||
endStationName: ''
|
endStationName: ''
|
||||||
},
|
},
|
||||||
simulationWorkParam: {}
|
simulationWorkParam: {},
|
||||||
|
conversationMessage: {}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
},
|
},
|
||||||
@ -381,6 +382,9 @@ const socket = {
|
|||||||
},
|
},
|
||||||
setSimulationWorkParam: (state, data) => {
|
setSimulationWorkParam: (state, data) => {
|
||||||
state.simulationWorkParam = data;
|
state.simulationWorkParam = data;
|
||||||
|
},
|
||||||
|
setConversationMessage: (state, message) => {
|
||||||
|
state.conversationMessage = message;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -604,6 +608,10 @@ const socket = {
|
|||||||
},
|
},
|
||||||
setSimulationWorkParam: ({ commit }, data) => {
|
setSimulationWorkParam: ({ commit }, data) => {
|
||||||
commit('setSimulationWorkParam', data);
|
commit('setSimulationWorkParam', data);
|
||||||
|
},
|
||||||
|
setConversationMessage: ({ commit }, message) => {
|
||||||
|
console.log('----------------');
|
||||||
|
commit('setConversationMessage', message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -68,7 +68,7 @@ function handle(data) {
|
|||||||
handleSimulationInfo(msg);
|
handleSimulationInfo(msg);
|
||||||
break;
|
break;
|
||||||
case 'Simulation_Conversation_Operation': // 仿真-用户交互消息(聊天/命令)-新
|
case 'Simulation_Conversation_Operation': // 仿真-用户交互消息(聊天/命令)-新
|
||||||
handleSimulationInfo({id: msg.id, message: msg, messageType: 'MESSAGE'});
|
store.dispatch('socket/setConversationMessage', msg);
|
||||||
break;
|
break;
|
||||||
case 'Simulation_ApplyHandle': // 请求处理消息(旧版可能在用,新版地图不用这个)
|
case 'Simulation_ApplyHandle': // 请求处理消息(旧版可能在用,新版地图不用这个)
|
||||||
store.dispatch('socket/handlePushMsgQueue', msg);
|
store.dispatch('socket/handlePushMsgQueue', msg);
|
||||||
|
@ -27,7 +27,7 @@ import TrainingTip from './trainingList/trainingTip';
|
|||||||
import TrainingPositionTip from './trainingList/trainingPositionTip.vue';
|
import TrainingPositionTip from './trainingList/trainingPositionTip.vue';
|
||||||
import TrainingMenu from './trainingList/trainingMenu';
|
import TrainingMenu from './trainingList/trainingMenu';
|
||||||
import TrainingDesign from './trainingDesign/designPane.vue';
|
import TrainingDesign from './trainingDesign/designPane.vue';
|
||||||
import VoiceChatBox from './voiceChatBox';
|
import VoiceChatBox from './voiceChatBox/chatBox';
|
||||||
import DesignTrainingMenu from './trainingList/designTrainingMenu';
|
import DesignTrainingMenu from './trainingList/designTrainingMenu';
|
||||||
export default {
|
export default {
|
||||||
name: 'DisplayDraft',
|
name: 'DisplayDraft',
|
||||||
|
507
src/views/newMap/display/voiceChatBox/chatBox.vue
Normal file
507
src/views/newMap/display/voiceChatBox/chatBox.vue
Normal file
@ -0,0 +1,507 @@
|
|||||||
|
<template>
|
||||||
|
<div v-quickMenuDrag class="voice-chat-box">
|
||||||
|
<div v-if="min" :id="sideButtonDom.domId" @click="clickBtn">
|
||||||
|
<el-button circle style="color: #0C161A;" icon="el-icon-mic" />
|
||||||
|
</div>
|
||||||
|
<div v-show="!min" class="chat-box-main">
|
||||||
|
<div class="chat-box-header">
|
||||||
|
<div style="margin-right: 10px;cursor: pointer;">
|
||||||
|
<i class="el-icon-minus" style="color: #000;" @click="minimize" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chat-box-content">
|
||||||
|
<div v-for="(content,index) in messageList" :key="index" style="width: 100%;height: 65px;">
|
||||||
|
<div :class="content.memberId == myMemberId?'rightUser':'leftUser'">
|
||||||
|
<div class="userHeader">
|
||||||
|
<div class="userName">{{ covertName(content.memberId) }}</div>
|
||||||
|
<div :class="content.memberId == myMemberId?'userChatTime textRight':'userChatTime'">{{ content.time }}</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="content.type === 'Text'" class="userBubble">
|
||||||
|
<div class="userMessage">
|
||||||
|
<span class="messageText">{{ content.content }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="userBubble" style="height: 30px;width: 140px;" @click="playAudio(content.audioPath, content)">
|
||||||
|
<div class="userMessage">
|
||||||
|
<div class="wifi-symbol">
|
||||||
|
<div class="wifi-circle first" />
|
||||||
|
<div class="wifi-circle second" :class="{'second-amit': content.activeAuto}" />
|
||||||
|
<div class="wifi-circle third" :class="{'third-amit': content.activeAuto}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chat-box-footer">
|
||||||
|
<el-input v-model="textContent" size="small" placeholder="请输入会话文字,点击T发送" style="flex: 1; margin-left: 5px;" :rows="1" />
|
||||||
|
<el-button :id="sendTextId" size="mini" class="chat-box-footer-create" :disabled="contentSend" @click="sendText">T</el-button>
|
||||||
|
<el-button class="chat-box-footer-create chat-box-footer-send" :class="{'active': recordSending}" :disabled="audioPlay" size="mini" type="primary" @click="startRecording()">
|
||||||
|
<el-progress id="voice_progress_bar" type="circle" :show-text="false" :percentage="100/60*seconds" :width="40" :stroke-width="2" status="success" />
|
||||||
|
<i v-if="recordSending" class="el-icon-close close_icon" @click.stop="cancelRecording()" />
|
||||||
|
<span class="iconfont icon-yuyin"></span>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<audio id="audioPlay" style="display:none" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import RecordRTC from 'recordrtc';
|
||||||
|
import {sendChatAudioBase64, getAllConversition} from '@/api/chat';
|
||||||
|
import { OperationEvent } from '@/scripts/cmdPlugin/OperationHandler';
|
||||||
|
import {menuOperate, commitOperate} from '@/jmapNew/theme/components/utils/menuOperate';
|
||||||
|
import {UserOperationType} from '@/scripts/ConstDic';
|
||||||
|
export default {
|
||||||
|
name: 'ChatBox',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
recordSending:false,
|
||||||
|
seconds:0,
|
||||||
|
inter:null,
|
||||||
|
recorders: null,
|
||||||
|
microphone:null,
|
||||||
|
audioPlay:false,
|
||||||
|
textContent: '',
|
||||||
|
min: true,
|
||||||
|
messageList: [], // 消息列表
|
||||||
|
currentAudioList:[],
|
||||||
|
currentMessage: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
group() {
|
||||||
|
return this.$route.query.group;
|
||||||
|
},
|
||||||
|
contentSend() {
|
||||||
|
return !this.textContent;
|
||||||
|
},
|
||||||
|
myMemberId() {
|
||||||
|
return this.$store.state.training.myMemberId;
|
||||||
|
},
|
||||||
|
userId() {
|
||||||
|
return this.$store.state.user.id;
|
||||||
|
},
|
||||||
|
sendTextId() {
|
||||||
|
return OperationEvent.Conversation.Chat.menu.domId;
|
||||||
|
},
|
||||||
|
sideButtonDom() {
|
||||||
|
return OperationEvent.Conversation.Chat.sideButton;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.socket.simulationReset': function () { // 仿真重置
|
||||||
|
this.messageList = [];
|
||||||
|
},
|
||||||
|
'$store.state.socket.conversationMessage':function (val) { // 仿真聊天
|
||||||
|
const message = {...val};
|
||||||
|
this.messageList.push(message);
|
||||||
|
console.log(val, '----------');
|
||||||
|
if (val.memberId != this.myMemberId) {
|
||||||
|
this.currentAudioList.push(message);
|
||||||
|
if (!this.isPlay) {
|
||||||
|
this.playAllAudio();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.scrollTop();
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initConversationData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
scrollTop() {
|
||||||
|
|
||||||
|
},
|
||||||
|
initConversationData() {
|
||||||
|
getAllConversition(this.group).then(resp => {
|
||||||
|
if (resp.data && resp.data.length) {
|
||||||
|
const conversation = resp.data.find(con => con.id === 'chat_room_key');
|
||||||
|
this.messageList = conversation ? conversation.messageList : [];
|
||||||
|
} else {
|
||||||
|
this.messageList = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
playAllAudio() {
|
||||||
|
this.$nextTick(function() {
|
||||||
|
this.currentMessage = this.currentAudioList.shift();
|
||||||
|
document.querySelector('#audioPlay').src = this.currentMessage.audioPath;
|
||||||
|
document.querySelector('#audioPlay').play();
|
||||||
|
this.$set(this.currentMessage, 'activeAuto', true);
|
||||||
|
this.play = true;
|
||||||
|
document.querySelector('#audioPlay').onended = () => {
|
||||||
|
this.$set(this.currentMessage, 'activeAuto', false);
|
||||||
|
if (!this.currentAudioList || !this.currentAudioList.length) {
|
||||||
|
this.play = false;
|
||||||
|
} else {
|
||||||
|
this.playAllAudio();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
playAudio(audioPath, data) {
|
||||||
|
this.$set(this.currentMessage, 'activeAuto', false);
|
||||||
|
this.currentAudioList = [];
|
||||||
|
this.currentMessage = data;
|
||||||
|
this.play = true;
|
||||||
|
document.querySelector('#audioPlay').src = audioPath;
|
||||||
|
document.querySelector('#audioPlay').play();
|
||||||
|
this.$set(this.currentMessage, 'activeAuto', true);
|
||||||
|
document.querySelector('#audioPlay').onended = () => { this.play = false; this.$set(this.currentMessage, 'activeAuto', false); };
|
||||||
|
},
|
||||||
|
covertName(memberId) {
|
||||||
|
let name = '';
|
||||||
|
const member = this.$store.state.training.memberData[memberId];
|
||||||
|
if (member && member.userId) {
|
||||||
|
const user = this.$store.state.training.simulationUserList.find(user => user.userId == member.userId);
|
||||||
|
name = member.labelName + '(' + user.nickName + ')';
|
||||||
|
} else if (member) {
|
||||||
|
name = member.labelName;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
},
|
||||||
|
clickBtn() {
|
||||||
|
const operate = {
|
||||||
|
operation: this.sideButtonDom.operation,
|
||||||
|
param: { min: this.min },
|
||||||
|
userOperationType: UserOperationType.LEFTCLICK
|
||||||
|
};
|
||||||
|
this.min = false;
|
||||||
|
this.$store.dispatch('trainingNew/next', operate);
|
||||||
|
},
|
||||||
|
minimize() {
|
||||||
|
this.min = true;
|
||||||
|
},
|
||||||
|
sendText() {
|
||||||
|
commitOperate(menuOperate.Conversation.Chat, {content: this.textContent}, 3).then(({valid})=>{
|
||||||
|
if (valid) {
|
||||||
|
this.textContent = '';
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
this.$message.error('发送会话文字失败:' + error.message);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cancelRecording() {
|
||||||
|
if (this.microphone) {
|
||||||
|
clearInterval(this.inter);
|
||||||
|
this.seconds = 0;
|
||||||
|
this.microphone.stop();
|
||||||
|
this.microphone = null;
|
||||||
|
this.recordSending = false;
|
||||||
|
this.recorders = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 停止录制 发送语音
|
||||||
|
stopRecording() {
|
||||||
|
this.audioPlay = true;
|
||||||
|
clearInterval(this.inter);
|
||||||
|
this.seconds = 0;
|
||||||
|
const that = this;
|
||||||
|
this.recorders.stopRecording(function(blobURL) {
|
||||||
|
that.recorders.getDataURL(function(BaseURL) {
|
||||||
|
sendChatAudioBase64(that.group, {fileBase64Str: BaseURL})
|
||||||
|
.then((data) => {
|
||||||
|
that.textContent = '';
|
||||||
|
that.audioPlay = false;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
that.$message.error('语音发送失败: ' + error.message);
|
||||||
|
that.audioPlay = false;
|
||||||
|
});
|
||||||
|
if (that.microphone) {
|
||||||
|
that.microphone.stop();
|
||||||
|
that.microphone = null;
|
||||||
|
that.recordSending = false;
|
||||||
|
that.recorders = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 语音录制开始
|
||||||
|
startRecording() {
|
||||||
|
this.audioPlay = true;
|
||||||
|
const that = this;
|
||||||
|
if (!this.recordSending) {
|
||||||
|
if (!this.recordSending && !this.recorders && !this.microphone) {
|
||||||
|
const StereoAudioRecorder = RecordRTC.StereoAudioRecorder;
|
||||||
|
navigator.getUserMedia(
|
||||||
|
{ audio: true } // 只启用音频
|
||||||
|
, function (stream) {
|
||||||
|
that.microphone = stream;
|
||||||
|
that.recorders = new RecordRTC(that.microphone, {
|
||||||
|
type: 'audio',
|
||||||
|
recorderType: StereoAudioRecorder,
|
||||||
|
numberOfAudioChannels: 1,
|
||||||
|
bitsPerSecond:256000,
|
||||||
|
desiredSampRate: 16000
|
||||||
|
});
|
||||||
|
that.recorders.startRecording();
|
||||||
|
that.recordSending = true;
|
||||||
|
that.audioPlay = false;
|
||||||
|
that.inter = setInterval(() => {
|
||||||
|
if (that.seconds < 60) {
|
||||||
|
that.seconds++;
|
||||||
|
} else {
|
||||||
|
clearInterval(that.inter);
|
||||||
|
that.stopRecording();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}, function (error) {
|
||||||
|
that.audioPlay = false;
|
||||||
|
switch (error.code || error.name) {
|
||||||
|
case 'PERMISSION_DENIED':
|
||||||
|
case 'PermissionDeniedError':
|
||||||
|
that.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: '用户拒绝提供信息',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'NOT_SUPPORTED_ERROR':
|
||||||
|
case 'NotSupportedError':
|
||||||
|
that.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: '浏览器不支持硬件设备',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'MANDATORY_UNSATISFIED_ERROR':
|
||||||
|
case 'MandatoryUnsatisfiedError':
|
||||||
|
that.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: '无法发现指定的硬件设备',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
that.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: '无法打开麦克风',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.stopRecording(); // 发送语音
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.voice-chat-box {
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
bottom: 50%;
|
||||||
|
height: 1px;
|
||||||
|
width: 1px;
|
||||||
|
z-index: 2000;
|
||||||
|
}
|
||||||
|
.chat-box-header{
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
border-bottom: 1px #dedede solid;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: right;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
.chat-box-content{
|
||||||
|
height: 250px;
|
||||||
|
position: relative;
|
||||||
|
border-top: 1px #9a9a9a solid;
|
||||||
|
margin-top: 8px;
|
||||||
|
display: block;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
// 谷歌、safari、qq浏览器、360浏览器滚动条样式
|
||||||
|
// 定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸
|
||||||
|
.chat-box-content::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
// height: 110px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
/*定义滚动条轨道 内阴影+圆角*/
|
||||||
|
.chat-box-content::-webkit-scrollbar-track {
|
||||||
|
// box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #FFFFFF;;
|
||||||
|
}
|
||||||
|
/*定义滑块 内阴影+圆角*/
|
||||||
|
.chat-box-content::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
// box-shadow: inset 0 0 6px rgba(0,0,0,.3);
|
||||||
|
background-color: #cacaca;
|
||||||
|
}
|
||||||
|
/*滑块效果*/
|
||||||
|
.chat-box-content::-webkit-scrollbar-thumb:hover {
|
||||||
|
border-radius: 5px;
|
||||||
|
// box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
|
||||||
|
background: rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
.chat-box-footer{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 55px;
|
||||||
|
border-top: 1px solid #afafaf;
|
||||||
|
}
|
||||||
|
.chat-box-main{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
height: 350px;
|
||||||
|
width: 503px;
|
||||||
|
top: 0;
|
||||||
|
border-right: 1px #dedede solid;
|
||||||
|
z-index: 4;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.chat-box-footer-create{
|
||||||
|
font-size: 16px;
|
||||||
|
color: #fff;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: green;
|
||||||
|
border: none;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.chat-box-footer-send{
|
||||||
|
position: relative;
|
||||||
|
background: #F2F2F2;
|
||||||
|
cursor: pointer;
|
||||||
|
.icon-yuyin{
|
||||||
|
color: #333;
|
||||||
|
font-size: 24px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
&.active{
|
||||||
|
.icon-yuyin{
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.close_icon{
|
||||||
|
position: absolute;
|
||||||
|
top: -15px;
|
||||||
|
left: 11px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#voice_progress_bar{
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.chat-box-footer-send.disbled{
|
||||||
|
cursor: no-drop;
|
||||||
|
}
|
||||||
|
.leftUser{
|
||||||
|
float: left;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 80%;
|
||||||
|
}
|
||||||
|
.rightUser{
|
||||||
|
float: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 80%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.userHeader{margin-bottom: 2px;}
|
||||||
|
.userName{font-size: 12px;display:inline-block;margin-right:10px;}
|
||||||
|
.userChatTime{font-size: 12px;display:inline-block;}
|
||||||
|
.textRight{text-align: right;}
|
||||||
|
.userBubble{
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 5px 10px 6px 10px;
|
||||||
|
min-width: 140px;
|
||||||
|
background: #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
display:inline-block;
|
||||||
|
}
|
||||||
|
.userMessage{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.messageText{
|
||||||
|
line-height: 20px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
.wifi-symbol {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
transform: rotate(135deg);
|
||||||
|
position: absolute;
|
||||||
|
left: 5px;
|
||||||
|
top: -13px;
|
||||||
|
}
|
||||||
|
.wifi-circle {
|
||||||
|
border: 1px solid #000000;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first {
|
||||||
|
width: 9px;
|
||||||
|
height: 9px;
|
||||||
|
background: #cccccc;
|
||||||
|
top: 45px;
|
||||||
|
left: 45px;
|
||||||
|
border: 2px solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.second {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
top: 40px;
|
||||||
|
left: 40px;
|
||||||
|
&.second-amit{
|
||||||
|
animation: fadeInOut 1s infinite 0.2s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.third {
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
top: 36px;
|
||||||
|
left: 36px;
|
||||||
|
&.third-amit{
|
||||||
|
animation: fadeInOut 1s infinite 0.4s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeInOut {
|
||||||
|
0% {
|
||||||
|
opacity: 0; /*初始状态 透明度为0*/
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1; /*结尾状态 透明度为1*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,363 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="chatcontentIn" :style="{width: width}">
|
|
||||||
<div class="chatcontentInner">
|
|
||||||
<div v-for="(chatContent,index) in messageList" :key="index" class="chatContentInClass">
|
|
||||||
<div :class="chatContent.memberId == myMemberId?'rightUser':'leftUser'">
|
|
||||||
<div class="userHeader">
|
|
||||||
<div v-if="!chatContent.self" class="userName">{{ covertName(chatContent.memberId) }}</div>
|
|
||||||
<div :class="chatContent.memberId == myMemberId?'userChatTime textRight':'userChatTime'">{{ covertTime(chatContent.time) }}</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="chatContent.type == 'Text'" class="userBubble">
|
|
||||||
<div class="userMessage">
|
|
||||||
<span class="messageText">{{ chatContent.content }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else class="userBubble" style="height: 30px;width: 140px;" @click="playAudio(baseUrl+chatContent.src, chatContent)">
|
|
||||||
<div class="userMessage">
|
|
||||||
<!-- <span class="el-icon-video-play playicon" /> -->
|
|
||||||
<!-- <img :src="yuyin" class="playicon1"> -->
|
|
||||||
<!-- 语音播放 -->
|
|
||||||
<div class="wifi-symbol">
|
|
||||||
<div class="wifi-circle first" />
|
|
||||||
<div class="wifi-circle second" :class="{'second-amit': chatContent.activeAtuo}" />
|
|
||||||
<div class="wifi-circle third" :class="{'third-amit': chatContent.activeAtuo}" />
|
|
||||||
</div>
|
|
||||||
<!-- <span class="messageText">{{ chatContent.content }}</span> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<audio id="audioPlay" style="display:none" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import {overConversationMessage} from '@/api/chat';
|
|
||||||
export default {
|
|
||||||
props:{
|
|
||||||
messageList:{
|
|
||||||
type:Array,
|
|
||||||
required:true
|
|
||||||
},
|
|
||||||
conversitionStateMap: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
isAnswering:{
|
|
||||||
type:Boolean,
|
|
||||||
required:true
|
|
||||||
},
|
|
||||||
conversitionId: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
conversitionMemberList: {
|
|
||||||
type: Array,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
simulationUsers: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
userRole: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
commonConversation: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
myMemberId: {
|
|
||||||
type: String,
|
|
||||||
default() {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
width: {
|
|
||||||
type: String,
|
|
||||||
default() {
|
|
||||||
return '100%';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
chatContentList:[],
|
|
||||||
currentAudioList:[],
|
|
||||||
// yuyin:yuyin,
|
|
||||||
currentAudioIndex:0,
|
|
||||||
isPlay:false,
|
|
||||||
baseUrl: this.$store.state.user.resourcesUrl
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch:{
|
|
||||||
'$store.state.socket.conversationInfo':function (val, old) { // 仿真聊天
|
|
||||||
const conversationInfo = this.$store.state.socket.conversationInfo;
|
|
||||||
const member = this.$store.state.training.memberData[val.message.memberId];
|
|
||||||
conversationInfo.message.src = `${conversationInfo.message.audioPath}`;
|
|
||||||
this.$emit('changeMessageList', conversationInfo);
|
|
||||||
if (this.conversitionId == val.id && this.conversitionStateMap[this.myMemberId] && this.conversitionStateMap[this.myMemberId].connect) {
|
|
||||||
if (member && member.userId != this.$store.state.user.id) {
|
|
||||||
this.currentAudioList.push({audioUrl:this.baseUrl + conversationInfo.message.audioPath, id:val.message.id});
|
|
||||||
if (!this.isPlay) {
|
|
||||||
this.isPlay = true;
|
|
||||||
this.$store.dispatch('scriptRecord/updateAudioPlay', true);
|
|
||||||
this.playAllAudio();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.scrollTop();
|
|
||||||
} else if (this.userRole === 'AUDIENCE' || this.commonConversation) {
|
|
||||||
if (member && member.userId != this.$store.state.user.id) {
|
|
||||||
this.currentAudioList.push({audioUrl:this.baseUrl + conversationInfo.message.audioPath, id:val.message.id});
|
|
||||||
if (!this.isPlay) {
|
|
||||||
this.isPlay = true;
|
|
||||||
this.$store.dispatch('scriptRecord/updateAudioPlay', true);
|
|
||||||
this.playAllAudio();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'$store.state.scriptRecord.audioPlay':function(val) {
|
|
||||||
this.isPlay = val;
|
|
||||||
if (!val) {
|
|
||||||
this.currentAudioList = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
},
|
|
||||||
methods:{
|
|
||||||
scrollTop() {
|
|
||||||
this.$nextTick(function() {
|
|
||||||
const scrollTop = document.querySelector('.chatcontentInner').offsetHeight - document.querySelector('.chatcontentIn').offsetHeight + 30;
|
|
||||||
document.querySelector('.chatcontentIn').scrollTop = scrollTop;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
playAllAudio() {
|
|
||||||
this.playEachAudio(this.currentAudioList[this.currentAudioIndex]);
|
|
||||||
},
|
|
||||||
playEachAudio(audioObject) {
|
|
||||||
this.$nextTick(function() {
|
|
||||||
this.messageList.forEach(item => {
|
|
||||||
if (item.id == audioObject.id) {
|
|
||||||
this.$set(item, 'activeAtuo', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
document.querySelector('#audioPlay').src = audioObject.audioUrl;
|
|
||||||
document.querySelector('#audioPlay').play();
|
|
||||||
const that = this;
|
|
||||||
document.querySelector('#audioPlay').onended = function() {
|
|
||||||
that.messageList.forEach(item => {
|
|
||||||
if (item.id == audioObject.id) {
|
|
||||||
that.$set(item, 'activeAtuo', false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
overConversationMessage(that.$route.query.group, audioObject.id).then(res=>{
|
|
||||||
that.currentAudioList.shift();
|
|
||||||
if (that.currentAudioList.length > 0) {
|
|
||||||
that.playEachAudio(that.currentAudioList[that.currentAudioIndex]);
|
|
||||||
} else {
|
|
||||||
that.isPlay = false;
|
|
||||||
that.$store.dispatch('scriptRecord/updateAudioPlay', false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
covertName(memberId) {
|
|
||||||
let name = '';
|
|
||||||
const member = this.$store.state.training.memberData[memberId];
|
|
||||||
if (member && member.userId) {
|
|
||||||
const user = this.simulationUsers[member.userId];
|
|
||||||
name = member.label + '(' + user.nickName + ')';
|
|
||||||
} else if (member) {
|
|
||||||
name = member.label;
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
},
|
|
||||||
covertTime(time) {
|
|
||||||
const date = new Date(time);
|
|
||||||
let hour = date.getHours();
|
|
||||||
let minute = date.getMinutes();
|
|
||||||
let second = date.getSeconds();
|
|
||||||
hour = hour > 9 ? hour : '0' + hour;
|
|
||||||
minute = minute > 9 ? minute : '0' + minute;
|
|
||||||
second = second > 9 ? second : '0' + second;
|
|
||||||
return hour + ':' + minute + ':' + second;
|
|
||||||
},
|
|
||||||
playAudio(audioUrl, data) {
|
|
||||||
this.messageList.forEach(item => {
|
|
||||||
this.$set(item, 'activeAtuo', false);
|
|
||||||
});
|
|
||||||
if (!this.isPlay) {
|
|
||||||
const that = this;
|
|
||||||
document.querySelector('#audioPlay').src = audioUrl;
|
|
||||||
this.$set(data, 'activeAtuo', true);
|
|
||||||
document.querySelector('#audioPlay').play();
|
|
||||||
document.querySelector('#audioPlay').onended = function() {
|
|
||||||
that.$set(data, 'activeAtuo', false);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
conversationChange() {
|
|
||||||
this.currentAudioList = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.chatcontentIn{
|
|
||||||
// height: 200px;
|
|
||||||
height: calc(100% - 5px);
|
|
||||||
// width: 360px;
|
|
||||||
width: 100%;
|
|
||||||
display: inline-block;
|
|
||||||
overflow: auto;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
cursor:auto;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
.leftUser{
|
|
||||||
float: left;
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
display: inline-block;
|
|
||||||
max-width: 80%;
|
|
||||||
}
|
|
||||||
.rightUser{
|
|
||||||
float: right;
|
|
||||||
margin-right: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
display: inline-block;
|
|
||||||
max-width: 80%;
|
|
||||||
}
|
|
||||||
.userHeader{margin-bottom: 2px;}
|
|
||||||
.userName{font-size: 12px;display:inline-block;margin-right:10px;}
|
|
||||||
.userChatTime{font-size: 12px;display:inline-block;}
|
|
||||||
.userBubble{
|
|
||||||
font-size: 12px;
|
|
||||||
// padding: 10px;
|
|
||||||
padding: 5px 10px 6px 10px;
|
|
||||||
min-width: 140px;
|
|
||||||
background: #ccc;
|
|
||||||
border-radius: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
display:inline-block;
|
|
||||||
// height: 30px;
|
|
||||||
// overflow: hidden;
|
|
||||||
}
|
|
||||||
.playicon{
|
|
||||||
font-size: 20px;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
// .playicon1{
|
|
||||||
// width:17px;
|
|
||||||
// }
|
|
||||||
.wifi-symbol {
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
overflow: hidden;
|
|
||||||
transform: rotate(135deg);
|
|
||||||
position: absolute;
|
|
||||||
left: 5px;
|
|
||||||
top: -13px;
|
|
||||||
}
|
|
||||||
.wifi-circle {
|
|
||||||
border: 1px solid #000000;
|
|
||||||
border-radius: 50%;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.first {
|
|
||||||
width: 9px;
|
|
||||||
height: 9px;
|
|
||||||
background: #cccccc;
|
|
||||||
top: 45px;
|
|
||||||
left: 45px;
|
|
||||||
border: 2px solid #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.second {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
top: 40px;
|
|
||||||
left: 40px;
|
|
||||||
&.second-amit{
|
|
||||||
animation: fadeInOut 1s infinite 0.2s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.third {
|
|
||||||
width: 26px;
|
|
||||||
height: 26px;
|
|
||||||
top: 36px;
|
|
||||||
left: 36px;
|
|
||||||
&.third-amit{
|
|
||||||
animation: fadeInOut 1s infinite 0.4s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeInOut {
|
|
||||||
0% {
|
|
||||||
opacity: 0; /*初始状态 透明度为0*/
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1; /*结尾状态 透明度为1*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.textRight{text-align: right;}
|
|
||||||
.userMessage{
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.messageText{
|
|
||||||
line-height: 20px;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
.chatContentInClass{
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightUser .userBubble{
|
|
||||||
float:right;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 谷歌、safari、qq浏览器、360浏览器滚动条样式
|
|
||||||
// 定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸
|
|
||||||
.chatcontentIn::-webkit-scrollbar {
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
// height: 110px;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
}
|
|
||||||
/*定义滚动条轨道 内阴影+圆角*/
|
|
||||||
.chatcontentIn::-webkit-scrollbar-track {
|
|
||||||
// box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
|
||||||
border-radius: 10px;
|
|
||||||
background-color: #FFFFFF;;
|
|
||||||
}
|
|
||||||
/*定义滑块 内阴影+圆角*/
|
|
||||||
.chatcontentIn::-webkit-scrollbar-thumb {
|
|
||||||
border-radius: 10px;
|
|
||||||
// box-shadow: inset 0 0 6px rgba(0,0,0,.3);
|
|
||||||
background-color: #cacaca;
|
|
||||||
}
|
|
||||||
/*滑块效果*/
|
|
||||||
.chatcontentIn::-webkit-scrollbar-thumb:hover {
|
|
||||||
border-radius: 5px;
|
|
||||||
// box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
|
|
||||||
background: rgba(0,0,0,0.4);
|
|
||||||
}
|
|
||||||
/*IE滚动条颜色*/
|
|
||||||
html {
|
|
||||||
scrollbar-face-color:#bfbfbf;/*滚动条颜色*/
|
|
||||||
scrollbar-highlight-color:#000;
|
|
||||||
scrollbar-3dlight-color:#000;
|
|
||||||
scrollbar-darkshadow-color:#000;
|
|
||||||
scrollbar-Shadow-color:#adadad;/*滑块边色*/
|
|
||||||
scrollbar-arrow-color:rgba(0,0,0,0.4);/*箭头颜色*/
|
|
||||||
scrollbar-track-color:#eeeeee;/*背景颜色*/
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,127 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div v-show="dialogVisible" class="chat-popup">
|
|
||||||
<div class="chat-setting-header">
|
|
||||||
<div class="chat-setting-title">设置</div>
|
|
||||||
<div class="chat-setting-close">
|
|
||||||
<i class="el-icon-close" @click="dialogVisible=false" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="chat-setting-content">
|
|
||||||
<div class="chat-setting-language">
|
|
||||||
<div class="setting-language-title">语言: </div>
|
|
||||||
<el-switch
|
|
||||||
v-model="form.language"
|
|
||||||
class="setting-language-select"
|
|
||||||
active-color="#409EFF"
|
|
||||||
inactive-color="#ff4949"
|
|
||||||
active-text="中"
|
|
||||||
inactive-text="En"
|
|
||||||
active-value="zh"
|
|
||||||
inactive-value="en"
|
|
||||||
@change="changeLanguage()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="chat-setting-sex">
|
|
||||||
<div class="setting-sex-title">性别: </div>
|
|
||||||
<el-switch
|
|
||||||
v-model="form.sex"
|
|
||||||
class="setting-sex-select"
|
|
||||||
active-color="#409EFF"
|
|
||||||
inactive-color="#ff4949"
|
|
||||||
active-icon-class="el-icon-male"
|
|
||||||
inactive-icon-class="el-icon-female"
|
|
||||||
active-value="1"
|
|
||||||
inactive-value="0"
|
|
||||||
@change="changeSex()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'ChatSetting',
|
|
||||||
props:{
|
|
||||||
form:{
|
|
||||||
type:Object,
|
|
||||||
required:true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
dialogVisible: false,
|
|
||||||
loading:false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods:{
|
|
||||||
doShow() {
|
|
||||||
this.dialogVisible = true;
|
|
||||||
},
|
|
||||||
doClose() {
|
|
||||||
this.dialogVisible = false;
|
|
||||||
},
|
|
||||||
changeLanguage() {
|
|
||||||
this.$emit('setSetting', this.form);
|
|
||||||
},
|
|
||||||
changeSex() {
|
|
||||||
this.$emit('setSetting', this.form);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.chat-popup{
|
|
||||||
position: absolute;
|
|
||||||
// width: 54%;
|
|
||||||
width: 200px;
|
|
||||||
height: 143px;
|
|
||||||
border: 1px #dedede solid;
|
|
||||||
left: 100px;
|
|
||||||
top: 70px;
|
|
||||||
z-index: 7;
|
|
||||||
border-radius: 4px;
|
|
||||||
-webkit-box-shadow: 3px 3px 3px #928787;
|
|
||||||
box-shadow: 3px 3px 3px #928787;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
.chat-setting-header{
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-top: 6px;
|
|
||||||
font-size: 14px;
|
|
||||||
border-bottom: 1px #dedede solid;
|
|
||||||
padding-bottom: 6px;
|
|
||||||
}
|
|
||||||
.chat-setting-title{
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.chat-setting-close{
|
|
||||||
float: right;
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 5px;
|
|
||||||
font-size: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.chat-setting-content{
|
|
||||||
|
|
||||||
}
|
|
||||||
.chat-setting-language,.chat-setting-sex{
|
|
||||||
display: inline-block;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
.setting-language-title,.setting-sex-title{
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 14px;
|
|
||||||
margin-left: 20px;
|
|
||||||
vertical-align: top;
|
|
||||||
margin-top: 3px;
|
|
||||||
}
|
|
||||||
.setting-language-select,.setting-sex-select{
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style lang="scss">
|
|
||||||
.setting-sex-select .el-icon-male,.setting-sex-select .el-icon-female{
|
|
||||||
font-size:18px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user