123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- <template>
- <div class="review">
- <div class="review-head">
- <h2 v-if="reviewStore.curTask" class="review-title">
- {{ reviewStore.curTask.examNumber }} - {{ reviewStore.curTask.name }} -
- CET4
- </h2>
- <div class="review-stat">
- <p class="color-success">
- <CheckCircleFilled />已处理:{{ progress.finishCount }}
- </p>
- <p class="color-error">
- <CloseCircleFilled />未处理:{{ progress.todoCount }}
- </p>
- </div>
- <div class="review-prev">
- <a-button v-if="reviewStore.tabKey === 'review'" :disabled="loading">
- <template #icon><ArrowLeftOutlined /></template> 上一个
- </a-button>
- </div>
- </div>
- <!-- body -->
- <div class="review-body">
- <ReviewImage />
- <!-- ReviewMarkPan -->
- <ReviewMarkPan
- v-if="reviewStore.curTask"
- :task-info="{
- examNumber: reviewStore.curTask.examNumber,
- name: reviewStore.curTask.name,
- }"
- @mark="onMark"
- />
- </div>
- <!-- action -->
- <ReviewAction @mark="onMark" @reset="onReset" @search="onSearch" />
- <!-- reset confirm -->
- <ResetConfirmDialog
- ref="resetConfirmDialogRef"
- :subject="resetSubject"
- @confirm="onResetConfirm"
- />
- </div>
- </template>
- <script setup lang="ts">
- import { computed, ref, reactive, onMounted, watch } from "vue";
- import {
- CheckCircleFilled,
- CloseCircleFilled,
- ArrowLeftOutlined,
- } from "@ant-design/icons-vue";
- import { message } from "ant-design-vue";
- import {
- reviewTaskList,
- reviewTaskReset,
- reviewTaskSave,
- reviewProgress,
- } from "@/ap/review";
- import { ReviewTaskListItem } from "@/ap/types/review";
- import { SubjectItem } from "@/ap/types/base";
- import { useUserStore, useReviewStore } from "@/store";
- import useLoading from "@/hooks/useLoading";
- import ReviewAction from "./ReviewAction.vue";
- import ReviewImage from "./ReviewImage.vue";
- import ResetConfirmDialog from "./ResetConfirmDialog.vue";
- import ReviewMarkPan from "./ReviewMarkPan.vue";
- const userStore = useUserStore();
- const reviewStore = useReviewStore();
- defineOptions({
- name: "review",
- });
- // 任务进度
- const progress = ref({
- finishCount: 0,
- todoCount: 0,
- });
- async function updateProgress() {
- const res = await reviewProgress({ examId: userStore.curExam.id });
- progress.value = res || {};
- }
- // 任务相关
- const searchModel = reactive({
- examId: userStore.curExam.id,
- subjectCode: "",
- });
- const { loading, setLoading } = useLoading();
- const dataList = ref<ReviewTaskListItem[]>([]);
- const curTaskIndex = ref(0);
- async function getTasks() {
- // TODO:假设一次取3个
- const res = await reviewTaskList(searchModel);
- dataList.value = res || [];
- }
- function setCurTask() {
- reviewStore.setInfo({ curTask: dataList.value[curTaskIndex.value] });
- }
- async function getNextTask() {
- if (curTaskIndex.value >= dataList.value.length - 1) {
- await getTasks();
- if (!dataList.value.length) {
- message.error("没有下一个了!");
- reviewStore.setInfo({ curTask: null });
- return;
- }
- curTaskIndex.value = 0;
- setCurTask();
- return;
- }
- curTaskIndex.value++;
- setCurTask();
- }
- async function getPrevTask() {
- if (loading.value) return;
- loading.value = true;
- if (curTaskIndex.value <= 0) {
- let result = true;
- await getTasks().catch(() => {
- result = false;
- });
- if (!result) return;
- loading.value = false;
- if (!dataList.value.length) {
- message.error("没有上一个了!");
- reviewStore.setInfo({ curTask: null });
- return;
- }
- curTaskIndex.value = dataList.value.length - 1;
- setCurTask();
- return;
- }
- curTaskIndex.value--;
- setCurTask();
- }
- // actions
- async function onMark(result: boolean) {
- if (!reviewStore.curTask) return;
- if (loading.value) return;
- loading.value = true;
- try {
- await reviewTaskSave({ id: reviewStore.curTask.id, result });
- reviewStore.setInfo({
- curTask: Object.assign({}, reviewStore.curTask, {
- markStatus: result,
- }),
- });
- if (reviewStore.tabKey === "history") return;
- await getNextTask();
- } catch (error) {
- loading.value = false;
- }
- }
- async function onSearch(subjectCode: string) {
- searchModel.subjectCode = subjectCode;
- await getTasks();
- curTaskIndex.value = 0;
- setCurTask();
- }
- const resetConfirmDialogRef = ref();
- const resetSubject = ref<SubjectItem | null>(null);
- async function onReset(data: SubjectItem | null) {
- resetSubject.value = data;
- resetConfirmDialogRef.value?.open();
- }
- function onResetConfirm() {
- onSearch("");
- }
- // watch
- watch(
- () => reviewStore.tabKey,
- (val) => {
- if (val === "review") {
- reviewStore.setInfo({
- curTask: dataList.value[curTaskIndex.value] || null,
- });
- }
- }
- );
- onMounted(() => {
- // test
- dataList.value = [
- {
- id: 1,
- name: "考生2",
- studentCode: "360080241304012",
- subjectCode: "SX0001",
- subjectName: "数学",
- examNumber: "360080241304012",
- markStatus: false,
- breachCount: 1,
- pages: [
- {
- index: 1,
- uri: "",
- },
- {
- index: 2,
- uri: "",
- },
- ],
- },
- ];
- reviewStore.setInfo({
- curTask: dataList.value[curTaskIndex.value] || null,
- tabKey: "review",
- });
- });
- </script>
|