Hwf 8 mēneši atpakaļ
vecāks
revīzija
aab3f84520

+ 19 - 1
src/api/globalMap/onlinePlotting.ts

@@ -72,7 +72,25 @@ export const endCollaboration = (data) => {
 export const closeCollaboration = (data) => {
   return request({
     url: '/api/pattern/ws/bz_add',
-    method: 'post',
+    method: 'put',
     data: data
   });
 };
+
+// 标注列表
+export const getBzList = (params) => {
+  return request({
+    url: '/api/pattern/ws/bz_list',
+    method: 'get',
+    params: params
+  });
+};
+
+// 添加分组
+export const addGroup = (params) => {
+  return request({
+    url: '/api/pattern/ws/add_group',
+    method: 'get',
+    params: params
+  });
+};

BIN
src/assets/images/map/rightMenu/layerDetail/icon1.png


BIN
src/assets/images/map/rightMenu/layerDetail/icon2.png


BIN
src/assets/images/map/rightMenu/layerDetail/icon3.png


BIN
src/assets/images/map/rightMenu/layerDetail/icon4.png


BIN
src/assets/images/map/rightMenu/layerDetail/icon5.png


+ 1 - 0
src/components/Dialog/index.vue

@@ -168,6 +168,7 @@ const handleShowAddTag = () => {
     }
   }
   .dialog-header {
+    padding-top: 6px;
     &::before {
       content: '';
       position: absolute;

+ 6 - 2
src/hooks/AMap/useAMap.ts

@@ -277,10 +277,14 @@ export function useAMap(options) {
     movePolyline?.remove();
     movePassedPolyline?.remove();
     moveMarker?.remove();
+    const icon = new AMap.Icon({
+      size: new AMap.Size(26, 52),
+      image: 'https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png'
+    });
     moveMarker = new AMap.Marker({
       map: map,
       position: [116.478935, 39.997761],
-      icon: 'https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png',
+      icon: icon,
       offset: new AMap.Pixel(-13, -26)
     });
     // 绘制轨迹
@@ -310,7 +314,7 @@ export function useAMap(options) {
         movePolyline.remove();
         movePassedPolyline.remove();
         moveMarker.remove();
-      }, 2000);
+      }, 5000);
     });
     moveMarker.moveAlong(lineArr, {
       // 每一段的时长

+ 16 - 0
src/types/components.d.ts

@@ -29,9 +29,13 @@ declare module 'vue' {
     ElButton: typeof import('element-plus/es')['ElButton']
     ElCard: typeof import('element-plus/es')['ElCard']
     ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
+    ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
     ElCol: typeof import('element-plus/es')['ElCol']
+    ElCollapse: typeof import('element-plus/es')['ElCollapse']
+    ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
     ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
+    ElContainer: typeof import('element-plus/es')['ElContainer']
     ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
     ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
     ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
@@ -44,23 +48,31 @@ declare module 'vue' {
     ElEmpty: typeof import('element-plus/es')['ElEmpty']
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
+    ElHeader: typeof import('element-plus/es')['ElHeader']
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
     ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
     ElLink: typeof import('element-plus/es')['ElLink']
+    ElMain: typeof import('element-plus/es')['ElMain']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
     ElPopover: typeof import('element-plus/es')['ElPopover']
     ElRadio: typeof import('element-plus/es')['ElRadio']
+    ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
     ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSegmented: typeof import('element-plus/es')['ElSegmented']
     ElSelect: typeof import('element-plus/es')['ElSelect']
+    ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
+    ElSkeletonItem: typeof import('element-plus/es')['ElSkeletonItem']
     ElSlider: typeof import('element-plus/es')['ElSlider']
+    ElSpace: typeof import('element-plus/es')['ElSpace']
+    ElStep: typeof import('element-plus/es')['ElStep']
+    ElSteps: typeof import('element-plus/es')['ElSteps']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTable: typeof import('element-plus/es')['ElTable']
@@ -73,6 +85,7 @@ declare module 'vue' {
     ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElTree: typeof import('element-plus/es')['ElTree']
+    ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
     ElUpload: typeof import('element-plus/es')['ElUpload']
     ExcelEditor: typeof import('./../components/ExcelEditor/index.vue')['default']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']
@@ -84,6 +97,9 @@ declare module 'vue' {
     HikvisionPlayer: typeof import('./../components/HKVideo/hikvision-player.vue')['default']
     HKVideo: typeof import('./../components/HKVideo/index.vue')['default']
     IconSelect: typeof import('./../components/IconSelect/index.vue')['default']
+    IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default']
+    IEpCaretTop: typeof import('~icons/ep/caret-top')['default']
+    IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default']
     IFrame: typeof import('./../components/iFrame/index.vue')['default']
     ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default']
     ImageUpload: typeof import('./../components/ImageUpload/index.vue')['default']

+ 186 - 0
src/views/globalMap/RightMenu/OnlinePlotting/LayerDetail.vue

@@ -0,0 +1,186 @@
+<template>
+  <Dialog title="预案名称" custom-show hide-footer>
+    <div class="btn-box1">
+      <div class="btn1">
+        <i class="icon1" />
+        邀请协同
+      </div>
+      <div class="btn1" style="margin-left: 10px">
+        <i class="icon2" />
+        协同用户
+      </div>
+    </div>
+    <div class="btn-box2">
+      <div class="box-left">
+        <div class="text1">分类</div>
+        <el-select v-model="type" :teleported="false" class="custom-select" popper-class="custom-select-popper" style="width: 140px">
+          <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </div>
+      <div class="box-right">
+        <div class="btn1">
+          <i class="icon3" />
+          显示标注
+        </div>
+        <div class="btn1" style="margin-left: 10px">
+          <i class="icon4" />
+          导入图层
+        </div>
+        <div class="btn1" style="margin-left: 10px" @click="handleShowGroup">
+          <i class="icon5" />
+          添加分组
+        </div>
+      </div>
+    </div>
+    <div class="common-table">
+      <div class="table-header">
+        <div class="td" style="width: 40px"></div>
+        <div class="td">标注名称</div>
+        <div class="td">用户</div>
+        <div class="td">单位</div>
+        <div class="td">时间</div>
+        <div class="td">操作</div>
+      </div>
+      <div v-for="(item, index) in dataList" :key="index" class="tr">
+        <div class="td" :title="item.event_title">{{ item.event_title }}</div>
+      </div>
+    </div>
+  </Dialog>
+  <Dialog v-model="showGroup" :title="groupForm.groupId ? '编辑分组' : '添加分组'" type="xs" hide-footer>
+    <div class="form-item">
+      <div class="text1">分组名称</div>
+      <el-input v-model="groupForm.name" class="custom-input" placeholder="请输入" />
+    </div>
+    <div class="form-action">
+      <div class="common-btn-primary" @click="handleAddGroup">保存</div>
+      <div class="common-btn-primary" @click="handleDeleteGroup">删除</div>
+      <div class="common-btn" @click="handleCanle">取消</div>
+    </div>
+  </Dialog>
+</template>
+
+<script lang="ts" setup name="LayerDetail">
+import { addGroup, getBzList } from '@/api/globalMap/onlinePlotting';
+const props = defineProps({
+  modelValue: Boolean,
+  patternId: String
+});
+const emits = defineEmits(['update:modelValue']);
+let type = ref('');
+let typeOptions = ref([
+  { label: '全部', value: '' },
+  { label: '点', value: '1' },
+  { label: '线', value: '2' },
+  { label: '面', value: '3' },
+  { label: '其他', value: '4' }
+]);
+let queryParams = reactive({
+  pattern_id: props.patternId
+});
+let dataList = ref([]);
+
+let showGroup = ref(false);
+let groupForm = ref({
+  groupId: '',
+  name: ''
+});
+const handleShowGroup = () => {
+  showGroup.value = true;
+};
+const handleAddGroup = () => {
+  addGroup(groupForm.value).then((res) => {
+    emits('update:modelValue', false);
+  });
+};
+onMounted(() => {
+  getBzList(queryParams).then((res) => {
+    dataList.value = res.data;
+  });
+});
+</script>
+
+<style lang="scss" scoped>
+.btn-box1 {
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  position: absolute;
+  top: 30px;
+  right: 22px;
+}
+.btn-box2 {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: 15px;
+  margin-bottom: 10px;
+  .box-left {
+    display: flex;
+    align-items: center;
+    .text1 {
+      font-size: 14px;
+      margin-right: 5px;
+    }
+  }
+  .box-right {
+    display: flex;
+    align-items: center;
+  }
+}
+.btn1 {
+  width: 104px;
+  height: 29px;
+  background: url('@/assets/images/map/rightMenu/btn.png') no-repeat;
+  background-size: 100% 100%;
+  padding: 0 5px;
+  display: flex;
+  align-items: center;
+  cursor: pointer;
+  .icon1 {
+    width: 28px;
+    height: 25px;
+    background: url('@/assets/images/map/rightMenu/layerDetail/icon1.png') no-repeat;
+    background-size: 100% 100%;
+  }
+  .icon2 {
+    width: 23px;
+    height: 24px;
+    background: url('@/assets/images/map/rightMenu/layerDetail/icon2.png') no-repeat;
+    background-size: 100% 100%;
+  }
+  .icon3 {
+    width: 22px;
+    height: 22px;
+    background: url('@/assets/images/map/rightMenu/layerDetail/icon3.png') no-repeat;
+    background-size: 100% 100%;
+  }
+  .icon4 {
+    width: 26px;
+    height: 26px;
+    background: url('@/assets/images/map/rightMenu/layerDetail/icon4.png') no-repeat;
+    background-size: 100% 100%;
+  }
+  .icon5 {
+    width: 23px;
+    height: 23px;
+    background: url('@/assets/images/map/rightMenu/layerDetail/icon5.png') no-repeat;
+    background-size: 100% 100%;
+  }
+}
+.form-item {
+  display: flex;
+  align-items: center;
+  .text1 {
+    flex-shrink: 0;
+    margin-right: 10px;
+  }
+  .custom-input {
+    flex: 1;
+  }
+}
+.form-action {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+</style>

+ 31 - 16
src/views/globalMap/RightMenu/OnlinePlotting/index.vue

@@ -1,6 +1,10 @@
 <template>
   <div class="menu-content">
     <div class="gradient-text common-dialog-title2">实时标绘</div>
+    <div v-show="collaboration" style="display: flex; align-items: center; justify-content: flex-end">
+      <div class="btn2" style="margin-left: 10px" @click="handleCloseCollaboration">关闭协同</div>
+      <div class="btn2" style="margin-left: 10px">保存</div>
+    </div>
     <div class="line">
       <div class="tabs1">
         <div v-for="(item, index) in menu" :key="index" :class="menuActive1 === index ? 'tab tab_active' : 'tab'" @click="clickTab(index)">
@@ -8,16 +12,15 @@
         </div>
       </div>
       <div class="btn-box">
-        <div v-show="!collaboration" class="btn2" @click="handleShare('1')">协同标绘</div>
-        <div v-show="collaboration" class="btn2" @click="handleShowLayer">查看图层</div>
-        <div v-show="collaboration" class="btn2" style="margin-left: 10px" @click="handleCloseCollaboration">关闭协同</div>
-        <div v-show="collaboration" class="btn2" style="margin-left: 10px">保存</div>
+        <div class="btn1" @click="handleScreenshot">
+          <div class="icon1"></div>
+          当前地图截图导出
+        </div>
+<!--        <div v-show="!collaboration" class="btn2" @click="handleShare('1')">协同标绘</div>-->
+<!--        v-show="collaboration"-->
+        <div class="btn2" @click="handleShowLayer">查看图层</div>
       </div>
     </div>
-    <div class="btn1" @click="handleScreenshot">
-      <div class="icon1"></div>
-      当前地图截图导出
-    </div>
     <div v-if="menuActive1 === 0" class="content">
       <div class="box1">
         <div class="box-item">
@@ -143,18 +146,26 @@
       <el-input v-model="form.pattern_name" class="custom-input" placeholder="请输入" style="flex: 1" />
     </div>
   </Dialog>
+  <LayerDetail v-if="showLayer" v-model="showLayer" :patternId="patternId" />
 </template>
 
 <script lang="ts" setup name="OnlinePlotting">
 import { nanoid } from 'nanoid';
 import { deepClone } from '@/utils';
 import { useHistory } from '@/hooks/useHistory';
-import { deletePatternById, getPatternInfo, getPatternList, createCollaboration } from '@/api/globalMap/onlinePlotting';
+import {
+  deletePatternById,
+  getPatternInfo,
+  getPatternList,
+  createCollaboration,
+  closeCollaboration
+} from '@/api/globalMap/onlinePlotting';
 import TextEdit from '@/views/globalMap/RightMenu/OnlinePlotting/TextEdit.vue';
 import EditDialog from '@/views/globalMap/RightMenu/OnlinePlotting/EditDialog.vue';
 import { Search } from '@element-plus/icons-vue';
 import html2canvas from 'html2canvas';
 import websocketStore from '@/store/modules/websocketStore';
+import LayerDetail from './LayerDetail.vue';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const userWebsocket = websocketStore();
@@ -346,6 +357,7 @@ let shareState = reactive({
   showShare: false,
   id: ''
 });
+let patternId = ref('');
 let shareId = ref('');
 const overlays = [];
 const overlaysData = [];
@@ -687,7 +699,9 @@ const handleCloseShare = () => {
   shareState.id = '';
 };
 const handleCloseCollaboration = () => {
-  collaboration.value = false;
+  closeCollaboration({pattern_id: patternId.value}).then(() => {
+    collaboration.value = false;
+  });
 };
 let showForm = ref(false);
 let form = ref({
@@ -724,6 +738,7 @@ const handleShareConfirm = (data) => {
 const handleSendForm = () => {
   userWebsocket.init();
   createCollaboration(form.value);
+  patternId.value = form.value.pattern_id;
   collaboration.value = true;
 };
 watch(userWebsocket.webSocketList, (newVal) => {
@@ -829,8 +844,8 @@ onMounted(() => {
   }
 }
 .btn1 {
-  width: 176px;
-  height: 48px;
+  width: 200px;
+  height: 60px;
   background: url('@/assets/images/map/rightMenu/onlinePlotting/btn1.png') no-repeat;
   background-size: 100% 100%;
   display: flex;
@@ -1024,8 +1039,8 @@ onMounted(() => {
       }
       .checked1 {
         position: absolute;
-        top: 3px;
-        right: 3px;
+        top: 8px;
+        right: 8px;
         width: 13px;
         height: 13px;
         background: url('@/assets/images/map/rightMenu/onlinePlotting/checked1.png') no-repeat;
@@ -1033,8 +1048,8 @@ onMounted(() => {
       }
       .checked2 {
         position: absolute;
-        top: 3px;
-        right: 3px;
+        top: 8px;
+        right: 8px;
         width: 13px;
         height: 13px;
         background: url('@/assets/images/map/rightMenu/onlinePlotting/checked2.png') no-repeat;