Просмотр исходного кода

feat: 布局管理-场景布局-编辑公司主页布局页面 新增点击右键出现删除按钮功能 && 新增点击返回时提示未保存功能 && 修复改变标签颜色不生效问题

“fujiacheng” 1 год назад
Родитель
Сommit
f916162e7d

+ 10 - 2
src/api/scene/scene.ts

@@ -92,8 +92,16 @@ export const updateCompanyLayout = (param: SceneTypes.UpdateCompanyLayoutParam)
   return updateCompanyLayoutApi({ ...param });
   return updateCompanyLayoutApi({ ...param });
 };
 };
 
 
-/** 查询公司主页配置 */
-// export const getCompanyLayoutApi = (params: { companyId: number }) => {
+/** 根据公司查询Mobile主页布局 */
+export const getMobileCompanyLayoutApi = (params: { companyId: number }) => {
+  return http.request({
+    url: '/admin/homepageConfig/getMobileCompanyLayout',
+    method: 'get',
+    params,
+  });
+};
+
+/** 根据公司查询PC主页布局 */
 export const getCompanyLayoutApi = (params: { companyId: number }) => {
 export const getCompanyLayoutApi = (params: { companyId: number }) => {
   return http.request({
   return http.request({
     url: '/admin/homepageConfig/getPcCompanyLayout',
     url: '/admin/homepageConfig/getPcCompanyLayout',

+ 31 - 3
src/views/page-config/ConfigEdit.vue

@@ -7,7 +7,7 @@
         </div>
         </div>
         <div class="top-bar">
         <div class="top-bar">
           <div class="back-and-company">
           <div class="back-and-company">
-            <div class="back" @click="router.back">
+            <div class="back" @click="handelClickBack">
               <img src="@/assets/rollback.png" />
               <img src="@/assets/rollback.png" />
               <span>返回</span>
               <span>返回</span>
             </div>
             </div>
@@ -111,7 +111,12 @@
   import usePageConfig from './usePageConfig';
   import usePageConfig from './usePageConfig';
   import MapContainer from './component/mapContainer/MapContainer.vue';
   import MapContainer from './component/mapContainer/MapContainer.vue';
   import useMapEditor, { LabelPositionEnum } from './stores/useMapEditor';
   import useMapEditor, { LabelPositionEnum } from './stores/useMapEditor';
-  import { uploadCompanyLayout, updateCompanyLayout, getCompanyLayoutApi } from '@/api/scene/scene';
+  import {
+    uploadCompanyLayout,
+    updateCompanyLayout,
+    getCompanyLayoutApi,
+    getMobileCompanyLayoutApi,
+  } from '@/api/scene/scene';
   import safeParse from '@/utils/safeParse';
   import safeParse from '@/utils/safeParse';
   import { useRouter } from 'vue-router';
   import { useRouter } from 'vue-router';
   import urlJoin from 'url-join';
   import urlJoin from 'url-join';
@@ -119,6 +124,7 @@
   import { getHeaders } from '@/utils/http/axios';
   import { getHeaders } from '@/utils/http/axios';
   import { ShopType } from '@/types/page-config/type';
   import { ShopType } from '@/types/page-config/type';
   import ShopTagEditArea from './component/ShopTagEditArea.vue';
   import ShopTagEditArea from './component/ShopTagEditArea.vue';
+  import { ViewType } from '@/types/page-config/type';
 
 
   const mapEditor = useMapEditor();
   const mapEditor = useMapEditor();
   const { bgImg, addedShops, activeShopId, showShops, mapHeight, mapWidth } =
   const { bgImg, addedShops, activeShopId, showShops, mapHeight, mapWidth } =
@@ -156,6 +162,8 @@
     ),
     ),
   );
   );
 
 
+  const defaultLayoutString = ref(''); // 默认布局的string,用于点击返回时判断是否未保存布局就离开
+
   const handleBeforeUpload = (rawFile) => {
   const handleBeforeUpload = (rawFile) => {
     if (
     if (
       rawFile.type !== 'image/jpg' &&
       rawFile.type !== 'image/jpg' &&
@@ -204,11 +212,15 @@
   };
   };
 
 
   const getShopContent = () => {
   const getShopContent = () => {
+    const companyLayoutApiMap = {
+      [ViewType.companyHomepage_PC]: getCompanyLayoutApi,
+      [ViewType.companyHomepage_phone]: getMobileCompanyLayoutApi,
+    };
     getWorkshopListApi({ companyId: companyId.value! }).then((res) => {
     getWorkshopListApi({ companyId: companyId.value! }).then((res) => {
       shopList.value = res;
       shopList.value = res;
     });
     });
 
 
-    getCompanyLayoutApi({
+    companyLayoutApiMap[viewType.value!]({
       companyId: companyId.value!,
       companyId: companyId.value!,
     }).then((res) => {
     }).then((res) => {
       if (!res) {
       if (!res) {
@@ -223,6 +235,7 @@
       }
       }
       hasBg.value = true;
       hasBg.value = true;
       createMap(layoutJSON);
       createMap(layoutJSON);
+      defaultLayoutString.value = res.layout;
     });
     });
   };
   };
 
 
@@ -303,8 +316,23 @@
         },
         },
       );
       );
     }
     }
+    defaultLayoutString.value = layout;
   };
   };
 
 
+  function handelClickBack() {
+    const json = calcLayout(mapContainerRef.value?.getLayout().json);
+
+    if (json !== defaultLayoutString.value) {
+      ElMessageBox.confirm('未保存当前设置,是否离开?', '提示', {
+        confirmButtonText: '确认',
+        cancelButtonText: '取消',
+        type: 'warning',
+      }).then(() => {
+        router.back();
+      });
+    } else router.back();
+  }
+
   watch(
   watch(
     () => mapHeight.value,
     () => mapHeight.value,
     () => {
     () => {

+ 12 - 3
src/views/page-config/component/ShopTagEditArea.vue

@@ -137,15 +137,16 @@
       </div>
       </div>
       <hr />
       <hr />
     </div>
     </div>
-    <div class="save-wrapper">
+    <!-- <div class="save-wrapper">
       <el-button type="primary" @click="deleteShop">删除</el-button>
       <el-button type="primary" @click="deleteShop">删除</el-button>
-    </div>
+    </div> -->
   </div>
   </div>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-  import { computed } from 'vue';
+  import { computed, watch } from 'vue';
   import { storeToRefs } from 'pinia';
   import { storeToRefs } from 'pinia';
+  import { cloneDeep } from 'lodash-es';
   import { colorRGB2Hex } from '@/utils';
   import { colorRGB2Hex } from '@/utils';
   import useMapEditor, { LabelPositionEnum, MapWorkShopInfoItem } from '../stores/useMapEditor';
   import useMapEditor, { LabelPositionEnum, MapWorkShopInfoItem } from '../stores/useMapEditor';
 
 
@@ -179,6 +180,14 @@
     addedShops.value = addedShops.value.filter((x) => x.id != tempId);
     addedShops.value = addedShops.value.filter((x) => x.id != tempId);
     activeShopId.value = undefined;
     activeShopId.value = undefined;
   };
   };
+
+  watch(
+    () => editShop.value,
+    () => {
+      addedShops.value = cloneDeep(showShops.value);
+    },
+    { deep: true },
+  );
 </script>
 </script>
 
 
 <style scoped>
 <style scoped>

+ 64 - 1
src/views/page-config/component/mapContainer/MapContainer.vue

@@ -26,6 +26,13 @@
         <v-transformer ref="transformerRef" :config="transformerConfig" />
         <v-transformer ref="transformerRef" :config="transformerConfig" />
       </v-layer>
       </v-layer>
     </v-stage>
     </v-stage>
+    <div
+      v-show="defaultShow"
+      class="opt-container"
+      :style="{ position: 'absolute', left: posX + 'px', top: posY + 'px' }"
+    >
+      <div class="opt-item" @click="handelDeleteShop">删除标签</div>
+    </div>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -49,6 +56,14 @@
   const layerRef = ref<Konva.Layer>();
   const layerRef = ref<Konva.Layer>();
   const transformerRef = ref<Konva.Transformer>();
   const transformerRef = ref<Konva.Transformer>();
 
 
+  //右键点击是否出现
+  const defaultShow = ref<boolean>(false);
+  const posX = ref<number>();
+  const posY = ref<number>();
+  document.oncontextmenu = () => {
+    return false;
+  };
+
   const stageSize = computed(() => {
   const stageSize = computed(() => {
     return {
     return {
       height: 1080,
       height: 1080,
@@ -100,9 +115,14 @@
     if (e.target.attrs.name === 'bg') {
     if (e.target.attrs.name === 'bg') {
       activeShopId.value = -1;
       activeShopId.value = -1;
       updateTransformer();
       updateTransformer();
+      defaultShow.value = false;
     }
     }
 
 
     if (e.target.parent.attrs.name === 'group') {
     if (e.target.parent.attrs.name === 'group') {
+      if (e.evt.button === 2) {
+        setContextMenu(e);
+      } else defaultShow.value = false;
+
       if (e.target.parent.id() === activeShopId.value) {
       if (e.target.parent.id() === activeShopId.value) {
         return;
         return;
       }
       }
@@ -111,6 +131,26 @@
     }
     }
   };
   };
 
 
+  function setContextMenu(e) {
+    if (e.evt.offsetX + 160 > 1920) {
+      posX.value = e.evt.offsetX - 160;
+    } else posX.value = e.evt.offsetX + 20;
+
+    if (e.evt.offsetY + 50 > 1080) {
+      posY.value = e.evt.offsetY - 50;
+    } else posY.value = e.evt.offsetY;
+
+    defaultShow.value = true;
+  }
+
+  const handelDeleteShop = () => {
+    const tempId = activeShopId.value;
+    showShops.value = showShops.value.filter((x) => x.id != tempId);
+    addedShops.value = addedShops.value.filter((x) => x.id != tempId);
+    activeShopId.value = undefined;
+    defaultShow.value = false;
+  };
+
   // 拖拽回调
   // 拖拽回调
   const handleGroupDragend = (e) => {
   const handleGroupDragend = (e) => {
     const activeShopInShowShops = showShops.value.find((item) => {
     const activeShopInShowShops = showShops.value.find((item) => {
@@ -172,4 +212,27 @@
   defineExpose({ getLayout, updateLayoutTransformer });
   defineExpose({ getLayout, updateLayoutTransformer });
 </script>
 </script>
 
 
-<style scoped></style>
+<style scoped>
+  .opt-container {
+    width: 160px;
+    padding: 10px;
+    border-radius: 5px;
+    background-color: #ffffff;
+  }
+
+  .opt-item {
+    height: 30px;
+    font-size: 14px;
+    color: #404040;
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    padding-left: 8px;
+    border-radius: 3px;
+    cursor: pointer;
+
+    &:hover {
+      background-color: #f1f2f5;
+    }
+  }
+</style>