Hwf 9 miesięcy temu
rodzic
commit
e65dde8242

BIN
src/assets/images/map/rightMenu/btn.png


BIN
src/assets/images/videoTagEdit/box1.png


BIN
src/assets/images/videoTagEdit/btn.png


BIN
src/assets/images/videoTagEdit/close.png


BIN
src/assets/images/videoTagEdit/industry.png


BIN
src/assets/images/videoTagEdit/line1.png


BIN
src/assets/images/videoTagEdit/line2.png


BIN
src/assets/images/videoTagEdit/type.png


+ 52 - 4
src/components/Dialog/index.vue

@@ -1,9 +1,13 @@
 <template>
   <div v-if="modelValue || customShow" class="common-dialog" :style="{ width: computedWidth, height: computedHeight }">
-    <div :class="type === 'xs' ? 'dialog-header2' : 'dialog-header'">
+    <div :class="type === 'xs' || headerType === 'header2' ? 'dialog-header2' : 'dialog-header'">
       <div v-if="!hideTitle" class="dialog-title">
         {{ title ? title : '弹窗' }}
       </div>
+      <div v-if="!!getTagId" class="tags">
+        <div v-for="(item, index) in tags" :key="index" class="tag">{{ item.name }}</div>
+        <div class="add-tag" @click="handleShowAddTag">+添加标签</div>
+      </div>
       <i class="decoration" />
       <i class="dialog-close" @click="closeDialog" />
     </div>
@@ -21,10 +25,14 @@
     <i class="triangle2" />
     <i class="triangle3" />
     <i class="triangle4" />
+    <VideoTagEdit v-model="showAddTag" :id="getTagId" />
   </div>
 </template>
 
 <script lang="ts" setup name="Dialog">
+interface Tag {
+  name: string;
+}
 // type: xs、sm、md、lg、xl
 interface Props {
   modelValue?: boolean;
@@ -39,6 +47,9 @@ interface Props {
   confirmClass?: string;
   hideFooter?: boolean;
   customShow?: boolean;
+  headerType?: string;
+  getTagId?: string;
+  tags?: Tag[];
 }
 const props = withDefaults(defineProps<Props>(), {
   modelValue: false,
@@ -94,6 +105,11 @@ const confirm = () => {
     emit('update:modelValue', false);
   }
 };
+// 显示添加标签
+let showAddTag = ref(false);
+const handleShowAddTag = () => {
+  showAddTag.value = true;
+};
 </script>
 
 <style lang="scss" scoped>
@@ -174,10 +190,42 @@ const confirm = () => {
     }
   }
   .dialog-header2 {
+    display: flex;
+    .dialog-title {
+      width: auto;
+    }
+    .tags {
+      display: flex;
+      align-items: center;
+      margin-top: -18px;
+      .tag {
+        width: 126px;
+        height: 26px;
+        background: url('@/assets/images/map/tag.png') no-repeat;
+        background-size: 100% 100%;
+        flex-shrink: 0;
+        color: #ffffff;
+        font-size: 14px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+      .add-tag {
+        width: 104px;
+        height: 29px;
+        background: url('@/assets/images/map/rightMenu/btn.png') no-repeat;
+        background-size: 100% 100%;
+        margin-left: 12px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        cursor: pointer;
+      }
+    }
     &::before {
       content: '';
       position: absolute;
-      bottom: 12px;
+      bottom: 6px;
       left: 0;
       width: 47px;
       height: 20px;
@@ -188,8 +236,8 @@ const confirm = () => {
       content: '';
       position: absolute;
       bottom: 15px;
-      left: 0;
-      width: 100%;
+      left: 52px;
+      width: calc(100% - 47px);
       height: 2px;
       background-image: linear-gradient(to right, rgba(10, 154, 196, 1) 0%, rgba(10, 154, 196, 0) 100%);
       background-size: 100% 100%;

+ 243 - 0
src/components/VideoTagEdit/index.vue

@@ -0,0 +1,243 @@
+<template>
+  <div v-show="modelValue" class="edit-container">
+    <div class="edit-header">
+      <div class="title">视频标签</div>
+      <i class="close" @click="handleClose" />
+    </div>
+    <div class="edit-content">
+      <div class="title-box">
+        <div class="title">当前标签</div>
+      </div>
+      <div class="tags">
+        <div v-for="(item, index) in currentTags" :key="index" class="tag">{{ item.name }}</div>
+      </div>
+      <div class="title-box">
+        <div class="title">新建标签</div>
+      </div>
+      <div class="tags">
+        <div class="tag">{{ addTag }}</div>
+        <el-input v-model="addTag" class="custom-input" placeholder="不超过20个字,回车添加" @keyup.enter="handleAdd"></el-input>
+      </div>
+      <div class="title-box2">
+        <div class="title">最近标签</div>
+      </div>
+      <div class="tags">
+        <div v-for="(item, index) in recentTags" :key="index" class="tag">{{ item.name }}</div>
+      </div>
+      <div class="title-box3">
+        <i class="icon-type" />
+        <div class="title">类型</div>
+        <el-select
+          v-model="type"
+          :teleported="false"
+          class="custom-select"
+          popper-class="custom-select-popper"
+          style="width: 140px; margin-bottom: 10px;"
+        >
+          <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </div>
+      <div class="tags">
+        <div v-for="(item, index) in typeTags" :key="index" class="tag">{{ item.name }}</div>
+      </div>
+      <div class="title-box3">
+        <i class="icon-industry" />
+        <div class="title">行业</div>
+        <el-select
+          v-model="industry"
+          :teleported="false"
+          class="custom-select"
+          popper-class="custom-select-popper"
+          style="width: 140px; margin-bottom: 10px;"
+        >
+          <el-option v-for="item in industryOptions" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </div>
+      <div class="tags">
+        <div v-for="(item, index) in industryTags" :key="index" class="tag">{{ item.name }}</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup name="VideoTagEdit">
+const props = defineProps({
+  modelValue: String,
+  id: String
+});
+const emits = defineEmits(['update:modelValue']);
+let currentTags = ref([]);
+let addTag = ref('');
+let recentTags = ref([]);
+let type = ref('');
+let typeTags = ref([]);
+let typeOptions = ref([]);
+let industry = ref('');
+let industryTags = ref([]);
+let industryOptions = ref([]);
+watch(
+  () => props.id,
+  () => {
+    if (!!props.id) {
+      currentTags.value = [{ name: '河坝' }, { name: '水库' }];
+      recentTags.value = [{ name: '河坝' }, { name: '水库' }, { name: '山塘' }];
+      typeTags.value = [{ name: '河坝' }, { name: '水库' }, { name: '山塘' }];
+      industryTags.value = [{ name: '河坝' }, { name: '水库' }, { name: '山塘' }];
+      typeOptions.value = [
+        { label: '全部', value: '' },
+        { label: '水库', value: '1' }
+      ];
+      industryOptions.value = [
+        { label: '全部', value: '' },
+        { label: '水库', value: '1' }
+      ];
+    } else {
+      currentTags.value = [];
+      addTag.value = '';
+      recentTags.value = [];
+      typeTags.value = [];
+      industryTags.value = [];
+    }
+  },
+  {
+    immediate: true
+  }
+);
+//关闭
+const handleClose = () => {
+  emits('update:modelValue', false);
+};
+const handleAdd = () => {
+  addTag.value = '';
+}
+</script>
+
+<style lang="scss" scoped>
+.edit-container {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  z-index: 100;
+  width: 407px;
+  height: 602px;
+  background: url('@/assets/images/videoTagEdit/box1.png') no-repeat;
+  background-size: 100% 100%;
+  .edit-header {
+    height: 40px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 0 20px;
+    position: relative;
+    .title {
+      color: transparent;
+      background-image: linear-gradient(to bottom, #ffffff 30%, #edf7fe 50%, #5cc4fa 70%, #40a2e7 100%);
+      -webkit-background-clip: text;
+      background-clip: text;
+      display: inline-block;
+      font-family: 'YouSheBiaoTiHei';
+      font-size: 24px;
+    }
+    .close {
+      width: 16px;
+      height: 16px;
+      background: url('@/assets/images/videoTagEdit/close.png') no-repeat;
+      background-size: 100% 100%;
+      cursor: pointer;
+    }
+    &::before {
+      content: '';
+      width: 43px;
+      height: 18px;
+      background: url('@/assets/images/videoTagEdit/line1.png') no-repeat;
+      background-size: 100% 100%;
+      position: absolute;
+      bottom: -8px;
+      left: 0;
+    }
+    &::after {
+      content: '';
+      width: calc(100% - 83px);
+      height: 2px;
+      background: url('@/assets/images/videoTagEdit/line2.png') no-repeat;
+      background-size: 100% 100%;
+      position: absolute;
+      bottom: 0;
+      left: 47px;
+    }
+  }
+  .edit-content {
+    margin-top: 10px;
+    height: 500px;
+    overflow-y: auto;
+    .title-box {
+      width: 379px;
+      height: 39px;
+      background: url('@/assets/images/map/titleBox3.png') no-repeat;
+      background-size: 100% 100%;
+      padding-left: 30px;
+      margin-top: 10px;
+      .title {
+        font-size: 16px;
+      }
+    }
+    .title-box2 {
+      width: 135px;
+      height: 24px;
+      background: url('@/assets/images/map/rightMenu/titleBox2.png') no-repeat bottom left;
+      background-size: 135px 20px;
+      padding-left: 30px;
+      margin-top: 10px;
+      .title {
+        font-size: 16px;
+        color: #96aac1;
+      }
+    }
+    .title-box3 {
+      display: flex;
+      align-items: center;
+      margin-top: 10px;
+      .title {
+        font-size: 16px;
+        color: #96aac1;
+        margin: 0 6px;
+      }
+      .icon-type {
+        width: 28px;
+        height: 26px;
+        background: url('@/assets/images/videoTagEdit/type.png') no-repeat;
+        background-size: 100% 100%;
+      }
+      .icon-industry {
+        width: 26px;
+        height: 27px;
+        background: url('@/assets/images/videoTagEdit/industry.png') no-repeat;
+        background-size: 100% 100%;
+      }
+    }
+    .tags {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin-top: -5px;
+      .tag {
+        min-width: 126px;
+        height: 26px;
+        background: url('@/assets/images/map/tag.png') no-repeat;
+        background-size: 100% 100%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin-top: 10px;
+        padding: 0 20px 0 15px;
+      }
+      .custom-input {
+        width: 230px;
+        margin-left: 20px;
+        margin-top: 10px;
+      }
+    }
+  }
+}
+</style>

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

@@ -128,6 +128,7 @@ declare module 'vue' {
     UserSelect: typeof import('./../components/UserSelect/index.vue')['default']
     VideoContainer: typeof import('./../components/HKVideo/video-container.vue')['default']
     VideoContainer2: typeof import('./../components/HKVideo/video-container2.vue')['default']
+    VideoTagEdit: typeof import('./../components/VideoTagEdit/index.vue')['default']
     YztMap: typeof import('./../components/Map/YztMap/index.vue')['default']
   }
   export interface ComponentCustomProperties {

+ 6 - 1
src/views/globalMap/RightMenu/RiverMonitor.vue

@@ -34,7 +34,7 @@
       </div>
     </div>
   </div>
-  <Dialog v-model="showDialog" type="xl" title="河道监测" hide-footer>
+  <Dialog v-model="showDialog" type="xl" headerType="header2" title="河道监测" getTagId="1" v-model:tags="tags" hide-footer>
     <div class="flex">
       <div class="detail-container">
         <div class="flex">
@@ -111,6 +111,7 @@ const queryParams = reactive({
 });
 // 总数量
 let total = ref(0);
+let tags = ref([]);
 // 数据
 const riverMonitorData = reactive({
   time: '',
@@ -125,6 +126,10 @@ const initData = async () => {
   getRiverWaterStatus().then((res) => {
     riverMonitorData.statusList = res.rows || [];
   });
+  tags.value = [
+    { name: '河坝' },
+    { name: '水库' }
+  ]
 };
 
 initData();