123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- <script setup lang="ts">
- import { OfflineExam } from "@/types/student-client";
- import {
- exportOfflinePaperApi,
- getOfflineCourseApi,
- startOfflineExamApi,
- } from "@/api/offlineExam";
- import { CloudDownload } from "@vicons/ionicons5";
- import { onMounted } from "vue";
- import { store } from "@/store/store";
- import {
- downloadBlobByApi,
- downloadByBlob,
- toBlobByUrl,
- } from "@/utils/download";
- import OfflineExamUploadModal from "./OfflineExamUploadModal.vue";
- interface OfflineExamUploadModalInst {
- open: () => void;
- }
- const OfflineExamUploadModalRef = $ref<OfflineExamUploadModalInst | null>(null);
- const timeDifference = store.sysTime.difference;
- let loading = $ref(false);
- // 科目列表
- let courseList = $ref<OfflineExam[]>();
- let curCourse: OfflineExam = $ref();
- async function getCourseList() {
- const res = await getOfflineCourseApi();
- courseList = res.data || [];
- }
- function checkCourseTime(time: string) {
- return new Date(time).getTime() - Date.now() > timeDifference;
- }
- // 下载离线文件
- async function toDownloadOfflineFile(url: string, name: string) {
- logger({
- cnl: ["local", "server"],
- pgn: "离线考试",
- act: "下载作答",
- });
- if ([".png", ".jpg", ".jpeg"].some((v) => name.endsWith(v))) {
- const blob = await toBlobByUrl(url);
- downloadByBlob(blob, name);
- } else {
- window.location.href = url;
- }
- }
- async function toEnterExam(course: OfflineExam) {
- logger({
- cnl: ["local", "server"],
- pgn: "离线考试",
- act: "抽取试卷",
- ext: {
- examStudentId: course.examStudentId,
- },
- });
- loading = true;
- const res = await startOfflineExamApi(course.examStudentId).catch(
- () => false
- );
- loading = false;
- if (!res) return;
- void getCourseList();
- }
- function toViewPaper(course: OfflineExam) {
- logger({
- cnl: ["local", "server"],
- pgn: "离线考试",
- act: "查看试卷",
- });
- const user = {
- loginName: course.examStudentId,
- backUrl: window.document.location.href,
- isOnlineExam: true,
- };
- window.name = JSON.stringify(user);
- /** 此地址为后台管理系统中的页面, 后台管理系统与学生端页面同域*/
- window.location.href = `/admin/preview_paper/${course.paperId}?isback=true`;
- }
- let downloading = $ref(false);
- async function toDownloadPaper(course: OfflineExam) {
- if (downloading) return;
- logger({
- cnl: ["local", "server"],
- pgn: "离线考试",
- act: "下载试卷",
- });
- downloading = true;
- await downloadBlobByApi(() => {
- return exportOfflinePaperApi(course.paperId);
- }).catch(() => false);
- downloading = false;
- // 由于无法知晓用户是否取消保存,所以此时无法做相应的提示
- // if (result) {
- // $message.success("下载成功!");
- // } else {
- // $message.error("下载失败,请重新尝试!");
- // }
- }
- function toUploadPaper(course: OfflineExam) {
- logger({
- cnl: ["local", "server"],
- pgn: "离线考试",
- act: "上传答案",
- });
- curCourse = course;
- OfflineExamUploadModalRef?.open();
- }
- onMounted(() => {
- void getCourseList();
- });
- </script>
- <template>
- <div class="off-exam-courses">
- <n-table class="n-table-text-center" :singleLine="false">
- <colgroup>
- <col />
- <col />
- <col width="200px" />
- <col />
- <col width="200px" />
- </colgroup>
- <thead>
- <tr>
- <th>课程</th>
- <th>专业</th>
- <th>考试进入时间</th>
- <th>状态</th>
- <th>操作</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(course, index) in courseList" :key="index">
- <td>{{ course.courseName }}</td>
- <td>{{ course.specialtyName }}</td>
- <td>
- <p>{{ course.startTime }}</p>
- <p>~</p>
- <p>{{ course.endTime }}</p>
- </td>
- <td>
- <div v-if="course.offlineFiles">
- <n-button
- v-for="(file, findex) in course.offlineFiles"
- :key="findex"
- :title="file.originalFileName"
- text
- block
- @click="
- toDownloadOfflineFile(
- file.offlineFileUrl,
- file.originalFileName
- )
- "
- >
- <template #icon>
- <n-icon :component="CloudDownload" :size="16"></n-icon>
- </template>
- 下载作答
- </n-button>
- </div>
- <div v-else>未上传</div>
- </td>
- <td>
- <div v-if="course.paperId">
- <n-button type="success" block @click="toViewPaper(course)"
- >查看试卷</n-button
- >
- <n-button
- type="success"
- :loading="downloading"
- :disabled="downloading"
- block
- @click="toDownloadPaper(course)"
- >下载试卷</n-button
- >
- <n-button type="success" block @click="toUploadPaper(course)"
- >上传答案</n-button
- >
- </div>
- <div v-else>
- <div v-if="checkCourseTime(course.startTime)">未开始</div>
- <div v-else-if="!checkCourseTime(course.endTime)">已结束</div>
- <div v-else>
- <n-button
- type="success"
- :loading="loading"
- @click="toEnterExam(course)"
- >
- 抽取试卷
- </n-button>
- </div>
- </div>
- </td>
- </tr>
- </tbody>
- </n-table>
- </div>
- <OfflineExamUploadModal
- ref="OfflineExamUploadModalRef"
- :course="curCourse"
- @modified="getCourseList"
- />
- </template>
|