forked from drone/command-center-dashboard

罗广辉
2025-04-08 4a4c65d0d2e7b5db4c4ea6ba7af0e800f83a890a
feat: 事件概况left对接完成
4 files modified
5 files added
477 ■■■■■ changed files
src/components/CommonTitle.vue 2 ●●● patch | view | raw | blame | history
src/store/modules/home.js 4 ●●●● patch | view | raw | blame | history
src/views/Home/EventOverviewDetail/EventOverviewDetail.vue 7 ●●●●● patch | view | raw | blame | history
src/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventDataAnalysis.vue 115 ●●●●● patch | view | raw | blame | history
src/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventOverviewDetailLeft.vue 70 ●●●●● patch | view | raw | blame | history
src/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventTop5.vue 98 ●●●●● patch | view | raw | blame | history
src/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventTrendAnalysis.vue 106 ●●●●● patch | view | raw | blame | history
src/views/Home/Home.vue 61 ●●●● patch | view | raw | blame | history
src/views/Home/HomeRight/EventOverview.vue 14 ●●●● patch | view | raw | blame | history
src/components/CommonTitle.vue
@@ -10,7 +10,7 @@
const props = defineProps({
  title: {
    type: String,
    default: '机巢概况',
    default: '标题',
  },
  text: {
    type: String,
src/store/modules/home.js
@@ -5,6 +5,7 @@
  state: {
    machineNestDetail: false, // 机巢详情
    singleUavHome: {},
        isEventOverviewDetail: false,//是事件概述详细信息
    singleTotal: {}, // 统计单个机巢数据
    // 项目id
    selectedWorkSpaceId: window.localStorage.getItem('bs_workspace_id'),
@@ -36,6 +37,9 @@
  },
  actions: {},
  mutations: {
        setIsEventOverviewDetail: (state, data) => {
            state.isEventOverviewDetail = data;
        },
    setMachineNestDetail: (state, data) => {
      state.machineNestDetail = data;
    },
src/views/Home/EventOverviewDetail/EventOverviewDetail.vue
New file
@@ -0,0 +1,7 @@
<template>
    <EventOverviewDetailLeft />
</template>
<script setup>
import EventOverviewDetailLeft from './EventOverviewDetailLeft/EventOverviewDetailLeft.vue'
</script>
<style scoped lang="scss"></style>
src/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventDataAnalysis.vue
New file
@@ -0,0 +1,115 @@
<template>
    <common-title title="行业数据分析" />
    <div class="chart" ref="echartsRef"></div>
</template>
<script setup>
import CommonTitle from '@/components/CommonTitle.vue'
import { getEventIndustryData } from '@/api/home/event'
import * as echarts from 'echarts'
const echartsRef = ref(null)
let chart = null
const echartsOption = {
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow',
        },
    },
    grid: {
        top: '5%',
        left: 0,
        right: 0,
        bottom: 0,
        containLabel: true,
    },
    xAxis: {
        type: 'category',
        axisLabel: {
            rotate: -45, // 旋转角度
            interval: 0, // 显示所有标签
            color: '#FFFFFF',
            fontFamily: 'Source Han Sans CN, Source Han Sans CN',
            fontWeight: 400,
            fontSize: 10,
        },
        data: [],
    },
    yAxis: [
        {
            type: 'value',
            axisLabel: {
                interval: 0, // 显示所有标签
                color: '#FFFFFF',
                fontFamily: 'Source Han Sans CN, Source Han Sans CN',
                fontWeight: 400,
                fontSize: 10,
            },
            axisLine: {
                lineStyle: {
                    color: '#ffffff',
                },
            },
            splitLine: {
                lineStyle: {
                    color: 'rgba(255, 255, 255, 0.1)',
                    type: 'dashed', // 设置为虚线
                },
            },
        },
    ],
    series: [],
}
const testObj = color => ({
    type: 'bar',
    emphasis: {
        focus: 'series',
    },
    itemStyle: { color },
    data: [],
})
const eventType = [
    { name: '事件', ...testObj('#6FCAFF') },
    { name: '任务', ...testObj('#8EFFAC') },
]
const params = inject('eventOverviewParams')
watch(params, () => {
    getData()
})
// 获取数据
const getData = async () => {
    const res = await getEventIndustryData(params.value)
    const list = res?.data?.data || []
    echartsOption.xAxis.data = list.map(item => item.name)
    //
    eventType.forEach(item => {
        item.data = []
    })
    list.forEach(item => {
        item.data.forEach(item1 => {
            eventType.forEach(item2 => {
                item2.name === item1.name && item2.data.push(item1.value)
            })
        })
    })
    echartsOption.series = eventType
    chart.setOption(echartsOption)
}
onMounted(() => {
    chart = echarts.init(echartsRef.value)
    window.addEventListener('resize', chart.resize)
    getData()
})
</script>
<style scoped lang="scss">
.chart {
    width: 356px;
    height: 190px;
}
</style>
src/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventOverviewDetailLeft.vue
New file
@@ -0,0 +1,70 @@
<template>
    <div class="left">
        <div class="do-return" @click="goBack">
            <img src="@/assets/images/signMachineNest/return.png" alt="" />
        </div>
        <common-title title="事件数据分析" />
        <CommonDateTime class="dateTime" v-model="timeArr" @change="timeChange" />
        <EventDataAnalysis />
        <EventTrendAnalysis />
        <EventTop5 />
    </div>
</template>
<script setup>
import EventDataAnalysis from './EventDataAnalysis.vue'
import CommonTitle from '@/components/CommonTitle.vue'
import CommonDateTime from '@/components/CommonDateTime.vue'
import dayjs from 'dayjs'
import { useStore } from 'vuex'
import EventTrendAnalysis from '@/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventTrendAnalysis.vue'
import EventTop5 from '@/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventTop5.vue'
const today = dayjs().format('YYYY-MM-DD')
const timeArr = ref([today, today])
const store = useStore()
const params = ref({
    date_enum: 'TODAY',
    end_date: undefined,
    start_date: undefined,
})
provide('eventOverviewParams', params)
// 时间变化
const timeChange = (value, date_enum) => {
    params.value = {
        ...params.value,
        date_enum,
    }
}
const goBack = () => {
    store.commit('setIsEventOverviewDetail', false)
}
</script>
<style scoped lang="scss">
.left {
    position: absolute;
    top: 88px;
    color: #e7f5ff;
    display: flex;
    flex-direction: column;
    align-items: center;
    .dateTime {
        width: 356px;
        margin: 0 0 8px 0;
    }
    .do-return {
        position: absolute;
        top: 50px;
        right: -50px;
        cursor: pointer;
        img {
            width: 40px;
            height: 40px;
        }
    }
}
</style>
src/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventTop5.vue
New file
@@ -0,0 +1,98 @@
<template>
    <common-title title="同类事件TOP5统计" />
    <div class="chart" ref="echartsRef"></div>
</template>
<script setup>
import CommonTitle from '@/components/CommonTitle.vue'
import { getEventTopFive, getEventTrend } from '@/api/home/event'
import * as echarts from 'echarts'
const echartsRef = ref(null)
let chart = null
const echartsOption = {
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow',
        },
    },
    grid: {
        top: '5%',
        left: 0,
        right: 0,
        bottom: 0,
        containLabel: true,
    },
    xAxis: {
        type: 'category',
        axisLabel: {
            rotate: -45, // 旋转角度
            interval: 0, // 显示所有标签
            color: '#FFFFFF',
            fontFamily: 'Source Han Sans CN, Source Han Sans CN',
            fontWeight: 400,
            fontSize: 10,
        },
        data: [],
    },
    yAxis: [
        {
            type: 'value',
            axisLabel: {
                interval: 0, // 显示所有标签
                color: '#FFFFFF',
                fontFamily: 'Source Han Sans CN, Source Han Sans CN',
                fontWeight: 400,
                fontSize: 10,
            },
            axisLine: {
                lineStyle: {
                    color: '#ffffff',
                },
            },
            splitLine: {
                lineStyle: {
                    color: 'rgba(255, 255, 255, 0.1)',
                    type: 'dashed', // 设置为虚线
                },
            },
        },
    ],
    series: {
        type: 'bar',
        emphasis: {
            focus: 'series',
        },
        itemStyle: { color:'#6FCAFF' },
        data: [],
    },
}
const params = inject('eventOverviewParams')
watch(params, () => {
    getData()
})
// 获取数据
const getData = async () => {
    const res = await getEventTopFive(params.value)
    const list = res?.data?.data || []
    echartsOption.xAxis.data = list.map(item => item.name)
    echartsOption.series.data = list.map(item => item.value)
    chart.setOption(echartsOption)
}
onMounted(() => {
    chart = echarts.init(echartsRef.value)
    window.addEventListener('resize', chart.resize)
    getData()
})
</script>
<style scoped lang="scss">
.chart {
    width: 356px;
    height: 190px;
}
</style>
src/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventTrendAnalysis.vue
New file
@@ -0,0 +1,106 @@
<template>
    <common-title title="事件趋势分析" />
    <div class="chart" ref="echartsRef"></div>
</template>
<script setup>
import CommonTitle from '@/components/CommonTitle.vue'
import { getEventTrend } from '@/api/home/event'
import * as echarts from 'echarts'
const echartsRef = ref(null)
let chart = null
const echartsOption = {
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow',
        },
    },
    grid: {
        top: '5%',
        left: 0,
        right: 0,
        bottom: 0,
        containLabel: true,
    },
    xAxis: {
        type: 'category',
        axisLabel: {
            rotate: -45, // 旋转角度
            interval: 0, // 显示所有标签
            color: '#FFFFFF',
            fontFamily: 'Source Han Sans CN, Source Han Sans CN',
            fontWeight: 400,
            fontSize: 10,
        },
        data: [],
    },
    yAxis: [
        {
            type: 'value',
            axisLabel: {
                interval: 0, // 显示所有标签
                color: '#FFFFFF',
                fontFamily: 'Source Han Sans CN, Source Han Sans CN',
                fontWeight: 400,
                fontSize: 10,
            },
            axisLine: {
                lineStyle: {
                    color: '#ffffff',
                },
            },
            splitLine: {
                lineStyle: {
                    color: 'rgba(255, 255, 255, 0.1)',
                    type: 'dashed', // 设置为虚线
                },
            },
        },
    ],
    series: {
        type: 'line',
        itemStyle: {
            color: '#0CEBF7', // 设置颜色
        },
        lineStyle: {
            width: 2, // 线条宽度
            type: 'solid', // 线条类型
        },
        symbol: 'circle', // 数据点符号
        symbolSize: 6, // 数据点符号大小
        emphasis: {
            focus: 'series',
        },
        data: [], // 示例数据,根据实际完成率计算
    },
}
const params = inject('eventOverviewParams')
watch(params, () => {
    getData()
})
// 获取数据
const getData = async () => {
    const res = await getEventTrend(params.value)
    const list = res?.data?.data || []
    echartsOption.xAxis.data = list.map(item => item.name)
    echartsOption.series.data = list.map(item => item.value)
    chart.setOption(echartsOption)
}
onMounted(() => {
    chart = echarts.init(echartsRef.value)
    window.addEventListener('resize', chart.resize)
    getData()
})
</script>
<style scoped lang="scss">
.chart {
    width: 356px;
    height: 190px;
}
</style>
src/views/Home/Home.vue
@@ -1,39 +1,44 @@
<template>
  <template v-if="!singleUavHome?.device_sn">
    <SearchBox />
    <HomeLeft />
    <HomeRight />
  </template>
  <template v-else>
    <SignMachineNest />
  </template>
  <RSide />
  <Footer />
    <template v-if="singleUavHome?.device_sn">
        <SignMachineNest />
    </template>
    <template v-else>
        <EventOverviewDetail v-if="isEventOverviewDetail" />
        <template v-else>
            <SearchBox />
            <HomeLeft />
            <HomeRight />
        </template>
    </template>
    <RSide />
    <Footer />
</template>
<script setup>
import HomeRight from '@/views/Home/HomeRight/HomeRight.vue';
import HomeLeft from '@/views/Home/HomeLeft/HomeLeft.vue';
import SearchBox from '@/views/Home/SearchBox.vue';
import SignMachineNest from '@/views/SignMachineNest/SignMachineNest.vue';
import { useStore } from 'vuex';
import Footer from '@/views/Home/Footer.vue';
import RSide from '@/views/Home/RSide.vue';
import { onMounted } from 'vue';
import cesiumOperation from '@/utils/cesium-tsa';
import MeasuringDistance from '@/components/MeasuringDistance.vue';
const store = useStore();
const { _init,viewerDestory } = cesiumOperation();
import HomeRight from '@/views/Home/HomeRight/HomeRight.vue'
import HomeLeft from '@/views/Home/HomeLeft/HomeLeft.vue'
import SearchBox from '@/views/Home/SearchBox.vue'
import SignMachineNest from '@/views/SignMachineNest/SignMachineNest.vue'
import { useStore } from 'vuex'
import Footer from '@/views/Home/Footer.vue'
import RSide from '@/views/Home/RSide.vue'
import { onMounted } from 'vue'
import cesiumOperation from '@/utils/cesium-tsa'
import EventOverviewDetail from '@/views/Home/EventOverviewDetail/EventOverviewDetail.vue'
const singleUavHome = computed(() => store.state.home.singleUavHome);
const store = useStore()
const { _init, viewerDestory } = cesiumOperation()
onUnmounted(()=>{
  store.commit('setSingleUavHome',null);
const singleUavHome = computed(() => store.state.home.singleUavHome)
const isEventOverviewDetail = computed(() => store.state.home.isEventOverviewDetail)
onUnmounted(() => {
    store.commit('setSingleUavHome', null)
    console.log('home销毁')
  viewerDestory()
    viewerDestory()
})
onMounted(() => {
  _init('cesium');
});
    _init('cesium')
})
</script>
src/views/Home/HomeRight/EventOverview.vue
@@ -1,5 +1,5 @@
<template>
  <CommonTitle title="事件概况" />
  <CommonTitle title="事件概况" @Details="details"/>
  <div :style="{ marginLeft: pxToRem(14) }">
    <div class="eventOverview">
      <div class="overviewData">
@@ -63,6 +63,7 @@
import { getJobEventBrokerLine, getJobEventByStatus, getJobEventTotal } from '@/api/home';
import dayjs from 'dayjs';
import { selectDevicePage } from '@/api/home/machineNest';
import { useStore } from 'vuex'
const echartsOption = {
  tooltip: {
@@ -175,6 +176,11 @@
  start_date: undefined,
});
const store = useStore()
const details = () =>{
   store.commit('setIsEventOverviewDetail',true)
}
// 远程查询
const remoteMethod = nickname => {
  devicePageParams.value.nickname = nickname;
@@ -222,6 +228,8 @@
  getJobEventBrokerLine(params.value).then(res => {
    const list = res?.data?.data || [];
    echartsOption.xAxis.data = list.map(item => item.name);
        // 赋值前清空数据
        Object.keys(seriesObj).forEach(key => {seriesObj[key].data = []})
    list.forEach(item => {
      item.data.forEach((item1, index) => {
        seriesObj[item1.status].data.push(item1.value);
@@ -256,9 +264,7 @@
onMounted(() => {
  chart = echarts.init(echartsRef.value);
  window.addEventListener('resize', () => {
    chart.resize();
  });
  window.addEventListener('resize',  chart.resize);
  getJobEventTotal().then(res => {
    eventTotal.value = res?.data?.data || 0;
  });