feiyu02
2025-07-21 5be9679fb4288936b576cf3d1f1548af1c4151b8
2025.7.21 任务管理-监管地图功能(待完成)
已修改8个文件
已添加1个文件
281 ■■■■ 文件已修改
src/components.d.ts 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/map/SceneMap.vue 99 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/search-option/FYOptionScene.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/search-option/FYOptionSupervisionStatus.vue 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/enum/scene.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/map/marks.js 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/task/TaskManage.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/task/components/CompMonitorPlan.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/task/components/CompTaskMap.vue 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components.d.ts
@@ -13,6 +13,7 @@
    CompGenericWrapper: typeof import('./components/CompGenericWrapper.vue')['default']
    CompQuickSet: typeof import('./components/search-option/CompQuickSet.vue')['default']
    Content: typeof import('./components/core/Content.vue')['default']
    copy: typeof import('./components/search-option/FYOptionUserType copy.vue')['default']
    ElAffix: typeof import('element-plus/es')['ElAffix']
    ElAside: typeof import('element-plus/es')['ElAside']
    ElAvatar: typeof import('element-plus/es')['ElAvatar']
@@ -20,7 +21,6 @@
    ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
    ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
    ElButton: typeof import('element-plus/es')['ElButton']
    ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
    ElCalendar: typeof import('element-plus/es')['ElCalendar']
    ElCard: typeof import('element-plus/es')['ElCard']
    ElCascader: typeof import('element-plus/es')['ElCascader']
@@ -37,9 +37,6 @@
    ElDialog: typeof import('element-plus/es')['ElDialog']
    ElDivider: typeof import('element-plus/es')['ElDivider']
    ElDrawer: typeof import('element-plus/es')['ElDrawer']
    ElDropdown: typeof import('element-plus/es')['ElDropdown']
    ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
    ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
    ElEmpty: typeof import('element-plus/es')['ElEmpty']
    ElForm: typeof import('element-plus/es')['ElForm']
    ElFormItem: typeof import('element-plus/es')['ElFormItem']
@@ -55,17 +52,9 @@
    ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
    ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
    ElOption: typeof import('element-plus/es')['ElOption']
    ElPageHeader: typeof import('element-plus/es')['ElPageHeader']
    ElPagination: typeof import('element-plus/es')['ElPagination']
    ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
    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']
    ElScroll: typeof import('element-plus/es')['ElScroll']
    ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
    ElSegmented: typeof import('element-plus/es')['ElSegmented']
    ElSelect: typeof import('element-plus/es')['ElSelect']
    ElSpace: typeof import('element-plus/es')['ElSpace']
    ElStep: typeof import('element-plus/es')['ElStep']
@@ -79,7 +68,6 @@
    ElTag: typeof import('element-plus/es')['ElTag']
    ElText: typeof import('element-plus/es')['ElText']
    ElTooltip: typeof import('element-plus/es')['ElTooltip']
    ElTransfer: typeof import('element-plus/es')['ElTransfer']
    ElTree: typeof import('element-plus/es')['ElTree']
    ElUpload: typeof import('element-plus/es')['ElUpload']
    Footer: typeof import('./components/core/Footer.vue')['default']
@@ -91,9 +79,12 @@
    FYImageSelectDialog: typeof import('./components/FYImageSelectDialog.vue')['default']
    FYInfoSearch: typeof import('./components/search-option/FYInfoSearch.vue')['default']
    FYList: typeof import('./components/table/FYList.vue')['default']
    FYOption: typeof import('./components/search-option/FYOption.vue')['default']
    FYOptionLocation: typeof import('./components/search-option/FYOptionLocation.vue')['default']
    FYOptionOnlineStatus: typeof import('./components/search-option/FYOptionOnlineStatus.vue')['default']
    FYOptionScene: typeof import('./components/search-option/FYOptionScene.vue')['default']
    FYOptionSupervision: typeof import('./components/search-option/FYOptionSupervision.vue')['default']
    FYOptionSupervisionStatus: typeof import('./components/search-option/FYOptionSupervisionStatus.vue')['default']
    FYOptionText: typeof import('./components/search-option/base/FYOptionText.vue')['default']
    FYOptionTime: typeof import('./components/search-option/FYOptionTime.vue')['default']
    FYOptionUserType: typeof import('./components/search-option/FYOptionUserType.vue')['default']
src/components/map/SceneMap.vue
@@ -1,8 +1,17 @@
<template>
  <BaseMap></BaseMap>
  <el-row class="left-top-wrap">
    <FYOptionScene
      label=""
      :allOption="true"
      :type="2"
      v-model:value="scenetype"
    ></FYOptionScene>
    <slot name="left-top"></slot>
  </el-row>
</template>
<script setup>
import { watch } from 'vue';
import { ref, watch } from 'vue';
import { map, onMapMounted } from '@/utils/map/index';
import marks from '@/utils/map/marks';
import { sceneIcon } from '@/assets/scene-icon';
@@ -11,32 +20,100 @@
  data: Array
});
var markViewList = [];
let allMarkViews = [];
let markViewList = [];
const scenetype = ref();
watch(
  () => props.data,
  (nV, oV) => {
    if (nV != oV) {
      drawSceneMarks();
      clearSceneMarks();
      createSceneMarks();
      filterMarkViews();
    }
  },
  { immediate: true }
);
function drawSceneMarks() {
watch(scenetype, (nV, oV) => {
  if (nV != oV) {
    clearSceneMarks();
    filterMarkViews();
  }
});
function createSceneMarks() {
  onMapMounted(() => {
    markViewList = [];
    allMarkViews = [];
    props.data.forEach((d) => {
      // åˆ›å»ºåœºæ™¯åœ°å›¾æ ‡æ³¨
      const mark = marks.createMarker({
        position: [d.longitude, d.latitude],
        icon: sceneIcon(d.typeid),
        label: d.name,
        extData: d.guid
        img: sceneIcon(d.typeid),
        // label: d.name,
        extData: d
      });
      markViewList.push(mark);
      // æ·»åŠ ç‚¹å‡»äº‹ä»¶
      mark.on('click', (ev) => {
        const _mark = ev.target;
        const _extData = _mark.getExtData();
        if (_extData._show) {
          ev.target.setLabel({
            content: ''
            // direction: 'bottom'
          });
          _extData._show = false
          ev.target.setExtData(_extData)
        } else {
          ev.target.setLabel({
            content: _extData.name
            // direction: 'bottom'
          });
          _extData._show = true
          ev.target.setExtData(_extData)
        }
      });
      allMarkViews.push(mark);
    });
    map.setFitView(markViewList);
  });
}
/**
 * ç­›é€‰æ‰€é€‰ç±»åž‹çš„场景
 */
function filterMarkViews() {
  onMapMounted(() => {
    if (scenetype.value == undefined) {
      markViewList = allMarkViews;
    } else {
      markViewList = allMarkViews.filter((v) => {
        return (
          scenetype.value.value == null ||
          v.getExtData().typeid + '' == scenetype.value.value
        );
      });
    }
    map.add(markViewList);
    setTimeout(() => {
      map.setFitView(markViewList);
    }, 1000);
  });
}
function clearSceneMarks() {
  onMapMounted(() => {
    if (markViewList.length > 0) {
      map.remove(markViewList);
    }
  });
}
</script>
<style scoped></style>
<style scoped>
.left-top-wrap {
  position: absolute;
  left: 0;
  top: 0;
}
</style>
src/components/search-option/FYOptionScene.vue
@@ -1,12 +1,17 @@
<template>
  <el-form-item label="场景类型" :prop="prop">
  <el-form-item :label="label" :prop="prop">
    <el-select
      :model-value="value"
      @change="handleChange"
      placeholder="场景类型"
      :placeholder="label"
      style="width: 150px"
    >
      <el-option v-for="s in sceneTypes" :key="s.value" :label="s.label" :value="s" />
      <el-option
        v-for="s in sceneTypes"
        :key="s.value"
        :label="s.label"
        :value="s"
      />
    </el-select>
  </el-form-item>
</template>
@@ -21,6 +26,10 @@
      type: Boolean,
      default: true
    },
    label: {
      type: String,
      default: '场景类型'
    },
    // 1:飞羽环境系统;2:飞羽监管系统;
    type: {
      type: Number || String,
src/components/search-option/FYOptionSupervisionStatus.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
<template>
  <el-form-item :label="label" :prop="prop">
    <el-select
      :model-value="value"
      @change="handleChange"
      :placeholder="label"
      style="width: 150px"
    >
      <el-option
        v-for="s in options"
        :key="s.value"
        :label="s.label"
        :value="s"
      />
    </el-select>
  </el-form-item>
</template>
<script>
export default {
  props: {
    // æ˜¯å¦åœ¨é¦–选项处添加“全部”选项
    allOption: {
      type: Boolean,
      default: true
    },
    label: {
      type: String,
      default: '监管状态'
    },
    // è¿”回结果
    value: Object,
    // æ˜¯å¦é»˜è®¤è¿”回初始选项
    initValue: {
      type: Boolean,
      default: true
    },
    prop: {
      type: String,
      default: '_usertype'
    }
  },
  emits: ['update:value'],
  data() {
    return {
      options: [
        {
          label: '全部监管状态',
          value: null
        },
        {
          label: '未监管',
          value: '0'
        },
        {
          label: '已监管',
          value: '1'
        },
        {
          label: '已复核',
          value: '2'
        }
      ]
    };
  },
  methods: {
    handleChange(value) {
      this.$emit('update:value', value);
    }
  },
  mounted() {
    if (this.initValue) {
      this.handleChange(this.options[0]);
    }
  }
};
</script>
src/enum/scene.js
@@ -35,7 +35,7 @@
function _enumScene_1() {
  return [
    {
      label: '全部',
      label: '全部场景',
      value: null
    },
    {
@@ -81,7 +81,7 @@
function _enumScene_2() {
  return [
    {
      label: '全部',
      label: '全部场景',
      value: null
    },
    {
src/utils/map/marks.js
@@ -145,10 +145,17 @@
    return layer;
  },
  createMarker({ position, icon, label, extData }) {
  createMarker({ position, img, label, extData }) {
    //创建 AMap.Icon å®žä¾‹ï¼š
    const icon = new AMap.Icon({
      size: new AMap.Size(30, 30), //图标尺寸
      image: img, //Icon çš„图像
      // imageOffset: new AMap.Pixel(-9, -3), //图像相对展示区域的偏移量,适于雪碧图等
      imageSize: new AMap.Size(30, 30) //根据所设置的大小拉伸或压缩图片
    });
    const marker = new AMap.Marker({
      position: position,
      offset: new AMap.Pixel(-10, -10),
      // offset: new AMap.Pixel(-13, -30),
      icon: icon, //添加 icon å›¾æ ‡ URL
      title: label,
      label: {
@@ -157,7 +164,7 @@
      },
      extData
    });
    map.add(marker);
    // map.add(marker);
    return marker;
  }
};
src/views/fysp/task/TaskManage.vue
@@ -43,7 +43,7 @@
                  <CompMonitorPlan
                    ref="planRef"
                    :task="curTask.data"
                    :day-task-list="dayTaskList"
                    :day-task-list="curDayTaskList"
                    @date-change="onDateChange"
                  ></CompMonitorPlan>
                </el-col>
@@ -283,7 +283,7 @@
      return taskApi
        .fetchDayTasks(this.curTask.data.tguid)
        .then((res) => {
          this.dayTaskList = res;
          this.curDayTaskList = res;
        })
        .finally(() => (this.dayTaskLoading = false));
    },
src/views/fysp/task/components/CompMonitorPlan.vue
@@ -104,7 +104,7 @@
watch(
  () => props.dayTaskList,
  (nV, oV) => {
    if (nV != oV && dateValue.value) {
    if (nV && dateValue.value) {
      onDateChange(dateValue.value);
    }
  },
src/views/fysp/task/components/CompTaskMap.vue
@@ -1,10 +1,19 @@
<template>
  <div style="width: 70vw; height: 600px; background-color: aliceblue">
    <SceneMap :data="scenes"></SceneMap>
  <div style="width: 68vw; height: 600px; background-color: aliceblue">
    <SceneMap :data="scenes">
      <template #left-top>
        <FYOptionSupervisionStatus
          label=""
          :allOption="true"
          v-model:value="supervisionStatus"
        ></FYOptionSupervisionStatus>
      </template>
    </SceneMap>
  </div>
</template>
<script setup>
import { computed } from 'vue';
import { ref, computed } from 'vue';
const props = defineProps({
  // åœºæ™¯è®¡åˆ’
  plans: {
@@ -17,9 +26,37 @@
  }
});
const supervisionStatus = ref();
const scenes = computed(() => {
  return props.plans.map((p) => {
    return p.scene;
  });
  return props.plans
    .filter((v) => {
      if (supervisionStatus.value) {
        switch (supervisionStatus.value.value) {
          case '0':
            return (
              v.extension1 == undefined ||
              v.extension1 == null ||
              v.extension1 == '0'
            );
          case '1':
            return v.extension1 == '1';
          case '2':
            return v.extension1 == '2';
          default:
            return true;
        }
      } else {
        return true
      }
      // if (supervisionStatus.value) {
      //   supervisionStatus.value;
      // } else {
      //   return true;
      // }
    })
    .map((p) => {
      return p.scene;
    });
});
</script>