浏览代码

feat: 前端更好的图片查看方式

WANGKANG 8 月之前
父节点
当前提交
e32389916a
共有 3 个文件被更改,包括 413 次插入320 次删除
  1. 219 221
      src/api/interface/demo/DataSeq.ts
  2. 21 9
      src/api/modules/demo/DataSeq.ts
  3. 173 90
      src/views/demo/DataSeq/index.vue

+ 219 - 221
src/api/interface/demo/DataSeq.ts

@@ -1,223 +1,221 @@
 import { PageQuery, BaseEntity } from '@/api/interface/index'
 export interface DataSeqVO extends BaseEntity {
-    /**
-    * id
-    */
-        id: string | number;
-
-    /**
-    * 名称
-    */
-        name: string;
-
-    /**
-    * 数据类型
-    */
-        dataType: string;
-
-    /**
-    * 文件类型
-    */
-        fileType: string;
-
-    /**
-    * 目标类型
-    */
-        objectType: string;
-
-    /**
-    * 目标子类型
-    */
-        objectSubtype: string;
-
-    /**
-    * 批次号
-    */
-        batchNum: string;
-
-    /**
-    * 场景
-    */
-        scene: string;
-
-    /**
-    * 数据源
-    */
-        dataSource: string;
-
-    /**
-    * 采集时间
-    */
-        gatherTime: string;
-
-    /**
-    * 采集地点
-    */
-        gatherSpot: string;
-
-    /**
-    * 图片url
-    */
-        url: string;
-
-    /**
-    * 日志
-    */
-        log: string;
-
-    /**
-    * 备注
-    */
-        remarks: string;
-
-    }
-
-    export interface DataSeqForm {
-        /**
-        * id
-        */
-        id?: string | number;
-
-        /**
-        * 名称
-        */
-        name?: string;
-
-        /**
-        * 数据类型
-        */
-        dataType?: string;
-
-        /**
-        * 文件类型
-        */
-        fileType?: string;
-
-        /**
-        * 目标类型
-        */
-        objectType?: string;
-
-        /**
-        * 目标子类型
-        */
-        objectSubtype?: string;
-
-        /**
-        * 批次号
-        */
-        batchNum?: string;
-
-        /**
-        * 场景
-        */
-        scene?: string;
-
-        /**
-        * 数据源
-        */
-        dataSource?: string;
-
-        /**
-        * 采集时间
-        */
-        gatherTime?: string;
-
-        /**
-        * 采集地点
-        */
-        gatherSpot?: string;
-
-        /**
-        * 图片url
-        */
-        url?: string;
-
-        /**
-        * 日志
-        */
-        log?: string;
-
-        /**
-        * 备注
-        */
-        remarks?: string;
-
-        /**
-        * 乐观锁
-        */
-        version?: number;
-
-    }
-
-    export interface DataSeqQuery extends PageQuery {
-        /**
-        * 名称
-        */
-        name?: string;
-
-        /**
-        * 数据类型
-        */
-        dataType?: string;
-
-        /**
-        * 文件类型
-        */
-        fileType?: string;
-
-        /**
-        * 目标类型
-        */
-        objectType?: string;
-
-        /**
-        * 目标子类型
-        */
-        objectSubtype?: string;
-
-        /**
-        * 批次号
-        */
-        batchNum?: string;
-
-        /**
-        * 场景
-        */
-        scene?: string;
-
-        /**
-        * 数据源
-        */
-        dataSource?: string;
-
-        /**
-        * 采集时间
-        */
-        gatherTime?: string;
-
-        /**
-        * 采集地点
-        */
-        gatherSpot?: string;
-
-        /**
-        * 图片url
-        */
-        url?: string;
-
-        /**
-        * 日志
-        */
-        log?: string;
-
-        /**
-        * 备注
-        */
-        remarks?: string;
-
-    /**
-    * 日期范围参数
-    */
-    params?: any;
-    }
+  /**
+   * id
+   */
+  id: string | number
+
+  /**
+   * 名称
+   */
+  name: string
+
+  /**
+   * 数据类型
+   */
+  dataType: string
+
+  /**
+   * 文件类型
+   */
+  fileType: string
+
+  /**
+   * 目标类型
+   */
+  objectType: string
+
+  /**
+   * 目标子类型
+   */
+  objectSubtype: string
+
+  /**
+   * 批次号
+   */
+  batchNum: string
+
+  /**
+   * 场景
+   */
+  scene: string
+
+  /**
+   * 数据源
+   */
+  dataSource: string
+
+  /**
+   * 采集时间
+   */
+  gatherTime: string
+
+  /**
+   * 采集地点
+   */
+  gatherSpot: string
+
+  /**
+   * 图片url
+   */
+  url: string
+
+  /**
+   * 日志
+   */
+  log: string
+
+  /**
+   * 备注
+   */
+  remarks: string
+}
+
+export interface DataSeqForm {
+  /**
+   * id
+   */
+  id?: string | number
+
+  /**
+   * 名称
+   */
+  name?: string
+
+  /**
+   * 数据类型
+   */
+  dataType?: string
+
+  /**
+   * 文件类型
+   */
+  fileType?: string
+
+  /**
+   * 目标类型
+   */
+  objectType?: string
+
+  /**
+   * 目标子类型
+   */
+  objectSubtype?: string
+
+  /**
+   * 批次号
+   */
+  batchNum?: string
+
+  /**
+   * 场景
+   */
+  scene?: string
+
+  /**
+   * 数据源
+   */
+  dataSource?: string
+
+  /**
+   * 采集时间
+   */
+  gatherTime?: string
+
+  /**
+   * 采集地点
+   */
+  gatherSpot?: string
+
+  /**
+   * 图片url
+   */
+  url?: string
+
+  /**
+   * 日志
+   */
+  log?: string
+
+  /**
+   * 备注
+   */
+  remarks?: string
+
+  /**
+   * 乐观锁
+   */
+  version?: number
+}
+
+export interface DataSeqQuery extends PageQuery {
+  /**
+   * 名称
+   */
+  name?: string
+
+  /**
+   * 数据类型
+   */
+  dataType?: string
+
+  /**
+   * 文件类型
+   */
+  fileType?: string
+
+  /**
+   * 目标类型
+   */
+  objectType?: string
+
+  /**
+   * 目标子类型
+   */
+  objectSubtype?: string
+
+  /**
+   * 批次号
+   */
+  batchNum?: string
+
+  /**
+   * 场景
+   */
+  scene?: string
+
+  /**
+   * 数据源
+   */
+  dataSource?: string
+
+  /**
+   * 采集时间
+   */
+  gatherTime?: string
+
+  /**
+   * 采集地点
+   */
+  gatherSpot?: string
+
+  /**
+   * 图片url
+   */
+  url?: string
+
+  /**
+   * 日志
+   */
+  log?: string
+
+  /**
+   * 备注
+   */
+  remarks?: string
+
+  /**
+   * 日期范围参数
+   */
+  params?: any
+}

+ 21 - 9
src/api/modules/demo/DataSeq.ts

@@ -1,12 +1,12 @@
 import http from '@/api'
-import { DataSeqVO, DataSeqForm, DataSeqQuery  } from '@/api/interface/demo/DataSeq'
+import { DataSeqVO, DataSeqForm, DataSeqQuery } from '@/api/interface/demo/DataSeq'
 /**
  * @name 查询数据管理列表
  * @param query 参数
  * @returns 返回列表
  */
 export const listDataSeqApi = (query: DataSeqQuery) => {
-    return http.get<DataSeqVO[]>('/demo/DataSeq/list', query, { loading: true })
+  return http.get<DataSeqVO[]>('/demo/DataSeq/list', query, { loading: true })
 }
 
 /**
@@ -15,7 +15,7 @@ export const listDataSeqApi = (query: DataSeqQuery) => {
  * @returns returns
  */
 export const getDataSeqApi = (id: string | number) => {
-    return http.get<DataSeqVO>(`/demo/DataSeq/${id}`)
+  return http.get<DataSeqVO>(`/demo/DataSeq/${id}`)
 }
 
 /**
@@ -24,7 +24,7 @@ export const getDataSeqApi = (id: string | number) => {
  * @returns returns
  */
 export const addDataSeqApi = (data: DataSeqForm) => {
-    return http.post<any>('/demo/DataSeq', data, { loading: false })
+  return http.post<any>('/demo/DataSeq', data, { loading: false })
 }
 
 /**
@@ -33,7 +33,7 @@ export const addDataSeqApi = (data: DataSeqForm) => {
  * @returns returns
  */
 export const updateDataSeqApi = (data: DataSeqForm) => {
-    return http.put<any>('/demo/DataSeq', data, { loading: false })
+  return http.put<any>('/demo/DataSeq', data, { loading: false })
 }
 
 /**
@@ -42,7 +42,7 @@ export const updateDataSeqApi = (data: DataSeqForm) => {
  * @returns returns
  */
 export const delDataSeqApi = (id: string | number | Array<string | number>) => {
-    return http.delete<any>(`/demo/DataSeq/${id}`)
+  return http.delete<any>(`/demo/DataSeq/${id}`)
 }
 
 /**
@@ -50,7 +50,7 @@ export const delDataSeqApi = (id: string | number | Array<string | number>) => {
  * @returns returns
  */
 export const importTemplateApi = () => {
-    return http.downloadPost('/demo/DataSeq/importTemplate', {})
+  return http.downloadPost('/demo/DataSeq/importTemplate', {})
 }
 
 /**
@@ -58,7 +58,7 @@ export const importTemplateApi = () => {
  * @returns returns
  */
 export const importDataSeqDataApi = (data: any) => {
-    return http.post('/demo/DataSeq/importData', data)
+  return http.post('/demo/DataSeq/importData', data)
 }
 
 /**
@@ -66,5 +66,17 @@ export const importDataSeqDataApi = (data: any) => {
  * @returns returns
  */
 export const exportDataSeqApi = (data: any) => {
-    return http.downloadPost('/demo/DataSeq/export', data)
+  return http.downloadPost('/demo/DataSeq/export', data)
+}
+
+/**
+ * @name 导入数据集
+ * @returns returns
+ */
+export const batchAdDataSeqApi = (data: any) => {
+  return http.post('/demo/DataSeq/batchAdd', data)
+}
+
+export const getAllImagesApi = (ossId: any) => {
+  return http.get('/demo/DataSeq/getAllImages/' + ossId)
 }

+ 173 - 90
src/views/demo/DataSeq/index.vue

@@ -3,9 +3,9 @@
     <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: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 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
           type="danger"
           v-auth="['demo:DataSeq:remove']"
@@ -22,15 +22,39 @@
         <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="EditPen" v-auth="['demo:DataSeq:edit']" @click="openDialog(2, '数据管理编辑', scope.row)">
+        <el-button type="primary" link icon="View" v-auth="['demo:DataSeq:query']" @click="showImages(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> -->
         <el-button type="primary" link icon="Delete" v-auth="['demo:DataSeq:remove']" @click="deleteDataSeq(scope.row)"> 删除 </el-button>
       </template>
     </ProTable>
     <FormDialog ref="formDialogRef" />
-    <ImportExcel ref="dialogRef" />
   </div>
+  <!-- <ImportExcel ref="dialogRef" /> -->
+  <el-dialog v-model="dialogVisible" :title="'数据集预览 - 共' + currentImageUrls.length + '张 当前第' + (imageIdx + 1) + '张'" width="80%">
+    <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="tsx" name="DataSeq">
@@ -50,8 +74,61 @@ import {
   importTemplateApi,
   importDataSeqDataApi,
   exportDataSeqApi,
-  getDataSeqApi
+  getDataSeqApi,
+  getAllImagesApi
 } from '@/api/modules/demo/DataSeq'
+import { enumsSubSystem } from '../utils'
+
+const dialogVisible = ref(false)
+const imageFps = ref(0)
+const intervalChangeFps: any = ref()
+const imageIdx = ref(0)
+const currentImageUrls = ref<string[]>([])
+const newImageIdx = ref()
+
+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 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
+  }
+}
 
 // ProTable 实例
 const proTable = ref<ProTableInstance>()
@@ -118,22 +195,15 @@ const columns = reactive<ColumnProps<any>[]>([
     label: '名称',
     search: {
       el: 'input'
-    },
-    width: 120
-  },
-  {
-    prop: 'dataType',
-    label: '数据类型',
-    search: {
-      el: 'input'
-    },
-    width: 120
+    }
   },
   {
-    prop: 'fileType',
-    label: '文件类型',
+    prop: 'subsystem',
+    label: '分系统',
+    tag: true,
+    enum: enumsSubSystem,
     search: {
-      el: 'input'
+      el: 'select'
     },
     width: 120
   },
@@ -158,65 +228,49 @@ const columns = reactive<ColumnProps<any>[]>([
     label: '批次号',
     search: {
       el: 'input'
-    },
-    width: 120
+    }
   },
   {
     prop: 'scene',
     label: '场景',
     search: {
       el: 'input'
-    },
-    width: 120
+    }
   },
   {
     prop: 'dataSource',
     label: '数据源',
     search: {
       el: 'input'
-    },
-    width: 120
-  },
-  {
-    prop: 'gatherTime',
-    label: '采集时间',
-    search: {
-      el: 'date-picker',
-      props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
-    },
-    width: 120
+    }
   },
   {
     prop: 'gatherSpot',
     label: '采集地点',
     search: {
       el: 'input'
-    },
-    width: 120
+    }
   },
   {
-    prop: 'url',
-    label: '图片url',
+    prop: 'remarks',
+    label: '备注',
     search: {
       el: 'input'
-    },
-    width: 120
+    }
   },
   {
-    prop: 'log',
-    label: '日志',
+    prop: 'filePath',
+    label: '文件路径',
     search: {
       el: 'input'
-    },
-    width: 120
+    }
   },
   {
-    prop: 'remarks',
-    label: '备注',
+    prop: 'unzipPath',
+    label: '解压路径',
     search: {
       el: 'input'
-    },
-    width: 120
+    }
   },
   { prop: 'operation', label: '操作', width: 230, fixed: 'right' }
 ])
@@ -233,25 +287,46 @@ const setItemsOptions = () => {
       }
     },
     {
-      label: '数据类型',
-      prop: 'dataType',
-      rules: [{ required: true, message: '数据类型不能为空', trigger: 'blur' }],
+      label: '分系统',
+      prop: 'subsystem',
+      rules: [{ required: true, message: '分系统不能为空', trigger: 'blur' }],
+      compOptions: {
+        elTagName: 'select',
+        enum: enumsSubSystem,
+        placeholder: '请选择分系统'
+      }
+    },
+    {
+      label: '批次号',
+      prop: 'batchNum',
+      rules: [{ required: true, message: '批次号不能为空', trigger: 'blur' }],
       compOptions: {
-        placeholder: '请输入数据类型'
+        placeholder: '请输入批次号'
       }
     },
     {
-      label: '文件类型',
-      prop: 'fileType',
-      rules: [{ required: true, message: '文件类型不能为空', trigger: 'blur' }],
+      label: '上传文件',
+      prop: 'inputOssId',
+      rules: [{ required: true, message: '数据集文件不能为空', trigger: 'blur' }],
       compOptions: {
-        placeholder: '请输入文件类型'
+        elTagName: 'file-upload',
+        fileSize: 4096,
+        fileType: ['zip'],
+        placeholder: '请上传数据集文件'
       }
     },
+    // {
+    //   label: '文件类型',
+    //   prop: 'fileType',
+    //   rules: [{ required: true, message: '文件类型不能为空', trigger: 'blur' }],
+    //   compOptions: {
+    //     placeholder: '请输入文件类型'
+    //   }
+    // },
     {
       label: '目标类型',
       prop: 'objectType',
-      rules: [{ required: true, message: '目标类型不能为空', trigger: 'blur' }],
+      rules: [{ required: false, message: '目标类型不能为空', trigger: 'blur' }],
       compOptions: {
         placeholder: '请输入目标类型'
       }
@@ -259,23 +334,15 @@ const setItemsOptions = () => {
     {
       label: '目标子类型',
       prop: 'objectSubtype',
-      rules: [{ required: true, message: '目标子类型不能为空', trigger: 'blur' }],
+      rules: [{ required: false, message: '目标子类型不能为空', trigger: 'blur' }],
       compOptions: {
         placeholder: '请输入目标子类型'
       }
     },
-    {
-      label: '批次号',
-      prop: 'batchNum',
-      rules: [{ required: true, message: '批次号不能为空', trigger: 'blur' }],
-      compOptions: {
-        placeholder: '请输入批次号'
-      }
-    },
     {
       label: '场景',
       prop: 'scene',
-      rules: [{ required: true, message: '场景不能为空', trigger: 'blur' }],
+      rules: [{ required: false, message: '场景不能为空', trigger: 'blur' }],
       compOptions: {
         placeholder: '请输入场景'
       }
@@ -283,7 +350,7 @@ const setItemsOptions = () => {
     {
       label: '数据源',
       prop: 'dataSource',
-      rules: [{ required: true, message: '数据源不能为空', trigger: 'blur' }],
+      rules: [{ required: false, message: '数据源不能为空', trigger: 'blur' }],
       compOptions: {
         placeholder: '请输入数据源'
       }
@@ -291,7 +358,7 @@ const setItemsOptions = () => {
     {
       label: '采集时间',
       prop: 'gatherTime',
-      rules: [{ required: true, message: '采集时间不能为空', trigger: 'change' }],
+      rules: [{ required: false, message: '采集时间不能为空', trigger: 'change' }],
       compOptions: {
         elTagName: 'date-picker',
         type: 'date',
@@ -301,33 +368,33 @@ const setItemsOptions = () => {
     {
       label: '采集地点',
       prop: 'gatherSpot',
-      rules: [{ required: true, message: '采集地点不能为空', trigger: 'blur' }],
+      rules: [{ required: false, message: '采集地点不能为空', trigger: 'blur' }],
       compOptions: {
         placeholder: '请输入采集地点'
       }
     },
-    {
-      label: '图片url',
-      prop: 'url',
-      rules: [{ required: true, message: '图片url不能为空', trigger: 'blur' }],
-      compOptions: {
-        placeholder: '请输入图片url'
-      }
-    },
-    {
-      label: '日志',
-      prop: 'log',
-      rules: [{ required: true, message: '日志不能为空', trigger: 'blur' }],
-      compOptions: {
-        type: 'textarea',
-        clearable: true,
-        placeholder: '请输入内容'
-      }
-    },
+    // {
+    //   label: '图片url',
+    //   prop: 'url',
+    //   rules: [{ required: true, message: '图片url不能为空', trigger: 'blur' }],
+    //   compOptions: {
+    //     placeholder: '请输入图片url'
+    //   }
+    // },
+    // {
+    //   label: '日志',
+    //   prop: 'log',
+    //   rules: [{ required: true, message: '日志不能为空', trigger: 'blur' }],
+    //   compOptions: {
+    //     type: 'textarea',
+    //     clearable: true,
+    //     placeholder: '请输入内容'
+    //   }
+    // },
     {
       label: '备注',
       prop: 'remarks',
-      rules: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
+      rules: [{ required: false, message: '备注不能为空', trigger: 'blur' }],
       compOptions: {
         placeholder: '请输入备注'
       }
@@ -335,3 +402,19 @@ 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>