Browse Source

Merge remote-tracking branch 'origin/master'

S0025136190 1 year ago
parent
commit
340aa45315

+ 18 - 0
Web/src/api/custom/index.ts

@@ -69,6 +69,8 @@ export type BatchDownloadMediaFileApi = (params: BatchDownloadMediaFileApiParams
 export type FetchFileListByFolderApi = (dirId: string, params: FetchFileListByFolderApiParams) => Promise<any>;
 export type FetchFileDetailApi = (fileId: string) => Promise<any>;
 export type BatchDownloadFileApi = (params: BatchDownloadFileApiParams) => Promise<any>;
+export type CreateMapElementApi = (fileId: string) => Promise<any>;
+export type DeleteMapElementApi = (fileId: string) => Promise<any>;
 export type UpdateFileNameApi = (fileId: string, data: { [key: string]: any }) => Promise<any>;
 export type BatchDeletePictureApi = (params: BatchDeletePictureApiParams) => Promise<any>;
 export type FetchTrajectoryListApi = (params: FetchTrajectoryListApiParams) => Promise<any>;
@@ -134,6 +136,20 @@ const batchDownloadFileApi: BatchDownloadFileApi = async (params) => {
     return res.data;
 };
 
+// 添加图片元素
+const createMapElementApi: CreateMapElementApi = async (fileId) => {
+    const url = `/media/api/v1/files/workspaces/${workspaceId}/createMapElement/${fileId}`
+    const result = await request.post(url)
+    return result.data;
+}
+
+// 删除图片元素
+const deleteMapElementApi: DeleteMapElementApi = async (fileId) => {
+    const url = `/media/api/v1/files/workspaces/${workspaceId}/deleteMapElement/${fileId}`
+    const result = await request.delete(url)
+    return result.data;
+}
+
 // 更新文件名称
 const updateFileNameApi: UpdateFileNameApi = async (fileId, data) => {
     const url = `/media/api/v1/files/${workspaceId}/updateFile/${fileId}`
@@ -171,6 +187,8 @@ export const apis = {
     fetchFileListByFolder: fetchFileListByFolderApi,
     fetchFileDetail: fetchFileDetailApi,
     batchDownloadFile: batchDownloadFileApi,
+    createMapElement: createMapElementApi,
+    deleteMapElement: deleteMapElementApi,
     updateFileName: updateFileNameApi,
     batchDeletePicture: batchDeletePictureApi,
     fetchTrajectoryList: fetchTrajectoryListApi,

+ 1 - 1
Web/src/components/LayersTree.vue

@@ -15,7 +15,7 @@
         </template>
         <template v-if="layer.elements">
           <a-tree-node v-for="resource in layer.elements" :id="getLayerTreeKey('resource', resource.id)"
-            :key="getLayerTreeKey('resource', resource.id)">
+            :parent="{ id: layer.id, type: layer.type }" :key="getLayerTreeKey('resource', resource.id)">
             <template #title>
               <div style="display: flex;align-items: center;">
                 <Icon v-if="resource.resource.type === 0">

+ 74 - 16
Web/src/pages/page-web/projects/layer/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="project-layer-wrapper height-100">
     <div class="scrollbar">
-      <LayersTree :layer-data="mapLayers" class="project-layer-content" @check="checkLayer" @select="selectLayer"
+      <LayersTree :layer-data="mapLayers" class="project-layer-content" @select="selectLayer"
         v-model:selectedKeys="selectedKeys" v-model:checkedKeys="checkedKeys" v-model:expandedKeys="expandedKeys" />
     </div>
     <a-drawer title="地图元素" placement="right" :closable="true" v-model:visible="visible" :mask="true"
@@ -54,6 +54,56 @@
         <a-button type="primary" @click="deleteElement">删除</a-button>
       </div>
     </a-drawer>
+    <!-- <a-drawer title="图片信息" placement="right" :closable="true" v-model:visible="visible" :mask="true"
+      getContainer="#g-container" :wrap-style="{ position: 'absolute' }" wrapClassName="drawer-element-wrapper"
+      @close="closeDrawer" width="300">
+      <div class="drawer-element-content">
+        <div class="name element-item">
+          <span class="mr30">名称:</span>
+          <a-input v-model:value="layerState.layerName" style="width:110px" placeholder="element name"
+            @change="changeLayer" />
+        </div>
+        <div class="longitude element-item" v-if="layerState.currentType === geoType.Point">
+          <span class="mr30">经度:</span>
+          {{ layerState.longitude || '--' }}
+        </div>
+        <div class="latitude element-item" v-if="layerState.currentType === geoType.Point">
+          <span class="mr30">纬度:</span>
+          {{ layerState.latitude || '--' }}
+        </div>
+        <div class="latitude element-item" v-if="layerState.element_from === 2">
+          <span class="mr30">高度:</span>
+          {{ layerState.height || '--' }}
+        </div>
+        <div class="color-content">
+          <span class="mr30">颜色: </span>
+          <div v-for="item in colors" :key="item.id" class="color-item" :style="'background:' + item.color"
+            @click="changeColor(item)">
+            <svg-icon v-if="item.color === layerState.color" :size="18" name="check"></svg-icon>
+          </div>
+        </div>
+        <div class="element-item">
+          <span class="mr30">用户:</span>
+          {{ layerState.user_name || '--' }}
+        </div>
+        <div class="element-item">
+          <span class="mr30">来源:</span>
+          <Icon v-if="layerState.element_from === 2">
+            <template #component>
+              <svg width="1em" height="1em" fill="currentColor" viewBox="0 0 1024 1024">
+                <path
+                  d="M1024 418.21v576H0v-576h1024z m-672 192c-53.02 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96z m320 0c-53.02 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96zM236.59 29.79h125.55v320H236.59v-320z m425.28 0h125.55v320H661.87v-320z"
+                  p-id="4408" />
+              </svg>
+            </template>
+          </Icon>
+          <DesktopOutlined v-else />
+        </div>
+      </div>
+      <div class="flex-row flex-justify-around flex-align-center mt20">
+        <a-button type="primary" @click="deleteElement">删除</a-button>
+      </div>
+    </a-drawer> -->
   </div>
 </template>
 
@@ -67,12 +117,11 @@ import {
 import Icon from '@ant-design/icons-vue';
 import { DesktopOutlined } from '@ant-design/icons-vue';
 import LayersTree from '/@/components/LayersTree.vue'
-import { MapDoodleColor, MapElementEnum } from '/@/constants/map'
+import { MapElementEnum } from '/@/constants/map'
 import { useGMapCover } from '/@/hooks/use-g-map-cover'
 import { useMyStore } from '/@/store'
 import { GeojsonCoordinate, LayerResource } from '/@/types/map'
 import { Color, GeoType } from '/@/types/mapLayer'
-import { generatePoint } from '/@/utils/genjson'
 import { gcj02towgs84, wgs84togcj02 } from '/@/vendors/coordtransform'
 
 interface Props {
@@ -85,9 +134,12 @@ const props = withDefaults(defineProps<Props>(), {
 
 watch(() => props.mapClickId, (newValue, oldValue) => {
   if (newValue) {
-    // 只有一个文件夹,所以取第一个id即可
-    const mapLayerList: any = mapLayers.value;
-    const pid = mapLayerList[0].id;
+    // 默认文件夹列表
+    const defaultFileList: any = mapLayers.value.filter((item: any) => item.type === 2);
+    if (defaultFileList.length === 0) {
+      return;
+    }
+    const pid = defaultFileList[0].id;
     expandedKeys.value = [pid];
     selectedKeys.value = [`resource__${newValue}`];
     selectedLayer.value = getCurrentLayer(`resource__${newValue}`)
@@ -184,19 +236,25 @@ function updateMapElement(
   }
 }
 
-function checkLayer(keys: string[]) {
-
-}
-
 function selectLayer(keys: string[], e) {
-  if (e.selected) {
-    selectedKey.value = e.node.eventKey
-    selectedLayer.value = getCurrentLayer(selectedKey.value)
-    setBaseInfo()
-  }
-  visible.value = e.selected
+  visible.value = false
   store.commit('SET_DRAW_VISIBLE_INFO', visible.value)
+  if (!e.selected) {
+    return;
+  }
+  selectedKey.value = e.node.eventKey
+  selectedLayer.value = getCurrentLayer(selectedKey.value)
+  setBaseInfo()
+  const info = e.selectedNodes[0];
+  const { type } = info.props.parent;
+  if (type === 2) {// 默认文件夹
+    visible.value = e.selected
+    store.commit('SET_DRAW_VISIBLE_INFO', visible.value)
+  } else if (type === 3) {// 图片标注
+    console.log('此处写图片标注弹出层逻辑');
+  }
 }
+
 function getCurrentLayer(id: string) {
   const Layers = store.state.Layers
   const key = id.replaceAll('resource__', '')

+ 37 - 3
Web/src/pages/page-web/projects/media/detail/components/FileInfo.vue

@@ -119,6 +119,14 @@
         <a-tooltip placement="bottom" title="下载">
           <DownloadOutlined style="font-size: 20px;margin-right: 20px;" @click="onClickDownload" />
         </a-tooltip>
+        <div v-if="[1, 3].includes(state.info.media_type)">
+          <a-tooltip placement="bottom" title="在地图上加载" v-if="!state.info.element_id">
+            <EyeOutlined style="font-size: 20px;margin-right: 20px;" @click="onClickCreateMapElement" />
+          </a-tooltip>
+          <a-tooltip placement="bottom" title="在地图上取消加载" v-else>
+            <EyeInvisibleOutlined style="font-size: 20px;margin-right: 20px;" @click="onClickDeleteMapElement" />
+          </a-tooltip>
+        </div>
       </div>
       <div class="fileInfo-previewList">
         <div class="fileInfo-previewList-item">
@@ -131,7 +139,8 @@
 
 <script lang="ts" setup>
 import { reactive, onMounted } from 'vue';
-import { CloseOutlined, EnvironmentOutlined, DownloadOutlined } from '@ant-design/icons-vue';
+import { message } from 'ant-design-vue';
+import { CloseOutlined, EnvironmentOutlined, DownloadOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons-vue';
 import Panoramic from '/@/components/panoramic/index.vue';
 import { useGMapManage } from '/@/hooks/use-g-map';
 import { apis } from '/@/api/custom';
@@ -141,7 +150,7 @@ import { downloadMediaFile } from '/@/api/media';
 
 interface Props {
   fileId: string,
-  onClose: () => void,
+  onClose: () => Promise<any>,
 };
 
 const props = withDefaults(defineProps<Props>(), {
@@ -154,8 +163,9 @@ const state = reactive({
   info: {
     url: '',
     thumbnail_url: '',// 缩略图
-    media_type: null,
+    media_type: 0,
     file_id: '',
+    element_id: '',
     file_name: '',
     picture_type: '',
     task_name: '',
@@ -227,6 +237,30 @@ const onClickDownload = async () => {
   }
 }
 
+// 点击在地图上加载
+const onClickCreateMapElement = async () => {
+  try {
+    const id = state.info.file_id;
+    const res = await apis.createMapElement(id);
+    state.info.element_id = res.data.element_id;
+    message.success('在地图上加载成功');
+  } catch (e: any) {
+    console.error(e);
+  }
+}
+
+// 点击在地图上取消加载
+const onClickDeleteMapElement = async () => {
+  try {
+    const id = state.info.file_id;
+    await apis.deleteMapElement(id);
+    state.info.element_id = '';
+    message.success('在地图上取消加载成功');
+  } catch (e: any) {
+    console.error(e);
+  }
+}
+
 // 点击地图位置重置
 const onClickMapLocationReset = () => {
   const markerPosition = [state.info.longitude, state.info.latitude];

+ 36 - 8
Web/src/pages/page-web/projects/media/detail/index.vue

@@ -72,9 +72,15 @@
               </div>
               <!-- 非编辑态操作 -->
               <div class="flex-align-center flex-row" style="color: #2d8cf0" v-else>
-                <a-tooltip title="照片位置" v-if="[1, 3].includes(record.media_type)">
-                  <EnvironmentOutlined style="margin-right: 10px;" @click="onClickPhotoPosition" />
-                </a-tooltip>
+                <div v-if="[1, 3].includes(record.media_type)">
+                  <a-tooltip title="在地图上加载" v-if="!record.element_id">
+                    <EyeOutlined style="margin-right: 10px;" @click="onClickCreateMapElement(record.file_id)" />
+                  </a-tooltip>
+                  <a-tooltip title="在地图上取消加载" v-else>
+                    <EyeInvisibleOutlined style="color: #e70102;margin-right: 10px;"
+                      @click="onClickDeleteMapElement(record.file_id)" />
+                  </a-tooltip>
+                </div>
                 <a-tooltip title="重命名" v-else-if="record.media_type === 4">
                   <EditOutlined style="margin-right: 10px;" @click="onClickRechristen(record)" />
                 </a-tooltip>
@@ -119,7 +125,8 @@
 
 <script lang="ts" setup>
 import { reactive, onMounted } from 'vue';
-import { MenuOutlined, AppstoreOutlined, EditOutlined, DeleteOutlined, DownloadOutlined, EnvironmentOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons-vue';
+import { message } from 'ant-design-vue';
+import { MenuOutlined, AppstoreOutlined, EditOutlined, DeleteOutlined, DownloadOutlined, EyeOutlined, EyeInvisibleOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons-vue';
 import Search from './components/Search.vue';
 import FileInfo from './components/FileInfo.vue';
 import pictureSrc from '/@/assets/media/picture.svg';
@@ -318,14 +325,35 @@ const onClickLookFile = (record: any) => {
 }
 
 // 文件信息-点击关闭
-const fileInfoOnClickClose = () => {
+const fileInfoOnClickClose = async () => {
   state.fileId = '';
   state.fileInfoVisible = false;
+  const query = state.query;
+  await fetchList(query);
 }
 
-// 点击照片位置
-const onClickPhotoPosition = () => {
-  console.log('点击之后,在地图上显示这个图片的点标记信息');
+// 点击在地图上加载
+const onClickCreateMapElement = async (id: string) => {
+  try {
+    await apis.createMapElement(id);
+    const query = state.query;
+    await fetchList(query);
+    message.success('在地图上加载成功');
+  } catch (e: any) {
+    console.error(e);
+  }
+}
+
+// 点击在地图上取消加载
+const onClickDeleteMapElement = async (id: string) => {
+  try {
+    await apis.deleteMapElement(id);
+    const query = state.query;
+    await fetchList(query);
+    message.success('在地图上取消加载成功');
+  } catch (e: any) {
+    console.error(e);
+  }
 }
 
 // 点击重命名

+ 5 - 9
Web/src/pages/page-web/projects/media/index/index.vue

@@ -44,14 +44,9 @@
             </template>
             <!-- 操作 -->
             <template #action="{ record }">
-              <div class="flex-align-center flex-row" style="color: #2d8cf0">
-                <a-tooltip title="压缩下载">
-                  <DownloadOutlined style="margin-right: 10px;" @click="onClickDownload(record)" />
-                </a-tooltip>
-                <a-tooltip title="轨迹回放">
-                  <EnvironmentOutlined @click="onClickTrajectory" />
-                </a-tooltip>
-              </div>
+              <a-tooltip title="压缩下载">
+                <DownloadOutlined style="color: #2d8cf0;" @click="onClickDownload(record)" />
+              </a-tooltip>
             </template>
           </a-table>
         </div>
@@ -229,7 +224,8 @@ const columns = [
     title: '操作',
     dataIndex: 'actions',
     fixed: 'right',
-    width: 80,
+    align: 'center',
+    width: 60,
     slots: { customRender: 'action' },
   },
 ]

+ 2 - 2
Web/src/pages/page-web/projects/trajectory/index.vue

@@ -8,7 +8,7 @@
         <!-- 操作 -->
         <template #action="{ record }">
           <a-tooltip title="查看轨迹">
-            <EnvironmentOutlined style="color: #2d8cf0;margin-right: 10px;" @click="onClickLookTrajectory(record.id)" />
+            <EnvironmentOutlined style="color: #2d8cf0;" @click="onClickLookTrajectory(record.id)" />
           </a-tooltip>
         </template>
       </a-table>
@@ -129,7 +129,7 @@ const columns = [
     dataIndex: 'actions',
     fixed: 'right',
     align: 'center',
-    width: 50,
+    width: 60,
     slots: { customRender: 'action' },
   },
 ]

+ 2 - 5
Web/src/pages/page-web/projects/tsa.vue

@@ -229,23 +229,20 @@
       <a-button style="margin-right: 10px;" type="primary" @click="onClickGoHome">
         返回
       </a-button>
-      <!-- <a-button style="margin-right: 10px;" type="primary" @click="openLivestreamOthers">
-        测试直播
-      </a-button> -->
     </div>
   </div>
 </template>
 
 <script lang="ts" setup>
 import { computed, onMounted, reactive, ref, watch } from 'vue'
-import Layer from '/@/pages/page-web/projects/layer/index.vue'
+import Layer from './layer/index.vue'
 import { EDeviceTypeName, ELocalStorageKey } from '/@/types'
 import noData from '/@/assets/icons/no-data.png'
 import rc from '/@/assets/icons/rc.png'
 import { OnlineDevice, EModeCode, EDockModeCode } from '/@/types/device'
 import { useMyStore } from '/@/store'
 import { getDeviceTopo, getUnreadDeviceHms, updateDeviceHms } from '/@/api/manage'
-import { RocketOutlined, EyeInvisibleOutlined, EyeOutlined, RobotOutlined, DoubleRightOutlined, ImportOutlined } from '@ant-design/icons-vue'
+import { RocketOutlined, EyeInvisibleOutlined, EyeOutlined, RobotOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'
 import { EHmsLevel, ERouterName } from '/@/types/enums'
 import { getRoot } from '/@/root'