1028 lines
25 KiB
Vue
1028 lines
25 KiB
Vue
<template>
|
||
<view class="sparring-detail max_page">
|
||
<view class="sparring-detail-loading" v-show="showLoading">
|
||
<view class="loading-img"></view>
|
||
</view>
|
||
<view class="sparring-detail-body">
|
||
<view class="top-box">
|
||
<view class="top-title">
|
||
<view class="back-icon" @click="goBack()"></view>
|
||
{{ detailInfo.traName }}
|
||
</view>
|
||
<view class="top-desc">内容由AI生成</view>
|
||
</view>
|
||
<scroll-view
|
||
:class="[' body-content index-dialog-body', detailInfo.traInterTyp === '01' ? 'talking-type1' : '']"
|
||
:scroll-y="true"
|
||
refresher-default-style="none"
|
||
:scroll-top="scrollTop"
|
||
:show-scrollbar="false"
|
||
:scroll-with-animation="false"
|
||
>
|
||
<view :class="['body-content-role', showRoleInfo ? '' : 'hide-info']">
|
||
<view :class="['role-title']">
|
||
<ImagePreview class="role-title-avatar" :src="detailInfo.ossAddr" :isCache="true"></ImagePreview>
|
||
<view class="role-title-info" @click="showRoleInfo = !showRoleInfo">
|
||
<view class="arrow-r-icon"></view>
|
||
<view class="role-name card-title">
|
||
<text class="card-title-name">{{ detailInfo.chaName }}</text>
|
||
<text class="card-title-age">{{ detailInfo.chaAge }}岁</text>
|
||
<text class="card-title-img">
|
||
<image
|
||
class="card-title-icon"
|
||
v-if="detailInfo.gender === 'm' || detailInfo.gender === '01'"
|
||
src="@/static/images/me/man.png"
|
||
></image>
|
||
<image
|
||
class="card-title-icon"
|
||
v-if="detailInfo.gender === 'f' || detailInfo.gender === '02'"
|
||
src="@/static/images/me/wuman.png"
|
||
></image>
|
||
</text>
|
||
</view>
|
||
<view class="role-desc">
|
||
预计时长: {{ detailInfo.traStartLimit }} ~ {{ detailInfo.traEndLimit }} 分钟
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="role-content">
|
||
<view class="role-content-item">
|
||
<!-- 身份情况 -->
|
||
{{ detailInfo.occupation }}
|
||
</view>
|
||
<view class="role-content-item">
|
||
<!-- 性格特点 -->
|
||
{{ detailInfo.personality }}
|
||
</view>
|
||
<view class="role-content-item">
|
||
<!-- 提问思路 -->
|
||
{{ detailInfo.thoughtProcess }}
|
||
</view>
|
||
<view class="role-content-item">
|
||
<!-- 人物描述 -->
|
||
{{ detailInfo.chaDesc }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="body-scene">
|
||
<view class="body-scene-title">场景描述</view>
|
||
<!-- sceneDesc -->
|
||
{{ detailInfo.sceneDesc }}
|
||
</view>
|
||
<view class="talking-desc">
|
||
陪练角色不具备主动终止场景陪练的功能,当用户完成预设陪练目标时,需由用户手动发起结束陪练操作。
|
||
</view>
|
||
<view class="talking-box" v-if="detailInfo.traInterTyp !== '01'">
|
||
<view class="tip-text">-请点击下方按钮开始{{ detailInfo.traInterTypDesc }}</view>
|
||
</view>
|
||
<view class="talking-box" v-else>
|
||
<TalkingItem
|
||
v-for="(item, index) in talkingList"
|
||
:talkingType="item.type"
|
||
:talkingInfo="item"
|
||
:roleInfo="detailInfo"
|
||
:traId="traId"
|
||
:execId="execId"
|
||
:isExam="talkingType === '02'"
|
||
:isLast="index + 1 === talkingList.length"
|
||
:isAnswering="!answerIsOver"
|
||
:activeVoiceId="activeVoiceTalkingItemId"
|
||
@handleEvents="talkItemEvents"
|
||
></TalkingItem>
|
||
</view>
|
||
</scroll-view>
|
||
<view class="over-btn-box" v-if="detailInfo.traInterTyp === '01'">
|
||
<view class="over-btn" @click="overTalking">结束陪练</view>
|
||
</view>
|
||
<TouchBtn
|
||
class="body-bottom"
|
||
@uploadVoice="uploadRecordNow"
|
||
@startRecord="changePlayItemId('')"
|
||
:isLoading="!answerIsOver"
|
||
:isDisabled="false"
|
||
v-if="detailInfo.traInterTyp === '01'"
|
||
/>
|
||
<view class="body-bottom" v-else>
|
||
<view class="body-bottom-btn" @click="beforeToTalking">
|
||
<view class="center-text">
|
||
<image
|
||
class="type-icon"
|
||
src="@/static/images/sparring/video-icon.png"
|
||
v-if="detailInfo.traInterTyp === '03'"
|
||
></image>
|
||
<image
|
||
class="type-icon"
|
||
src="@/static/images/sparring/phone-icon.png"
|
||
v-else-if="detailInfo.traInterTyp === '02'"
|
||
></image>
|
||
<image v-else class="type-icon" src="@/static/images/sparring/talk-icon.png"></image>
|
||
{{ detailInfo.traInterTypDesc }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<badge ref="badgeRef"></badge>
|
||
<points ref="pointsRef"></points>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, unref, onMounted, computed, nextTick } from 'vue';
|
||
import { onShow, onHide, onLoad, onUnload, onLaunch, onBackPress } from '@dcloudio/uni-app';
|
||
import common from '@/common/common';
|
||
import { getPhoneEnvBool } from '@/common/common';
|
||
import TouchBtn from './components/touchBtn.vue';
|
||
import ImagePreview from '@/components/image-preview/image-preview.vue';
|
||
import { commonUploadVoiceFile } from '@/api/common.js';
|
||
import { queryTraPartnerCharacterInfoById, partnerChatReportTrigger, checkTraPartnerInfoById } from '@/api/sparring.js';
|
||
import { useSocketStore } from '@/store/socket.js';
|
||
import { useStorageStore } from '@/store/storage.js';
|
||
import { storeToRefs } from 'pinia';
|
||
import TalkingItem from './components/talking-item.vue';
|
||
import badge from '@/components/points-and-badge/badge';
|
||
import points from '@/components/points-and-badge/points';
|
||
import usePointsAndBadge from '@/components/points-and-badge/usePointsAndBadge';
|
||
|
||
import { initRecord } from '@/composables/useExamSubject.js';
|
||
import permissionApi from '@/common/permission';
|
||
const { pointAndBadgesRun, badgeRef, pointsRef } = usePointsAndBadge();
|
||
const socketStore = useSocketStore();
|
||
const { SocketObj } = storeToRefs(socketStore);
|
||
|
||
const traId = ref('');
|
||
const chaId = ref('');
|
||
const talkingType = ref('');
|
||
// const badgeRef = ref(null);
|
||
// const pointsRef = ref(null);
|
||
const isPreview = ref(false);
|
||
const detailInfo = ref({});
|
||
const currentIndex = ref(0);
|
||
const showRoleInfo = ref(false);
|
||
const showLoading = ref(true);
|
||
const talkingList = ref([]);
|
||
// {
|
||
// type: 'answer',
|
||
// talkingText: 'asad我是回答内容',
|
||
// isLoading: false,
|
||
// id: new Date().getTime(),
|
||
// },
|
||
const askData = ref({});
|
||
const execId = ref('');
|
||
const answerIsOver = ref(true);
|
||
|
||
const getDetailInfo = () => {
|
||
queryTraPartnerCharacterInfoById({
|
||
traId: traId.value,
|
||
chaId: chaId.value
|
||
}).then((res) => {
|
||
console.log(res);
|
||
detailInfo.value = {
|
||
...res.body
|
||
};
|
||
if (detailInfo.value.traInterTyp === '01') {
|
||
initsocketTask();
|
||
}
|
||
setTimeout(() => {
|
||
showLoading.value = false;
|
||
}, Math.random() * 1000 + 500);
|
||
});
|
||
};
|
||
const scrollTop = ref(99999);
|
||
const scrollToBottomNow = (time = 100) => {
|
||
nextTick(() => {
|
||
setTimeout(() => {
|
||
scrollTop.value += 100;
|
||
scrollTop.value += 100;
|
||
}, time);
|
||
});
|
||
};
|
||
const uploadRecordNow = (voicePath, voiceTime) => {
|
||
console.log(voicePath, voiceTime);
|
||
if (!execId.value) {
|
||
common.show('提示', '网络连接失败,请重新加载', false).then((res) => {
|
||
if (res) {
|
||
common.redirectTo(
|
||
'/pages/sparring/tip?traId=' +
|
||
traId.value +
|
||
'&chaId=' +
|
||
chaId.value +
|
||
'&type=' +
|
||
talkingType.value +
|
||
'&isPreview=' +
|
||
(isPreview.value ? '1' : '')
|
||
);
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
//#ifndef APP-PLUS
|
||
// h5 假数据
|
||
// #endif
|
||
//#ifdef APP-PLUS
|
||
talkingList.value.push({
|
||
type: 'question',
|
||
talkingText: '',
|
||
isLoading: true
|
||
});
|
||
scrollToBottomNow();
|
||
// 设为提问中状态
|
||
answerIsOver.value = false;
|
||
commonUploadVoiceFile(voicePath, '/trapractice/traPartnerChat/voiceTrans', {})
|
||
.then((_res) => {
|
||
if (!!(_res.body.transContent || '').trim()) {
|
||
askData.value = {
|
||
execId: execId.value,
|
||
intrctWay: '02', //01-文本;02-语音;03-图片
|
||
intrctContent: _res.body.transContent,
|
||
fileId: _res.body.fileId,
|
||
ossFileAddr: _res.body.ossFileAddr,
|
||
talkingVoice: voicePath,
|
||
voiceTime: voiceTime
|
||
};
|
||
sendMessage({
|
||
commond: 'ASK',
|
||
body: askData.value
|
||
});
|
||
} else {
|
||
answerIsOver.value = true;
|
||
talkingList.value.pop();
|
||
uni.showToast({
|
||
title: '未识别到文字',
|
||
icon: 'none',
|
||
duration: 1000
|
||
});
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
answerIsOver.value = true;
|
||
talkingList.value.pop();
|
||
uni.showToast({
|
||
title: '系统异常,请联系管理员',
|
||
icon: 'none',
|
||
duration: 1000
|
||
});
|
||
});
|
||
// #endif
|
||
};
|
||
const beforeToTalking = () => {
|
||
if (isPreview.value) {
|
||
toTalking();
|
||
return;
|
||
}
|
||
checkTraPartnerInfoById({
|
||
traId: traId.value
|
||
}).then((res) => {
|
||
if (res.body.inRange) {
|
||
toTalking();
|
||
} else {
|
||
common.show('提示', res.body.message, false);
|
||
}
|
||
});
|
||
};
|
||
const toTalking = async () => {
|
||
try {
|
||
//#ifdef APP-PLUS
|
||
console.log('申请权限');
|
||
try {
|
||
await permissionApi.judgeIosPermission('record');
|
||
if (detailInfo.value.traInterTyp === '03') {
|
||
await permissionApi.judgeIosPermission('camera');
|
||
}
|
||
} catch (e) {
|
||
console.error('摄像头或者麦克风权限申请失败:', e);
|
||
return;
|
||
}
|
||
//#endif
|
||
common.setPageCache('tipMsgsceneDesc', {
|
||
ossAddr: detailInfo.value.ossAddr,
|
||
chaName: detailInfo.value.chaName,
|
||
traInterTyp: detailInfo.value.traInterTyp,
|
||
traInterTypDesc: detailInfo.value.traInterTypDesc
|
||
});
|
||
let _gotUrl;
|
||
if (detailInfo.value.traInterTyp === '02') {
|
||
_gotUrl = '/pages/sparring/talk';
|
||
} else if (detailInfo.value.traInterTyp === '03') {
|
||
_gotUrl = '/pages/sparring/talk'; // 没改好,暂时跳到一个页
|
||
}
|
||
common.redirectTo(
|
||
_gotUrl +
|
||
'?traId=' +
|
||
traId.value +
|
||
'&chaId=' +
|
||
chaId.value +
|
||
'&type=' +
|
||
talkingType.value +
|
||
'&traInterTyp=' +
|
||
detailInfo.value.traInterTyp +
|
||
'&isPreview=' +
|
||
(isPreview.value ? '1' : '0')
|
||
);
|
||
} catch (err) {
|
||
console.error('申请权限失败');
|
||
}
|
||
};
|
||
const activeVoiceTalkingItemId = ref('');
|
||
// 关闭播放状态
|
||
const changePlayItemId = (id = '') => {
|
||
activeVoiceTalkingItemId.value = id;
|
||
};
|
||
|
||
const talkItemEvents = ({ type, data, id, info = {} }) => {
|
||
switch (type) {
|
||
case 'changePlay':
|
||
activeVoiceTalkingItemId.value = id;
|
||
break;
|
||
case 'scrollToBottom':
|
||
scrollToBottomNow();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
};
|
||
|
||
const watchFlag = ref(1);
|
||
const showModelComfirm = ref(false);
|
||
const reconcatNum = ref(0);
|
||
const answerText = ref('');
|
||
const touchBtnCallBack = ref(null);
|
||
let isLeave = false;
|
||
const initsocketTask = () => {
|
||
let _src = isPreview.value ? '/trapractice/previewsocket/open' : '/trapractice/partnersocket/open';
|
||
socketStore.creatSocket(_src + '?summary=');
|
||
// unref(SocketObj).on('open', (res)=>{
|
||
// if(!answerIsOver.value){
|
||
// sendMessage({
|
||
// "commond" : 'ASK-RE-START',
|
||
// "body" : {
|
||
// execId: execId.value,
|
||
// seqNo: seqNo.value,
|
||
// answerContent: answerText.value
|
||
// }
|
||
// })
|
||
// }
|
||
// })
|
||
unref(SocketObj).on('error', () => {
|
||
if (watchFlag.value === 1 || showModelComfirm.value) return;
|
||
if (reconcatNum.value === 5) {
|
||
common.msg('系统网络异常,请稍后再试!');
|
||
common.redirectTo(`/pages/index/dialog`);
|
||
return;
|
||
}
|
||
showModelComfirm.value = true;
|
||
reconcatNum.value += 1;
|
||
common
|
||
.show('提示信息', '网络环境不稳定,请重试!', false, '', '确认')
|
||
.then((res) => {
|
||
overNow(() => {
|
||
reconcatNum.value += 1;
|
||
// common.redirectTo(`/pages/index/dialog`);
|
||
socketStore?.closeSocket();
|
||
common.redirectTo(
|
||
'/pages/sparring/result?isOver=1&traId=' +
|
||
traId.value +
|
||
'&execId=' +
|
||
execId.value +
|
||
'&type=' +
|
||
talkingType.value +
|
||
'&isPreview=' +
|
||
(isPreview.value ? '1' : '')
|
||
);
|
||
});
|
||
})
|
||
.finally(() => {
|
||
showModelComfirm.value = false;
|
||
});
|
||
});
|
||
unref(SocketObj).on('message', (res) => {
|
||
const { rtnCode, body, commond } = JSON.parse(res.data);
|
||
let _id = new Date().getTime() + 'id';
|
||
if (rtnCode === '0000') {
|
||
if (commond === 'ASK-OPEN') {
|
||
console.log('ASK-OPEN!', body);
|
||
// 新连接
|
||
sendMessage({
|
||
commond: 'ASK-START',
|
||
body: {
|
||
traId: traId.value,
|
||
chaId: chaId.value,
|
||
traTyp: talkingType.value,
|
||
execId: execId.value || ''
|
||
}
|
||
});
|
||
sendMessage({
|
||
commond: 'ASK-PING',
|
||
body: {
|
||
execId: execId.value || ''
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
if (commond === 'ASK-START') {
|
||
console.log('开启对话!', body);
|
||
execId.value = body.execId;
|
||
return;
|
||
}
|
||
if (commond === 'ASK') {
|
||
console.log('发送问题成功!');
|
||
console.log(body);
|
||
console.log(talkingList.value[talkingList.value.length - 1].isLoading);
|
||
if (talkingList.value.length > 0 && talkingList.value[talkingList.value.length - 1].isLoading) {
|
||
talkingList.value = talkingList.value.filter((t) => {
|
||
return !(t.type === 'question' && t.isLoading);
|
||
});
|
||
}
|
||
// seqNo.value = body.seqNo;
|
||
// touchBtnCallBack.value && touchBtnCallBack.value();
|
||
// touchBtnCallBack.value = null;
|
||
talkingList.value.push({
|
||
type: 'question',
|
||
talkingText: body.content,
|
||
isLoading: false,
|
||
intrctWay: '02',
|
||
id: _id + 'qns',
|
||
...body,
|
||
talkingVoice: askData.value.talkingVoice
|
||
});
|
||
talkingList.value.push({
|
||
type: 'answer',
|
||
isLoading: true,
|
||
id: _id + 'loading'
|
||
});
|
||
scrollToBottomNow();
|
||
return;
|
||
}
|
||
if (commond === 'ASK-STOP') {
|
||
console.log('停止回答标记!');
|
||
stopAnswerCallBack.value && stopAnswerCallBack.value(askData.value);
|
||
setTimeout(() => {
|
||
stopAnswerCallBack.value = null;
|
||
answerIsOver.value = true;
|
||
}, 10);
|
||
return;
|
||
}
|
||
if (commond === 'ASK-ANSWER') {
|
||
if (body.event === 'start') {
|
||
answerIsOver.value = false;
|
||
answerText.value = '';
|
||
// talkingList.value.pop();
|
||
talkingList.value = talkingList.value.filter((t) => {
|
||
return !(t.type === 'answer' && t.isLoading);
|
||
});
|
||
talkingList.value.push({
|
||
type: 'answer',
|
||
talkingText: answerText.value,
|
||
isLoading: false,
|
||
execLogId: body.execLogId || '',
|
||
id: _id + 'ans',
|
||
...body,
|
||
askData: {
|
||
...askData.value
|
||
}
|
||
});
|
||
} else if (body.event === 'token') {
|
||
answerIsOver.value = false;
|
||
answerText.value += body.data;
|
||
talkingList.value[talkingList.value.length - 1].talkingText = answerText.value;
|
||
} else if (body.event === 'end') {
|
||
answerIsOver.value = true;
|
||
} else if (body.event === 'recordAi') {
|
||
talkingList.value[talkingList.value.length - 1].execLogId = body.execLogId;
|
||
}
|
||
scrollToBottomNow();
|
||
return;
|
||
}
|
||
if (commond === 'ASK-RE-ANSWER') {
|
||
// console.log('开始继续回答!')
|
||
if (body.event === 'start') {
|
||
answerIsOver.value = false;
|
||
answerText.value = '';
|
||
} else if (body.event === 'token') {
|
||
answerIsOver.value = false;
|
||
answerText.value = body.data;
|
||
} else if (body.event === 'end') {
|
||
answerIsOver.value = true;
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (commond === 'ASK-ERR') {
|
||
console.log('提问失败,系统异常!');
|
||
return;
|
||
}
|
||
if (commond === 'ASK-OVER') {
|
||
console.log(body);
|
||
console.log('陪练已结束,去结果页面!');
|
||
socketStore?.closeSocket();
|
||
common.redirectTo(
|
||
'/pages/sparring/result?isOver=1&traId=' +
|
||
traId.value +
|
||
'&execId=' +
|
||
execId.value +
|
||
'&type=' +
|
||
talkingType.value +
|
||
'&isPreview=' +
|
||
(isPreview.value ? '1' : '')
|
||
);
|
||
return;
|
||
}
|
||
if (commond === 'ASK-PONG') {
|
||
console.log('PONG');
|
||
if (isLeave) return;
|
||
setTimeout(() => {
|
||
sendMessage({
|
||
commond: 'ASK-PING',
|
||
body: {
|
||
execId: execId.value || ''
|
||
}
|
||
});
|
||
}, 30000);
|
||
}
|
||
} else {
|
||
if (['0005', 'QQ0005'].includes(res.rtnCode)) {
|
||
goto_login_fun();
|
||
}
|
||
}
|
||
});
|
||
watchFlag.value += 1;
|
||
};
|
||
const goBack = () => {
|
||
if (detailInfo.value.traInterTyp === '01') {
|
||
overTalking();
|
||
} else {
|
||
common.navigateBack();
|
||
}
|
||
};
|
||
const overTalking = () => {
|
||
common.show('提示', '确定结束陪练吗?').then((res) => {
|
||
if (res) {
|
||
overNow();
|
||
}
|
||
});
|
||
};
|
||
const overNow = (cb = () => {}) => {
|
||
partnerChatReportTrigger({
|
||
execId: execId.value,
|
||
traId: traId.value,
|
||
talkingType: isPreview.value ? 'preview' : 'practice'
|
||
})
|
||
.then((res) => {
|
||
watchFlag.value = 1;
|
||
sendMessage({
|
||
commond: 'ASK-STOP',
|
||
body: {
|
||
execId: execId.value || ''
|
||
}
|
||
});
|
||
socketStore?.closeSocket();
|
||
changePlayItemId('');
|
||
common.redirectTo(
|
||
'/pages/sparring/result?isOver=1&traId=' +
|
||
traId.value +
|
||
'&execId=' +
|
||
execId.value +
|
||
'&type=' +
|
||
talkingType.value +
|
||
'&isPreview=' +
|
||
(isPreview.value ? '1' : '')
|
||
);
|
||
// pointAndBadgesRun(talkingType.value === '01'? '07': '08', '', ()=>{
|
||
// common.redirectTo('/pages/sparring/result?isOver=1&traId=' + traId.value + '&execId=' + execId.value + '&type=' + talkingType.value + '&isPreview=' + (isPreview.value ?'1':''))
|
||
// })
|
||
})
|
||
.catch(() => {
|
||
cb();
|
||
});
|
||
};
|
||
const sendMessage = (data) => {
|
||
unref(SocketObj).send(data);
|
||
if (data.commond == 'ASK-PING') {
|
||
console.log('PING');
|
||
}
|
||
};
|
||
// let timer = null
|
||
//#ifdef APP-PLUS
|
||
onShow(() => {
|
||
isLeave = false;
|
||
// timer = setInterval(() => {
|
||
// sendMessage({
|
||
// commond: 'ASK-PING',
|
||
// body: {
|
||
// execId: execId.value || ''
|
||
// }
|
||
// }, 1000)
|
||
// })
|
||
});
|
||
onHide(() => {
|
||
isLeave = true;
|
||
// clearInterval(timer)
|
||
// timer = null
|
||
});
|
||
// #endif
|
||
onLoad((params) => {
|
||
traId.value = params.traId;
|
||
chaId.value = params.chaId;
|
||
talkingType.value = params.type;
|
||
isPreview.value = params.isPreview === '1';
|
||
getDetailInfo();
|
||
console.log('onLoad');
|
||
//#ifdef APP-PLUS
|
||
plus.screen.lockOrientation('portrait-primary');
|
||
// #endif
|
||
});
|
||
onUnload(() => {
|
||
console.log('onUnload');
|
||
watchFlag.value = 1;
|
||
sendMessage({
|
||
commond: 'ASK-STOP',
|
||
body: {
|
||
execId: execId.value || ''
|
||
}
|
||
});
|
||
if (detailInfo.value.traInterTyp === '01') {
|
||
socketStore?.closeSocket();
|
||
}
|
||
execId.value = '';
|
||
});
|
||
onLaunch(() => {
|
||
console.log('onLaunch');
|
||
});
|
||
onMounted(() => {
|
||
// getDetailInfo()
|
||
});
|
||
onBackPress((res) => {
|
||
if (res.from === 'backbutton') {
|
||
goBack();
|
||
return true;
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.sparring-detail {
|
||
position: relative;
|
||
overflow-x: hidden;
|
||
overflow-y: auto;
|
||
flex-direction: column;
|
||
background-image: url(@/static/images/sparring/bg.png);
|
||
background-size: cover;
|
||
|
||
// background-color: #f2f6fd;
|
||
.sparring-detail-loading {
|
||
position: fixed;
|
||
z-index: 20;
|
||
height: 100vh;
|
||
width: 100vw;
|
||
background-image: url(@/static/images/sparring/bg.png);
|
||
|
||
.loading-img {
|
||
position: absolute;
|
||
width: 380rpx;
|
||
height: 590rpx;
|
||
top: 40%;
|
||
transform: translateY(-50%) translateX(-50%);
|
||
left: 50%;
|
||
padding-top: 540rpx;
|
||
line-height: 50rpx;
|
||
box-sizing: border-box;
|
||
text-align: center;
|
||
background-image: url(@/static/images/sparring/waiting.png);
|
||
background-repeat: no-repeat;
|
||
background-size: cover;
|
||
}
|
||
}
|
||
|
||
.sparring-detail-body {
|
||
position: absolute;
|
||
overflow-x: hidden;
|
||
overflow-y: hidden;
|
||
left: 0;
|
||
top: 0;
|
||
height: 100vh;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
// background-color: #f6f8ff;
|
||
z-index: 1;
|
||
padding: calc(var(--status-bar-height) + 90rpx) 0 180rpx;
|
||
|
||
.top-box {
|
||
height: 90rpx;
|
||
width: 100%;
|
||
position: fixed;
|
||
top: var(--status-bar-height);
|
||
left: 0;
|
||
z-index: 2;
|
||
|
||
.top-desc {
|
||
position: absolute;
|
||
bottom: 0;
|
||
font-size: 18rpx;
|
||
color: #999;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
}
|
||
|
||
.top-title {
|
||
height: 90rpx;
|
||
// background-color: red;
|
||
text-align: center;
|
||
font-size: 33rpx;
|
||
padding: 10rpx 100rpx 0;
|
||
line-height: 46rpx;
|
||
box-sizing: border-box;
|
||
font-weight: 500;
|
||
color: #000;
|
||
position: relative;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
|
||
// margin-bottom: 23rpx;
|
||
.arrow-icon {
|
||
position: absolute;
|
||
left: 36rpx;
|
||
top: 20rpx;
|
||
color: #fff !important;
|
||
}
|
||
|
||
.back-icon {
|
||
position: absolute;
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
cursor: pointer;
|
||
left: 50rpx;
|
||
top: 33rpx;
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.back-icon::before,
|
||
.back-icon::after {
|
||
content: '';
|
||
position: absolute;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.back-icon::after {
|
||
top: 25%;
|
||
left: 25%;
|
||
width: 40%;
|
||
height: 40%;
|
||
border-top: 4rpx solid #000;
|
||
border-left: 4rpx solid #000;
|
||
transform: rotate(-45deg);
|
||
}
|
||
}
|
||
}
|
||
|
||
.body-content {
|
||
height: 100%;
|
||
padding: 10rpx 24rpx 20rpx;
|
||
box-sizing: border-box;
|
||
overflow-y: auto;
|
||
|
||
&.talking-type1 {
|
||
padding: 10rpx 24rpx 140rpx;
|
||
}
|
||
|
||
.body-content-role {
|
||
background-color: #fff;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
margin-bottom: 30rpx;
|
||
|
||
&.hide-info {
|
||
.arrow-r-icon::after {
|
||
transform: rotate(225deg) !important;
|
||
}
|
||
|
||
.role-content {
|
||
max-height: 0rpx !important;
|
||
padding-bottom: 0rpx !important;
|
||
}
|
||
}
|
||
|
||
.role-title {
|
||
height: 154rpx;
|
||
position: relative;
|
||
padding-left: 180rpx;
|
||
|
||
&-avatar {
|
||
width: 92rpx;
|
||
height: 92rpx;
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 42rpx;
|
||
transform: translateY(-50%);
|
||
border-radius: 50%;
|
||
overflow: hidden;
|
||
}
|
||
|
||
&-info {
|
||
position: relative;
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
padding-top: 34rpx;
|
||
|
||
.role-name {
|
||
width: 100%;
|
||
|
||
&.card-title {
|
||
display: flex;
|
||
font-size: 29rpx;
|
||
line-height: 44rpx;
|
||
font-weight: 500;
|
||
color: #000;
|
||
overflow: hidden;
|
||
text-align: left;
|
||
justify-content: start;
|
||
margin-bottom: 8rpx;
|
||
|
||
.card-title-name {
|
||
margin-right: 20rpx;
|
||
line-height: 44rpx;
|
||
}
|
||
|
||
.card-title-age {
|
||
margin-right: 20rpx;
|
||
line-height: 44rpx;
|
||
}
|
||
|
||
.card-title-img {
|
||
height: 44rpx;
|
||
width: 30rpx;
|
||
padding: 5rpx 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.card-title-icon {
|
||
height: 30rpx;
|
||
width: 30rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.role-desc {
|
||
width: 100%;
|
||
font-size: 25rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.arrow-r-icon {
|
||
position: absolute;
|
||
width: 36rpx;
|
||
height: 36rpx;
|
||
cursor: pointer;
|
||
right: 50rpx;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.arrow-r-icon::before,
|
||
.arrow-r-icon::after {
|
||
content: '';
|
||
position: absolute;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.arrow-r-icon::after {
|
||
top: 25%;
|
||
left: 25%;
|
||
width: 40%;
|
||
height: 40%;
|
||
border-top: 2rpx solid #000;
|
||
border-left: 2rpx solid #000;
|
||
transform: rotate(135deg);
|
||
}
|
||
}
|
||
}
|
||
|
||
.role-content {
|
||
max-height: 800rpx;
|
||
transition: all 0.3s ease;
|
||
padding-bottom: 12rpx;
|
||
|
||
&-item {
|
||
position: relative;
|
||
padding: 8rpx 46rpx 8rpx 76rpx;
|
||
line-height: 42rpx;
|
||
font-size: 29rpx;
|
||
|
||
&::before {
|
||
content: '';
|
||
display: block;
|
||
background-color: #000;
|
||
width: 12rpx;
|
||
height: 12rpx;
|
||
border-radius: 50%;
|
||
position: absolute;
|
||
left: 46rpx;
|
||
top: 22rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.body-scene {
|
||
background: linear-gradient(209deg, #fefeff 0%, #d7dfff 100%);
|
||
border: 2rpx solid rgba(255, 255, 255, 0.65);
|
||
position: relative;
|
||
line-height: 42rpx;
|
||
font-size: 29rpx;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
padding: 108rpx 46rpx 30rpx;
|
||
|
||
.body-scene-title {
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
background-color: #06f;
|
||
border-radius: 0 0 36rpx 0;
|
||
width: 170rpx;
|
||
height: 78rpx;
|
||
line-height: 78rpx;
|
||
color: #fff;
|
||
text-align: center;
|
||
}
|
||
}
|
||
.talking-desc {
|
||
// padding-top: 24rpx;
|
||
padding: 24rpx 20rpx 0;
|
||
font-size: 24rpx;
|
||
// text-align: center;
|
||
color: #999;
|
||
}
|
||
|
||
.talking-box {
|
||
padding-top: 24rpx;
|
||
|
||
.tip-text {
|
||
color: #7295cb;
|
||
text-align: center;
|
||
font-size: 29rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.over-btn-box {
|
||
position: absolute;
|
||
bottom: 180rpx;
|
||
height: 140rpx;
|
||
padding: 0 23rpx;
|
||
width: 100%;
|
||
|
||
.over-btn {
|
||
float: right;
|
||
width: 194rpx;
|
||
height: 76rpx;
|
||
line-height: 72rpx;
|
||
border: 2rpx solid #06f;
|
||
border-radius: 15rpx;
|
||
text-align: center;
|
||
color: #06f;
|
||
margin-top: 34rpx;
|
||
}
|
||
}
|
||
|
||
.body-bottom {
|
||
height: 180rpx;
|
||
background-color: #fff;
|
||
padding: 36rpx 23rpx 0;
|
||
position: fixed;
|
||
width: 100vw;
|
||
bottom: 0;
|
||
left: 0;
|
||
|
||
&-btn {
|
||
width: 100%;
|
||
height: 92rpx;
|
||
line-height: 92rpx;
|
||
background-color: #06f;
|
||
text-align: center;
|
||
color: #fff;
|
||
font-size: 29rpx;
|
||
border-radius: 23rpx;
|
||
position: relative;
|
||
|
||
.center-text {
|
||
height: 35rpx;
|
||
line-height: 35rpx;
|
||
width: 100%;
|
||
position: absolute;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
|
||
.type-icon {
|
||
width: 35rpx;
|
||
height: 35rpx;
|
||
margin-right: 10rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|