|
|
@@ -34,8 +34,9 @@ import {
|
|
|
} from '@/types/injectionSymbols';
|
|
|
import { useAppStore } from '@/store/appStore';
|
|
|
import { useEnv } from '@/hooks/useEnv';
|
|
|
-import { events } from '@/common/report';
|
|
|
+import { useReport } from '@/hooks/useReport';
|
|
|
|
|
|
+const { report, events } = useReport();
|
|
|
const appStore = useAppStore();
|
|
|
const { platform } = useEnv();
|
|
|
const userStore = useUserStore();
|
|
|
@@ -206,10 +207,11 @@ const handleSubmit = (tempSave: boolean = false) => {
|
|
|
const start = Date.now();
|
|
|
await commitExamineePaper(params);
|
|
|
const costTime = Date.now() - start;
|
|
|
- uni.report(events.examStartSubmitSuccess, getReportData({ time: costTime }));
|
|
|
+ report(events.ExamStartSubmitSuccess, { time: costTime });
|
|
|
if (isSimulationExam.value || isTestExam.value) {
|
|
|
if (!tempSave) {
|
|
|
setTimeout(async () => {
|
|
|
+ report(events.ExamStartExit);
|
|
|
uni.$ie.hideLoading();
|
|
|
await nextTick();
|
|
|
confirmQuit.value = true;
|
|
|
@@ -233,6 +235,7 @@ const handleSubmit = (tempSave: boolean = false) => {
|
|
|
} else if (isPracticeExam.value) {
|
|
|
if (!tempSave) {
|
|
|
setTimeout(async () => {
|
|
|
+ report(events.ExamStartExit);
|
|
|
uni.$ie.hideLoading();
|
|
|
await nextTick();
|
|
|
confirmQuit.value = true;
|
|
|
@@ -249,6 +252,7 @@ const handleSubmit = (tempSave: boolean = false) => {
|
|
|
});
|
|
|
}, 2500);
|
|
|
} else {
|
|
|
+ report(events.ExamStartExit);
|
|
|
uni.$ie.hideLoading();
|
|
|
confirmQuit.value = true;
|
|
|
confirmShowing.value = false;
|
|
|
@@ -312,9 +316,7 @@ const getOpenExamineeWithTimeoutCheck = async (params: Study.OpenExamineeRequest
|
|
|
}
|
|
|
// 上报超时数据,超时时间单位为秒
|
|
|
// 每个时间点如果请求还未返回,都会上报一次
|
|
|
- uni.report(events.ExamStartLoadSlow, getReportData({
|
|
|
- time: timeout
|
|
|
- }));
|
|
|
+ report(events.ExamStartLoadSlow, { time: timeout });
|
|
|
}, timeout) as unknown as number;
|
|
|
timers.push(timer);
|
|
|
});
|
|
|
@@ -357,9 +359,7 @@ const getPaperWithTimeoutCheck = async (params: Study.GetExamPaperRequestDTO) =>
|
|
|
}
|
|
|
// 上报超时数据,超时时间单位为秒
|
|
|
// 每个时间点如果请求还未返回,都会上报一次
|
|
|
- uni.report(events.ExamStartGetPaperSlow, getReportData({
|
|
|
- time: timeout
|
|
|
- }));
|
|
|
+ report(events.ExamStartGetPaperSlow, { time: timeout });
|
|
|
}, timeout) as unknown as number;
|
|
|
timers.push(timer);
|
|
|
});
|
|
|
@@ -380,6 +380,49 @@ const getPaperWithTimeoutCheck = async (params: Study.GetExamPaperRequestDTO) =>
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * 带超时检测的 beginExaminee 请求
|
|
|
+ * 在 3s, 5s, 10s, 15s, 20s 这 5 个时间点检测超时并上报
|
|
|
+ * 每个时间点如果请求还未返回,都会上报一次
|
|
|
+ */
|
|
|
+const beginExamineeWithTimeoutCheck = async (examineeId: number) => {
|
|
|
+ // 超时时间档次(单位:毫秒)
|
|
|
+ const timeoutLevels = [3000, 5000, 10000, 15000, 20000];
|
|
|
+ // 存储所有定时器ID,用于清理
|
|
|
+ const timers: number[] = [];
|
|
|
+ // 请求是否已完成
|
|
|
+ let isCompleted = false;
|
|
|
+
|
|
|
+ // 创建超时检测定时器
|
|
|
+ timeoutLevels.forEach((timeout) => {
|
|
|
+ const timer = setTimeout(() => {
|
|
|
+ // 如果请求已完成,不进行上报
|
|
|
+ if (isCompleted) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 上报超时数据,超时时间单位为秒
|
|
|
+ // 每个时间点如果请求还未返回,都会上报一次
|
|
|
+ report(events.ExamStartBeginExamineeSlow, { time: timeout });
|
|
|
+ }, timeout) as unknown as number;
|
|
|
+ timers.push(timer);
|
|
|
+ });
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 执行请求
|
|
|
+ const result = await beginExaminee(examineeId);
|
|
|
+ // 标记请求已完成
|
|
|
+ isCompleted = true;
|
|
|
+ // 清除所有定时器
|
|
|
+ timers.forEach((timer) => clearTimeout(timer));
|
|
|
+ return result;
|
|
|
+ } catch (error) {
|
|
|
+ // 请求失败时也要清除定时器
|
|
|
+ isCompleted = true;
|
|
|
+ timers.forEach((timer) => clearTimeout(timer));
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
// 1、加载知识点练习数据
|
|
|
const loadPracticeData = async () => {
|
|
|
const { paperType, readonly, practiceInfo } = prevData.value;
|
|
|
@@ -405,13 +448,9 @@ const loadPracticeData = async () => {
|
|
|
data = res.data || {};
|
|
|
const costTime = Date.now() - start;
|
|
|
console.log('开卷用时:', costTime);
|
|
|
- uni.report(events.examStartLoadSuccess, getReportData({
|
|
|
- time: costTime
|
|
|
- }));
|
|
|
+ report(events.ExamStartLoadSuccess, { time: costTime, request: params, response: res.data || {} });
|
|
|
} catch (error) {
|
|
|
- uni.report(events.examStartLoadError, getReportData({
|
|
|
- error: error
|
|
|
- }));
|
|
|
+ report(events.ExamStartLoadError, { error: error });
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -433,8 +472,16 @@ const loadExamData = async () => {
|
|
|
const res = await getExamineeResult(simulationInfo.examineeId);
|
|
|
data = res.data;
|
|
|
} else {
|
|
|
- const res = await beginExaminee(simulationInfo.examineeId);
|
|
|
- data = res.data || {};
|
|
|
+ try {
|
|
|
+ const start = Date.now();
|
|
|
+ const res = await beginExamineeWithTimeoutCheck(simulationInfo.examineeId);
|
|
|
+ data = res.data || {};
|
|
|
+ const costTime = Date.now() - start;
|
|
|
+ report(events.ExamStartBeginExamineeSuccess, { time: costTime, request: { examineeId: simulationInfo.examineeId }, response: res.data || {} });
|
|
|
+ } catch (error) {
|
|
|
+ report(events.ExamStartBeginExamineeError, { error: error });
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
}
|
|
|
if (!data) {
|
|
|
uni.$ie.hideLoading();
|
|
|
@@ -472,22 +519,49 @@ const loadExamData = async () => {
|
|
|
// }
|
|
|
const combinePaperData = async (examinee: Study.Examinee, paperType: EnumPaperType) => {
|
|
|
examineeId.value = examinee.examineeId;
|
|
|
- if (examinee.paperId) {
|
|
|
+ report(events.ExamStartCombineData, {
|
|
|
+ envUser: localStorage.getItem('ie-user'),
|
|
|
+ envApp: localStorage.getItem('ie-app'),
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!examinee.paperId) {
|
|
|
+ report(events.ExamStartGetPaperError, {
|
|
|
+ error: '获取试卷数据失败,没有paperId',
|
|
|
+ examineeId: examinee.examineeId
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第一步:请求试卷数据(单独 try-catch)
|
|
|
+ let res;
|
|
|
+ try {
|
|
|
const start = Date.now();
|
|
|
- const res = await getPaperWithTimeoutCheck({
|
|
|
+ res = await getPaperWithTimeoutCheck({
|
|
|
type: paperType,
|
|
|
id: examinee.paperId
|
|
|
});
|
|
|
const costTime = Date.now() - start;
|
|
|
+ report(events.ExamStartGetPaperSuccess, {
|
|
|
+ time: costTime,
|
|
|
+ paperId: examinee.paperId,
|
|
|
+ paperType: paperType
|
|
|
+ });
|
|
|
+ } catch (error: any) {
|
|
|
+ // 请求失败的错误上报
|
|
|
+ report(events.ExamStartGetPaperError, {
|
|
|
+ error: error
|
|
|
+ });
|
|
|
+ throw error; // 继续抛出,让外层处理
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第二步:处理和组装数据(单独 try-catch)
|
|
|
+ try {
|
|
|
paperData.value = res.data;
|
|
|
paperData.value.questions = restoreQuestion(examinee.questions, res.data.questions);
|
|
|
console.log('初始化数据', paperData.value.questions)
|
|
|
setQuestionList(paperData.value.questions);
|
|
|
setDuration(examinee.duration || 0);
|
|
|
|
|
|
- uni.report(events.examStartGetPaperSuccess, getReportData({
|
|
|
- time: costTime
|
|
|
- }));
|
|
|
await nextTick();
|
|
|
const targetQuestion = flatQuestionList.value.find(item => item.id === prevData.value.questionId);
|
|
|
if (targetQuestion) {
|
|
|
@@ -519,10 +593,16 @@ const combinePaperData = async (examinee: Study.Examinee, paperType: EnumPaperTy
|
|
|
startTime();
|
|
|
}
|
|
|
}
|
|
|
- } else {
|
|
|
- uni.report(events.examStartGetPaperError, getReportData({
|
|
|
- error: '获取试卷数据失败,没有paperId'
|
|
|
- }));
|
|
|
+ report(events.ExamStartCombineDataSuccess, {
|
|
|
+ paperId: examinee.paperId,
|
|
|
+ paperType: paperType
|
|
|
+ });
|
|
|
+ } catch (error: any) {
|
|
|
+ // 数据处理失败的错误上报
|
|
|
+ report(events.ExamStartCombineDataError, {
|
|
|
+ error: error
|
|
|
+ });
|
|
|
+ throw error; // 继续抛出,让外层处理
|
|
|
}
|
|
|
}
|
|
|
const handleSwiperTipNext = () => {
|
|
|
@@ -545,24 +625,18 @@ const loadData = async () => {
|
|
|
loadExamData();
|
|
|
}
|
|
|
} catch (error) {
|
|
|
- uni.report(events.examStartInitError, getReportData(error));
|
|
|
+ report(events.ExamStartInitError, { error });
|
|
|
+ uni.$ie.showToast('加载失败,请稍后重试');
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.$ie.hideLoading();
|
|
|
+ transferBack();
|
|
|
+ }, 1000);
|
|
|
}
|
|
|
};
|
|
|
-const getReportData = (extraData: any = {}) => {
|
|
|
- return {
|
|
|
- pageOptions: prevData.value,
|
|
|
- userInfo: {
|
|
|
- userName: userStore.userInfo.userName,
|
|
|
- phonenumber: userStore.userInfo.phonenumber,
|
|
|
- },
|
|
|
- platform: platform.value,
|
|
|
- extraData,
|
|
|
- createTime: Date.now()
|
|
|
- }
|
|
|
-}
|
|
|
+
|
|
|
onLoad(() => {
|
|
|
console.log(prevData.value)
|
|
|
- uni.report(events.examStartEnter, getReportData());
|
|
|
+ report(events.ExamStartEnter);
|
|
|
loadData();
|
|
|
uni.addInterceptor('navigateBack', {
|
|
|
invoke: (e) => {
|