Merge branch 'develop' of http://25.13.9.101:9000/K17_AITS/tra-app into develop

This commit is contained in:
杨航
2025-09-23 19:00:21 +08:00
11 changed files with 74 additions and 35 deletions
+3
View File
@@ -6,6 +6,7 @@ import common from '@/common/common.js'
const ENV = import.meta.env
export const get_base_url = (url = '') => {
if (ENV.MODE === 'development') { // 开发环境
// #ifdef H5
if (url) {
@@ -20,7 +21,9 @@ export const get_base_url = (url = '') => {
return ENV.VITE_APP_BASE_API_Url
// #endif
} else { // 其他环境,包括生产环境,sit环境,uat环境
return ENV.VITE_APP_BASE_API_Url
// return ENV.VITE_APP_BASE_API_Url
}
}
+2 -1
View File
@@ -176,12 +176,12 @@
};
const playVoice = () => {
// isPlaying.value = true;
console.log('点击播放');
innerAudio.playAudio();
};
let unsubscribe = () => {};
onMounted(() => {
console.log('question的onMounted');
// 2. 监听 Store 中 isPlaying 的变化,实时同步
// unsubscribe = innerAudio.$subscribe((mutation, state) => {
// isPlaying.value = state.isPlaying;
@@ -214,6 +214,7 @@
console.log('去下载oss内容333', props.dataInfo);
if (newVal === '' && props.dataInfo.ossKey) {
// 去下载oss内容
console.log('真下载oss内容');
downloadFile(props.dataInfo.ossKey).then((res) => {
voiceTime.value = '';
innerAudio.setAudioSrc(res.tempFilePath);
+19 -6
View File
@@ -73,7 +73,7 @@
</template>
<script setup>
import {ref, computed, onMounted, nextTick, watch, reactive } from 'vue';
import { ref, computed, onMounted, nextTick, watch, reactive } from 'vue';
import common from '@/common/common';
import permission from '@/common/permission.js';
import { getPhoneEnvBool } from '@/common/common.js';
@@ -133,7 +133,11 @@
const startTimer = ref(null); // 延迟启动的定时器ID
const startFlag = ref(1);
const startRecord = async (obj) => {
try {await initRecord()}catch(err) {return;}
try {
await initRecord();
} catch (err) {
return;
}
if (props.isDisabled) return;
// 开始录音
console.log('开始录音', recordingStatus.value);
@@ -163,9 +167,10 @@
const endTime = Date.now();
const times = Math.max(500 - endTime + startTime, 0);
setTimeout(() => {
popupRef.value.close();
console.log('停止录音');
recorderManager.stop();
recorderManager?.stop();
popupRef.value?.close();
}, times);
}
nextTick(() => (recordingStatus.value = 'not_started'));
@@ -184,7 +189,7 @@
return;
}
popupRef.value?.close();
recordingStatus.value = 'not_started'
recordingStatus.value = 'not_started';
// stopRecord(true); // 在去主动执行一次关闭
console.log('录音结束,时长:', recordDuration, '秒');
emit('submit', 'voice', res.tempFilePath);
@@ -215,6 +220,7 @@
const btnHeight = (windowInfo.screenWidth / 750) * 234;
return touchY.value < safeArea.bottom - btnHeight;
});
const activeNum = ref(1);
const handleMove = (obj) => {
touchY.value = obj.changedTouches[0].pageY;
@@ -224,7 +230,7 @@
inputText.value = text;
return old_text;
};
defineExpose({ clearinputText });
// 发送文本
const showKeyboard = () => {
if (keyboardIsShow.value) {
@@ -249,6 +255,13 @@
console.log('禁用时点击给的提示');
if (props.isDisabled) common.msg(props.disabledText);
};
// 外面调用放弃这次
const give_up = () => {
console.log('调用结束语音回答');
stopRecord(false)
};
defineExpose({ clearinputText, give_up });
</script>
<style lang="scss" scoped>
+10 -5
View File
@@ -12,7 +12,7 @@ const audioStopFun = ref(null)
export const useAudio = () => {
const audioInstance = uni.createInnerAudioContext();
const callbacks = reactive({
onEnded: null, // 播放完成回调
@@ -20,17 +20,23 @@ export const useAudio = () => {
onLoaded: null, // 音频加载完成回调(可获取时长)
onStop: null
})
let isInitialized = false;
const isPlaying = ref(false)
// 加载状态
const isLoading = ref(false)
// 当前播放的音频地址
const currentSrc = ref('')
const errorMsg = ref('')
// 初始化音频实例(确保全局唯一)
const initAudio = () => {
console.log('初始化音频实例(确保全局唯一)');
// if (isInitialized) return;
// isInitialized = true;
bindAudioEvents();
}
const bindAudioEvents = () => {
if (!audioInstance) return;
@@ -101,7 +107,7 @@ export const useAudio = () => {
const setAudioSrc = (src) => {
console.log('预设置音频地址并加载', src);
if (!src || src === currentSrc.value) return; // 地址不变则不重复加载
initAudio();
isLoading.value = true;
currentSrc.value = src;
errorMsg.value = '';
@@ -185,7 +191,6 @@ export const useAudio = () => {
callbacks.onEnded = callback;
}
}
// 注册播放错误回调
const onAudioError = (callback) => {
if (typeof callback === 'function') {
@@ -203,7 +208,7 @@ export const useAudio = () => {
callbacks.onStop = callback;
}
}
initAudio();
return {
isPlaying,
@@ -1,8 +1,8 @@
<template>
<view>
<image :src="imgUrlShow" :mode="mode" @click="showDetail" style="width: 100%; height: 100%"></image>
<uni-popup ref="PopupRef" class="popup" mask-background-color="rgba(0,0,0,.2)" @change="changeShow">
<view class="overlay-box" @click="closePopup">
<uni-popup ref="PopupRef" class="popup" mask-background-color="rgba(0,0,0,.2)" background-color="rgba(0,0,0,.2)" @change="changeShow">
<view class="overlay-box" @click="closePopup" @touchmove.stop>
<image class="detail-img" :src="imgUrlShow" :mode="mode"></image>
</view>
</uni-popup>
+1 -1
View File
@@ -711,7 +711,7 @@
<style lang="scss">
.ai-answer {
width: 100%;
overflow: hidden;
// overflow: hidden;
margin-bottom: 20rpx;
.user-info {
+12 -9
View File
@@ -19,7 +19,7 @@
<view class="question">
<view class="grey">剩余时间</view>
<uv-count-down
class="countdown_time"
class="countdown_time paperData limitTm"
ref="countDownRef"
:time="paperData.limitTm * 1000"
format="HH:mm:ss"
@@ -248,6 +248,7 @@
// 倒计时结束
const finish = (item) => {
touchBtnRef.value?.give_up(); // 调用结束
// 交卷成功,清除缓存
examinationAnswerCacheKey && common.setValue(examinationAnswerCacheKey, null);
// 考试完成事件
@@ -386,7 +387,7 @@
paperData.flagQueryDetail = examination.flagQueryDetail || 'Y';
mode = paperData.examId ? 'PAPERS' : 'CRS'; // 课程考试CRS,考试中心考试PAPERS
// 设置缓存的键的名称
examinationAnswerCacheKey = 'examinationAnswerCache' + paperData.execId;
answerCacheList.value = common.getValue(examinationAnswerCacheKey);
console.log('assaasas', answerCacheList.value);
@@ -424,19 +425,21 @@
}
})();
const my_answer = (() => {
console.log();
const default_return_data = res.qnsTyp==='ES'?{}:[];
try {
// 基础数据校验
if (!paperData || typeof paperData !== 'object') {
return [];
return default_return_data;
}
// 如果不需要缓存,直接返回空数组
if (paperData.isCacheExam === 'N') {
return [];
return default_return_data;
}
// 校验缓存列表是否存在且为对象类型
// if (!answerCacheList.value || typeof answerCacheList.value !== 'object') {
// return [];
// }
if (!answerCacheList.value || typeof answerCacheList.value !== 'object') {
return default_return_data;
}
// 校验问题ID是否有效
// if (!res || typeof res.qnsId === 'undefined') {
// return [];
@@ -448,10 +451,10 @@
return cachedAnswer;
}
// 缓存中不存在时返回空数组
return [];
return default_return_data;
} catch (error) {
console.error('获取my_answer出错:', error);
return []; // 任何异常都返回空数组,保证程序稳定性
return default_return_data; // 任何异常都返回空数组,保证程序稳定性
}
})();
return {
+15 -6
View File
@@ -3,7 +3,7 @@
<nav-bar :is_seat="true"></nav-bar>
<view class="nav-div">
<view class="title ellipsis-text">
{{result.mode==='record'?'考试纪录':'考试结算'}}
{{ result.mode === 'record' ? '考试纪录' : '考试结算' }}
</view>
<view class="back_div" @click="goto_back()">
<view class="back-icon"></view>
@@ -68,7 +68,11 @@
时长{{ formatSecondsToText(result.examLenTm) }}
</view>
<view class="fl1"></view>
<view class="examination" @click="goExamRanking" v-if="result.mode === 'examination' && flagQuery === 'Y'">
<view
class="examination"
@click="goExamRanking"
v-if="result.mode === 'examination' && flagQuery === 'Y'"
>
<view>考试排行榜</view>
<view class="back-icon"></view>
</view>
@@ -106,7 +110,12 @@
<image src="@/static/images/examination/unable_img.png" mode="widthFix" class="img"></image>
<view class="tip">您暂无权限查看此试卷详情</view>
</view>
<view v-if="flagQueryDetail === 'Y'" v-show="index === sheet_index" :class="getStatusClass(index)" v-for="(item, index) in topicList">
<view
v-if="flagQueryDetail === 'Y'"
v-show="index === sheet_index"
:class="getStatusClass(index)"
v-for="(item, index) in topicList"
>
<Subject :item="item" mode="settlement" :clearResult="false" :isPreview="true"></Subject>
</view>
</view>
@@ -236,8 +245,8 @@
const get_result = () => {
// 检查是否已达到最大请求次数
if (requestCount.value >= 15) {
console.log('已达到最大请求次数(15次),停止请求');
if (requestCount.value >= 20) {
console.log('已达到最大请求次数(20次),停止请求');
requestCount.value = 0;
return;
}
@@ -303,7 +312,7 @@
flagQueryDetail.value = e.flagQueryDetail;
flagQuery.value = e.flagQuery;
// if (flagQueryDetail.value === 'Y' || flagQuery.value === 'Y') {
// }
get_result();
});
+3 -1
View File
@@ -73,6 +73,7 @@
import type_02 from '@/static/images/messageNotification/type_02.png';
import type_03 from '@/static/images/messageNotification/type_03.png';
import type_04 from '@/static/images/messageNotification/type_04.png';
import type_05 from '@/static/images/messageNotification/type_05.png';
import useZpaging from '@/composables/useZpaging.js';
const { pagingRef, queryList, data_list, reload } = useZpaging({
fetchFunction: queryTraPersonalMessageNoticePaging
@@ -81,7 +82,8 @@
'01': type_01,
'02': type_02,
'03': type_03,
'04': type_04
'04': type_04,
'05': type_05
};
const readLoading = ref(false);
const offset = ref(0);