294 lines
6.4 KiB
Vue
294 lines
6.4 KiB
Vue
<template>
|
|
<view class="talk-btns" ref="talkBtnRef">
|
|
<view
|
|
class="touch-btn"
|
|
@touchstart="showOverlayTalking"
|
|
@touchend="hideOverlayTalking"
|
|
@touchmove="handleMove"
|
|
v-if="!keyboardIsShow"
|
|
>按住说话
|
|
</view>
|
|
<view class="touch-btn" v-if="keyboardIsShow">
|
|
<uv-input class="input-box" ref="inputRef" v-model.trim="answerValue" maxlength="1000"
|
|
placeholderStyle='color:#999999;font-size:26rpx' placeholder="请输入答案">
|
|
</uv-input>
|
|
</view>
|
|
<view class="talk-btn-box" @click.stop="showKeyboard">
|
|
<image class="talk-btn-icon" v-show="!keyboardIsShow" src="/src/static/images/course/jianpan.png" mode=""></image>
|
|
<image class="talk-btn-icon" v-show="keyboardIsShow" src="/src/static/images/course/send.png" mode=""></image>
|
|
</view>
|
|
<uv-overlay :show="showTalkingModel" opacity=".9" @click="showTalkingModel = false">
|
|
<view class="overlay-box">
|
|
<view class="circle-bg-box">
|
|
<view class="icon-box">
|
|
<image src="/src/static/images/course/talk-icon.png" mode=""></image>
|
|
</view>
|
|
</view>
|
|
<view class="tips-box">松开发送</view>
|
|
<view class="btns-box">
|
|
<view :class="['close-btn',isOut?'is-out':'']" >取消
|
|
<image class="btn-box" v-if="!isOut" src="/src/static/images/course/close.png" mode=""></image>
|
|
<image class="btn-box" v-else src="/src/static/images/course/close-active.png" mode=""></image>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</uv-overlay>
|
|
</view>
|
|
|
|
</template>
|
|
|
|
<script setup>
|
|
import { toRefs, ref, computed, unref, onMounted, onUnmounted, nextTick } from 'vue';
|
|
const emit = defineEmits(['uploadVoice', 'submitAnswer','startRecord'])
|
|
const props = defineProps({
|
|
answerType:{
|
|
default: 0,
|
|
type: Number
|
|
}
|
|
})
|
|
const { answerType } = toRefs(props)
|
|
const showTalkingModel = ref(false)
|
|
const keyboardIsShow = ref(false)
|
|
const answerValue = ref('')
|
|
const talkBtnRef = ref()
|
|
// 录音
|
|
const audioPath = ref('')
|
|
const audioObj = uni.createInnerAudioContext()
|
|
//#ifdef APP-PLUS
|
|
// app端
|
|
const recordObjCom = uni.getRecorderManager()
|
|
const initRecord = () => {
|
|
unref(recordObjCom)?.onStop((res, duration)=>{
|
|
audioPath.value = res.tempFilePath
|
|
})
|
|
}
|
|
const startRecord = () => {
|
|
unref(recordObjCom).start({format:'mp3'})
|
|
}
|
|
const stopRecord = () => {
|
|
unref(recordObjCom)?.stop?.()
|
|
}
|
|
// #endif
|
|
//#ifndef APP-PLUS
|
|
const recordObjCom = {}
|
|
const initRecord = () => {}
|
|
// #endif
|
|
onMounted(()=>{
|
|
initRecord?.()
|
|
})
|
|
// const playRecord = () => {
|
|
// audioObj.src = audioPath.value
|
|
// unref(audioObj).play()
|
|
// }
|
|
// 录音结束
|
|
|
|
// 记录 按下移动位置
|
|
const touchX = ref(0)
|
|
const touchY = ref(0)
|
|
const baseY = ref(0)
|
|
const windowInfo = uni.getWindowInfo()
|
|
// 计算是否超出按下盒子位置
|
|
const isOut = computed(() => {
|
|
let _btnHeight = windowInfo.screenWidth/750 * 234
|
|
let moveVal = (windowInfo.screenHeight - touchY.value) > _btnHeight
|
|
return moveVal
|
|
})
|
|
const showOverlayTalking = (obj) => {
|
|
emit('startRecord')
|
|
if(answerType.value === 4){
|
|
showTalkingModel.value = true
|
|
touchX.value = obj.changedTouches[0].pageX
|
|
touchY.value = obj.changedTouches[0].pageY
|
|
baseY.value = obj.currentTarget.offsetTop
|
|
//#ifdef APP-PLUS
|
|
startRecord()
|
|
// #endif
|
|
}else{
|
|
uni.showToast({
|
|
title: '请先获取问题信息!',
|
|
icon: "none",
|
|
duration:1000
|
|
})
|
|
}
|
|
}
|
|
const hideOverlayTalking = (obj) => {
|
|
showTalkingModel.value = false
|
|
//#ifdef APP-PLUS
|
|
stopRecord()
|
|
// #endif
|
|
if(!isOut.value){
|
|
setTimeout(()=>{
|
|
emit('uploadVoice', audioPath.value)
|
|
},1000)
|
|
}
|
|
}
|
|
|
|
const handleMove = (obj) => {
|
|
touchX.value = obj.changedTouches[0].pageX
|
|
touchY.value = obj.changedTouches[0].pageY
|
|
}
|
|
// 发送文本
|
|
const showKeyboard = () => {
|
|
if(answerType.value === 4){
|
|
if(keyboardIsShow.value){
|
|
if(answerValue.value){
|
|
emit(
|
|
'submitAnswer',
|
|
answerValue.value,
|
|
() => {
|
|
keyboardIsShow.value = !keyboardIsShow.value
|
|
answerValue.value = ''
|
|
}
|
|
)
|
|
}else{
|
|
keyboardIsShow.value = !keyboardIsShow.value
|
|
}
|
|
}else{
|
|
keyboardIsShow.value = !keyboardIsShow.value
|
|
}
|
|
}else{
|
|
uni.showToast({
|
|
title: '请先获取问题信息!',
|
|
icon: "none",
|
|
duration:1000
|
|
})
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.talk-btns{
|
|
height: 150rpx;
|
|
background-color: #fff;
|
|
padding: 25rpx 30rpx 0;
|
|
position: relative;
|
|
.touch-btn{
|
|
height: 92rpx;
|
|
box-shadow: 0 8rpx 20rpx 0 rgba(0,0,0,.06);
|
|
text-align: center;
|
|
line-height: 92rpx;
|
|
color: #000;
|
|
font-weight: 400;
|
|
position: relative;
|
|
.input-box{
|
|
width: 100%;
|
|
height: 92rpx;
|
|
line-height: 92rpx;
|
|
text-align: left;
|
|
box-sizing: border-box;
|
|
padding:0 40rpx 0 40rpx;
|
|
}
|
|
}
|
|
.talk-btn-box{
|
|
position: absolute;
|
|
height: 100%;
|
|
width: 120rpx;
|
|
right: 0;
|
|
top:0;
|
|
.talk-btn-icon{
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
position: absolute;
|
|
right: 60rpx;
|
|
top: 50%;
|
|
margin-top: -20rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.overlay-box{
|
|
display: flex;
|
|
flex-direction: column-reverse;
|
|
// justify-content: flex-end;
|
|
width: 100%;
|
|
height: 100%;
|
|
.circle-bg-box{
|
|
height: 234rpx;
|
|
background: url(@/static/images/course/talking.png) no-repeat;
|
|
background-size: cover;
|
|
position: relative;
|
|
.icon-box{
|
|
position: absolute;
|
|
left:50%;
|
|
top: 50%;
|
|
margin-left: -17rpx;
|
|
margin-top: -24rpx;
|
|
width: 34rpx;
|
|
height: 48rpx;
|
|
image{
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
}
|
|
.tips-box{
|
|
height: 40rpx;
|
|
line-height: 40rpx;
|
|
color:#c0c0c0;
|
|
text-align: center;
|
|
margin: 12rpx 0 24rpx;
|
|
}
|
|
.btns-box{
|
|
height: 270rpx;
|
|
// padding: 0 120rpx;
|
|
width: 154rpx;
|
|
margin: 0 auto 100rpx;
|
|
overflow: hidden;
|
|
font-size: 28rpx;
|
|
text-align: center;
|
|
line-height: 116rpx;
|
|
.close-btn{
|
|
float: left;
|
|
height: 100%;
|
|
width: 154rpx;
|
|
overflow: hidden;
|
|
color:#999;
|
|
&.is-out{
|
|
color:#fff;
|
|
}
|
|
}
|
|
.translate-btn{
|
|
float: right;
|
|
height: 100%;
|
|
width: 154rpx;
|
|
overflow: hidden;
|
|
color:#999;
|
|
}
|
|
.btn-box{
|
|
width: 100%;
|
|
height: 154rpx;
|
|
}
|
|
}
|
|
.talk-dialog{
|
|
width: 506rpx;
|
|
height: 234rpx;
|
|
margin: 0 auto;
|
|
background-color: #06f;
|
|
}
|
|
.white-bg-box{
|
|
height: 365rpx;
|
|
background-color: #fff;
|
|
overflow: hidden;
|
|
border-radius: 32rpx 32rpx 0 0;
|
|
padding: 58rpx 36rpx;
|
|
.box-title{
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
line-height: 46rpx;
|
|
margin-bottom: 46rpx;
|
|
}
|
|
.box-btns{
|
|
height: 46rpx;
|
|
line-height: 46rpx;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
color: #999;
|
|
.is-active{
|
|
color: #06f;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
</style>
|