Browse Source

feat: 扫描任务管理和文档管理

zhangjie 10 tháng trước cách đây
mục cha
commit
7091156a12

+ 5 - 0
src/components/ImageContain.vue

@@ -238,6 +238,11 @@ export default {
     toRotate() {
     toRotate() {
       this.transform.rotate = this.transform.rotate + 90;
       this.transform.rotate = this.transform.rotate + 90;
       this.setStyleTransform();
       this.setStyleTransform();
+
+      this.$emit(
+        "on-rotate",
+        this.transform.rotate >= 360 ? 0 : this.transform.rotate
+      );
       // 调整图片尺寸
       // 调整图片尺寸
       const { naturalWidth, naturalHeight } = this.$refs.PreviewImgDetail;
       const { naturalWidth, naturalHeight } = this.$refs.PreviewImgDetail;
       const imageSize = this.getImageSizePos({
       const imageSize = this.getImageSizePos({

+ 9 - 0
src/modules/record/api.js

@@ -12,6 +12,9 @@ export const clearScanTaskData = (paperScanTaskId) => {
     paperScanTaskId,
     paperScanTaskId,
   });
   });
 };
 };
+export const clearStudentScanData = (datas) => {
+  return $postParam("/api/admin/paper/scan_task/clear_data", datas);
+};
 export const unbindScanTaskUser = (paperScanTaskId) => {
 export const unbindScanTaskUser = (paperScanTaskId) => {
   return $postParam("/api/admin/paper/scan_task/unbind_scanner", {
   return $postParam("/api/admin/paper/scan_task/unbind_scanner", {
     paperScanTaskId,
     paperScanTaskId,
@@ -104,3 +107,9 @@ export const documentOtherDetialListPage = (datas) => {
 // export const deleteArchives = (ids) => {
 // export const deleteArchives = (ids) => {
 //   return $postParam("/api/admin/paper/archives/delete", { ids: ids.join() });
 //   return $postParam("/api/admin/paper/archives/delete", { ids: ids.join() });
 // };
 // };
+export const updateDocumentImageRotate = (datas) => {
+  return $postParam("/api/admin/paper/document/other_detail", datas);
+};
+export const deleteDocumentImage = (datas) => {
+  return $postParam("/api/admin/paper/document/other_detail", datas);
+};

+ 121 - 35
src/modules/record/components/ArchivesDetailStudentDialog.vue

@@ -8,21 +8,17 @@
       :close-on-press-escape="false"
       :close-on-press-escape="false"
       append-to-body
       append-to-body
       fullscreen
       fullscreen
-      @open="visibleChange"
+      @open="reloadData"
     >
     >
       <div class="archives-student-body">
       <div class="archives-student-body">
         <div class="archives-student-content part-box">
         <div class="archives-student-content part-box">
-          <el-carousel
-            height="100%"
-            :autoplay="false"
-            :loop="false"
-            arrow="always"
-            @change="imageChange"
-          >
-            <el-carousel-item v-for="item in imageList" :key="item">
-              <el-image :src="item" fit="contain"></el-image>
-            </el-carousel-item>
-          </el-carousel>
+          <image-contain
+            ref="ImageContain"
+            :image="curImage"
+            @on-prev="toPrevImage"
+            @on-next="toNextImage"
+            @on-rotate="imageRotateChange"
+          ></image-contain>
         </div>
         </div>
         <div class="archives-student-action part-box">
         <div class="archives-student-action part-box">
           <div class="archives-student-info">
           <div class="archives-student-info">
@@ -53,6 +49,16 @@
           </div>
           </div>
           <el-divider></el-divider>
           <el-divider></el-divider>
           <el-button type="primary" size="small" @click="toFix">纠错</el-button>
           <el-button type="primary" size="small" @click="toFix">纠错</el-button>
+          <el-button
+            type="primary"
+            size="small"
+            :disabled="!curImageRotate"
+            @click="toSaveRotate"
+            >保存旋转</el-button
+          >
+          <el-button type="danger" size="small" @click="toDelete"
+            >删除</el-button
+          >
           <p class="tips-info tips-error">
           <p class="tips-info tips-error">
             注意:<br />
             注意:<br />
             当图片里学生信息与右侧学生信息不一致时请执行纠错操作!
             当图片里学生信息与右侧学生信息不一致时请执行纠错操作!
@@ -67,18 +73,24 @@
       ref="LibraryDialog"
       ref="LibraryDialog"
       mode="fix"
       mode="fix"
       :student="studentInfo"
       :student="studentInfo"
-      @closed="getImageList"
+      @closed="reloadData"
     ></library-dialog>
     ></library-dialog>
   </div>
   </div>
 </template>
 </template>
 
 
 <script>
 <script>
 import LibraryDialog from "./LibraryDialog.vue";
 import LibraryDialog from "./LibraryDialog.vue";
-import { studentPictureList } from "../api";
+import ImageContain from "@/components/ImageContain.vue";
+import {
+  studentPictureList,
+  updateDocumentImageRotate,
+  deleteDocumentImage,
+} from "../api";
+import { uncacheUrl } from "@/plugins/utils";
 
 
 export default {
 export default {
   name: "archives-detail-student-dialog",
   name: "archives-detail-student-dialog",
-  components: { LibraryDialog },
+  components: { LibraryDialog, ImageContain },
   props: {
   props: {
     student: {
     student: {
       type: Object,
       type: Object,
@@ -91,14 +103,25 @@ export default {
     return {
     return {
       modalIsShow: false,
       modalIsShow: false,
       imageList: [],
       imageList: [],
-      imageIndex: 0,
       pageList: [],
       pageList: [],
       studentInfo: {},
       studentInfo: {},
+      // image preview
+      curImage: { url: "" },
+      curImageIndex: 0,
+      curImageRotate: 0,
     };
     };
   },
   },
   methods: {
   methods: {
-    visibleChange() {
-      this.getImageList();
+    async reloadData() {
+      this.initData();
+      await this.getImageList();
+    },
+    initData() {
+      this.imageList = [];
+      this.pageList = [];
+      this.curImage = { url: "" };
+      this.curImageRotate = 0;
+      this.curImageIndex = 0;
     },
     },
     cancel() {
     cancel() {
       this.modalIsShow = false;
       this.modalIsShow = false;
@@ -112,31 +135,94 @@ export default {
         studentId: this.student.studentId,
         studentId: this.student.studentId,
       });
       });
       this.pageList = resData.fileUrls || [];
       this.pageList = resData.fileUrls || [];
-      let imageList = [];
-      this.pageList.forEach((item) => {
-        imageList.push(...item.fileUrls);
-      });
-      this.imageList = imageList;
-    },
-    imageChange(imageIndex) {
-      this.imageIndex = imageIndex;
+      // this.pageList.forEach((item) => {
+      //   item.fileUrls = item.fileUrls.map((img) => uncacheUrl(img));
+      // });
+      this.imageList = this.pageList.map((item) => item.fileUrls).flat();
+      this.selectImage(0);
     },
     },
+    // actions
     toFix() {
     toFix() {
-      const curImage = this.imageList[this.imageIndex];
-      const curPage = this.pageList.find((item) =>
-        item.fileUrls.includes(curImage)
-      );
-      if (!curPage) return;
+      const info = this.getImageInfo(this.curImage.url);
 
 
       this.studentInfo = {
       this.studentInfo = {
         ...this.student,
         ...this.student,
-        curPagePaperIndex: curPage.fileUrls.indexOf(curImage),
-        pageList: [
-          { ...curPage, paperScanTaskId: this.student.paperScanTaskId },
-        ],
+        curPagePaperIndex: info.pindex,
+        pageList: [{ ...info, paperScanTaskId: this.student.paperScanTaskId }],
       };
       };
       this.$refs.LibraryDialog.open();
       this.$refs.LibraryDialog.open();
     },
     },
+    getImageInfo(url) {
+      const curPage = this.pageList.find((item) => item.fileUrls.includes(url));
+      const pindex = curPage.fileUrls.indexOf(url);
+      return { ...curPage, pindex };
+    },
+    imageRotateChange(rotate) {
+      this.curImageRotate = rotate;
+    },
+    async toSaveRotate() {
+      if (!this.curImageRotate) return;
+
+      const { paperLibraryId, pindex } = this.getImageInfo(this.curImage.url);
+
+      await updateDocumentImageRotate({
+        paperScanTaskId: this.student.paperScanTaskId,
+        studentId: this.student.studentId,
+        paperLibraryId,
+        pindex,
+        rotate: this.curImageRotate,
+      });
+
+      this.updateImageSource(this.curImage.url, uncacheUrl(this.curImage.url));
+    },
+    updateImageSource(oldUrl, newUrl) {
+      const curPage = this.pageList.find((item) =>
+        item.fileUrls.includes(oldUrl)
+      );
+      const pindex = curPage.fileUrls.indexOf(oldUrl);
+      curPage.fileUrls[pindex] = newUrl;
+
+      const imgIndex = this.imageList.indexOf(oldUrl);
+      this.imgIndex[imgIndex] = newUrl;
+    },
+    async toDelete() {
+      const res = await this.$confirm(`确认要删除当前页已扫描数据?`, "提示", {
+        type: "warning",
+      }).catch(() => {});
+      if (res !== "confirm") return;
+
+      const { paperLibraryId } = this.getImageInfo(this.curImage.url);
+
+      await deleteDocumentImage({
+        paperScanTaskId: this.student.paperScanTaskId,
+        studentId: this.student.studentId,
+        paperLibraryId,
+      });
+      this.$message.success("操作成功!");
+      this.reloadData();
+    },
+    selectImage(index) {
+      this.curImage = { url: this.imageList[index] };
+      this.curImageRotate = 0;
+    },
+    toPrevImage() {
+      if (this.curImageIndex === 0) {
+        this.curImageIndex = this.imageList.length - 1;
+      } else {
+        this.curImageIndex--;
+      }
+
+      this.selectImage(this.curImageIndex);
+    },
+    toNextImage() {
+      if (this.curImageIndex === this.imageList.length - 1) {
+        this.curImageIndex = 0;
+      } else {
+        this.curImageIndex++;
+      }
+
+      this.selectImage(this.curImageIndex);
+    },
   },
   },
 };
 };
 </script>
 </script>

+ 34 - 1
src/modules/record/components/ScanTaskDetailDialog.vue

@@ -39,6 +39,22 @@
           label="绑定张数"
           label="绑定张数"
           width="120"
           width="120"
         ></el-table-column>
         ></el-table-column>
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          width="90"
+          fixed="right"
+        >
+          <template slot-scope="scope">
+            <el-button
+              v-if="checkPrivilege('link', 'ClearScanData')"
+              class="btn-danger"
+              type="text"
+              @click="toClear(scope.row)"
+              >清除数据</el-button
+            >
+          </template>
+        </el-table-column>
       </el-table>
       </el-table>
       <div class="part-page">
       <div class="part-page">
         <el-pagination
         <el-pagination
@@ -56,7 +72,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
-import { scanTaskDetailPage } from "../api";
+import { scanTaskDetailPage, clearStudentScanData } from "../api";
 
 
 export default {
 export default {
   name: "scan-task-detail-dialog",
   name: "scan-task-detail-dialog",
@@ -107,6 +123,23 @@ export default {
       this.current = page;
       this.current = page;
       this.getList();
       this.getList();
     },
     },
+    async toClear(row) {
+      const res = await this.$confirm(
+        `确认要清除【${row.studentName}】已扫描数据?`,
+        "提示",
+        {
+          type: "warning",
+        }
+      ).catch(() => {});
+      if (res !== "confirm") return;
+
+      await clearStudentScanData({
+        paperScanTaskId: this.task.paperScanTaskId,
+        studentCode: row.studentCode,
+      });
+      this.$message.success("操作成功!");
+      this.getList();
+    },
   },
   },
 };
 };
 </script>
 </script>

+ 12 - 0
src/plugins/utils.js

@@ -411,3 +411,15 @@ export function parseHrefParam(href, paramName = null) {
 
 
   return paramName ? params[paramName] : params;
   return paramName ? params[paramName] : params;
 }
 }
+
+export function uncacheUrl(url) {
+  const tk = "__t";
+  const tkVal = parseHrefParam(url, tk);
+  if (tkVal) {
+    return url.replace(`${tk}=${tkVal}`, `${tk}=${Date.now()}`);
+  } else {
+    const pre = url.indexOf("?") === -1 ? "?" : "&";
+
+    return `${url}${pre}${tk}=${Date.now()}`;
+  }
+}