forked from drone/command-center-dashboard

chenyao
2025-04-16 f63c6fff5e77374b699c69ac08abbad3dab1d147
feat:更新事件概况和智引即飞
9 files modified
6 files added
457 ■■■■ changed files
src/api/home/common.js 8 ●●●● patch | view | raw | blame | history
src/api/home/event.js 8 ●●●●● patch | view | raw | blame | history
src/assets/images/aiNowFly/photo.png patch | view | raw | blame | history
src/assets/images/aiNowFly/stop.png patch | view | raw | blame | history
src/assets/images/home/useEventOperate/close.png patch | view | raw | blame | history
src/assets/images/home/useEventOperate/expand.png patch | view | raw | blame | history
src/assets/images/home/useEventOperate/point-active.png patch | view | raw | blame | history
src/assets/images/home/useEventOperate/point.png patch | view | raw | blame | history
src/store/modules/common.js 4 ●●●● patch | view | raw | blame | history
src/views/Home/AINowFly.vue 188 ●●●●● patch | view | raw | blame | history
src/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventOverviewDetailLeft.vue 41 ●●●● patch | view | raw | blame | history
src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue 178 ●●●● patch | view | raw | blame | history
src/views/Home/Footer.vue 7 ●●●● patch | view | raw | blame | history
src/views/Home/RSide.vue 6 ●●●●● patch | view | raw | blame | history
src/views/Home/SearchBox.vue 17 ●●●●● patch | view | raw | blame | history
src/api/home/common.js
@@ -25,18 +25,18 @@
        params,
    })
}
// 机巢搜索
// 地址搜索
export const searchByKeyword = params => {
    return request({
        url: `/drone-device-core/map/amap/searchByKeyword?keyword=${params}`,
        method: 'get',
    })
}
// 地址搜索
export const selectDeviceList = params => {
// 机巢搜索
export const selectDeviceList = data => {
    return request({
        url: `/drone-device-core/manage/api/v1/devices/selectDeviceList`,
        method: 'post',
        params,
        data: data,
    })
}
src/api/home/event.js
@@ -55,3 +55,11 @@
        data,
    })
}
// 点击图片关联的事件历史图片列表
export const findImgHistory = id => {
    return request({
        url: '/drone-device-core/jobEvent/findImgHistory?eventId='+id,
        method: 'get',
    })
}
src/assets/images/aiNowFly/photo.png
src/assets/images/aiNowFly/stop.png
src/assets/images/home/useEventOperate/close.png
src/assets/images/home/useEventOperate/expand.png
src/assets/images/home/useEventOperate/point-active.png
src/assets/images/home/useEventOperate/point.png
src/store/modules/common.js
@@ -36,8 +36,12 @@
      visual: '3D',
      isDark: false,
    },
    isHideBottomIcon: true,
  },
  mutations: {
    setHideBottomIcon (state, data) {
      state.isHideBottomIcon = data
    },
    setMapSetting: (state, data) => {
      state.mapSetting = data
      loadLAYER()
src/views/Home/AINowFly.vue
@@ -14,21 +14,46 @@
                <el-input disabled type="text" v-model="di" placeholder="地名&经纬度"/>
            </el-form-item>
            <!--            todo-->
            <el-form-item label="事件">
            <el-form-item label="飞行事件">
                <div class="event">
                    <img src="@/assets/images/aiNowFly/picture-recording.png" alt="">
                    <div class="img-close" v-show="isPhoto">
                        <img @click="isPhoto=false" class="close" src="@/assets/images/aiNowFly/close.png" alt="">
                        <img src="@/assets/images/aiNowFly/photo.png" alt="">
                    </div>
                    <div class="img-close" v-show="isStop">
                        <img @click="isStop=false" class="close" src="@/assets/images/aiNowFly/close.png" alt="">
                        <img src="@/assets/images/aiNowFly/stop.png" alt="">
                    </div>
                    <div class="add-event" @click="isShowEvent = !isShowEvent">+
                        <div class="event-select" v-show="isShowEvent">
                            <div class="photo" @click="isPhoto=true">拍照</div>
                            <div class="stop" @click="isStop=true">悬停</div>
                        </div>
                    </div>
                </div>
            </el-form-item>
        </el-form>
        <div class="title-list">可飞行机巢列表:</div>
        <el-table :data="list" height="120" @selection-change="handleSelectionChange">
            <el-table-column type="selection" />
            <!-- <el-table-column type="index" label="序号" /> -->
            <el-table-column prop="nickname" label="机巢名称" />
            <el-table-column prop="minute" label="可飞行时间" />
            <el-table-column prop="exe_distance" label="可飞行距离" />
        </el-table>
        <div class="tabledata">
            <div class="table-content">
                <div class="tabler-item">
                    <el-checkbox v-model="isCheckAll" @change="checkedAll"/>
                </div>
                <div class="table-item">机巢名称</div>
                <div class="table-item">可飞行时间</div>
                <div class="table-item">可飞行距离</div>
            </div>
            <div class="table-content" v-for="item in list">
                <div class="tabler-item">
                    <el-checkbox v-model="item.checked" @change="handleItemCheck"/>
                </div>
                <div class="table-item">{{ item.nickname }}</div>
                <div class="table-item">{{ item.minute }}</div>
                <div class="table-item">{{ item.exe_distance }}</div>
            </div>
        </div>
        <div class="btn-submit" @click="nowFly"><img src="@/assets/images/aiNowFly/fly.png" alt=""></div>
    </div>
</template>
@@ -61,9 +86,17 @@
    type: 1,
    begin_time: nowTime,
    end_time: nowTime,
    action_modes: [{action_actuator_func: 'startRecord'}],
}
const params = ref(_.cloneDeep(paramsInit))
const di = computed(() => params.value.longitude + ',' + params.value.latitude)
// 事件默认隐藏
const isShowEvent = ref(false);
// 添加事件
const isPhoto = ref(false)
const isStop = ref(false)
const rules = ref({
    name: [
@@ -89,6 +122,12 @@
    await ruleFormRef.value.validate()
    if (!params.value.dock_sns.length) return ElMessage.warning('请选择将要飞行的机巢')
    if (!params.value.longitude) return ElMessage.warning('请选择飞行的点')
    if (isPhoto.value) {
        params.value.action_modes.push({action_actuator_func:'takePhoto'})
    }
    if (isStop.value) {
        params.value.action_modes.push({action_actuator_func:'hover'})
    }
    createTask(params.value).then(res => {
        ElMessage.success('起飞成功')
        if (params.value.dock_sns.length === 1) {
@@ -205,6 +244,7 @@
  size: 10
});
const isCheckAll = ref(false);
// 获取飞机列表
const getFJList = async () => {
    let pageParams = ref({
@@ -215,10 +255,27 @@
    const res = await getFlyingNestBy(pageParams.value, pagingParams.value)
    list.value = (res.data?.data || []).map(item => ({
        ...item,
        checked: false,
        minute: _.round(item.estimated_arrival_time / 60, 0),
    }))
    if (!list.value.length) ElMessage.warning('附近暂无可用无人机')
    renderingLine()
}
// 单个选择框变化
const handleItemCheck = () => {
  const allChecked = list.value.every(item => item.checked)
  const someChecked = list.value.some(item => item.checked)
  isCheckAll.value = allChecked
  params.value.dock_sns = list.value.filter(item => item.checked).map(item => item.device_sn)
}
// 全选
const checkedAll = () => {
    list.value.forEach(item => {
        item.checked = isCheckAll.value
    })
    params.value.dock_sns = isCheckAll.value ? list.value.map(item => item.device_sn) : []
}
const initMap = () => {
@@ -240,6 +297,8 @@
    list.value = []
    eventPoint = {}
    store.commit('setFootActiveIndex', 0)
    // 显示相关的按钮
    store.commit('setHideBottomIcon', true)
}
onBeforeUnmount(() => {
@@ -304,79 +363,82 @@
      box-shadow: 0 0 0 1px #026AD6;
    }
        .event {
            display: flex;
            img {
                width: 40px;
                height: 34px;
                margin-right: 10px;
            }
            .img-close {
                position: relative;
                .close {
                    cursor: pointer;
                    width: 8px;
                    height: 8px;
                    position: absolute;
                    top: -8px;
                    right: 1px;
                }
            }
            .add-event {
                width: 38px;
                height: 38px;
                background: rgba(83,179,255,0.16);
                border-radius: 8px 8px 8px 8px;
                border: 1px dashed;
                text-align: center;
                line-height: 38px;
                color: #11C4FF;
                position: relative;
                cursor: pointer;
                // border-image: linear-gradient(180deg, rgba(17, 196, 255, 1), rgba(255, 255, 255, 1)) 1 1;
                .event-select {
                    z-index: 10;
                    position: absolute;
                    top: 40px;
                    width: 72px;
                    height: 70px;
                    background: #0F1929;
                    box-shadow: inset 0px -50px 50px 0px rgba(27,148,255,0.13);
                    border-radius: 8px 8px 8px 8px;
                    border: 1px solid #51A8FF;
                    text-align: center;
                    color: #D3E9FF;
                    .photo {
                        height: 36px;
                        border-bottom: 1px solid #51A8FF;
                    }
                }
            }
        }
    }
    .title-list {
        padding: 0 0 14px 11px;
    }
    .el-table {
        width: 300px;
    .tabledata {
        height: 120px;
        margin: 0 0 0 11px;
        overflow: hidden;
        :deep(.el-scrollbar__wrap) {
            overflow-x: hidden !important;
        border: 1px dashed #fff;
        margin: 0px 10px;
        .table-content {
            padding: 0 8px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            border-bottom: 1px dashed #fff;
        }
        :deep(.el-table__body-wrapper) {
            overflow-x: hidden !important;
        }
        :deep(.el-table__header-wrapper) {
            th {
                font-size: 12px;
                color: #D3E9FF;
                background-color: #122348;
                font-weight: normal;
                border-bottom: none;
            }
        }
        :deep(.el-table__empty-block) {
            background-color: #0A1734;
            height: auto !important;  // 移除固定高度
        min-height: 60px;        // 设置最小高度
            .el-table__empty-text {
                color: #FFFFFF;
            }
        }
        :deep(.el-table__body) {
            background-color: #0A1734;
            tr {
                background-color: #0A1734 !important;
                color: #FFFFFF;
                &:hover > td {
                    background-color: #0A1734 !important;
                }
            }
        }
        :deep(.el-scrollbar) {
            background-color: #0A1734;
        .table-item {
            width: 100px;
            text-align: center;
            height: 32px;
            line-height: 32px;
        }
    }
    .btn-submit {
        cursor: pointer;
        margin-left: 88px;
        margin-top: 12px;
        img { width: 138px; height: 38px; }
    }
    :deep(.el-table__inner-wrapper) {
    border: 1px dashed #2F497D;
    &::before {
      display: none;
    }
  }
  :deep(.el-table__cell) {
    border: none;
  }
  :deep(.el-table__border) {
    display: none;
  }
}
</style>
src/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventOverviewDetailLeft.vue
@@ -1,12 +1,12 @@
<template>
    <!--时间 天气-->
    <common-weather></common-weather>
    <div class="event-overview-detail-left">
        <!--返回-->
        <div class="do-return" @click="goBack">
            <img src="@/assets/images/return.png" alt="" />
        </div>
        <common-title title="事件数据分析" />
    <!--返回-->
    <div class="do-return" :style="{left:isHideBottomIcon?pxToRem(430):pxToRem(46)}" @click="goBack">
        <img src="@/assets/images/return.png" alt="" />
    </div>
    <common-title v-show="isHideBottomIcon" :style="{left:pxToRem(14)}" title="事件数据分析" />
    <div v-show="isHideBottomIcon" class="event-overview-detail-left">
        <CommonDateTime class="dateTime" v-model="timeArr" @change="timeChange" />
        <EventDataAnalysis />
        <EventTrendAnalysis />
@@ -22,6 +22,7 @@
import { useStore } from 'vuex'
import EventTrendAnalysis from '@/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventTrendAnalysis.vue'
import EventTop5 from '@/views/Home/EventOverviewDetail/EventOverviewDetailLeft/EventTop5.vue'
import { pxToRem } from '@/utils/rem'
// 选中机巢默认日
// const today = dayjs().format('YYYY-MM-DD')
@@ -30,6 +31,8 @@
const startOfWeek = dayjs().startOf('week').add(1, 'day').format('YYYY-MM-DD')
const endOfWeek = dayjs().endOf('week').add(1, 'day').format('YYYY-MM-DD')
const timeArr = ref([startOfWeek, endOfWeek])
const isHideBottomIcon = computed(() => store.state.common.isHideBottomIcon)
const store = useStore()
@@ -49,6 +52,7 @@
    store.commit('setEventTimeType', [type, date_enum]);
}
const goBack = () => {
    store.commit('setHideBottomIcon', true)
    store.commit('setIsEventOverviewDetail', false)
}
</script>
@@ -56,8 +60,8 @@
.event-overview-detail-left {
    position: absolute;
    width: 390px;
    height: 920px;
    top: 120px;
    height: 870px;
    top: 166px;
    margin-left: 29px;
    background: linear-gradient(
    270deg,
@@ -72,20 +76,19 @@
    align-items: center;
    .dateTime {
        width: 400px;
        width: 356px;
        margin: 0 0 8px 0;
    }
}
.do-return {
    position: absolute;
    top: 136px;
    left: 430px;
    cursor: pointer;
    .do-return {
        position: absolute;
        right: -50px;
        cursor: pointer;
        img {
            width: 60px;
            height: 33px;
        }
    img {
        width: 60px;
        height: 33px;
    }
}
</style>
src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue
@@ -1,9 +1,9 @@
<template>
    <div class="event-overviewdetail-right" :class="{ isMore }">
        <CommonTitle title="工单列表" />
        <CommonTitle title="事件概况" :style="{right: isMore?pxToRem(410):pxToRem(0)}" />
        <div class="content">
            <img class="leftArrow" :src="isMore ? rightArrowImg : leftArrowImg" @click="leftArrowFun" alt="" />
            <img class="leftArrow" :class="isMore?'rightArrow':''" :src="isMore ? rightArrowImg : leftArrowImg" @click="leftArrowFun" alt="" />
            <el-date-picker
                class="ztzf-date-picker"
@@ -50,12 +50,12 @@
                    <img class="statusItemImg" :src="item.img" alt="" />
                    <div class="statusItemInfo">
                        <div class="statusItemName">{{ item.name }}</div>
                        <div class="statusItemNum">{{ item.num || 0 }}</div>
                        <div class="statusItemNum" :style="{ color:item.color }">{{ item.num || 0 }}</div>
                    </div>
                </div>
            </div>
            <el-checkbox-group v-model="params.event_keys" @change="getList">
            <el-checkbox-group v-show="isMore" v-model="params.event_keys" @change="getList">
                <el-checkbox v-for="item in eventList" :value="item.status" :key="item.dictKey">
                    <template #default>
                        <span class="eventListItemCheckboxName">{{ item.name }}</span>
@@ -70,6 +70,7 @@
                        class="eventListItemImg"
                        :src="getSmallImg(item.photo_url)"
                        alt=""
                        @click="getFindImgHistory(item.id)"
                    />
                    <div class="eventListItemPosition" :title="item.address" @click="positioning(item)">
                        <img :src="positioningImg" alt="" title="点击定位" />
@@ -95,6 +96,25 @@
            </div>
        </div>
    </div>
    <div class="image-list" v-if="isShowBigImg">
        <div class="title">
            <img @click="isShowBigImg=false" src="@/assets/images/home/useEventOperate/close.png" alt="">
        </div>
        <div class="content">
            <img :src="clickImgSrc" alt="">
        </div>
        <div class="card">
            <div v-for="(item,index) in imageList">
                <div class="time-top" :class="index===selectedImgIndex?'active':''" @click="clickWeekTime(item,index)">{{ item.create_time_str }}</div>
                <div class="time-point">
                    <img v-if="index===selectedImgIndex" src="@/assets/images/home/useEventOperate/point-active.png" alt="">
                    <img v-else src="@/assets/images/home/useEventOperate/point.png" alt="">
                </div>
                <div class="time-bottom">{{ item.create_time }}</div>
            </div>
            <div class="time-line"></div>
        </div>
    </div>
</template>
<script setup>
import status0Img from '@/assets/images/home/eventOverviewDetail/status0.png'
@@ -110,7 +130,7 @@
import dayjs from 'dayjs'
import { selectDevicePage } from '@/api/home/machineNest'
import { getMultipleDictionary } from '@/api/system/dictbiz'
import { getEvenNum, getEventPage, getEventStatusNum } from '@/api/home/event'
import { getEvenNum, getEventPage, getEventStatusNum, findImgHistory } from '@/api/home/event'
import cesiumOperation from '@/utils/cesium-tsa'
import CommonTitle from '@/components/CommonTitle.vue'
import { pxToRem } from '@/utils/rem'
@@ -148,6 +168,8 @@
    isMore.value = !isMore.value
    params.value.size = isMore.value ? 16 : 8
    params.value.current = 1
    // 下半部分隐藏 右侧隐藏
    store.commit('setHideBottomIcon', !isMore.value)
    getList()
}
@@ -181,12 +203,12 @@
// 事件状态+数量
const statusList = ref([
    { name: '全部状态', img: status0Img, id: undefined,few: true },
    { name: '待审核', img: status1Img, id: 2 },
    { name: '待处理', img: status2Img, id: 0, few: true },
    { name: '处理中', img: status3Img, id: 3, few: true },
    { name: '已完成', img: status4Img, id: 4, few: true },
    { name: '待分拨', img: status5Img, id: 1 },
    { name: '全部状态', img: status0Img, id: undefined,few: true, color: '#FFD509' },
    { name: '待审核', img: status1Img, id: 2, color: '#8CFEA7' },
    { name: '待处理', img: status2Img, id: 0, few: true, color: '#FF7411' },
    { name: '处理中', img: status3Img, id: 3, few: true, color: '#FFC398' },
    { name: '已完成', img: status4Img, id: 4, few: true, color: '#AFD9FB' },
    { name: '待分拨', img: status5Img, id: 1, color: '#11C4FF' },
])
const getEventStatusNumFun = () => {
@@ -244,6 +266,24 @@
        total.value = resData.total
    })
}
const isShowBigImg = ref(false)
const imageList = ref([]);
const clickImgSrc = ref('');
const selectedImgIndex = ref(0);
// 点击图片放大 显示详细信息
const getFindImgHistory = (id) => {
    findImgHistory(id).then((res) => {
        if (res.data.code !== 0) return
        imageList.value = res.data.data
        clickImgSrc.value = res.data.data[0]?.url;
        isShowBigImg.value = true
    })
}
// 点击周期
const clickWeekTime = (item,index) => {
    clickImgSrc.value = item.url
    selectedImgIndex.value = index
}
const getDateRange = unit => {
  if (unit === 'today') {
@@ -282,25 +322,31 @@
    height: 922px;
    width: 405px;
    font-size: 18px;
    z-index: 10;
    &.isMore {
        width: 807px;
        width: 808px;
        .content {
            width: 792px;
            padding-left: 44px;
        }
    }
    .content {
        width: 390px;
        height: 877px;
        background: linear-gradient(270deg, #1f3e7a 0%, rgba(31, 62, 122, 0.35) 79%, rgba(31, 62, 122, 0) 100%);
        background: linear-gradient(
    270deg,
    rgba(31, 62, 122, 0) 0%,
    rgba(31, 62, 122, 0.35) 21%,
    #1f3e7a 100%);
        display: flex;
        justify-content: space-between;
        align-content: start;
        flex-wrap: wrap;
        padding: 7px 15px 0 11px;
        gap: 10px;
        padding: 7px 13px 0 11px;
        gap: 16px;
        .leftArrow {
            position: absolute;
@@ -310,38 +356,42 @@
            cursor: pointer;
        }
        .rightArrow {
            position: absolute;
            top: 50%;
            left: 30px;
            transform: translateY(-50%);
            cursor: pointer;
        }
        .statusList {
            width: 100%;
            display: flex;
            justify-content: space-between;
            .statusItem {
                width: 95px;
                // width: 95px;
                height: 44px;
                display: flex;
                flex: 1;
                justify-content: center;
                position: relative;
                cursor: pointer;
                // margin-right: 4px;
                &.active {
                    background: linear-gradient(
                        180deg,
                        rgba(19, 80, 141, 0) 0%,
                        rgba(22, 56, 91, 0.48) 48%,
                        #053462 91%,
                        #259dff 91%,
                        #259dff 98%
                    );
                    background: linear-gradient( 180deg, rgba(19,80,141,0) 0%, rgba(22,56,91,0.48) 48%, #053462 98%, #259DFF 98%, #259DFF 98%);
                }
                .statusItemImg {
                    width: 35px;
                    height: 35px;
                    width: 34px;
                    height: 34px;
                    margin-right: 1px;
                }
                .statusItemInfo {
                    .statusItemName {
                        width: 59px;
                        // width: 59px;
                        height: 17px;
                        font-family: Segoe UI, Segoe UI;
                        font-weight: 400;
@@ -351,6 +401,7 @@
                        text-align: left;
                        font-style: normal;
                        text-transform: none;
                        margin-bottom: 4px;
                    }
                    .statusItemNum {
@@ -408,6 +459,7 @@
                width: 175px;
                height: 140px;
                position: relative;
                cursor: pointer;
                .eventListItemImg {
                    width: 174px;
@@ -475,4 +527,76 @@
    display: flex;
    justify-content: center;
}
.image-list {
    position: absolute;
    left: 40%;
    transform: translate(-40%);
    bottom: 218px;
    width: 524px;
    height: 382px;
    background: #0F1929;
    box-shadow: inset 0px -50px 50px 0px rgba(27,148,255,0.13);
    border-radius: 0px 0px 0px 0px;
    border: 2px solid;
    border-image: linear-gradient(180deg, rgba(81, 168, 255, 0), rgba(48, 111, 202, 1), rgba(255, 255, 255, 1), rgba(27, 148, 255, 1)) 2 2;
    .title {
        position: relative;
        text-align: right;
        right: 12px;
        top: 12px;
        img {
            width: 10px;
            height: 10px;
            cursor: pointer;
        }
    }
    .content {
        width: 475px;
        height: 231px;
        box-shadow: 1px 3px 6px 0px rgba(81,168,255,0.58);
        border-radius: 20px 20px 20px 20px;
        border-image: linear-gradient(180deg, rgba(81, 168, 255, 1), rgba(189, 228, 255, 1)) 2 2;
        margin: 28px 28px;
        img {
            width: 100%;
            height: 230px;
        }
    }
    .card {
        margin: 26px 26px;
        color: #BECBEA;
        display: flex;
        justify-content: space-between;
        position: relative;
        .time-top {
            width: 50px;
            height: 30px;
            line-height: 30px;
            text-align: center;
            color: #ffffff;
            background: linear-gradient( 180deg, rgba(13,30,70,0.72) 0%, #142E6B 100%);
            border: 1px solid #0054D3;
            cursor: pointer;
        }
        .active {
            background: linear-gradient( 180deg, rgba(13,48,131,0.72) 0%, #023DC8 100%);
            border: 1px solid;
            border-image: linear-gradient(180deg, rgba(0, 84, 211, 1), rgba(146, 186, 245, 1)) 1 1;
        }
        .time-point {
            text-align: center;
            img {
                width: 8px;
                height: 12px;
            }
        }
        .time-line {
            position: absolute;
            background: linear-gradient( 82deg, rgba(23,40,79,0) 0%, #576D9F 17%, #576D9F 86%, rgba(23,40,79,0) 100%);
            height: 2px;
            top: 38px;
            width: 100%;
        }
    }
}
</style>
src/views/Home/Footer.vue
@@ -1,5 +1,5 @@
<template>
    <div class="footer">
    <div class="footer" v-show="isHideBottomIcon">
        <img
            v-for="(item,index) in list.filter(i => !i.show)"
            :class="item.className"
@@ -37,6 +37,7 @@
const store = useStore()
const footActiveIndex = computed(() => store.state.home.footActiveIndex)
const isHideBottomIcon = computed(() => store.state.common.isHideBottomIcon)
// 机巢聚合
const { init, removeAll } = useMapAggregation('device')
@@ -76,6 +77,10 @@
    fromItem?.removeAll?.()
    nextTick(() => toItem?.init?.())
    list.value = list.value.map(item => ({ ...item, active: item.name === toItem?.name }))
    if (index === 5) {
        // 相关图标不显示
        store.commit('setHideBottomIcon', false)
    }
}
watch(
src/views/Home/RSide.vue
@@ -1,5 +1,5 @@
<template>
    <div class="ai-chat">
    <div class="ai-chat" v-show="isHideBottomIcon">
        <el-popover placement="bottom" :visible="visible" :width="200" trigger="click">
            <template #reference>
                <div class="chat" id="chatID" v-drag:chatID @mousedown="handleMouseDown" @mouseup="handleMouseUp" />
@@ -11,7 +11,7 @@
        </el-popover>
        <img class="chat-bottom" src="../../assets/images/chat-bottom.png" alt="" />
    </div>
    <div class="r-side">
    <div class="r-side" v-show="isHideBottomIcon">
        <img
            v-for="(item, index) in images"
            :key="index"
@@ -49,6 +49,8 @@
const store = useStore()
const currentAreaPosition = computed(() => store.state.home.currentAreaPosition)
// 事件概况 展开隐藏
const isHideBottomIcon = computed(() => store.state.common.isHideBottomIcon)
let activeIndex = ref(null)
const activeChange = value => {
src/views/Home/SearchBox.vue
@@ -93,9 +93,7 @@
// 获取机巢搜索结果
const getDeviceList = async () => {
  const res = await selectDeviceList({
    keyword: searchKey.value,
  });
  const res = await selectDeviceList({nickname: searchKey.value});
  if (res.data.code !== 0) return;
  machineNestList.value = res?.data?.data || [];
  downList.value = res?.data?.data || [];
@@ -144,11 +142,12 @@
watch(searchKey, async (newVal) => {
  if (optionsValue.value === '2') {
    await getAddressList();
  } else {
    await getDeviceList();
  }
}, { immediate: false });
onMounted(() => {
  getDeviceList();
  document.addEventListener('click', handleClickOutside);
});
@@ -166,8 +165,8 @@
.select-down-list {
  position: absolute;
  top: 188px;
  left: 45%;
  transform: translateX(-45%);
  left: 44%;
  transform: translateX(-40%);
  width: 220px;
  height: 256px;
  overflow-y: auto;
@@ -175,6 +174,7 @@
  border-radius: 0px 0px 8px 8px;
  border: 1px solid;
  border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1;
  opacity: 0.8;
  &::-webkit-scrollbar {
    width: 0;
    display: none;
@@ -187,6 +187,11 @@
    line-height: 32px;
    text-align: center;
    cursor: pointer;
    &:hover {
      background: linear-gradient( 90deg, rgba(0,122,255,0) 0%, rgba(0,98,204,0.6) 50%, rgba(0,73,153,0) 100%);
      border: 1px solid;
      border-image: linear-gradient(90deg, rgba(0, 199, 190, 0), rgba(48, 176, 199, 1), rgba(0, 199, 190, 0)) 1 1;
    }
  }
}
.searchBox {