Browse Source

媒体管理

李富豪 1 year ago
parent
commit
ff7e14b1c2

+ 24 - 3
Web/src/api/custom/index.ts

@@ -23,11 +23,18 @@ export type FetchMediaFileListApiParams = {
     page_size: number,
 };
 
+export type FetchFileListByFolderApiParams = {
+    page: number,
+    page_size: number,
+};
+
 // Api函数类型
 export type FetchFeedbackRecordListApi = (data: FetchFeedbackRecordListApiParams) => Promise<any>;
 export type FetchChangeRecordListApi = (params: FetchFeedbackRecordListApiParams) => Promise<any>;
 export type FetchProjectListApi = () => Promise<any>;
 export type FetchMediaFileListApi = (params: FetchMediaFileListApiParams) => Promise<any>;
+export type FetchFileListByFolderApi = (dirId: string, params: FetchFileListByFolderApiParams) => Promise<any>;
+export type FetchFileDetailApi = (fileId: string) => Promise<any>;
 
 // 获取反馈记录列表
 const fetchFeedbackRecordListApi: FetchFeedbackRecordListApi = async (data) => {
@@ -37,7 +44,7 @@ const fetchFeedbackRecordListApi: FetchFeedbackRecordListApi = async (data) => {
 
 // 获取变化记录列表
 const fetchChangeRecordListApi: FetchChangeRecordListApi = async (params) => {
-    const res = await request.get('/manage/api/v1/oprlogs/' + workspaceId + '/devices/logs', { params: params });
+    const res = await request.get(`/manage/api/v1/oprlogs/${workspaceId}/devices/logs`, { params: params });
     return res.data;
 };
 
@@ -49,13 +56,27 @@ const fetchProjectListApi: FetchProjectListApi = async () => {
 
 // 获取文件夹列表
 const fetchMediaFileListApi: FetchMediaFileListApi = async (params) => {
-    const res = await request.get('/media/api/v1/files/' + workspaceId + '/dirs', { params: params });
+    const res = await request.get(`/media/api/v1/files/${workspaceId}/dirs`, { params: params });
     return res.data;
-}
+};
+
+// 获取文件夹下所有文件
+const fetchFileListByFolderApi: FetchFileListByFolderApi = async (dirId, params) => {
+    const res = await request.get(`/media/api/v1/files/${workspaceId}/files/${dirId}`, { params: params });
+    return res.data;
+};
+
+// 获取文件详情
+const fetchFileDetailApi: FetchFileDetailApi = async (fileId) => {
+    const res = await request.get(`/media/api/v1/files/${workspaceId}/file/${fileId}`);
+    return res.data;
+};
 
 export const apis = {
     fetchFeedbackRecordList: fetchFeedbackRecordListApi,
     fetchChangeRecordList: fetchChangeRecordListApi,
     fetchProjectList: fetchProjectListApi,
     fetchMediaFileList: fetchMediaFileListApi,
+    fetchFileListByFolder: fetchFileListByFolderApi,
+    fetchFileDetail: fetchFileDetailApi,
 };

+ 1 - 0
Web/src/assets/media/picture.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="1719905467401" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10546" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M930.936471 0C992.978824 0 1024 31.021176 1024 93.063529v837.872942c0 62.042353-31.021176 93.063529-93.063529 93.063529H93.063529C31.021176 1024 0 992.978824 0 930.936471V93.063529C0 31.021176 31.021176 0 93.063529 0h837.872942zM601.630118 384.722824a15.811765 15.811765 0 0 0-13.70353 7.318588l-147.57647 231.303529-67.282824-65.867294a15.811765 15.811765 0 0 0-24.18447 2.379294l-101.797648 149.624471a15.811765 15.811765 0 0 0 13.101177 24.69647h524.468706a15.811765 15.811765 0 0 0 13.733647-23.732706l-183.416471-317.801411a15.811765 15.811765 0 0 0-13.342117-7.920941z m-244.254118-93.816471a79.811765 79.811765 0 1 0 0 159.593412 79.811765 79.811765 0 0 0 0-159.593412z" p-id="10547" fill="#c0c6d1"></path></svg>

+ 1 - 0
Web/src/assets/media/video.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="1719905321017" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5358" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M450.048 213.504L305.152 42.496H140.8l144.896 170.496h164.352z m426.496 0L731.648 42.496h-164.352l144.896 170.496h164.352z m-212.992 0L518.656 42.496H354.304l144.896 170.496h164.352z m274.944-171.008h-157.696l144.896 170.496h76.8V106.496c0-36.352-27.648-64-64-64z m-846.848 0h-6.144c-36.352 0-64 27.648-64 64v106.496h215.552L91.648 42.496zM21.504 917.504c0 36.352 27.648 64 64 64h853.504c36.352 0 64-27.648 64-64V256H21.504v661.504z m340.992-469.504c0-36.352 29.696-53.248 64-53.248 10.752 0 23.552 2.048 34.304 8.704l243.2 140.8a60.416 60.416 0 0 1 0 106.496L460.8 791.552c-10.752 6.656-21.504 8.704-34.304 8.704-34.304 0-64-16.896-64-53.248V448z" fill="#c0c6d1" p-id="5359"></path></svg>

+ 14 - 3
Web/src/hooks/use-g-map.ts

@@ -2,14 +2,14 @@ import AMapLoader from '@amap/amap-jsapi-loader'
 import { App, reactive } from 'vue'
 import { AMapConfig } from '/@/constants/index'
 
-export function useGMapManage () {
+export function useGMapManage() {
   const state = reactive({
     aMap: null, // Map类
     map: null, // 地图对象
     mouseTool: null,
   })
 
-  async function initMap (container: string, app:App) {
+  async function initMap(container: string, app: App) {
     AMapLoader.load({
       ...AMapConfig
     }).then((AMap) => {
@@ -29,11 +29,22 @@ export function useGMapManage () {
     })
   }
 
-  function globalPropertiesConfig (app:App) {
+  function globalPropertiesConfig(app: App) {
     initMap('g-container', app)
   }
 
+  async function newMap(containerId: string, config: any) {
+    AMapLoader.load({
+      ...AMapConfig
+    }).then((AMap) => {
+      new AMap.Map(containerId, config)
+    }).catch(e => {
+      console.log(e)
+    })
+  }
+
   return {
     globalPropertiesConfig,
+    newMap,
   }
 }

+ 326 - 0
Web/src/pages/page-web/projects/media/detail/components/FileInfo.vue

@@ -0,0 +1,326 @@
+<template>
+  <div class="imageModal">
+    <div class="imageModal-detail">
+      <a-row>
+        <a-col flex="auto">
+          <div class="imageModal-detail-left">
+            <img :src="state.info.url" />
+          </div>
+        </a-col>
+        <a-col flex="420px">
+          <div class="imageModal-detail-info">
+            <CloseOutlined class="imageModal-detail-info-close" @click="onClose" />
+            <div class="imageModal-detail-info-title">
+              详细信息
+            </div>
+            <div class="imageModal-detail-info-item">
+              <div class="imageModal-detail-info-item-title">
+                照片名称
+              </div>
+              <div class="imageModal-detail-info-item-content">
+                {{ state.info.file_name || '--' }}
+              </div>
+            </div>
+            <div class="imageModal-detail-info-item">
+              <div class="imageModal-detail-info-item-title">
+                照片类型
+              </div>
+              <div class="imageModal-detail-info-item-content">
+                {{ state.info.file_type || '--' }}
+              </div>
+            </div>
+            <div class="imageModal-detail-info-item">
+              <div class="imageModal-detail-info-item-title">
+                任务名称
+              </div>
+              <div class="imageModal-detail-info-item-content">
+                {{ state.info.task_name || '--' }}
+              </div>
+            </div>
+            <div class="imageModal-detail-info-item">
+              <div class="imageModal-detail-info-item-title">
+                航线名称
+              </div>
+              <div class="imageModal-detail-info-item-content">
+                {{ state.info.wayline_name || '--' }}
+              </div>
+            </div>
+            <div class="imageModal-detail-info-item">
+              <div class="imageModal-detail-info-item-title">
+                照片分辨率
+              </div>
+              <div class="imageModal-detail-info-item-content">
+                <div class="imageModal-detail-info-item-content-line"
+                  v-if="state.info.image_width && state.info.image_height">
+                  {{ state.info.image_width }}*{{ state.info.image_height }}
+                </div>
+                <div>
+                  --
+                </div>
+              </div>
+            </div>
+            <div class="imageModal-detail-info-item">
+              <div class="imageModal-detail-info-item-title">
+                照片大小
+              </div>
+              <div class="imageModal-detail-info-item-content">
+                {{ state.info.size || '--' }}
+              </div>
+            </div>
+            <div class="imageModal-detail-info-item">
+              <div class="imageModal-detail-info-item-title">
+                拍摄负载
+              </div>
+              <div class="imageModal-detail-info-item-content">
+                {{ state.info.payload || '--' }}
+              </div>
+            </div>
+            <div class="imageModal-detail-info-item">
+              <div class="imageModal-detail-info-item-title">
+                拍摄来源
+              </div>
+              <div class="imageModal-detail-info-item-content">
+                {{ state.info.source_from || '--' }}
+              </div>
+            </div>
+            <div class="imageModal-detail-info-item">
+              <div class="imageModal-detail-info-item-title">
+                拍摄时间
+              </div>
+              <div class="imageModal-detail-info-item-content">
+                {{ state.info.picture_time || '--' }}
+              </div>
+            </div>
+            <div class="imageModal-detail-info-item">
+              <div class="imageModal-detail-info-item-title">
+                已关注进度
+              </div>
+              <div class="imageModal-detail-info-item-content">
+                {{ state.info.hot || '--' }}
+              </div>
+            </div>
+            <div class="imageModal-detail-info-map">
+              <div class="imageModal-detail-info-map-title">
+                <div class="imageModal-detail-info-map-title-text">
+                  照片位置
+                </div>
+                <div class="imageModal-detail-info-map-title-icon">
+                  <EnvironmentOutlined />
+                </div>
+              </div>
+              <div class="imageModal-detail-info-map-content">
+                <div id="photoPositionMap" :style="{ width: '100%', height: '100%' }"></div>
+              </div>
+            </div>
+          </div>
+        </a-col>
+      </a-row>
+    </div>
+    <div class="imageModal-area">
+      <a-tooltip title="record.file_name">
+        <DownloadOutlined style="font-size: 20px;margin-right: 20px;" />
+      </a-tooltip>
+      <a-tooltip title="record.file_name">
+        <DeleteOutlined style="font-size: 20px;" />
+      </a-tooltip>
+    </div>
+    <div class="imageModal-previewList">
+      <div class="imageModal-previewList-item">
+        <img :src="state.info.url" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { reactive, onMounted } from 'vue';
+import { CloseOutlined, EnvironmentOutlined, DownloadOutlined, DeleteOutlined } from '@ant-design/icons-vue';
+import { useGMapManage } from '/@/hooks/use-g-map';
+import { apis } from '/@/api/custom';
+
+interface Props {
+  fileId: string,
+  onClose: () => void,
+};
+
+const props = withDefaults(defineProps<Props>(), {
+
+});
+
+const state = reactive({
+  loading: false,
+  info: {
+    url: '',
+    file_name: '',
+    file_type: '',
+    task_name: '',
+    wayline_name: '',
+    image_width: '',// 照片分辨率-宽度
+    image_height: '',// 照片分辨率-高度
+    size: '',
+    payload: '',
+    source_from: '',
+    picture_time: '',
+    hot: '',// 已关注度
+    longitude: '',// 经度
+    latitude: '',// 纬度
+  }
+})
+
+// 高德地图Hook
+const AmapHook = useGMapManage();
+
+onMounted(async () => {
+  state.loading = true;
+  try {
+    const res = await apis.fetchFileDetail(props.fileId);
+    state.info = res.data;
+    if (state.info.longitude && state.info.latitude) {
+      AmapHook.newMap('photoPositionMap', {
+        center: [state.info.longitude, state.info.latitude],
+        zoom: 14
+      })
+    }
+  } catch (e) {
+    console.error(e);
+  } finally {
+    state.loading = false;
+  }
+})
+</script>
+
+<style lang="scss">
+.imageModal {
+  width: 100%;
+  height: 100vh;
+  background: #1C1C1C;
+  color: #FFFFFF;
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 9999;
+  overflow: auto;
+
+  ::-webkit-scrollbar {
+    width: 8px;
+    height: 8px;
+    background: transparent;
+  }
+
+  ::-webkit-scrollbar-thumb {
+    border-radius: 4px;
+    border: none;
+    background: rgb(89, 89, 89);
+  }
+
+  &-detail {
+    &-left {
+      width: 100%;
+      height: calc(100vh - 120px);
+      overflow: hidden;
+
+      img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+    }
+
+    &-info {
+      width: 100%;
+      height: calc(100vh - 120px);
+      padding: 24px;
+      overflow: auto;
+
+      &-close {
+        font-size: 20px;
+        position: absolute;
+        right: 24px;
+        top: 24px;
+        cursor: pointer;
+      }
+
+      &-title {
+        font-size: 16px;
+        margin-bottom: 16px;
+      }
+
+      &-item {
+        width: 100%;
+        height: 38px;
+        display: flex;
+        align-items: center;
+
+        &-title {
+          width: 85px;
+          color: hsla(0, 0%, 100%, .45);
+        }
+
+        &-content {
+          margin-left: 16px;
+
+          &-line {
+            display: flex;
+            align-items: center;
+          }
+        }
+      }
+
+      &-map {
+        &-title {
+          height: 38px;
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+
+          &-text {
+            color: hsla(0, 0%, 100%, .45);
+          }
+
+          &-icon {
+            color: $primary;
+          }
+        }
+
+        &-content {
+          width: 100%;
+          height: 250px;
+          background: #dddddd;
+          border-radius: 4px;
+          margin-top: 10px;
+        }
+      }
+    }
+  }
+
+  &-area {
+    width: 100%;
+    height: 50px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+
+  &-previewList {
+    width: 100%;
+    height: 70px;
+    display: flex;
+    justify-content: center;
+
+    &-item {
+      width: 80px;
+      height: 60px;
+      border: 2px solid $primary;
+      border-radius: 4px;
+      margin-bottom: 10px;
+      cursor: pointer;
+
+      img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+    }
+  }
+}
+</style>

+ 0 - 53
Web/src/pages/page-web/projects/media/detail/components/ImageModal.vue

@@ -1,53 +0,0 @@
-<template>
-  <a-modal title="图片详情" width="100%" wrapClassName="full-modal" :footer="null" v-model:visible="visible"
-    @cancel="onClose">
-    <a-row>
-      <a-col flex="auto">
-        <a-image-preview-group>
-          <a-image :width="200" src="https://aliyuncdn.antdv.com/vue.png" />
-          <a-image :width="200" src="https://aliyuncdn.antdv.com/logo.png" />
-        </a-image-preview-group>
-      </a-col>
-      <a-col flex="200px">
-        2313211323123123123
-      </a-col>
-    </a-row>
-  </a-modal>
-</template>
-
-<script lang="ts" setup>
-interface Props {
-  visible: boolean,
-  onClose: () => void,
-};
-
-const props = withDefaults(defineProps<Props>(), {
-
-});
-</script>
-
-<style lang="scss">
-.full-modal {
-  .ant-modal {
-    max-width: 100%;
-    top: 0;
-    padding-bottom: 0;
-    margin: 0;
-  }
-
-  .ant-modal-header {
-    background: #1b1b1b;
-  }
-
-  .ant-modal-content {
-    display: flex;
-    flex-direction: column;
-    height: calc(100vh);
-    background: #1b1b1b;
-  }
-
-  .ant-modal-body {
-    flex: 1;
-  }
-}
-</style>

+ 28 - 1
Web/src/pages/page-web/projects/media/detail/components/Search.vue

@@ -1,7 +1,8 @@
 <template>
   <a-row style="margin-bottom: 20px;" justify="space-between">
     <a-col style="display: flex;">
-      <a-upload name="file" :multiple="true">
+      <a-upload :action="uploadUrl" method="POST" :headers="getHeaders()" accept=".png,.jpg,.jpeg" :multiple="false"
+        :showUploadList="false" @change="handleChangeUploadFile">
         <a-button type="primary" @click="onClickDownload">
           上传合成文件
         </a-button>
@@ -77,11 +78,16 @@
 
 <script lang="ts" setup>
 import { ref, reactive } from 'vue';
+import { message } from 'ant-design-vue'
 import { SearchOutlined, ReloadOutlined } from '@ant-design/icons-vue';
+import router from '/@/router';
+import { ELocalStorageKey } from '/@/types'
 
 interface Props {
+  fetchList: () => Promise<any>,
   selectedRowKeys: string[],
   onClickDownload: () => Promise<any>,
+  onClickDelete: () => Promise<any>,
   onClickSearch: (query: any) => Promise<any>,
   onClickReset: (query: any) => Promise<any>,
 };
@@ -103,6 +109,27 @@ const state = reactive({
   visible: false,
 })
 
+const workspaceId: string = localStorage.getItem(ELocalStorageKey.WorkspaceId) || '';
+const dirId = router.currentRoute.value.params?.id;
+const uploadUrl = `/api/media/api/v1/files/${workspaceId}/file/${dirId}/upload`
+
+const getHeaders = () => {
+  const token = localStorage.getItem(ELocalStorageKey.Token);
+  return {
+    [ELocalStorageKey.Token]: token,
+  }
+}
+
+// 上传合成文件
+const handleChangeUploadFile = async (info: any) => {
+  if (info.file.status === 'done') {// 上传成功
+    await props.fetchList()
+    message.success('上传成功');
+  } else if (info.file.status === 'error') {// 上传失败
+    message.error('上传失败');
+  }
+}
+
 // 点击查询
 const handleClicSekarch = async () => {
   const values = formRef.value?.getFieldsValue();

+ 67 - 38
Web/src/pages/page-web/projects/media/detail/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="mediaDetail">
-    <Search :selectedRowKeys="state.selectedRowKeys" :onClickDownload="onClickBatchDownload"
-      :onClickSearch="async () => { }" :onClickReset="async () => { }" />
+    <Search :fetchList="fetchList" :selectedRowKeys="state.selectedRowKeys" :onClickDownload="onClickBatchDownload"
+      :onClickDelete="onClickBatchDelete" :onClickSearch="async () => { }" :onClickReset="async () => { }" />
     <div style="background: #FFFFFF;padding: 20px;">
       <div class="mediaDetail-info">
         <div class="mediaDetail-info-left">
@@ -21,7 +21,7 @@
               已选/全部:
             </div>
             <div>
-              0/175
+              {{ state.selectedRowKeys.length }}/{{ paginationConfig.total }}
             </div>
           </div>
           <a-button style="padding:0 5px;" :type="state.mode === 'table' ? 'primary' : 'default'"
@@ -44,8 +44,7 @@
             <a-tooltip :title="record.file_name">
               <div class="fileName" @click="onClickLookFile(record)">
                 <div>
-                  <img :src="record" v-if="1">
-                  <img :src="record" v-else>
+                  <img :src="pictureSrc">
                 </div>
                 <div>
                   {{ record.file_name }}
@@ -57,13 +56,13 @@
           <template #action="{ record }">
             <div class="flex-align-center flex-row" style="color: #2d8cf0">
               <a-tooltip title="照片位置" v-if="1">
-                <EnvironmentOutlined style="margin-right: 10px;" @click="onClickTrajectory" />
+                <EnvironmentOutlined style="margin-right: 10px;" @click="onClickPhotoPosition" />
               </a-tooltip>
               <a-tooltip title="重命名" v-else-if="1">
-                <EditOutlined style="margin-right: 10px;" @click="onClickTrajectory" />
+                <EditOutlined style="margin-right: 10px;" @click="onClickRechristen" />
               </a-tooltip>
               <a-tooltip title="删除" v-else-if="1">
-                <DeleteOutlined style="margin-right: 10px;" @click="onClickTrajectory" />
+                <DeleteOutlined style="margin-right: 10px;" @click="onClickDelete" />
               </a-tooltip>
               <a-tooltip title="压缩下载">
                 <DownloadOutlined @click="onClickDownload(record)" />
@@ -77,15 +76,15 @@
           :dataSource="state.list" :pagination="paginationConfig">
           <template #renderItem="{ item }">
             <a-list-item>
-              <a-card hoverable @click="onClickFile(item)">
+              <a-card hoverable @click="onClickLookFile(item)">
                 <template #cover>
                   <div style="display: flex;justify-content:center;align-items: center;">
-                    <img style="width: 70%;" :src="fileSrc" />
+                    <img style="width: 70%;margin: 10px;" :src="pictureSrc" />
                   </div>
                 </template>
                 <a-card-meta>
                   <template #description>
-                    <div>
+                    <div class="mediaDetail-list-name">
                       {{ item.file_name }}
                     </div>
                   </template>
@@ -97,34 +96,34 @@
       </div>
     </div>
   </div>
-  <ImageModal :visible="state.imageModalVisible" :onClose="imageModalOnClickClose" />
+  <FileInfo :fileId="state.fileId" :onClose="fileInfoOnClickClose" v-if="state.fileInfoVisible" />
 </template>
 
 <script lang="ts" setup>
 import { reactive, onMounted } from 'vue';
 import { MenuOutlined, AppstoreOutlined, EditOutlined, DeleteOutlined, DownloadOutlined, EnvironmentOutlined } from '@ant-design/icons-vue';
 import Search from './components/Search.vue';
-import ImageModal from './components/ImageModal.vue';
-import { getMediaFiles, downloadMediaFile } from '/@/api/media';
-import { downloadFile } from '/@/utils/common';
+import FileInfo from './components/FileInfo.vue';
+import pictureSrc from '/@/assets/media/picture.svg';
+import { apis } from '/@/api/custom';
 import router from '/@/router/index';
 
 interface State {
-  workspaceId: string,
   listLoading: boolean,
   list: any[],
   selectedRowKeys: string[],
   mode: 'table' | 'list',
-  imageModalVisible: boolean,
+  fileId: string,
+  fileInfoVisible: boolean,
 };
 
 const state: State = reactive({
-  workspaceId: localStorage.getItem('workspace_id') || '',
   listLoading: false,
   list: [],
   selectedRowKeys: [],
   mode: 'table',
-  imageModalVisible: false,
+  fileId: '',
+  fileInfoVisible: false,
 })
 
 const paginationConfig = reactive({
@@ -147,7 +146,8 @@ const paginationConfig = reactive({
 const fetchList = async () => {
   state.listLoading = true;
   try {
-    const res = await getMediaFiles(state.workspaceId, { page: paginationConfig.current, page_size: paginationConfig.pageSize });
+    const dirId = router.currentRoute.value.params?.id;
+    const res = await apis.fetchFileListByFolder(dirId as string, { page: paginationConfig.current, page_size: paginationConfig.pageSize });
     state.list = res.data.list;
     paginationConfig.current = res.data.pagination.page;
     paginationConfig.pageSize = res.data.pagination.page_size;
@@ -180,9 +180,12 @@ const columns = [
   },
   {
     title: '容量大小',
-    dataIndex: 'is_original',
+    dataIndex: 'size',
     width: 150,
     ellipsis: true,
+    customRender: ({ text }: any) => {
+      return text || '--';
+    }
   },
   {
     title: '创建时间',
@@ -192,13 +195,19 @@ const columns = [
   },
   {
     title: '媒体类型',
-    dataIndex: 'create_time',
+    dataIndex: 'media_name',
     width: 150,
+    customRender: ({ text }: any) => {
+      return text || '--';
+    }
   },
   {
     title: '照片类型',
-    dataIndex: 'create_time',
+    dataIndex: 'picture_type',
     width: 150,
+    customRender: ({ text }: any) => {
+      return text || '--';
+    }
   },
   {
     title: '操作',
@@ -222,6 +231,11 @@ const onClickBatchDownload = async () => {
   console.log(state.selectedRowKeys, '点击批量下载');
 }
 
+// 点击批量删除
+const onClickBatchDelete = async () => {
+  console.log(state.selectedRowKeys, '点击批量删除');
+}
+
 // 点击返回
 const onClickGoBack = () => {
   router.push({ path: '/media' })
@@ -234,35 +248,42 @@ const onSelectChange = (selectedRowKeys: string[]) => {
 
 // 点击查看文件
 const onClickLookFile = (record: any) => {
-  state.imageModalVisible = true;
+  state.fileId = record.file_id;
+  state.fileInfoVisible = true;
+}
+
+// 文件信息-点击关闭
+const fileInfoOnClickClose = () => {
+  state.fileId = '';
+  state.fileInfoVisible = false;
 }
 
-// 图片弹出层-点击关闭
-const imageModalOnClickClose = () => {
-  state.imageModalVisible = false;
+// 点击照片位置
+const onClickPhotoPosition = () => {
+
+}
+
+// 点击重命名
+const onClickRechristen = () => {
+
+}
+
+// 点击删除
+const onClickDelete = () => {
+
 }
 
 // 点击下载
 const onClickDownload = async (record: any) => {
   state.listLoading = true;
   try {
-    const res = await downloadMediaFile(state.workspaceId, record.file_id);
-    if (!res) {
-      return
-    }
-    const data = new Blob([res]);
-    downloadFile(data, record.file_name);
+
   } catch (e) {
     console.error(e);
   } finally {
     state.listLoading = false;
   }
 }
-
-// 点击轨迹回放
-const onClickTrajectory = () => {
-  router.push({ path: '/trajectory' })
-}
 </script>
 
 <style lang="scss">
@@ -303,6 +324,14 @@ const onClickTrajectory = () => {
       margin-right: 5px;
     }
   }
+
+  &-list {
+    &-name {
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+  }
 }
 
 .ant-table {

+ 21 - 11
Web/src/pages/page-web/projects/media/index/index.vue

@@ -13,7 +13,7 @@
               已选/全部:
             </div>
             <div>
-              0/175
+              {{ state.selectedRowKeys.length }}/{{ paginationConfig.total }}
             </div>
           </div>
           <a-button style="padding:0 5px;" :type="state.mode === 'table' ? 'primary' : 'default'"
@@ -67,9 +67,11 @@
                 </template>
                 <a-card-meta>
                   <template #description>
-                    <div>
-                      {{ item.dir_name }}
-                    </div>
+                    <a-tooltip placement="bottom" :title="item.dir_name">
+                      <div class="mediaList-list-name">
+                        {{ item.dir_name }}
+                      </div>
+                    </a-tooltip>
                   </template>
                 </a-card-meta>
               </a-card>
@@ -87,7 +89,6 @@ import { MenuOutlined, AppstoreOutlined, DownloadOutlined, EnvironmentOutlined }
 import Search from './components/Search.vue';
 import fileSrc from '/@/assets/media/file.svg';
 import { apis } from '/@/api/custom';
-import { downloadFile } from '/@/utils/common';
 import router from '/@/router/index';
 
 interface State {
@@ -166,6 +167,9 @@ const columns = [
     dataIndex: 'is_original',
     width: 150,
     ellipsis: true,
+    customRender: ({ text }: any) => {
+      return text || '--';
+    }
   },
   {
     title: '创建时间',
@@ -182,6 +186,9 @@ const columns = [
     title: '任务类型',
     dataIndex: 'template_type',
     width: 150,
+    customRender: ({ text }: any) => {
+      return text || '--';
+    }
   },
   {
     title: '创建人',
@@ -224,12 +231,7 @@ const onSelectChange = (selectedRowKeys: string[]) => {
 const onClickDownload = async (record: any) => {
   state.listLoading = true;
   try {
-    // const res = await downloadMediaFile(state.workspaceId, record.id);
-    // if (!res) {
-    //   return
-    // }
-    // const data = new Blob([res]);
-    // downloadFile(data, record.dir_name);
+
   } catch (e) {
     console.error(e);
   } finally {
@@ -276,6 +278,14 @@ const onClickTrajectory = () => {
       margin-right: 5px;
     }
   }
+
+  &-list {
+    &-name {
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+  }
 }
 
 .ant-table {