123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- <template>
- <div
- v-if="store.currentTask"
- class="mark-board-track-container"
- :class="[store.isScoreBoardCollapsed ? 'hide' : 'show']"
- >
- <div class="top-container tw-flex-shrink-0 tw-flex tw-items-center">
- <div class="tw-flex tw-flex-col tw-flex-1 tw-text-center">
- <div class="tw-flex tw-justify-center">
- <img
- src="../../mark/images/totalscore.png"
- style="width: 13px; height: 16px"
- />
- </div>
- <div>试卷总分</div>
- </div>
- <div class="tw-flex-1" style="font-size: 40px">
- {{ markerScore > 0 ? markerScore : 0 }}
- </div>
- </div>
- <div v-if="groups" class="question-list tw-flex-grow tw-overflow-auto">
- <template
- v-for="({ groupNumber, selectiveIndex }, index) in groups"
- :key="index"
- >
- <div class="question-item tw-mb-4 tw-bg-white tw-p-4 tw-pl-5 tw-pr-3">
- <div v-if="selectiveIndex" class="question-item-select-group">
- {{ selectiveIndex }}
- </div>
- <div
- class="tw-flex tw-justify-between tw-place-items-center hover:tw-bg-gray-200"
- @mouseover="addFocusTrack(groupNumber, undefined, undefined)"
- @mouseleave="removeFocusTrack"
- >
- <span class="secondary-text">分组 {{ groupNumber }}</span>
- <input
- class="tw-my-auto"
- title="打回"
- type="checkbox"
- :checked="groupChecked(groupNumber)"
- @click="groupClicked(groupNumber)"
- />
- </div>
- <div v-if="questions">
- <template v-for="(question, index2) in questions" :key="index2">
- <div
- v-if="question.groupNumber === groupNumber"
- class="question tw-flex tw-place-items-center tw-mb-1 tw-font-bold hover:tw-bg-gray-200"
- :class="{ uncalculate: question.uncalculate }"
- @mouseover="
- addFocusTrack(
- undefined,
- question.mainNumber,
- question.subNumber
- )
- "
- @mouseleave="removeFocusTrack"
- >
- <a-tooltip placement="left">
- <template #title>
- <span>未计入总分</span>
- </template>
- <MinusCircleFilled class="uncalculate-icon" />
- </a-tooltip>
- <span class="question-title">
- {{ question.title }} {{ question.mainNumber }}-{{
- question.subNumber
- }}
- </span>
- <span class="tw-text-center question-score">
- {{ question.score === -1 ? "未选做" : question.score || 0 }}
- </span>
- <input
- :disabled="question.score === -1"
- title="打回"
- type="checkbox"
- :checked="questionChecked(question)"
- @change="questionCheckChanged(question)"
- />
- </div>
- </template>
- </div>
- </div>
- </template>
- </div>
- <div class="tw-flex tw-flex-shrink-0 tw-justify-center">
- <qm-button
- v-if="
- store.currentTask.inspectTime && store.currentTask.inspectTime > 0
- "
- type="primary"
- class="full-width-btn undo-btn"
- @click="reject"
- >
- 打回
- </qm-button>
- <qm-button
- v-else-if="checkedQuestions.length === 0"
- type="primary"
- class="full-width-btn"
- @click="inspect"
- >
- 复核
- </qm-button>
- <qm-button
- v-else
- type="primary"
- class="full-width-btn undo-btn"
- @click="reject"
- >打回</qm-button
- >
- </div>
- </div>
- <review-return-dialog
- v-model:visible="reviewReturnVisible"
- @confirmReturn="onConfirmReturn"
- />
- </template>
- <script setup lang="ts">
- import type { Question } from "@/types";
- import { message } from "ant-design-vue";
- import { MinusCircleOutlined, MinusCircleFilled } from "@ant-design/icons-vue";
- import { reactive, watch } from "vue";
- import { store } from "@/store/store";
- import {
- addFocusTrack,
- removeFocusTrack,
- } from "@/features/mark/use/focusTracks";
- import ReviewReturnDialog from "@/features/library/inspect/ReviewReturnDialog.vue";
- const emit = defineEmits(["inspect", "reject"]);
- let checkedQuestions: Question[] = reactive([]);
- let reviewReturnVisible = $ref(false);
- watch(
- () => store.currentTask,
- () => {
- checkedQuestions.splice(0);
- }
- );
- const groups = $computed(() => {
- const gs = store.currentTaskEnsured.questionList.reduce((gs, q) => {
- if (!gs[q.groupNumber]) {
- gs[q.groupNumber] = {
- groupNumber: q.groupNumber,
- selectiveIndex: q.selectiveIndex,
- };
- }
- return gs;
- }, {} as Record<number, { groupNumber: number; selectiveIndex: number | null }>);
- return Object.values(gs);
- });
- const questions = $computed(() => {
- const qs = store.currentTaskEnsured.questionList;
- return qs;
- });
- const markerScore = $computed(() => store.currentTaskEnsured.markerScore || 0);
- function addToCheckedQuestion(question: Question) {
- checkedQuestions.push(question);
- }
- function removeCheckedQuestion(question: Question) {
- const idx = checkedQuestions.indexOf(question);
- checkedQuestions.splice(idx, 1);
- }
- function groupChecked(groupNumber: number) {
- return (
- checkedQuestions.filter((q) => q.groupNumber === groupNumber).length ===
- questions?.filter((q) => q.groupNumber === groupNumber).length
- );
- }
- function questionChecked(question: Question) {
- return checkedQuestions.includes(question);
- }
- function questionCheckChanged(question: Question) {
- const checked = questionChecked(question);
- if (checked) {
- removeCheckedQuestion(question);
- } else {
- addToCheckedQuestion(question);
- }
- }
- function groupClicked(groupNumber: number) {
- if (groupChecked(groupNumber)) {
- checkedQuestions
- .filter((q) => q.groupNumber === groupNumber)
- .forEach((q) => {
- const idx = checkedQuestions.indexOf(q);
- checkedQuestions.splice(idx, 1);
- });
- } else {
- questions
- ?.filter((q) => q.groupNumber === groupNumber)
- .forEach((q) => {
- if (!questionChecked(q)) checkedQuestions.push(q);
- });
- }
- }
- function reject() {
- if (checkedQuestions.length === 0) {
- void message.warn({ content: "请先选择试题。" });
- return;
- }
- reviewReturnVisible = true;
- // emit("reject", checkedQuestions);
- }
- function inspect() {
- emit("inspect");
- }
- function onConfirmReturn(reason: string) {
- emit("reject", { questions: checkedQuestions, reason });
- }
- </script>
- <style scoped>
- .mark-board-track-container {
- display: flex;
- flex-direction: column;
- max-width: 290px;
- min-width: 290px;
- max-height: calc(100vh - 56px);
- z-index: 1001;
- transition: margin-right 0.5s;
- color: var(--app-small-header-text-color);
- }
- .mark-board-track-container.show {
- margin-right: 0;
- }
- .mark-board-track-container.hide {
- margin-right: -290px;
- }
- .top-container {
- background-color: var(--app-container-bg-color);
- height: 86px;
- border-radius: 5px;
- margin: 20px;
- margin-bottom: 0;
- color: white;
- background-color: var(--app-primary-button-bg-color);
- }
- .question-list {
- padding: 20px;
- }
- .question-item {
- border-radius: 5px;
- position: relative;
- }
- /** 选做题分组 */
- .question-item-select-group {
- position: absolute;
- left: -12px;
- top: -12px;
- width: 24px;
- height: 24px;
- background: #d3d9e6;
- border-radius: 12px 12px 4px 12px;
- color: #435488;
- text-align: center;
- line-height: 24px;
- font-size: 12px;
- font-weight: bold;
- }
- .total-score {
- color: var(--app-main-text-color);
- font-size: 32px;
- }
- .question {
- min-width: 80px;
- background-color: var(--app-container-bg-color);
- }
- .question-title {
- flex: 1;
- }
- .question-score {
- flex-basis: 56px;
- padding: 0 3px;
- }
- .question.uncalculate {
- position: relative;
- }
- .question .uncalculate-icon {
- display: none;
- color: red;
- position: absolute;
- font-size: 15px;
- left: -16px;
- top: 0.3em;
- }
- .question.uncalculate .uncalculate-icon {
- display: block;
- }
- .full-width-btn {
- width: 100%;
- border-radius: 20px;
- }
- .undo-btn {
- background-color: var(--app-undo-button-bg-color);
- border-color: var(--app-undo-button-bg-color);
- }
- </style>
|