zhangjie 8 місяців тому
батько
коміт
aaf12e92e8

+ 14 - 1
src/render/store/modules/dataCheck/index.ts

@@ -26,6 +26,12 @@ interface UpdateSliceData extends UpdateSheetData {
   index: number;
 }
 
+interface UpdatePaperType {
+  paperIndex: number;
+  pageIndex: number;
+  paperType: string;
+}
+
 export const useDataCheckStore = defineStore("dataCheck", {
   state: (): DataCheckState => ({
     imageType: "ORIGIN",
@@ -54,7 +60,7 @@ export const useDataCheckStore = defineStore("dataCheck", {
         examId: this.curPage.examId,
         examNumber: this.curStudent.examNumber,
         paperNumber: this.curPage.paperNumber,
-        pageIndex: this.curPage.pageIndex,
+        pageIndex: this.curPage.pageIndex + 1,
         subjectCode: this.curStudent.subjectCode,
         ...data,
       };
@@ -70,6 +76,13 @@ export const useDataCheckStore = defineStore("dataCheck", {
       const { uri, pageIndex, paperIndex } = data;
       this.curStudent.papers[paperIndex].pages[pageIndex].sheetUri = uri;
     },
+    modifyPaperType(data: UpdatePaperType) {
+      if (!this.curStudent) return;
+      const { paperType, pageIndex, paperIndex } = data;
+      this.curStudent.paperType = paperType;
+      this.curStudent.papers[paperIndex].pages[pageIndex].paperType.result =
+        paperType;
+    },
   },
   persist: {
     storage: sessionStorage,

+ 3 - 0
src/render/styles/base.less

@@ -22,6 +22,9 @@ body {
 }
 
 // color
+.color-brand {
+  color: @brand-color;
+}
 .color-success {
   color: @success-color;
 }

+ 45 - 0
src/render/styles/pages.less

@@ -1088,3 +1088,48 @@
     }
   }
 }
+
+// modify-paper-type
+.modify-paper-type {
+  .paper-type-img {
+    height: 125px;
+    background: #f3f4f6;
+    border-radius: 6px;
+    border: 1px solid #d9d9d9;
+
+    img {
+      display: block;
+      object-fit: contain;
+      width: 100%;
+      height: 100%;
+    }
+  }
+  .type-list {
+    margin-right: -8px;
+    font-size: 0;
+  }
+  .type-item {
+    display: inline-block;
+    vertical-align: top;
+    font-size: 14px;
+    min-width: 64px;
+    height: 32px;
+    line-height: 24px;
+    background: #e8f3ff;
+    border-radius: 16px;
+    padding: 4px 8px;
+    margin: 0 8px 8px 0;
+    color: @brand-color;
+    text-align: center;
+    cursor: pointer;
+
+    &:hover {
+      opacity: 0.8;
+    }
+    &.is-active {
+      background-color: @brand-color;
+      color: #fff;
+      opacity: 1;
+    }
+  }
+}

+ 33 - 18
src/render/views/DataCheck/ModifyPaperType.vue

@@ -1,24 +1,27 @@
 <template>
-  <a-modal v-model:open="visible" :width="334" centered @ok="confirm">
+  <a-modal
+    v-model:open="visible"
+    :width="456"
+    centered
+    wrapClassName="modify-paper-type"
+    @ok="confirm"
+  >
     <template #title> 更改卷型号 </template>
 
-    <a-form
-      ref="formRef"
-      :model="formData"
-      :rules="rules"
-      :label-col="{ style: { width: '90px' } }"
-    >
-      <a-form-item label="识别结果">{{ recogData.result.join() }}</a-form-item>
+    <a-form ref="formRef" :label-col="{ style: { width: '90px' } }">
+      <a-form-item label="识别结果">
+        <span class="color-brand">{{ areaResult | "#" }}</span>
+      </a-form-item>
       <a-form-item label="识别图片">
         <div class="paper-type-img">
-          <img :src="recogData.areaImg" alt="识别图片" />
+          <img v-if="areaImg" :src="areaImg" alt="识别图片" />
         </div>
       </a-form-item>
       <a-form-item label="更改卷型">
-        <ul>
+        <ul class="type-list">
           <li
-            :class="['type-item', { 'is-active': paperType === '#' }]"
-            @click="selectPaperType('#')"
+            :class="['type-item', { 'is-active': paperType === '' }]"
+            @click="selectPaperType('')"
           >
           </li>
@@ -37,15 +40,13 @@
 </template>
 
 <script setup lang="ts">
-import { onMounted, ref } from "vue";
+import { onMounted, ref, watch } from "vue";
 import { message } from "ant-design-vue";
 
 import { getBaseDataConfig } from "@/ap/baseDataConfig";
 import { useUserStore } from "@/store";
 import useModal from "@/hooks/useModal";
 
-import { RecogBlock } from "@/utils/recog/recog";
-
 defineOptions({
   name: "ModifyPaperType",
 });
@@ -55,10 +56,11 @@ const { visible, open, close } = useModal();
 defineExpose({ open, close });
 
 const props = defineProps<{
-  recogData: RecogBlock;
+  areaImg: string;
+  areaResult: string;
 }>();
 
-const emit = defineEmits(["modified"]);
+const emit = defineEmits(["confirm"]);
 
 const paperTypeBarcodeContent = ref<string[]>([]);
 const userStore = useUserStore();
@@ -78,9 +80,22 @@ function confirm() {
     message.error("请选择卷型");
     return;
   }
-  emit("confirm");
+  emit("confirm", paperType.value);
+  close();
 }
 
+watch(
+  () => visible.value,
+  (val) => {
+    if (val) {
+      paperType.value = props.areaResult || "";
+    }
+  },
+  {
+    immediate: true,
+  }
+);
+
 onMounted(() => {
   getConfig();
 });

+ 68 - 3
src/render/views/DataCheck/QuestionPanel.vue

@@ -19,7 +19,7 @@
         </template>
         <template v-else>
           <a-button class="ant-gray m-r-4px">{{ info.paperType }}</a-button>
-          <a-button @click="onEditPaperType">
+          <a-button v-if="paperTypeArea" @click="onEditPaperType">
             <template #icon><SwapOutlined /></template>
           </a-button>
         </template>
@@ -71,7 +71,12 @@
     </div>
   </div>
 
-  <ModifyPaperType ref="modifyPaperTypeRef" />
+  <ModifyPaperType
+    ref="modifyPaperTypeRef"
+    :area-img="paperTypeImg"
+    :area-result="paperTypeResult"
+    @confirm="paperTypeModified"
+  />
 </template>
 
 <script setup lang="ts">
@@ -79,10 +84,14 @@ import { computed, ref, watch } from "vue";
 import { message } from "ant-design-vue";
 import { SwapOutlined } from "@ant-design/icons-vue";
 import { QuestionInfo } from "./types";
+import { parseRecogData } from "@/utils/recog/recog";
+
 import useDictOption from "@/hooks/dictOption";
 import ModifyPaperType from "./ModifyPaperType.vue";
+import { useDataCheckStore } from "@/store";
 
 import { vEleClickOutsideDirective } from "@/directives/eleClickOutside";
+import { getSliceFileUrl } from "@/utils/tool";
 
 defineOptions({
   name: "QuestionPanel",
@@ -103,6 +112,8 @@ const props = withDefaults(
 );
 const emit = defineEmits(["update:questions", "change", "examStatusChange"]);
 
+const dataCheckStore = useDataCheckStore();
+
 const { optionList: examStatusOptions } = useDictOption("EXAM_SIMPLE_STATUS");
 const examStatus = ref("");
 const questionList = ref([]);
@@ -185,10 +196,64 @@ function onSaveQuesion() {
 
 // edit paper
 const modifyPaperTypeRef = ref();
-function onEditPaperType() {
+const paperTypeArea = ref<AreaSize | null>(null);
+const paperTypeImg = ref("");
+const paperTypeResult = ref("");
+async function onEditPaperType() {
+  if (paperTypeArea.value) {
+    paperTypeImg.value = await getSliceFileUrl(
+      dataCheckStore.curPage?.sheetUri,
+      paperTypeArea.value
+    );
+  } else {
+    paperTypeImg.value = "";
+  }
   modifyPaperTypeRef.value?.open();
 }
 
+async function paperTypeModified(paperType: string) {
+  if (!dataCheckStore.curPage) return;
+
+  await dataCheckStore.updateField({
+    field: "PAPER_TYPE",
+    value: JSON.stringify({
+      ...dataCheckStore.curPage.paperType,
+      result: paperType,
+    }),
+  });
+  dataCheckStore.curPage.paperType.result = paperType;
+}
+
+watch(
+  () => dataCheckStore.curPage?.recogData,
+  (val) => {
+    paperTypeArea.value = null;
+    if (!val) return;
+
+    const regdata = parseRecogData(dataCheckStore.curPage.recogData);
+    if (!regdata) return;
+
+    const rect = regdata.paperType.rect || null;
+    if (!rect) {
+      paperTypeArea.value = null;
+      return;
+    }
+
+    const hasArea = rect.some((item) => item);
+    paperTypeArea.value = hasArea
+      ? {
+          x: rect[0],
+          y: rect[1],
+          w: rect[2],
+          h: rect[3],
+        }
+      : null;
+  },
+  {
+    immediate: true,
+  }
+);
+
 watch(
   () => props.questions,
   (val) => {

+ 1 - 0
src/render/views/DataCheck/SliceImage/index.vue

@@ -213,6 +213,7 @@ watch(
 
     img {
       display: block;
+      width: 100%;
     }
   }
   .image-action {