|
@@ -21,7 +21,7 @@
|
|
|
:leave-active-class="proxy?.animate.dialog.leave">
|
|
|
<div class="time" v-show="needStart && [42].includes(examState)">{{
|
|
|
time.countdownNum
|
|
|
- }}</div>
|
|
|
+ }}</div>
|
|
|
</transition>
|
|
|
<div class="tips" v-if="examState == 41">
|
|
|
<img v-if="parameter.gesture" src="@/assets/images/test/ready1.png" />
|
|
@@ -64,7 +64,7 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <div v-if="examState == 43 && !time.ready">
|
|
|
+ <div v-if="examState == 43 && !time.ready && readyState">
|
|
|
<div class="readyBoxBefore">
|
|
|
<div class="item" v-if="parameter.gesture">
|
|
|
<div><img src="@/assets/images/test/jushou.png" /></div>
|
|
@@ -81,7 +81,8 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <div class="btn" @click="getReady" v-if="needStart && examState == 43 && !time.ready">开 始</div>
|
|
|
+ <div class="btn" @click="getReady" v-if="needStart && examState == 43 && !time.ready && readyState">开 始
|
|
|
+ </div>
|
|
|
<!-- <div v-if="needStart"> -->
|
|
|
<!-- <div class="btn" @click="getOpenOneTestAndStartFace" v-if="examState == 3 || examState == 40">开始识别</div> -->
|
|
|
<!-- <div class="btn" @click="getStopFace" v-if="examState == 41 && !parameter.gesture">停止人脸识别</div> -->
|
|
@@ -103,37 +104,11 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="main-right">
|
|
|
- <div class="title">测试记录</div>
|
|
|
- <ul :ref="reportListRef" @scroll="getScroll($event)">
|
|
|
- <li v-for="(item, index) in reportList" :key="index" @click="openReport(item)">
|
|
|
- <div class="left">
|
|
|
- <div class="pic"><img :src="item.face_pic || item.logo_url" /></div>
|
|
|
- <div class="txt">
|
|
|
- <div>
|
|
|
- <div class="name">{{ item.student_name }}</div>
|
|
|
- <div class="className">{{ item.class_name }}</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="right" v-if="['basketballv1'].includes(parameter.project)">
|
|
|
- <div class="score">{{ proxy?.$utils.runTime(item.result, true, false) }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="right" v-else>
|
|
|
- <div class="score">{{ item.result }}
|
|
|
- </div>
|
|
|
- <div class="unit">{{ unit }}</div>
|
|
|
- </div>
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- <div class="erweima"> <img src="@/assets/images/login/erweima.png" />
|
|
|
- <span>扫码查看详情</span>
|
|
|
- </div>
|
|
|
+ <ReportList ref="reportListRef" :parameter="parameter" :showQRCode="true" />
|
|
|
</div>
|
|
|
</div>
|
|
|
<FaceWindow ref="faceWindowRef" :faceCheckStu="faceCheckStu" :gesture="parameter.gesture" />
|
|
|
<ChooseStudent ref="chooseStudentRef" @returnData="returnStudent" />
|
|
|
- <ReportWindow ref="reportWindowRef" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -147,7 +122,6 @@ const router = useRouter();
|
|
|
const route = useRoute();
|
|
|
const faceWindowRef = ref();
|
|
|
const chooseStudentRef = ref();
|
|
|
-const reportWindowRef = ref();
|
|
|
const reportListRef = ref();
|
|
|
const myInfo: any = localStorage.getItem("userInfo");
|
|
|
const dic: any = dataDictionary;
|
|
@@ -169,15 +143,9 @@ const data = reactive<any>({
|
|
|
backReasonStr: "",//犯规提示
|
|
|
needStart: false,//是否需要按钮
|
|
|
showTestAgain: false,//再测一次按钮
|
|
|
- reportList: [],//测试列表
|
|
|
- studentPage: {
|
|
|
- current: 1,
|
|
|
- size: 10,
|
|
|
- pages: 1,
|
|
|
- }, //学生分页
|
|
|
- debounceTime: '', //防抖状态
|
|
|
+ readyState: true,//倒计时按钮状态
|
|
|
});
|
|
|
-const { timerManager, parameter, time, userInfo, examState, resultId, faceCheckStu, currentResultObj, unit, backReason, backReasonStr, needStart, showTestAgain, reportList, studentPage, debounceTime } = toRefs(data);
|
|
|
+const { timerManager, parameter, time, userInfo, examState, resultId, faceCheckStu, currentResultObj, unit, backReason, backReasonStr, needStart, showTestAgain, readyState } = toRefs(data);
|
|
|
|
|
|
/**
|
|
|
* 接收消息
|
|
@@ -285,7 +253,7 @@ const getStopFace = async () => {
|
|
|
// }
|
|
|
getClearTimer("face");
|
|
|
if (needStart.value) {
|
|
|
- let txt = parameter.value.gesture ? ",请举手开始测试" : ",请准备";
|
|
|
+ let txt = parameter.value.gesture === true ? ",请举手开始测试" : ",请准备";
|
|
|
speckText(faceCheckStu.value.name + txt);
|
|
|
}
|
|
|
await stopFace();
|
|
@@ -476,8 +444,9 @@ const cleanData = () => {
|
|
|
const initProject = () => {
|
|
|
//停止计时
|
|
|
getClearTimer("countdownTimer");
|
|
|
+ //恢复倒计时按钮状态
|
|
|
+ readyState.value = true;
|
|
|
//自动项目定时进入下一步
|
|
|
-
|
|
|
let time = 0;
|
|
|
//控制新建测试的时间,第一次快,之后就慢
|
|
|
if (!faceCheckStu.value.student_id) {
|
|
@@ -525,7 +494,7 @@ const getCounting = (type: string) => {
|
|
|
* 人脸窗口
|
|
|
*/
|
|
|
const getFaceWindow = (data: boolean) => {
|
|
|
- let txt = parameter.value.gesture ? "请举手看摄像头人脸识别" : "请看摄像头进行人脸识别";
|
|
|
+ let txt = parameter.value.gesture === true ? "请举手看摄像头人脸识别" : "请看摄像头进行人脸识别";
|
|
|
speckText(txt);
|
|
|
//data=true为弹出框,data=false为不要弹出框
|
|
|
if (data) {
|
|
@@ -647,8 +616,7 @@ const getAchievement = (data: any) => {
|
|
|
} else {
|
|
|
speckText(faceCheckStu?.value.name + "成绩为" + (chineseNumber(count) || 0) + unit.value + ",请下一位准备!" || "");
|
|
|
}
|
|
|
- studentPage.value.current = 1;
|
|
|
- getReportList();
|
|
|
+ reportListRef.value.getIniReportList();
|
|
|
faceWindowRef.value.open("right");
|
|
|
//然后定时自动关闭
|
|
|
setTimeout(() => {
|
|
@@ -657,56 +625,12 @@ const getAchievement = (data: any) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
- * 成绩列表
|
|
|
-*/
|
|
|
-const getReportList = () => {
|
|
|
- let params: any = {
|
|
|
- exam_name: parameter.value.project,
|
|
|
- page: studentPage.value.current,
|
|
|
- per_page: studentPage.value.size
|
|
|
- };
|
|
|
- proxy?.$http.common.reportList(params).then((res: any) => {
|
|
|
- if (res.data.length > 0) {
|
|
|
- let list = res.data.map((item: any) => {
|
|
|
- let type = parameter.value.project;
|
|
|
- if (type == 'solidball' || type == 'shotball') {
|
|
|
- item.result = item.result / 100
|
|
|
- }
|
|
|
- let result = null;
|
|
|
- if (item.result.toString().indexOf(".") != -1) {
|
|
|
- if (['jump', 'longjump', 'run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1', 'basketballv1'].includes(type)) {
|
|
|
- result = item.result.toFixed(2)
|
|
|
- } else {
|
|
|
- result = item.result.toFixed(1);
|
|
|
- }
|
|
|
- } else {
|
|
|
- result = item.result
|
|
|
- }
|
|
|
- item.result = result;
|
|
|
- return item;
|
|
|
- });
|
|
|
- studentPage.value.current == 1 ?
|
|
|
- (reportList.value = list) :
|
|
|
- reportList.value.push(...list);
|
|
|
- studentPage.value.pages = res.total;
|
|
|
- getPages(res.total);
|
|
|
- }
|
|
|
- });
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * 计算页码
|
|
|
-*/
|
|
|
-const getPages = (data: any) => {
|
|
|
- studentPage.value.pages = Math.ceil(data / studentPage.value.size);
|
|
|
-};
|
|
|
-
|
|
|
/**
|
|
|
* 准备开始
|
|
|
*/
|
|
|
const getReady = () => {
|
|
|
speckCancel();
|
|
|
+ readyState.value = false;
|
|
|
time.value.ready = 5;
|
|
|
speckText(time.value.ready);
|
|
|
timerManager.value.readyTimer = setInterval(() => {
|
|
@@ -720,47 +644,61 @@ const getReady = () => {
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * 查看详情
|
|
|
+ * 输出犯规
|
|
|
*/
|
|
|
-const openReport = (data: any) => {
|
|
|
- reportWindowRef.value.open(parameter.value.project, data);
|
|
|
-};
|
|
|
+watch(() => backReason.value.length, (v) => {
|
|
|
+ backReasonStr.value = backReason.value[backReason.value.length - 1];
|
|
|
+ setTimeout(() => {
|
|
|
+ backReasonStr.value = "";
|
|
|
+ }, 1500)
|
|
|
+}, { immediate: true });
|
|
|
|
|
|
/**
|
|
|
-* 成绩翻页
|
|
|
+ * 播报时间
|
|
|
*/
|
|
|
-const getScroll = (event?: any) => {
|
|
|
- if (studentPage.value.current == studentPage.value.pages) {
|
|
|
+watch(() => time.value.countdownNum, (newData) => {
|
|
|
+ if (examState.value != 42) {
|
|
|
return false;
|
|
|
}
|
|
|
- let obj = event.target;
|
|
|
- let scrollHeight = obj.scrollHeight;
|
|
|
- let scrollTop = obj.scrollTop;
|
|
|
- let clientHeight = obj.clientHeight;
|
|
|
- //提前100高度加载数据
|
|
|
- if (scrollTop + clientHeight + 100 >= scrollHeight) {
|
|
|
- console.log('到底了!')
|
|
|
- //继续加载下一页
|
|
|
- if (debounceTime.value) {
|
|
|
- clearTimeout(debounceTime.value)
|
|
|
+ if (newData >= 30) {
|
|
|
+ if (newData % 30 == 0) {
|
|
|
+ speckText(
|
|
|
+ `还有${newData}秒`
|
|
|
+ );
|
|
|
}
|
|
|
- debounceTime.value = setTimeout(() => {
|
|
|
- studentPage.value.current++;
|
|
|
- getReportList();
|
|
|
- }, 500)
|
|
|
- } else {
|
|
|
- console.log('没到底')
|
|
|
}
|
|
|
-};
|
|
|
+ if (newData == 10) {
|
|
|
+ speckText("还有10秒");
|
|
|
+ }
|
|
|
+ if (newData <= 5) {
|
|
|
+ speckText(newData);
|
|
|
+ }
|
|
|
+}, { immediate: true });
|
|
|
|
|
|
/**
|
|
|
- * 输出犯规
|
|
|
+ * 成绩整数播报
|
|
|
*/
|
|
|
-watch(() => backReason.value.length, (v) => {
|
|
|
- backReasonStr.value = backReason.value[backReason.value.length - 1];
|
|
|
- setTimeout(() => {
|
|
|
- backReasonStr.value = "";
|
|
|
- }, 1500)
|
|
|
+watch(() => currentResultObj, (newData: any, oldData: any) => {
|
|
|
+ if (examState.value != 42 || newData.count <= 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ let project = parameter.value.project;
|
|
|
+ //引体向上比较慢所以都播报
|
|
|
+ if (
|
|
|
+ ["pullup"].includes(project) &&
|
|
|
+ newData.count > 0 &&
|
|
|
+ oldData.back_num == oldData.back_num
|
|
|
+ ) {
|
|
|
+ speckText(newData.count);
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ ["situp", "sidepullup", "jumprope", "jumpingjack"].includes(project) &&
|
|
|
+ newData.count > 0 &&
|
|
|
+ newData.count % 10 == 0 &&
|
|
|
+ oldData.back_num == oldData.back_num
|
|
|
+ ) {
|
|
|
+ speckText(newData.count);
|
|
|
+ }
|
|
|
}, { immediate: true });
|
|
|
|
|
|
onBeforeMount(() => {
|
|
@@ -788,7 +726,6 @@ onBeforeMount(() => {
|
|
|
getMessage(data);
|
|
|
});
|
|
|
initSpeech();
|
|
|
- getReportList();
|
|
|
})
|
|
|
|
|
|
onUnmounted(() => {
|
|
@@ -1211,124 +1148,6 @@ $waiPadding: 6.51rem;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
overflow: hidden;
|
|
|
-
|
|
|
- .title {
|
|
|
- height: 7.05vh;
|
|
|
- line-height: 7.05vh;
|
|
|
- width: 100%;
|
|
|
- text-align: center;
|
|
|
- color: #1A293A;
|
|
|
- font-size: 1.65rem;
|
|
|
- background: radial-gradient(120% 126% at 5% 93%, #8EFFA9 0%, #07FFE7 100%);
|
|
|
- }
|
|
|
-
|
|
|
- ul {
|
|
|
- height: 100%;
|
|
|
- overflow-y: scroll;
|
|
|
-
|
|
|
- li {
|
|
|
- border-bottom: 1px solid #48677E;
|
|
|
- padding: 8px 30px;
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
- cursor: pointer;
|
|
|
-
|
|
|
- &:hover {
|
|
|
- background: rgba(255, 255, 255, 0.4);
|
|
|
- }
|
|
|
-
|
|
|
- .left {
|
|
|
- display: flex;
|
|
|
-
|
|
|
- .pic {
|
|
|
- width: 7.5vh;
|
|
|
- height: 7.5vh;
|
|
|
- border-radius: 50%;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- overflow: hidden;
|
|
|
- box-sizing: border-box;
|
|
|
- border: 1px solid rgba(255, 255, 255, 0.5);
|
|
|
- margin-right: 13px;
|
|
|
-
|
|
|
- img {
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .txt {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
-
|
|
|
- .name {
|
|
|
- color: #F9F9F9;
|
|
|
- font-size: 1.38rem;
|
|
|
- }
|
|
|
-
|
|
|
- .className {
|
|
|
- color: #13ED84;
|
|
|
- font-size: 1.1rem;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- .right {
|
|
|
- display: flex;
|
|
|
- font-weight: bold;
|
|
|
- align-items: center;
|
|
|
-
|
|
|
- .score {
|
|
|
- color: #ffffff;
|
|
|
- font-size: 1.1rem;
|
|
|
- font-family: 'Saira-ExtraBold';
|
|
|
- }
|
|
|
-
|
|
|
- .unit {
|
|
|
- color: #ffffff;
|
|
|
- font-size: 0.8rem;
|
|
|
- margin-left: 2px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- &::-webkit-scrollbar {
|
|
|
- width: 0px;
|
|
|
- }
|
|
|
-
|
|
|
- &::-webkit-scrollbar-thumb {
|
|
|
- border-width: 2px;
|
|
|
- border-radius: 4px;
|
|
|
- border-style: dashed;
|
|
|
- border-color: transparent;
|
|
|
- background-color: rgba(216, 216, 216, 0.8);
|
|
|
- background-clip: padding-box;
|
|
|
- }
|
|
|
-
|
|
|
- &::-webkit-scrollbar-button:hover {
|
|
|
- border-radius: 6px;
|
|
|
- background: rgba(216, 216, 216, 0.8);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .erweima {
|
|
|
- text-align: center;
|
|
|
- padding: 1vh 0;
|
|
|
-
|
|
|
- img {
|
|
|
- width: 5rem;
|
|
|
- }
|
|
|
-
|
|
|
- span {
|
|
|
- display: block;
|
|
|
- color: #FFFFFF;
|
|
|
- font-size: 1.1rem;
|
|
|
- padding-top: 3px;
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
</style>
|