Browse Source

审核资源预览

natasha 4 days ago
parent
commit
524bbdfa87

+ 76 - 2
src/components/AuditRemark.vue

@@ -11,6 +11,7 @@
           content_select,
           component_id,
           audit_flow_node_name,
+          file_list,
         } in remarkList"
         :key="remarkId"
       >
@@ -19,6 +20,14 @@
           <span class="content-select">{{ content_select }}</span>
         </template>
         <p v-html="content"></p>
+        <template v-if="file_list.length > 0">
+          <div v-for="(item, index) in file_list" :key="index" class="file-item">
+            <SvgIcon :icon-class="item.icon_type" />
+            <span class="file-item-name">{{ item.file_name }}</span>
+            <SvgIcon icon-class="uploadPreview" @click="viewDialog(item)" />
+            <SvgIcon icon-class="download" @click="downLoad(item)" />
+          </div>
+        </template>
         <div v-if="isAudit" class="remark-bottom">
           <span>{{ remark_person_name + ':' + remark_time }}</span>
           <div class="btn-box">
@@ -39,10 +48,24 @@
       </li>
     </ul>
     <p v-else style="text-align: center">暂无批注</p>
+    <el-dialog
+      v-if="visible"
+      :visible.sync="visible"
+      :show-close="true"
+      :close-on-click-modal="true"
+      :modal-append-to-body="true"
+      :append-to-body="true"
+      :lock-scroll="true"
+      :width="'80%'"
+      top="0"
+    >
+      <iframe v-if="visible" :src="newpath" width="100%" :height="iframeHeight" frameborder="0"></iframe>
+    </el-dialog>
   </div>
 </template>
 
 <script>
+import { getToken, getConfig } from '@/utils/auth';
 export default {
   name: 'AuditRemark',
   props: {
@@ -56,7 +79,12 @@ export default {
     },
   },
   data() {
-    return {};
+    return {
+      file_preview_url: getConfig() ? getConfig().doc_preview_service_address : '',
+      visible: false,
+      newpath: '',
+      iframeHeight: `${window.innerHeight - 100}px`,
+    };
   },
   methods: {
     deleteRemarks(remarkId) {
@@ -65,6 +93,25 @@ export default {
     handleLocation(componentId) {
       this.$emit('handleLocationRemarks', componentId);
     },
+    // 下载文件
+    downLoad(file) {
+      let userInfor = getToken();
+      let AccessToken = '';
+      if (userInfor) {
+        AccessToken = userInfor.access_token;
+      }
+      let FileID = file.file_id;
+      let data = {
+        AccessToken,
+        FileID,
+      };
+      location.href = `${process.env.VUE_APP_EEP}/FileServer/WebFileDownload?AccessToken=${data.AccessToken}&FileID=${data.FileID}`;
+    },
+    // 预览
+    viewDialog(file) {
+      this.newpath = `${this.file_preview_url}onlinePreview?url=${Base64.encode(file.file_url)}`;
+      this.visible = true;
+    },
   },
 };
 </script>
@@ -88,7 +135,8 @@ export default {
     display: flex;
     gap: 8px;
     align-items: center;
-    width: 55px;
+
+    // width: 55px;
     padding: 0 10px;
     border-left: 1px solid #e5e5e5;
   }
@@ -137,5 +185,31 @@ export default {
       }
     }
   }
+
+  .file-item {
+    display: flex;
+    gap: 5px;
+    align-items: center;
+    padding: 3px;
+    margin: 5px;
+    background: #f2f3f5;
+    border-radius: 3px;
+
+    &-name {
+      flex: 1;
+      font-size: 12px;
+      word-break: break-all;
+    }
+
+    .svg-icon {
+      flex-shrink: 0;
+      font-size: 16px;
+    }
+
+    .uploadPreview,
+    .download {
+      cursor: pointer;
+    }
+  }
 }
 </style>

+ 18 - 0
src/components/CommonPreview.vue

@@ -938,6 +938,24 @@ export default {
       GetCoursewareAuditRemarkList({
         courseware_id: id,
       }).then(({ remark_list }) => {
+        remark_list.forEach((item) => {
+          item.file_list.forEach((items) => {
+            let suffix = items.file_name
+              .slice(items.file_name.lastIndexOf('.') + 1, items.file_name.length)
+              .toLowerCase();
+            if (suffix === 'png' || suffix === 'jpg' || suffix === 'jpeg') {
+              items.icon_type = 'image';
+            } else if (suffix === 'zip' || suffix === 'rar') {
+              items.icon_type = 'zip';
+            } else if (suffix === 'mp3') {
+              items.icon_type = 'mp3';
+            } else if (suffix === 'mp4') {
+              items.icon_type = 'video';
+            } else {
+              items.icon_type = 'file';
+            }
+          });
+        });
         this.remark_list = remark_list;
         if (!remark_list) return;
 

+ 1 - 0
src/icons/svg/image.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1777191958327" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5611" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M938.666667 553.92V768c0 64.8-52.533333 117.333333-117.333334 117.333333H202.666667c-64.8 0-117.333333-52.533333-117.333334-117.333333V256c0-64.8 52.533333-117.333333 117.333334-117.333333h618.666666c64.8 0 117.333333 52.533333 117.333334 117.333333v297.92z m-64-74.624V256a53.333333 53.333333 0 0 0-53.333334-53.333333H202.666667a53.333333 53.333333 0 0 0-53.333334 53.333333v344.48A290.090667 290.090667 0 0 1 192 597.333333a286.88 286.88 0 0 1 183.296 65.845334C427.029333 528.384 556.906667 437.333333 704 437.333333c65.706667 0 126.997333 16.778667 170.666667 41.962667z m0 82.24c-5.333333-8.32-21.130667-21.653333-43.648-32.917333C796.768 511.488 753.045333 501.333333 704 501.333333c-121.770667 0-229.130667 76.266667-270.432 188.693334-2.730667 7.445333-7.402667 20.32-13.994667 38.581333-7.68 21.301333-34.453333 28.106667-51.370666 13.056-16.437333-14.634667-28.554667-25.066667-36.138667-31.146667A222.890667 222.890667 0 0 0 192 661.333333c-14.464 0-28.725333 1.365333-42.666667 4.053334V768a53.333333 53.333333 0 0 0 53.333334 53.333333h618.666666a53.333333 53.333333 0 0 0 53.333334-53.333333V561.525333zM320 480a96 96 0 1 1 0-192 96 96 0 0 1 0 192z m0-64a32 32 0 1 0 0-64 32 32 0 0 0 0 64z" fill="#000000" p-id="5612"></path></svg>

+ 96 - 2
src/views/book/courseware/preview/CoursewarePreview.vue

@@ -107,12 +107,58 @@
         <span class="button" @click="setFeedback"> <SvgIcon icon-class="sidebar-feedback" size="14" /> 用户反馈</span> -->
       </template>
     </div>
+    <template v-if="showRemark && Object.keys(componentRemarkObj).length !== 0 && componentRemarkObj['WHOLE']">
+      <el-popover
+        v-for="(items, indexs) in componentRemarkObj['WHOLE']"
+        :key="'menu-remark-info' + indexs"
+        placement="bottom"
+        trigger="click"
+        popper-class="menu-remark-info"
+      >
+        <div v-html="items.content"></div>
+        <template v-if="items.file_list.length > 0">
+          <div v-for="(item, index) in items.file_list" :key="indexs + '-' + index" class="remark-file-item">
+            <SvgIcon :icon-class="item.icon_type" />
+            <span class="file-item-name">{{ item.file_name }}</span>
+            <SvgIcon icon-class="uploadPreview" @click="viewDialog(item)" />
+            <SvgIcon icon-class="download" @click="downLoad(item)" />
+          </div>
+        </template>
+        <template #reference>
+          <div
+            v-if="items.position_br_x - items.position_x > 3 && items.position_br_y - items.position_y > 3"
+            slot="reference"
+            :style="{
+              position: 'absolute',
+              top: `${items.position_y}px`,
+              left: `${items.position_x}px`,
+              width: `${items.position_br_x - items.position_x}px`,
+              height: `${items.position_br_y - items.position_y}px`,
+              border: '2px solid #165DFF',
+            }"
+          ></div>
+        </template>
+      </el-popover>
+    </template>
+    <el-dialog
+      v-if="visible"
+      :visible.sync="visible"
+      :show-close="true"
+      :close-on-click-modal="true"
+      :modal-append-to-body="true"
+      :append-to-body="true"
+      :lock-scroll="true"
+      :width="'80%'"
+      top="0"
+    >
+      <iframe v-if="visible" :src="newpath" width="100%" :height="iframeHeight" frameborder="0"></iframe>
+    </el-dialog>
   </div>
 </template>
 
 <script>
 import { previewComponentList } from '@/views/book/courseware/data/bookType';
-
+import { getToken, getConfig } from '@/utils/auth';
 import _ from 'lodash';
 
 export default {
@@ -198,6 +244,10 @@ export default {
       curSelectId: '', // 当前选中组件id
 
       isSelecting: false, // 是否开始框选内容
+      file_preview_url: getConfig() ? getConfig().doc_preview_service_address : '',
+      visible: false,
+      newpath: '',
+      iframeHeight: `${window.innerHeight - 100}px`,
     };
   },
   watch: {
@@ -1029,7 +1079,6 @@ export default {
     startSelection(event) {
       if (this.canRemark) {
         this.isSelecting = true;
-
         let clientRect = document.getElementById(`selectable-area-preview`).getBoundingClientRect();
         this.menuPosition.startX = event.clientX - clientRect.left;
         this.menuPosition.startY = event.clientY - clientRect.top;
@@ -1068,6 +1117,25 @@ export default {
     resetRemark() {
       this.menuPosition = { x: 0, y: 0, select_node: '', startX: null, startY: null, endX: null, endY: null };
     },
+    // 下载文件
+    downLoad(file) {
+      let userInfor = getToken();
+      let AccessToken = '';
+      if (userInfor) {
+        AccessToken = userInfor.access_token;
+      }
+      let FileID = file.file_id;
+      let data = {
+        AccessToken,
+        FileID,
+      };
+      location.href = `${process.env.VUE_APP_EEP}/FileServer/WebFileDownload?AccessToken=${data.AccessToken}&FileID=${data.FileID}`;
+    },
+    // 预览
+    viewDialog(file) {
+      this.newpath = `${this.file_preview_url}onlinePreview?url=${Base64.encode(file.file_url)}`;
+      this.visible = true;
+    },
   },
 };
 </script>
@@ -1173,4 +1241,30 @@ export default {
     max-width: 100%;
   }
 }
+
+.remark-file-item {
+  display: flex;
+  gap: 5px;
+  align-items: center;
+  padding: 3px;
+  margin: 5px 0;
+  background: #f2f3f5;
+  border-radius: 3px;
+
+  &-name {
+    flex: 1;
+    font-size: 12px;
+    word-break: break-all;
+  }
+
+  .svg-icon {
+    flex-shrink: 0;
+    font-size: 16px;
+  }
+
+  .uploadPreview,
+  .download {
+    cursor: pointer;
+  }
+}
 </style>