123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- <script setup lang="ts">
- import {
- onlinePracticeCourseListApi,
- onlinePracticeExamListApi,
- } from "@/api/onlinePractice";
- import { WEEKDAY_NAMES } from "@/constants/constants";
- import { store } from "@/store/store";
- import { PracticeExam } from "@/types/student-client";
- import moment from "moment";
- import { SelectOption } from "naive-ui";
- import { onMounted } from "vue";
- import { useRoute, useRouter } from "vue-router";
- const route = useRoute();
- const router = useRouter();
- // exam-list
- let examId: number = $ref();
- let examList = $ref<SelectOption[]>([]);
- async function getExamList() {
- const userId = store.user.id;
- const res = await onlinePracticeExamListApi(userId);
- let exams = res.data || [];
- examList = exams.map((item) => {
- return {
- label: item.name,
- value: item.id,
- };
- });
- }
- // course-list
- let enterButtonClicked = $ref(false);
- let courseList = $ref<PracticeExam[]>([]);
- async function getCourseList() {
- const res = await onlinePracticeCourseListApi(examId);
- courseList = res.data || [];
- }
- async function checkExamInProgress() {
- return Promise.resolve(false);
- }
- async function toEnterPractice(course: PracticeExam) {
- if (enterButtonClicked) return;
- // 有断点或者异常,停止后续处理
- if (await checkExamInProgress().catch(() => true)) return;
- void router.push({
- name: "OnlineExamOverview",
- params: {
- examId: course.examId,
- },
- });
- }
- function toEnterPracticeList(course: PracticeExam) {
- void router.push({
- name: "OnlinePracticeRecord",
- params: {
- examId: course.examId,
- },
- query: {
- examStudentId: course.examStudentId,
- examName: encodeURIComponent(course.examName),
- courseName: encodeURIComponent(course.courseName),
- },
- });
- }
- // transfer
- function weekDayNameTransfer(week: number): string {
- return WEEKDAY_NAMES[week] ? `周${WEEKDAY_NAMES[week]}` : "";
- }
- function courseInBetween(course: PracticeExam) {
- return moment(store.getTimeStamp).isBetween(
- moment(course.startTime),
- moment(course.endTime)
- );
- }
- function courseInCycle(course: PracticeExam) {
- if (!course.examCycleEnabled) return true;
- const weekday = moment(store.getTimeStamp).isoWeekday();
- if (!course.examCycleWeek.includes(weekday)) return false;
- const HHmm = moment(store.getTimeStamp).format("HH:mm");
- return course.examCycleTimeRange.some((range) =>
- range.timeRange.some((v) => HHmm >= v[0] && HHmm <= v[1])
- );
- }
- function courseIsDisabled(course: PracticeExam) {
- return (
- !courseInBetween(course) ||
- course.allowExamCount < 1 ||
- enterButtonClicked ||
- !courseInCycle(course)
- );
- }
- function courseDiableReason(course: PracticeExam) {
- if (!courseInBetween(course)) {
- return "当前时间不在练习开放时间范围";
- } else if (course.allowExamCount < 1) {
- return "无剩余练习次数";
- } else if (enterButtonClicked) {
- return "请稍后点击";
- } else if (!courseInCycle(course)) {
- return "不在练习时间周期内";
- } else {
- return "";
- }
- }
- // init
- async function initData() {
- await getExamList();
- if (route.query.examId) {
- examId = Number(route.query.examId);
- } else {
- examId = examList[0] && (examList[0].value as number);
- }
- void getCourseList();
- }
- onMounted(() => {
- void initData();
- });
- </script>
- <template>
- <div class="qm-mb-20">
- <span>选择考试批次:</span>
- <n-select
- v-model:value="examId"
- class="qm-select"
- :options="examList"
- ></n-select>
- </div>
- <n-table class="n-table-text-center" :singleLine="false">
- <colgroup>
- <col />
- <col />
- <col />
- <col />
- <col />
- <col />
- <col />
- <col width="200px" />
- </colgroup>
- <thead>
- <tr>
- <th>课程</th>
- <th>考试进入时间</th>
- <th>考试时间周期</th>
- <th>练习次数</th>
- <th>最近正确率</th>
- <th>平均正确率</th>
- <th>最高正确率</th>
- <th>操作</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="course in courseList" :key="course.courseCode">
- <td>{{ course.courseName }}</td>
- <td>
- {{ course.startTime }} <br />
- ~ <br />
- {{ course.endTime }}
- </td>
- <td>
- <div v-if="course.examCycleEnabled">
- <p>
- <span
- v-for="(week, index) in course.examCycleWeek"
- :key="index"
- >{{ weekDayNameTransfer(week) }}</span
- >
- </p>
- <p>
- <span
- v-for="(rang, rindex) in course.examCycleTimeRange"
- :key="rindex"
- >
- {{ rang.timeRange[0] }}~{{ rang.timeRange[1] }}
- </span>
- </p>
- </div>
- </td>
- <td>{{ course.practiceCount }}</td>
- <td>{{ course.recentObjectiveAccuracy }}%</td>
- <td>{{ course.aveObjectiveAccuracy }}%</td>
- <td>{{ course.maxObjectiveAccuracy }}%</td>
- <td>
- <n-button
- type="success"
- block
- :disabled="courseIsDisabled(course)"
- :title="courseDiableReason(course)"
- @click="toEnterPractice(course)"
- >进入练习</n-button
- >
- <n-button type="success" block @click="toEnterPracticeList(course)"
- >查看详情</n-button
- >
- </td>
- </tr>
- </tbody>
- </n-table>
- </template>
|