123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501 |
- <template>
- <div class="image-view h-full">
- <div class="tree-wrap">
- <div class="top">
- <div class="result-list">
- {{ curSubject.label }}{{ curDevice.label && ";" }}{{ curDevice.label
- }}{{ curBatch.label && ";" }}{{ curBatch.label }}
- </div>
- <div class="bread">
- <span
- :class="{ active: chooseLevel >= 1 }"
- @click="toggleListType('level1', 1)"
- >科目</span
- >
- <i>></i>
- <span
- :class="{ active: chooseLevel >= 2 }"
- @click="toggleListType('level2', 2)"
- >机器</span
- >
- <i>></i>
- <span
- :class="{ active: chooseLevel >= 3 }"
- @click="toggleListType('level3', 3)"
- >批次</span
- >
- <i>></i>
- <span :class="{ active: chooseLevel >= 4 }">考生</span>
- </div>
- </div>
- <div class="bottom">
- <div
- v-for="(item, index) in leftList"
- :key="index"
- class="list-row"
- :class="{ active: activeIndex === index }"
- @click="chooseLeft(item, index)"
- >
- {{ item[fieldNames.label] }}
- </div>
- </div>
- </div>
- <div class="info-wrap">
- <Accordion :arr="arr">
- <template #one>
- <div class="flex accordion-body items-center justify-between">
- <VerticalDateRange v-model="timeArr" />
- <qm-button size="large" type="primary" @click="search"
- >搜索</qm-button
- >
- </div>
- </template>
- <template #two>
- <div class="accordion-body">
- <a-radio-group
- v-model:value="imageType"
- @change="onImageTypeChange"
- >
- <a-radio
- v-for="item in imageTypeOptions"
- :key="item.value"
- :value="item.value"
- >{{ item.label }}</a-radio
- >
- </a-radio-group>
- </div>
- </template>
- <template #three>
- <div class="accordion-body">
- <QuestionPanel
- v-if="dataCheckStore.curStudent && dataCheckStore.curPage"
- v-model:questions="questions"
- :info="questionInfo"
- :simple="isSliceImage"
- :editable="false"
- @change="onQuestionsChange"
- />
- </div>
- </template>
- </Accordion>
- </div>
- <div class="image-wrap">
- <ScanImage
- v-if="dataCheckStore.curPage && isOriginImage"
- @prev="onPrevPage"
- @next="onNextPage"
- />
- <SliceImage v-if="dataCheckStore.curPage && !isOriginImage" />
- </div>
- </div>
- </template>
- <script name="ImageView" lang="ts" setup>
- import { ref, computed, onMounted, watch, onBeforeUnmount } from "vue";
- import VerticalDateRange from "@/components/VerticalDateRange/index.vue";
- import { useUserStore, useDataCheckStore } from "@/store";
- import { IMAGE_TYPE, enum2Options } from "@/constants/enums";
- import QuestionPanel from "../DataCheck/QuestionPanel.vue";
- import ScanImage from "../DataCheck/ScanImage/index.vue";
- import SliceImage from "../DataCheck/SliceImage/index.vue";
- import {
- batchSubjectList,
- batchDeviceList,
- batchList,
- batchStudentList,
- getStuCardDetail,
- } from "@/ap/scanManage";
- import { QuestionInfo } from "../DataCheck/types";
- import dayjs from "dayjs";
- const imageTypeOptions = enum2Options(IMAGE_TYPE);
- const dataCheckStore = useDataCheckStore();
- dataCheckStore.resetInfo();
- function onImageTypeChange() {
- dataCheckStore.setInfo({
- imageType: imageType.value,
- });
- }
- const timeArr = ref([Date.now() - 1000 * 60 * 60, Date.now()]);
- const timeParams = computed<any>(() => {
- return { startTime: timeArr.value[0], endTime: timeArr.value[1] };
- });
- const userStore = useUserStore();
- const examId = computed(() => userStore.curExam?.id);
- const _batchSubjectList = () => {
- batchSubjectList({ examId: examId.value, ...timeParams.value }).then(
- (res: any) => {
- leftList.value = res || [];
- listType.value = "level1";
- }
- );
- };
- const _batchDeviceList = () => {
- batchDeviceList({
- examId: examId.value,
- subjectCode: curSubject.value.value,
- ...timeParams.value,
- }).then((res: any) => {
- leftList.value = res || [];
- listType.value = "level2";
- });
- };
- const _batchList = () => {
- batchList({
- examId: examId.value,
- subjectCode: curSubject.value.value,
- device: curDevice.value.value,
- ...timeParams.value,
- }).then((res: any) => {
- leftList.value = res || [];
- listType.value = "level3";
- });
- };
- const _batchStudentList = () => {
- batchStudentList({ batchId: curBatch.value.value }).then((res: any) => {
- leftList.value = res || [];
- listType.value = "level4";
- });
- };
- function parseStudentPage(student: any) {
- dataList.value = [];
- student.papers.forEach((paper: any, paperIndex: number) => {
- if (!paper.pages) return;
- paper.pages.forEach((page: any, pageIndex: number) => {
- dataList.value.push({
- ...page,
- paperId: paper.id as number,
- pageIndex: page.index,
- paperIndex,
- paperNumber: paper.number,
- studentIndex: 0,
- studentId: student.id,
- examId: userStore.curExam?.id,
- kid: `${student.id}-${0}-${paperIndex}-${pageIndex}`,
- });
- });
- });
- }
- const loading = ref(false);
- const _getStuCardDetail = () => {
- loading.value = true;
- getStuCardDetail({
- batchId: curBatch.value.value,
- studentId: curStu.value.studentId,
- })
- .then((res: any) => {
- curStuCardData.value = res || {};
- parseStudentPage(curStuCardData.value);
- selectPage(0);
- })
- .finally(() => {
- loading.value = false;
- });
- };
- function selectPage(index: number) {
- dataCheckStore.setInfo({
- curPage: dataList.value[index],
- curPageIndex: index,
- });
- if (!dataCheckStore.curPage) return;
- dataCheckStore.setInfo({ curStudent: curStuCardData.value as any });
- }
- const arr = ref([
- { title: "搜索条件", name: "one", open: true },
- { title: "图片类别", name: "two", open: true },
- { title: "题卡信息", name: "three", open: true },
- ]);
- const listType = ref("level1");
- const fieldNames = computed(() => {
- let obj: any = {
- level1: { label: "subjectName", value: "subjectCode" },
- level2: { label: "deviceName", value: "device" },
- level3: { label: "batchId", value: "batchId" },
- level4: { label: "examNumber", value: "studentId" },
- };
- return obj[listType.value];
- });
- const chooseLevel = computed(() => {
- return listType.value === "level1"
- ? 1
- : listType.value === "level2"
- ? 2
- : listType.value === "level3"
- ? 3
- : 4;
- });
- const leftList = ref<any>([]);
- const curSubject = ref({ label: "", value: "" });
- const curDevice = ref({ label: "", value: "" });
- const curBatch = ref({ label: "", value: "" });
- const curStu = ref({
- examNumber: "",
- studentId: void 0,
- studentName: "",
- });
- const curStuCardData = ref({});
- const dataList = ref<any>([]);
- const chooseLeft = (item: any, index: number) => {
- if (loading.value) return;
- activeIndex.value = index;
- if (listType.value === "level1") {
- curSubject.value = { value: item.subjectCode, label: item.subjectName };
- _batchDeviceList();
- } else if (listType.value === "level2") {
- curDevice.value = { value: item.device, label: item.deviceName };
- _batchList();
- } else if (listType.value === "level3") {
- curBatch.value = { value: item.batchId, label: item.batchId };
- _batchStudentList();
- } else if (listType.value === "level4") {
- curStu.value = {
- examNumber: item.examNumber,
- studentId: item.studentId,
- studentName: item.studentName,
- };
- _getStuCardDetail();
- }
- };
- const toggleListType = (type: string, num: number) => {
- if (chooseLevel.value < num) {
- return;
- }
- const clearObj = { value: "", label: "" };
- leftList.value = [];
- if (type === "level1") {
- curSubject.value = { ...clearObj };
- curDevice.value = { ...clearObj };
- curBatch.value = { ...clearObj };
- _batchSubjectList();
- } else if (type === "level2") {
- curDevice.value = { ...clearObj };
- curBatch.value = { ...clearObj };
- _batchDeviceList();
- } else if (type === "level3") {
- curBatch.value = { ...clearObj };
- _batchList();
- }
- };
- const search = () => {
- toggleListType(listType.value, 0);
- };
- const activeIndex = ref();
- const imageType = ref(dataCheckStore.imageType);
- // imageType
- const isOriginImage = computed(() => {
- return dataCheckStore.imageType === "ORIGIN";
- });
- // imageType
- const isSliceImage = computed(() => {
- return dataCheckStore.imageType === "SLICE";
- });
- // question panel
- const questionInfo = computed(() => {
- if (!dataCheckStore.curStudent) return {} as QuestionInfo;
- return {
- examNumber: dataCheckStore.curStudent.examNumber,
- name: dataCheckStore.curStudent.name,
- examSite: dataCheckStore.curStudent.examSite,
- seatNumber: dataCheckStore.curStudent.seatNumber,
- paperType: dataCheckStore.curStudent.paperType,
- examStatus: dataCheckStore.curStudent.examStatus as string,
- packageCode: dataCheckStore.curStudent.packageCode as string,
- };
- });
- const questions = ref<any>([]);
- watch(
- () => dataCheckStore.curPageIndex,
- (val, oldval) => {
- if (val !== oldval) {
- if (!dataCheckStore.curPage || !dataCheckStore.curPage.question) return;
- questions.value = [...(dataCheckStore.curPage?.question?.result || [])];
- }
- }
- );
- async function onQuestionsChange() {
- if (!dataCheckStore.curPage) return;
- // dataCheckStore.curPage.question = [...questions.value];
- dataCheckStore.curPage.question.result = [...questions.value];
- await dataCheckStore
- .updateField({
- field: "QUESTION",
- value: JSON.stringify({
- type: dataCheckStore.curPage?.question?.type,
- result: questions.value,
- }),
- })
- .catch(() => {});
- }
- async function onPrevPage() {
- if (dataCheckStore.curPageIndex <= 0) {
- if (activeIndex.value == 0) {
- window.$message.error("没有上一张了");
- return;
- } else {
- chooseLeft(leftList.value[activeIndex.value - 1], activeIndex.value - 1);
- return;
- }
- }
- selectPage(dataCheckStore.curPageIndex - 1);
- }
- async function onNextPage() {
- if (dataCheckStore.curPageIndex >= dataList.value.length - 1) {
- if (activeIndex.value == leftList.value.length - 1) {
- window.$message.error("没有下一张了");
- return;
- } else {
- chooseLeft(leftList.value[activeIndex.value + 1], activeIndex.value + 1);
- return;
- }
- }
- selectPage(dataCheckStore.curPageIndex + 1);
- }
- function registShortcut() {
- document.addEventListener("keydown", shortcutHandle);
- }
- function removeShortcut() {
- document.removeEventListener("keydown", shortcutHandle);
- }
- function onPrevStudent() {
- if (activeIndex.value == 0) {
- window.$message.error("没有上一个学生了");
- return;
- }
- chooseLeft(leftList.value[activeIndex.value - 1], activeIndex.value - 1);
- }
- function onNextStudent() {
- if (activeIndex.value == leftList.value.length - 1) {
- window.$message.error("没有下一个学生了");
- return;
- }
- chooseLeft(leftList.value[activeIndex.value + 1], activeIndex.value + 1);
- }
- function shortcutHandle(e: KeyboardEvent) {
- if (!leftList.value.length || listType.value !== "level4") {
- return;
- }
- const moveAction = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
- if (!moveAction.includes(e.code) || e.repeat) {
- return;
- }
- e.preventDefault();
- if (e.code === "ArrowUp") {
- onPrevStudent();
- return;
- }
- if (e.code === "ArrowDown") {
- onNextStudent();
- return;
- }
- if (e.code === "ArrowLeft") {
- onPrevPage();
- return;
- }
- if (e.code === "ArrowRight") {
- onNextPage();
- return;
- }
- }
- onMounted(() => {
- _batchSubjectList();
- registShortcut();
- });
- onBeforeUnmount(() => {
- removeShortcut();
- });
- </script>
- <style lang="less" scoped>
- .image-view {
- .accordion-body {
- padding: 12px 16px;
- }
- .image-wrap {
- height: 100%;
- border-left: 1px solid #e5e6eb;
- border-right: 1px solid #e5e6eb;
- background: #eceef1;
- margin-left: 284px;
- margin-right: 400px;
- }
- .tree-wrap {
- width: 284px;
- float: left;
- height: 100%;
- display: flex;
- flex-direction: column;
- .bottom {
- flex: 1;
- overflow: auto;
- padding: 10px 8px;
- .list-row {
- padding: 6px 12px;
- line-height: 22px;
- color: @text-color1;
- cursor: pointer;
- &.active {
- font-weight: bold;
- background: #e8f3ff !important;
- border-radius: 6px;
- }
- &:hover {
- background: #f6f6f6;
- border-radius: 6px;
- }
- }
- }
- .top {
- border-bottom: 1px solid #e5e5e5;
- padding: 16px;
- .bread {
- margin-top: 16px;
- i {
- font-style: normal;
- color: @text-color3;
- margin: 0 4px;
- }
- span {
- color: @text-color3;
- &:not(:last-child) {
- cursor: pointer;
- }
- &.active {
- color: @text-color1;
- font-weight: bold;
- }
- }
- }
- .result-list {
- background: #f2f3f5;
- border-radius: 6px;
- padding: 0 8px;
- height: 32px;
- line-height: 32px;
- color: @text-color1;
- }
- }
- }
- .info-wrap {
- width: 400px;
- float: right;
- height: 100%;
- }
- }
- </style>
|