瀏覽代碼

协同标绘调整

Hwf 8 月之前
父節點
當前提交
534f74f056

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

@@ -32,7 +32,7 @@ export const updatePatternInfo = (data) => {
   });
 };
 
-// 预案
+// 预案新
 export const createPattern = (data) => {
   return request({
     url: '/api/pattern/create',
@@ -40,3 +40,12 @@ export const createPattern = (data) => {
     data: data
   });
 };
+
+// 开启协同
+export const startCollaboration = (data) => {
+  return request({
+    url: '/api/pattern/ws/add_user',
+    method: 'post',
+    data: data
+  });
+};

二進制
src/assets/images/map/rightMenu/btn2.png


+ 84 - 129
src/views/globalMap/RightMenu/OnlinePlotting/ShareDialog.vue → src/components/Contact/index.vue

@@ -1,35 +1,19 @@
 <template>
-  <Dialog custom-show type="lg" title="分享" @close="handleClose" @confirm="handleConfirm">
+  <Dialog custom-show type="lg" title="通讯录" @close="handleClose" @confirm="handleConfirm">
     <div class="content">
       <div class="left-content">
-        <el-input v-model="queryParams.keyword" class="custom-input" placeholder="组织架构搜索">
+        <el-input v-model="queryParams1.deptName" class="custom-input" placeholder="组织架构搜索">
           <template #prefix>
             <el-icon class="el-input__icon"><search /></el-icon>
           </template>
         </el-input>
         <div class="tree-container">
           <div class="tree-box">
-            <el-tree :data="treeData" accordion @node-click="handleNodeClick" />
+            <el-tree :data="treeData" :props="{ value: 'deptId', label: 'deptName', children: 'children' }" accordion @node-click="handleNodeClick" />
           </div>
         </div>
       </div>
       <div class="middle-content">
-        <div class="search-box">
-          <el-select
-            v-model="queryParams.value1"
-            class="custom-select select-box"
-            placeholder="全部"
-            popper-class="custom-select-popper"
-            :teleported="false"
-          >
-            <el-option v-for="level in options" :key="level.value" :label="level.name" :value="level.value"></el-option>
-          </el-select>
-          <el-input v-model="queryParams.keyword" class="custom-input" placeholder="组织架构搜索">
-            <template #prefix>
-              <el-icon class="el-input__icon"><search /></el-icon>
-            </template>
-          </el-input>
-        </div>
         <div class="user-box">
           <div class="user-table">
             <div class="tr">
@@ -44,7 +28,7 @@
                 <div class="td2">
                   <div :class="item.checked ? 'common-checked-active' : 'common-checked'" @click="handleChecked2(item)"></div>
                 </div>
-                <div class="td">{{ item.name }}</div>
+                <div class="td">{{ item.nickName }}</div>
                 <div class="td3">
                   {{ item.duty }}
                   <div class="phone-icon"></div>
@@ -65,12 +49,14 @@
         </div>
         <div class="select-content">
           <div v-for="(item, index) in selectList" :key="index" class="box-item">
-            <div class="line">
-              <div class="text1">{{ item.name }}</div>
-              <div class="text2">{{ item.duty }}</div>
-            </div>
-            <div class="line" style="margin-top: 20px">
-              <div class="text2">{{ item.dept }}</div>
+            <div class="box-left">
+              <div class="line">
+                <div class="text1">{{ item.nickName }}</div>
+                <div class="text2">{{ item.duty }}</div>
+              </div>
+              <div class="line" style="margin-top: 20px">
+                <div class="text2">{{ item.dept }}</div>
+              </div>
             </div>
             <div class="close-btn" @click="deleteItem(item)"></div>
           </div>
@@ -80,70 +66,31 @@
   </Dialog>
 </template>
 
-<script lang="ts" setup name="ShareDialog">
+<script lang="ts" setup name="Contact">
 import { Search } from '@element-plus/icons-vue';
+import { listDept } from '@/api/system/dept';
+import { DeptVO } from '@/api/system/dept/types';
+import { listUser } from '@/api/system/user';
 defineProps({
   modelValue: Boolean
 });
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const emits = defineEmits(['update:modelValue', 'close', 'confirm']);
-let activeIndex = ref(0);
-const options = ref([{ name: '全部', value: '全部' }]);
-const queryParams = ref({
-  value1: '',
-  keyword: ''
+let queryParams1 = ref({
+  pageNum: 1,
+  pageSize: 10,
+  deptName: undefined,
+  deptCategory: undefined,
+  status: undefined
 });
-const menu = ref([{ name: '视频会商' }, { name: '无人机' }, { name: '单兵设备' }]);
-const treeData = ref([
-  {
-    label: '茂名市',
-    children: [
-      {
-        label: '茂名市委',
-        children: [
-          {
-            label: '茂名市纪委监委',
-            isLeaf: true
-          },
-          {
-            label: '茂名市委办公室',
-            isLeaf: true
-          },
-          {
-            label: '茂名市委组织部',
-            isLeaf: true
-          }
-        ]
-      },
-      {
-        label: '茂名市人大',
-        children: [
-          {
-            label: '茂名市人大常委会秘书长、副秘书长',
-            isLeaf: true
-          },
-          {
-            label: '茂名市人大常委会办公室',
-            isLeaf: true
-          },
-          {
-            label: '茂名市人大常委会研究室',
-            isLeaf: true
-          }
-        ]
-      }
-    ]
-  }
-]);
-const userList = ref([]);
-const selectList = computed(() => {
-  const data = [];
-  userList.value.forEach((item) => {
-    if (item.checked) {
-      data.push(item);
-    }
-  });
-  return data;
+let queryParams2 = ref({
+  pageNum: 1,
+  pageSize: 100,
+  deptId: ''
 });
+const treeData = ref([]);
+const userList = ref([]);
+const selectList = ref([]);
 const getCheckedClass = () => {
   let res = 'common-checked';
   const len = userList.value.length;
@@ -155,51 +102,23 @@ const getCheckedClass = () => {
   }
   return res;
 };
-const handleNodeClick = (item) => {
-  if (item.isLeaf) {
-    const data = [
-      {
-        id: 1,
-        name: '李莉莉',
-        duty: '副主任',
-        dept: '茂名市/茂名市政府/茂名应急管理局'
-      },
-      {
-        id: 2,
-        name: '何里',
-        duty: '副主任',
-        dept: '茂名市/茂名市政府/茂名应急管理局'
-      },
-      {
-        id: 3,
-        name: '张三',
-        duty: '副主任',
-        dept: '茂名市/茂名市政府/茂名应急管理局'
-      },
-      {
-        id: 4,
-        name: '张三',
-        duty: '副主任',
-        dept: '茂名市/茂名市政府/茂名应急管理局'
-      },
-      {
-        id: 5,
-        name: '张三',
-        duty: '副主任',
-        dept: '茂名市/茂名市政府/茂名应急管理局'
-      },
-      {
-        id: 6,
-        name: '张三',
-        duty: '副主任',
-        dept: '茂名市/茂名市政府/茂名应急管理局'
-      }
-    ];
+const handleNodeClick = (data) => {
+  queryParams2.value.deptId = data.deptId;
+  getPerson();
+};
+const getPerson = () => {
+  listUser(queryParams2.value).then((res) => {
+    const data = res.rows;
     data.forEach((item) => {
-      item.checked = false;
+      for (let i = 0; i < selectList.value.length; i++) {
+        if (selectList.value[i].nickName === item.nickName) {
+          item.checked = true;
+          break;
+        }
+      }
     });
     userList.value = data;
-  }
+  });
 };
 // 全选、全取消
 const handleChecked = () => {
@@ -211,10 +130,28 @@ const handleChecked = () => {
   userList.value.forEach((item) => {
     item.checked = flag;
   });
+  computedSelectList();
 };
 // 单个选中、取消选中
 const handleChecked2 = (item) => {
   item.checked = !item.checked;
+  computedSelectList();
+};
+const computedSelectList = () => {
+  userList.value.forEach((item2) => {
+    let index = 0;
+    for (let i = 0; i < selectList.value.length; i++) {
+      if (!!item2.checked && selectList.value[i].userId !== item2.userId) {
+        index++;
+      } else if (!item2.checked && selectList.value[i].userId === item2.userId) {
+        selectList.value.splice(i, 1);
+        break;
+      }
+    }
+    if (!!item2.checked && selectList.value.length === index) {
+      selectList.value.push(item2);
+    }
+  });
 };
 // 清空
 const clearSelect = () => {
@@ -223,15 +160,17 @@ const clearSelect = () => {
       item.checked = false;
     }
   });
+  selectList.value = [];
 };
 // 清空指定项
 const deleteItem = (item) => {
   for (let i = 0; i < userList.value.length; i++) {
-    if (item.id === userList.value[i].id) {
+    if (item.userId === userList.value[i].userId) {
       userList.value[i].checked = false;
       break;
     }
   }
+  computedSelectList();
 };
 
 // 弹窗关闭后
@@ -245,6 +184,16 @@ const handleConfirm = () => {
   emits('confirm', selectList.value);
   emits('update:modelValue', false);
 };
+
+const initData = () => {
+  listDept(queryParams1.value).then((res: any) => {
+    const data = proxy?.handleTree<DeptVO>(res.data, 'deptId');
+    treeData.value = data;
+  });
+};
+onMounted(() => {
+  initData();
+});
 </script>
 
 <style lang="scss" scoped>
@@ -252,12 +201,12 @@ const handleConfirm = () => {
   display: flex;
   margin-top: 12px;
   .left-content {
-    width: 910px;
+    width: 303px;
     padding-right: 30px;
     border-right: 1px solid #2187ff;
   }
   .middle-content {
-    width: 910px;
+    width: 303px;
     padding: 0 30px;
     border-right: 1px solid #2187ff;
     .search-box {
@@ -379,7 +328,7 @@ const handleConfirm = () => {
   }
   .select-box2 {
     margin-left: 30px;
-    width: 910px;
+    width: 303px;
     height: 100%;
     .select-header {
       display: flex;
@@ -410,6 +359,11 @@ const handleConfirm = () => {
         border-bottom: 1px solid #247dff;
         padding: 20px;
         position: relative;
+        display: flex;
+        .box-left {
+          flex: 1;
+          margin-right: 5px;
+        }
         .line {
           color: #fff;
           font-size: 38px;
@@ -422,6 +376,7 @@ const handleConfirm = () => {
           }
         }
         .close-btn {
+          flex-shrink: 0;
           position: absolute;
           right: 10px;
           top: 50px;

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

@@ -14,6 +14,7 @@ declare module 'vue' {
     BuildCode: typeof import('./../components/BuildCode/index.vue')['default']
     Chart: typeof import('./../components/Chart/index.vue')['default']
     CompanyMap: typeof import('./../components/Map/company-map.vue')['default']
+    Contact: typeof import('./../components/Contact/index.vue')['default']
     Dialog: typeof import('./../components/Dialog/index.vue')['default']
     DictTag: typeof import('./../components/DictTag/index.vue')['default']
     Editor: typeof import('./../components/Editor/index.vue')['default']
@@ -96,6 +97,7 @@ declare module 'vue' {
     RouterView: typeof import('vue-router')['RouterView']
     Screenfull: typeof import('./../components/Screenfull/index.vue')['default']
     ScrollTable: typeof import('./../components/ScrollTable/index.vue')['default']
+    ShareDialog: typeof import('./../components/Contact/ShareDialog.vue')['default']
     SizeSelect: typeof import('./../components/SizeSelect/index.vue')['default']
     Step: typeof import('./../components/Step/index.vue')['default']
     SubmitVerify: typeof import('./../components/Process/submitVerify.vue')['default']

+ 28 - 18
src/views/globalMap/RightMenu/OnlinePlotting/index.vue

@@ -7,17 +7,15 @@
           {{ item.name }}
         </div>
       </div>
-      <div class="btn1" @click="handleScreenshot">
-        <div class="icon1"></div>
-        当前地图截图导出
+      <div class="btn-box">
+        <div v-show="!collaboration" class="btn2" @click="handleShare('1')">协同标绘</div>
+        <div v-show="collaboration" class="btn2" @click="handleCloseCollaboration">关闭协同</div>
+        <div v-show="collaboration" class="btn2" style="margin-left: 20px">保存</div>
       </div>
     </div>
-    <div class="btn-box">
-      <div v-show="!collaboration" class="btn1" @click="handleShare('1')">
-        协同标绘
-      </div>
-      <div v-show="collaboration" class="btn1" @click="handleCloseCollaboration">关闭协同</div>
-      <div v-show="collaboration" class="btn1">保存</div>
+    <div class="btn1" @click="handleScreenshot">
+      <div class="icon1"></div>
+      当前地图截图导出
     </div>
     <div v-if="menuActive1 === 0" class="content">
       <div class="box1">
@@ -137,19 +135,18 @@
   <div v-show="tipTitle !== ''" class="tipTitle">{{ tipTitle }}</div>
   <!--保存修改弹窗-->
   <EditDialog v-if="showEdit" v-model="showEdit" :edit-data="editData" @submit="handleSubmit" />
-  <ShareDialog v-if="shareState.showShare" v-model="shareState.showShare" @close="handleCloseShare" @confirm="handleShareConfirm" />
+  <Contact v-if="shareState.showShare" v-model="shareState.showShare" @close="handleCloseShare" @confirm="handleShareConfirm" />
 </template>
 
 <script lang="ts" setup name="OnlinePlotting">
 import { nanoid } from 'nanoid';
 import { deepClone } from '@/utils';
 import { useHistory } from '@/hooks/useHistory';
-import { deletePatternById, getPatternInfo, getPatternList } from '@/api/globalMap/onlinePlotting';
+import { deletePatternById, getPatternInfo, getPatternList, startCollaboration } 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 ShareDialog from '@/views/globalMap/RightMenu/OnlinePlotting/ShareDialog.vue';
 import websocketStore from '@/store/modules/websocketStore';
 import { tempData } from './tempData';
 
@@ -722,11 +719,7 @@ const handleCloseCollaboration = () => {
 const handleShareConfirm = (data) => {
   if (shareState.type === '1') {
     // 协同标绘
-    setTimeout(() => {
-      const data = tempData;
-      const mapUtils = getMapUtils();
-      mapUtils.drawData(data);
-    }, 1000);
+    startCollaboration()
     userWebsocket.init();
   } else {
     // 分享
@@ -846,6 +839,24 @@ onMounted(() => {
   cursor: pointer;
   font-size: 32px;
   color: #edfaff;
+  margin-bottom: -25px;
+  .icon1 {
+    width: 42px;
+    height: 42px;
+    background: url('@/assets/images/map/rightMenu/onlinePlotting/screenshot.png') no-repeat;
+    margin-right: 12px;
+  }
+}
+.btn2 {
+  width: 278px;
+  height: 78px;
+  background: url('@/assets/images/map/rightMenu/btn.png') no-repeat;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  cursor: pointer;
+  font-size: 32px;
+  color: #edfaff;
   margin-bottom: -57px;
   .icon1 {
     width: 42px;
@@ -1162,6 +1173,5 @@ onMounted(() => {
 .btn-box {
   display: flex;
   align-items: center;
-  margin: 10px 0;
 }
 </style>