123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- <template>
- <a-modal
- v-model:open="visible"
- width="100%"
- :footer="false"
- :closable="false"
- :mask="false"
- :maskClosable="false"
- :keyboard="false"
- wrapClassName="recog-edit-dialog"
- :afterClose="afterClose"
- >
- <div class="recog-edit">
- <div class="recog-row">
- <div class="recog-col is-static is-col1">
- <div class="modal-box">
- <p class="box-title">{{ recogTitle }}</p>
- <p class="box-cont">{{ recogTitleDesc }}</p>
- </div>
- </div>
- <div class="recog-col is-grow">
- <div class="modal-box modal-origin">
- <div class="modal-origin-body" :style="areaImgStyle">
- <img
- v-if="recogData.areaImg"
- ref="areaImgRef"
- :src="recogData.areaImg"
- alt="截图"
- @load="areaImgLoad"
- />
- <div
- v-for="(option, index) in recogData.options.slice(1)"
- :key="option"
- class="select-option"
- :style="getOptionStyle(index)"
- @click="selectOption(option)"
- >
- {{ option }}
- </div>
- </div>
- </div>
- </div>
- <div class="recog-col is-static is-col1">
- <div class="modal-box is-btn" @click="close">
- <p class="box-title">Esc键</p>
- <p class="box-cont">关闭</p>
- </div>
- </div>
- </div>
- <div class="recog-row">
- <div class="recog-col is-static is-col1">
- <div class="modal-box">
- <p class="box-title">识别结果</p>
- <p class="box-cont">{{ recogResult }}</p>
- </div>
- </div>
- <div class="recog-col is-grow">
- <div class="modal-box modal-options">
- <a-button
- v-for="option in recogData.options"
- :key="option"
- :type="selectResult.includes(option) ? 'primary' : 'default'"
- @click="selectOption(option)"
- >{{ recogResultTransform(option) }}</a-button
- >
- </div>
- </div>
- <div class="recog-col is-static is-col1">
- <div class="modal-box is-btn" @click="onConfirm">
- <p class="box-title">Enter键</p>
- <p class="box-cont">保存</p>
- </div>
- </div>
- </div>
- </div>
- </a-modal>
- </template>
- <script setup lang="ts">
- import { ref, computed, watch, nextTick } from "vue";
- import { message } from "ant-design-vue";
- import useModal from "@/hooks/useModal";
- import { RecogBlock } from "@/utils/recog/recog";
- import { getBoxImageSize, recogResultTransform } from "@/utils/tool";
- import { useUserStore, useDataCheckStore } from "@/store";
- import { debounce } from "lodash-es";
- defineOptions({
- name: "RecogEditDialog",
- });
- const { visible, open, close } = useModal();
- defineExpose({ open, close });
- const props = defineProps<{
- recogData: RecogBlock;
- }>();
- const emit = defineEmits(["confirm", "close"]);
- const userStore = useUserStore();
- const dataCheckStore = useDataCheckStore();
- const selectResult = ref([] as string[]);
- const titles = {
- question: "客观题",
- absent: "缺考",
- breach: "违纪",
- paperType: "卷型号",
- };
- const recogTitle = computed(() => {
- return titles[props.recogData.type];
- });
- const recogTitleDesc = computed(() => {
- if (props.recogData.type === "question") {
- return `#${props.recogData.index + 25}`;
- }
- return "--";
- });
- const recogResult = computed(() => {
- if (props.recogData.type === "question") {
- return props.recogData.result.join("");
- }
- return "";
- });
- function getOptionStyle(index: number): Record<string, any> {
- const optionSize = props.recogData.optionSizes[index];
- const option = props.recogData.options[index + 1];
- const borderColor = selectResult.value.includes(option)
- ? userStore.recogFillSet.fillColor
- : userStore.recogFillSet.unfillColor;
- return {
- width: `${optionSize.w}px`,
- height: `${optionSize.h}px`,
- fontSize: `${optionSize.h * 0.8}px`,
- fontWeight: "bold",
- color: borderColor,
- left: `${optionSize.x}px`,
- top: `${optionSize.y}px`,
- borderColor,
- };
- }
- const areaImgRef = ref();
- const areaImgStyle = ref({});
- function areaImgLoad() {
- const areaImgDom = areaImgRef.value as HTMLImageElement;
- const boxDom = areaImgDom.parentNode?.parentNode as HTMLDivElement;
- const recogDpi = dataCheckStore.curPage.recogDpi || 150;
- const scaleRate = (1.5 * 150) / recogDpi;
- const imgSize = getBoxImageSize({
- box: {
- width: boxDom.offsetWidth - 22,
- height: boxDom.offsetHeight - 22,
- },
- img: {
- width: areaImgDom.naturalWidth * scaleRate,
- height: areaImgDom.naturalHeight * scaleRate,
- },
- rotate: 0,
- });
- const rate = imgSize.width / areaImgDom.naturalWidth;
- areaImgStyle.value = {
- width: `${areaImgDom.naturalWidth}px`,
- height: `${areaImgDom.naturalHeight}px`,
- transform: `scale(${rate}) translate(-50%, -50%)`,
- };
- }
- function selectOption(option: string) {
- if (!props.recogData) return;
-
- if (!props.recogData.multiple) {
- selectResult.value = [option];
- return;
- }
-
-
- if (option === "#") {
- selectResult.value = ["#"];
- return;
- }
- let result = selectResult.value.filter((item) => item !== "#");
- if (result.includes(option)) {
- result = result.filter((item) => item !== option);
- } else {
- result.push(option);
- }
-
- selectResult.value = props.recogData.options.filter((item) =>
- result.includes(item)
- );
- }
- const onConfirm = debounce(save, 300);
- function save() {
-
- if (!selectResult.value.length) {
- message.error("请选择答案");
- return;
- }
- emit("confirm", selectResult.value);
- close();
- }
- function registKeyEvent() {
- document.addEventListener("keydown", keyEventHandle);
- }
- function removeKeyEvent() {
- document.removeEventListener("keydown", keyEventHandle);
- }
- function keyEventHandle(e: KeyboardEvent) {
- if (e.repeat) return;
- if (e.keyCode == 13) {
- e.preventDefault();
- onConfirm();
- return;
- } else if (e.code === "Escape") {
- e.preventDefault();
- close();
- return;
- }
- }
- function afterClose() {
- emit("close");
- }
- watch(
- () => visible.value,
- (val) => {
- if (val) {
- modalOpenHandle();
- } else {
- removeKeyEvent();
- }
- },
- {
- immediate: true,
- }
- );
- watch(
- () => props.recogData,
- (val) => {
- console.log(`props.recogData:${Date.now()}`, val);
- if (!val) return;
- selectResult.value = [...props.recogData.result];
- }
- );
- async function modalOpenHandle() {
- selectResult.value = [...props.recogData.result];
- await nextTick();
- registKeyEvent();
- }
- </script>
|