123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- <template>
- <div class="mark-tool">
- <div>
- <div
- v-if="checkValid('allPage')"
- class="mark-tool-item"
- @click="toAllPage"
- >
- <img src="@/assets/icons/icon-all-page.svg" />
- <p>全卷</p>
- </div>
- <div
- v-if="checkValid('paper') && markStore.paperUrl"
- :class="[
- 'mark-tool-item',
- { 'is-active': markStore.setting.uiSetting['paper.modal'] },
- ]"
- @click="toPaper"
- >
- <img src="@/assets/icons/icon-paper.svg" />
- <p>试卷</p>
- </div>
- <div
- v-if="checkValid('answer') && markStore.answerUrl"
- :class="[
- 'mark-tool-item',
- { 'is-active': markStore.setting.uiSetting['answer.modal'] },
- ]"
- @click="toAnswer"
- >
- <img src="@/assets/icons/icon-answer.svg" />
- <p>答案</p>
- </div>
- <div
- v-if="checkValid('minimap')"
- :class="[
- 'mark-tool-item',
- { 'is-active': markStore.setting.uiSetting['minimap.modal'] },
- ]"
- @click="toThumbnail"
- >
- <img src="@/assets/icons/icon-thumbnail.svg" />
- <p>缩略图</p>
- </div>
- <div
- v-if="checkValid('issuePaper')"
- class="mark-tool-item"
- @click="toIssuePaper"
- >
- <img src="@/assets/icons/icon-issue-paper.svg" />
- <p>问题试卷</p>
- </div>
- <div v-if="checkValid('sizeScale')" class="mark-tool-item tool-scale">
- <div>
- <span>Aa</span>
- <a-slider
- v-model:value="markStore.setting.uiSetting['score.fontSize.scale']"
- :min="0.5"
- :step="0.1"
- :max="3"
- />
- </div>
- <p>分数/标记大小</p>
- </div>
- <div
- v-if="checkValid('shortCut')"
- :class="[
- 'mark-tool-item',
- { 'is-active': markStore.setting.uiSetting['shortCut.modal'] },
- ]"
- @click="toShortcut"
- >
- <img src="@/assets/icons/icon-shortcut.svg" />
- <p>快捷键</p>
- </div>
- <div v-if="checkValid('specialTag')" class="tool-special">
- <div
- :class="[
- 'tag-item',
- { 'is-current': markStore.currentSpecialTag === '√' },
- ]"
- @click="chooseSpecialTag('√', 'RIGHT')"
- >
- <img src="@/assets/icons/icon-right.svg" />
- </div>
- <div
- :class="[
- 'tag-item',
- {
- 'is-current': markStore.currentSpecialTag === '乄',
- },
- ]"
- @click="chooseSpecialTag('乄', 'HALF_RIGTH')"
- >
- 乄
- </div>
- <div
- :class="[
- 'tag-item',
- { 'is-current': markStore.currentSpecialTag === 'X' },
- ]"
- @click="chooseSpecialTag('X', 'WRONG')"
- >
- <img src="@/assets/icons/icon-wrong.svg" />
- </div>
- <div
- :class="[
- 'tag-item',
- { 'is-current': markStore.currentSpecialTagType === 'CIRCLE' },
- ]"
- title="标记圆圈"
- @click="chooseSpecialTag('○', 'CIRCLE')"
- >
- <img src="@/assets/icons/icon-circle.svg" />
- </div>
- <div
- :class="[
- 'tag-item',
- { 'is-current': markStore.currentSpecialTagType === 'LINE' },
- ]"
- title="标记圆圈"
- @click="chooseSpecialTag('-', 'LINE')"
- >
- -
- </div>
- <div
- :class="[
- 'tag-item',
- { 'is-current': markStore.currentSpecialTagType === 'TEXT' },
- ]"
- title="标记文本"
- @click="chooseSpecialTag('', 'TEXT')"
- >
- <img src="@/assets/icons/icon-text.svg" />
- </div>
- <div class="tag-item tag-splite"></div>
- <div class="tag-item" title="回退" @click="clearLatestTagOfCurrentTask">
- <img src="@/assets/icons/icon-goback.svg" />
- </div>
- <div
- class="tag-item tag-danger"
- title="清空"
- @click="clearAllTagsOfCurrentTask"
- >
- <img src="@/assets/icons/icon-clear.svg" />
- </div>
- </div>
- </div>
- <div>
- <div
- v-if="checkValid('questionModel')"
- class="mark-tool-item"
- style="width: 70px"
- @click="toSwitchQuestionModal"
- >
- <img
- v-if="markStore.setting.questionModel === 'SINGLE'"
- src="@/assets/icons/icon-split-block.svg"
- />
- <img v-else src="@/assets/icons/icon-block.svg" />
- <p>{{ questionModalName }}</p>
- </div>
- <div class="mark-tool-item" @click="toEyecare">
- <img src="@/assets/icons/icon-eye-green.svg" />
- <p>护眼模式</p>
- </div>
- <div
- v-if="
- markStore.setting.enableAllZero && !markStore.setting.forceSpecialTag
- "
- class="mark-tool-item"
- @click="toAllZero"
- >
- <img src="@/assets/icons/icon-all-zero.svg" />
- <p>全部零分</p>
- </div>
- <template v-if="checkValid('imgScale')">
- <div
- :class="['mark-tool-item', { 'is-active': greaterThanOneScale }]"
- @click="toMagnify"
- >
- <img src="@/assets/icons/icon-magnify.svg" />
- <p>放大</p>
- </div>
- <div
- :class="['mark-tool-item', { 'is-active': lessThanOneScale }]"
- @click="toMinify"
- >
- <img src="@/assets/icons/icon-minify.svg" />
- <p>缩小</p>
- </div>
- <div
- :class="['mark-tool-item', { 'is-active': equalOneScale }]"
- @click="toOrigin"
- >
- <img src="@/assets/icons/icon-origin-size.svg" />
- <p>实际大小</p>
- </div>
- </template>
- </div>
- </div>
- <MarkProblemDialog v-if="checkValid('issuePaper')" ref="problemRef" />
- </template>
- <script setup lang="ts">
- import { computed, onMounted, onUnmounted } from "vue";
- import { useMarkStore } from "@/store";
- import { Modal } from "ant-design-vue";
- import { updateUISetting } from "@/api/markPage";
- import MarkProblemDialog from "./MarkProblemDialog.vue";
- const markStore = useMarkStore();
- /**
- * allPage:全卷
- * paper:试卷
- * answer:答案
- * minimap:缩略图
- * issuePaper:问题试卷
- * sizeScale:标记大小
- * shortCut:快捷键
- * specialTag:特殊标记
- * imgScale:图片缩放
- * questionModel:切换题目模式
- */
- const { actions = [] } = defineProps<{
- actions?: string[];
- }>();
- type ShowModalFunc = () => void;
- const checkValid = (name: string) => {
- if (!actions.length) return true;
- return actions.includes(name);
- };
- const emit = defineEmits(["allZeroSubmit"]);
- let problemRef = $ref<InstanceType<typeof MarkProblemDialog>>();
- const toAllPage = () => {
- markStore.allPaperModal = !markStore.allPaperModal;
- };
- const toThumbnail = () => {
- markStore.setting.uiSetting["minimap.modal"] =
- !markStore.setting.uiSetting["minimap.modal"];
- };
- const toAnswer = () => {
- markStore.setting.uiSetting["answer.modal"] =
- !markStore.setting.uiSetting["answer.modal"];
- };
- const toPaper = () => {
- markStore.setting.uiSetting["paper.modal"] =
- !markStore.setting.uiSetting["paper.modal"];
- };
- const toIssuePaper = () => {
- (problemRef.showModal as ShowModalFunc)();
- };
- const toShortcut = () => {
- markStore.setting.uiSetting["shortCut.modal"] =
- !markStore.setting.uiSetting["shortCut.modal"];
- };
- const toAllZero = () => {
- Modal.confirm({
- title: "操作警告",
- content: "确定给全零分?",
- onOk() {
- emit("allZeroSubmit");
- },
- });
- };
- const toMagnify = () => {
- const s = markStore.setting.uiSetting["answer.paper.scale"];
- if (s < 3)
- markStore.setting.uiSetting["answer.paper.scale"] = +(s + 0.2).toFixed(1);
- };
- const toMinify = () => {
- const s = markStore.setting.uiSetting["answer.paper.scale"];
- if (s > 0.2)
- markStore.setting.uiSetting["answer.paper.scale"] = +(s - 0.2).toFixed(1);
- };
- const toOrigin = () => {
- markStore.setting.uiSetting["answer.paper.scale"] = 1;
- };
- const greaterThanOneScale = computed(() => {
- return markStore.setting.uiSetting["answer.paper.scale"] > 1;
- });
- const lessThanOneScale = computed(() => {
- return markStore.setting.uiSetting["answer.paper.scale"] < 1;
- });
- const equalOneScale = computed(() => {
- return markStore.setting.uiSetting["answer.paper.scale"] === 1;
- });
- let eyecareMode = $ref(Number(window.localStorage.getItem("eyecareMode", "0")));
- eyecareMode = eyecareMode === 1 ? 0 : 1;
- toEyecare();
- function toEyecare() {
- const classList = Array.from(document.body.classList);
- const eyecareCls = "eyecare-mode";
- if (eyecareMode === 1) {
- eyecareMode = 0;
- document.body.classList = classList.filter((item) => item !== eyecareCls);
- } else {
- eyecareMode = 1;
- document.body.classList = [...classList, eyecareCls];
- }
- window.localStorage.setItem("eyecareMode", eyecareMode);
- }
- // 阅卷模式切换
- const questionModalName = computed(() => {
- return markStore.setting.questionModel === "SINGLE"
- ? "阅全部题目"
- : "按小题阅卷";
- });
- const toSwitchQuestionModal = () => {
- const qname =
- markStore.setting.questionModel === "SINGLE" ? "阅全部题目" : "按小题阅卷";
- Modal.confirm({
- title: "操作警告",
- content: `确定切换为${qname}吗?`,
- async onOk() {
- markStore.setting.questionModel =
- markStore.setting.questionModel === "SINGLE" ? "MULTI" : "SINGLE";
- await updateUISetting(
- markStore.setting.mode,
- markStore.setting.uiSetting,
- markStore.setting.questionModel
- );
- window.location.reload();
- },
- });
- };
- function clearLatestTagOfCurrentTask() {
- if (!markStore.currentTask?.markResult) return;
- markStore.currentTask.markResult.markerTagList.splice(-1);
- }
- function clearAllTagsOfCurrentTask() {
- if (!markStore.currentTask?.markResult) return;
- markStore.currentTask.markResult.markerTagList = [];
- }
- function chooseSpecialTag(tagName: string, tagType: string) {
- if (markStore.currentSpecialTag === tagName) {
- markStore.currentSpecialTag = undefined;
- markStore.currentSpecialTagType = undefined;
- } else {
- markStore.currentSpecialTag = tagName;
- markStore.currentSpecialTagType = tagType;
- markStore.currentScore = undefined;
- }
- }
- function keyListener(event: KeyboardEvent) {
- if (event.key === "+") {
- toMagnify();
- } else if (event.key === "-") {
- toMinify();
- }
- }
- onMounted(() => {
- document.addEventListener("keydown", keyListener);
- });
- onUnmounted(() => {
- document.removeEventListener("keydown", keyListener);
- });
- </script>
|