Преглед на файлове

feat: 封装预览组件

WANGKANG преди 8 месеца
родител
ревизия
3f16f67957
променени са 2 файла, в които са добавени 172 реда и са изтрити 124 реда
  1. 37 124
      src/views/demo/DataSeq/index.vue
  2. 135 0
      src/views/demo/components/PreviewImages.vue

+ 37 - 124
src/views/demo/DataSeq/index.vue

@@ -3,7 +3,8 @@
     <ProTable ref="proTable" :columns="columns" row-key="id" :request-api="listDataSeqApi">
       <!-- 表格 header 按钮 -->
       <template #tableHeader="scope">
-        <el-button type="primary" v-auth="['demo:DataSeq:add']" icon="CirclePlus" @click="openDialog(1, '数据集新增')"> 新增 </el-button>
+        <el-button type="primary" v-auth="['demo:DataSeq:add']" icon="CirclePlus" @click="openDialog(1, '数据集新增')"> 新增
+        </el-button>
         <!-- <el-button type="primary" v-auth="['demo:DataSeq:import']" icon="Upload" plain @click="batchAdd"> 导入 </el-button>
         <el-button type="primary" v-auth="['demo:DataSeq:export']" icon="Download" plain @click="downloadFile"> 导出 </el-button> -->
         <el-button
@@ -19,58 +20,33 @@
       </template>
       <!-- 表格操作 -->
       <template #operation="scope">
-        <el-button type="primary" link icon="View" v-auth="['demo:DataSeq:query']" @click="openDialog(3, '数据管理查看', scope.row)">
+        <el-button type="primary" link icon="View" v-auth="['demo:DataSeq:query']"
+                   @click="openDialog(3, '数据管理查看', scope.row)">
           查看
         </el-button>
-        <el-button type="primary" link icon="View" v-auth="['demo:DataSeq:query']" @click="showImages(scope.row)"> 预览 </el-button>
+        <el-button type="primary" link icon="View" v-auth="['demo:DataSeq:query']" @click="preview(scope.row)"> 预览</el-button>
         <!-- <el-button type="primary" link icon="EditPen" v-auth="['demo:DataSeq:edit']" @click="openDialog(2, '数据管理编辑', scope.row)">
           编辑
         </el-button> -->
-        <el-button type="primary" link icon="Delete" v-auth="['demo:DataSeq:remove']" @click="deleteDataSeq(scope.row)"> 删除 </el-button>
+        <el-button type="primary" link icon="Delete" v-auth="['demo:DataSeq:remove']" @click="deleteDataSeq(scope.row)"> 删除
+        </el-button>
       </template>
     </ProTable>
-    <FormDialog ref="formDialogRef" />
+    <FormDialog ref="formDialogRef"/>
     <!-- <ImportExcel ref="dialogRef" /> -->
-    <el-dialog
-      v-model="dialogVisible"
-      :title="'数据集预览 - 共' + currentImageUrls.length + '张 当前第' + (imageIdx + 1) + '张'"
-      width="80%"
-      :before-close="handleClose"
-    >
-      <el-form :inline="true">
-        <el-form-item label="帧率">
-          <el-select v-model="imageFps" placeholder="选择帧率" style="width: 200px" @change="changeFps">
-            <el-option label="0" value="0"></el-option>
-            <el-option label="5" value="5"></el-option>
-            <el-option label="15" value="15"></el-option>
-            <el-option label="30" value="30"></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="跳转至">
-          <el-input v-model="newImageIdx" type="number" style="width: 100px" />
-          <el-button type="primary" @click="confirmNewImageIdx" style="margin-left: 10px">确认</el-button>
-        </el-form-item>
-      </el-form>
-      <div class="image-dialog">
-        <el-image :src="currentImageUrls[imageIdx]" style="width: 40%"></el-image>
-      </div>
-      <div class="image-dialog-btn" v-if="imageFps == 0">
-        <el-button type="primary" @click="pre_picture" :disabled="imageIdx <= 0">上一个</el-button>
-        <el-button type="primary" @click="next_picture" :disabled="imageIdx >= currentImageUrls.length - 1">下一个</el-button>
-      </div>
-    </el-dialog>
+    <PreviewImages :visible="dialogVisible" :urls="imageUrls" @close="dialogVisible = false"/>
   </div>
 </template>
 
 <script setup lang="tsx" name="DataSeq">
-import { ref, reactive } from 'vue'
-import { useHandleData } from '@/hooks/useHandleData'
-import { useDownload } from '@/hooks/useDownload'
-import { ElMessageBox } from 'element-plus'
+import {ref, reactive} from 'vue'
+import {useHandleData} from '@/hooks/useHandleData'
+import {useDownload} from '@/hooks/useDownload'
+import {ElMessageBox} from 'element-plus'
 import ProTable from '@/components/ProTable/index.vue'
 import ImportExcel from '@/components/ImportExcel/index.vue'
 import FormDialog from '@/components/FormDialog/index.vue'
-import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
+import {ProTableInstance, ColumnProps} from '@/components/ProTable/interface'
 import {
   listDataSeqApi,
   delDataSeqApi,
@@ -82,65 +58,15 @@ import {
   getDataSeqApi,
   getAllImagesApi
 } from '@/api/modules/demo/DataSeq'
-import { enumsSubSystem } from '../utils'
-
+import {enumsSubSystem} from '../utils'
+import PreviewImages from "@/views/demo/components/PreviewImages.vue";
 const dialogVisible = ref(false)
-const imageFps = ref(0)
-const intervalChangeFps: any = ref()
-const imageIdx = ref(0)
-const currentImageUrls = ref<string[]>([])
-const newImageIdx = ref()
-
-const handleClose = (done: () => void) => {
-  console.log('handleClose')
-  if (intervalChangeFps.value) {
-    clearInterval(intervalChangeFps.value)
-  }
-  done()
-}
-
-const confirmNewImageIdx = () => {
-  const val = parseInt(newImageIdx.value)
-  if (val > 0 && val <= currentImageUrls.value.length) {
-    imageIdx.value = val - 1
-  } else {
-    ElMessageBox.alert('跳转索引有误,请检查!')
-  }
-}
-
-const showImages = async (row: any) => {
-  // console.log(row)
-  dialogVisible.value = true
-
+const imageUrls = ref([])
+const preview = async(row) => {
+  console.log("showImages")
   const data: any = await getAllImagesApi(row.inputOssId)
-  currentImageUrls.value = data.data
-}
-
-const changeFps = () => {
-  console.log('changeFps')
-  if (intervalChangeFps.value) {
-    clearInterval(intervalChangeFps.value)
-  }
-
-  if (imageFps.value == 0) {
-    return
-  }
-
-  intervalChangeFps.value = setInterval(() => {
-    next_picture()
-  }, 1000 / imageFps.value)
-}
-
-const next_picture = () => {
-  if (imageIdx.value <= currentImageUrls.value.length - 1) {
-    imageIdx.value += 1
-  }
-}
-
-const pre_picture = () => {
-  if (imageIdx.value > 0) {
-    imageIdx.value -= 1
-  }
+  imageUrls.value = data.data
+  dialogVisible.value = true
 }
 
 // ProTable 实例
@@ -161,7 +87,7 @@ const batchDelete = async (ids: string[]) => {
 
 // 导出数据管理列表
 const downloadFile = async () => {
-  ElMessageBox.confirm('确认导出数据管理数据?', '温馨提示', { type: 'warning' }).then(() =>
+  ElMessageBox.confirm('确认导出数据管理数据?', '温馨提示', {type: 'warning'}).then(() =>
     useDownload(exportDataSeqApi, '数据管理列表', proTable.value?.searchParam)
   )
 }
@@ -181,7 +107,7 @@ const batchAdd = () => {
 const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)
 // 打开弹框的功能
 const openDialog = async (type: number, title: string, row?: any) => {
-  let res = { data: {} }
+  let res = {data: {}}
   if (row?.id) {
     res = await getDataSeqApi(row?.id || null)
   }
@@ -201,8 +127,8 @@ const openDialog = async (type: number, title: string, row?: any) => {
 
 // 表格配置项
 const columns = reactive<ColumnProps<any>[]>([
-  { type: 'selection', fixed: 'left', width: 70 },
-  { prop: 'id', label: 'id' },
+  {type: 'selection', fixed: 'left', width: 70},
+  {prop: 'id', label: 'id'},
   {
     prop: 'name',
     label: '名称',
@@ -285,7 +211,7 @@ const columns = reactive<ColumnProps<any>[]>([
       el: 'input'
     }
   },
-  { prop: 'operation', label: '操作', width: 230, fixed: 'right' }
+  {prop: 'operation', label: '操作', width: 230, fixed: 'right'}
 ])
 // 表单配置项
 let itemsOptions: ProForm.ItemsOptions[] = []
@@ -294,7 +220,7 @@ const setItemsOptions = () => {
     {
       label: '名称',
       prop: 'name',
-      rules: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
+      rules: [{required: true, message: '名称不能为空', trigger: 'blur'}],
       compOptions: {
         placeholder: '请输入名称'
       }
@@ -302,7 +228,7 @@ const setItemsOptions = () => {
     {
       label: '分系统',
       prop: 'subsystem',
-      rules: [{ required: true, message: '分系统不能为空', trigger: 'blur' }],
+      rules: [{required: true, message: '分系统不能为空', trigger: 'blur'}],
       compOptions: {
         elTagName: 'select',
         enum: enumsSubSystem,
@@ -312,7 +238,7 @@ const setItemsOptions = () => {
     {
       label: '批次号',
       prop: 'batchNum',
-      rules: [{ required: true, message: '批次号不能为空', trigger: 'blur' }],
+      rules: [{required: true, message: '批次号不能为空', trigger: 'blur'}],
       compOptions: {
         placeholder: '请输入批次号'
       }
@@ -320,7 +246,7 @@ const setItemsOptions = () => {
     {
       label: '上传文件',
       prop: 'inputOssId',
-      rules: [{ required: true, message: '数据集文件不能为空', trigger: 'blur' }],
+      rules: [{required: true, message: '数据集文件不能为空', trigger: 'blur'}],
       compOptions: {
         elTagName: 'file-upload',
         fileSize: 4096,
@@ -339,7 +265,7 @@ const setItemsOptions = () => {
     {
       label: '目标类型',
       prop: 'objectType',
-      rules: [{ required: false, message: '目标类型不能为空', trigger: 'blur' }],
+      rules: [{required: false, message: '目标类型不能为空', trigger: 'blur'}],
       compOptions: {
         placeholder: '请输入目标类型'
       }
@@ -347,7 +273,7 @@ const setItemsOptions = () => {
     {
       label: '目标子类型',
       prop: 'objectSubtype',
-      rules: [{ required: false, message: '目标子类型不能为空', trigger: 'blur' }],
+      rules: [{required: false, message: '目标子类型不能为空', trigger: 'blur'}],
       compOptions: {
         placeholder: '请输入目标子类型'
       }
@@ -355,7 +281,7 @@ const setItemsOptions = () => {
     {
       label: '场景',
       prop: 'scene',
-      rules: [{ required: false, message: '场景不能为空', trigger: 'blur' }],
+      rules: [{required: false, message: '场景不能为空', trigger: 'blur'}],
       compOptions: {
         placeholder: '请输入场景'
       }
@@ -363,7 +289,7 @@ const setItemsOptions = () => {
     {
       label: '数据源',
       prop: 'dataSource',
-      rules: [{ required: false, message: '数据源不能为空', trigger: 'blur' }],
+      rules: [{required: false, message: '数据源不能为空', trigger: 'blur'}],
       compOptions: {
         placeholder: '请输入数据源'
       }
@@ -371,7 +297,7 @@ const setItemsOptions = () => {
     {
       label: '采集时间',
       prop: 'gatherTime',
-      rules: [{ required: false, message: '采集时间不能为空', trigger: 'change' }],
+      rules: [{required: false, message: '采集时间不能为空', trigger: 'change'}],
       compOptions: {
         elTagName: 'date-picker',
         type: 'date',
@@ -381,7 +307,7 @@ const setItemsOptions = () => {
     {
       label: '采集地点',
       prop: 'gatherSpot',
-      rules: [{ required: false, message: '采集地点不能为空', trigger: 'blur' }],
+      rules: [{required: false, message: '采集地点不能为空', trigger: 'blur'}],
       compOptions: {
         placeholder: '请输入采集地点'
       }
@@ -407,7 +333,7 @@ const setItemsOptions = () => {
     {
       label: '备注',
       prop: 'remarks',
-      rules: [{ required: false, message: '备注不能为空', trigger: 'blur' }],
+      rules: [{required: false, message: '备注不能为空', trigger: 'blur'}],
       compOptions: {
         placeholder: '请输入备注'
       }
@@ -417,17 +343,4 @@ const setItemsOptions = () => {
 </script>
 
 <style lang="scss" scoped>
-.image-dialog {
-  display: flex;
-  justify-content: center;
-  .el-image {
-    margin-right: 20px;
-    margin-bottom: 20px;
-  }
-}
-.image-dialog-btn {
-  display: flex;
-  justify-content: center;
-  margin-top: 20px;
-}
 </style>

+ 135 - 0
src/views/demo/components/PreviewImages.vue

@@ -0,0 +1,135 @@
+<!--
+# @Date: 2024-10-11 14:37:11
+# @Author: WANGKANG
+# @Blog:
+# @Email:
+# @Filepath: src\views\demo\components\PreviewImages.vue
+# @Description: PreviewImages.vue
+# Copyright 2024 WANGKANG, All Rights Reserved.
+-->
+
+<template>
+  <el-dialog
+    v-model="dialogVisible"
+    :title="'预览 - 共' + currentImageUrls.length + '张 当前第' + (imageIdx + 1) + '张'"
+    width="80%"
+    @open="handleOpen"
+    :before-close="handleClose"
+  >
+    <el-form :inline="true">
+      <el-form-item label="帧率">
+        <el-select v-model="imageFps" placeholder="选择帧率" style="width: 200px" @change="changeFps">
+          <el-option label="0" value="0"></el-option>
+          <el-option label="5" value="5"></el-option>
+          <el-option label="15" value="15"></el-option>
+          <el-option label="30" value="30"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="跳转至">
+        <el-input v-model="newImageIdx" type="number" style="width: 100px"/>
+        <el-button type="primary" @click="confirmNewImageIdx" style="margin-left: 10px">确认</el-button>
+      </el-form-item>
+    </el-form>
+    <div class="image-dialog">
+      <el-image :src="currentImageUrls[imageIdx]" style="width: 40%"></el-image>
+    </div>
+    <div class="image-dialog-btn" v-if="imageFps == 0">
+      <el-button type="primary" @click="pre_picture" :disabled="imageIdx <= 0">上一个</el-button>
+      <el-button type="primary" @click="next_picture" :disabled="imageIdx >= currentImageUrls.length - 1">下一个</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script setup lang="ts">
+import {ElMessageBox} from "element-plus";
+import {ref, watch} from "vue";
+
+const props = defineProps({
+  visible: {
+    type: Boolean, //接受的数据类型
+    default: false //接受默认数据
+  },
+  urls: {
+    type: Array,
+    default: ()=>[]
+  }
+})
+
+watch(() => props.visible, (val) => {
+  dialogVisible.value = val
+})
+
+const handleOpen = () => {
+  currentImageUrls.value = props.urls
+  imageIdx.value = 0
+}
+
+const dialogVisible = ref(false)
+const imageFps = ref(0)
+const intervalChangeFps: any = ref()
+const imageIdx = ref(0)
+const currentImageUrls = ref<any[]>([])
+const newImageIdx = ref()
+
+const handleClose = (done: () => void) => {
+  console.log('handleClose')
+  if (intervalChangeFps.value) {
+    clearInterval(intervalChangeFps.value)
+  }
+  done()
+}
+
+const confirmNewImageIdx = () => {
+  const val = parseInt(newImageIdx.value)
+  if (val > 0 && val <= currentImageUrls.value.length) {
+    imageIdx.value = val - 1
+  } else {
+    ElMessageBox.alert('跳转索引有误,请检查!')
+  }
+}
+
+const changeFps = () => {
+  console.log('changeFps')
+  if (intervalChangeFps.value) {
+    clearInterval(intervalChangeFps.value)
+  }
+
+  if (imageFps.value == 0) {
+    return
+  }
+
+  intervalChangeFps.value = setInterval(() => {
+    next_picture()
+  }, 1000 / imageFps.value)
+}
+
+const next_picture = () => {
+  if (imageIdx.value <= currentImageUrls.value.length - 1) {
+    imageIdx.value += 1
+  }
+}
+
+const pre_picture = () => {
+  if (imageIdx.value > 0) {
+    imageIdx.value -= 1
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.image-dialog {
+  display: flex;
+  justify-content: center;
+
+  .el-image {
+    margin-right: 20px;
+    margin-bottom: 20px;
+  }
+}
+
+.image-dialog-btn {
+  display: flex;
+  justify-content: center;
+  margin-top: 20px;
+}
+</style>