From 2800fa4f32f3900509cb4d6eefaf2bfaf54efdd7 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Mon, 21 Apr 2025 18:29:09 +0800
Subject: [PATCH] fix: 天气显示
---
src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue | 623 +++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 543 insertions(+), 80 deletions(-)
diff --git a/src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue b/src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue
index ff5d05a..fd49c26 100644
--- a/src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue
+++ b/src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue
@@ -1,10 +1,19 @@
<template>
- <UserOperate/>
- <div class="event-overviewdetail-right">
- <div>工单列表</div>
- <div>
+ <div class="event-overviewdetail-right" :class="{ isMore }">
+ <CommonTitle title="事件概况" :style="{ width: isMore ? pxToRem(820) : pxToRem(404) }" />
+
+ <div class="content">
+ <img
+ class="leftArrow"
+ :class="isMore ? 'rightArrow' : ''"
+ :src="isMore ? rightArrowImg : leftArrowImg"
+ @click="leftArrowFun"
+ alt=""
+ />
+
<el-date-picker
- style="width: 100%"
+ popper-class="custom-date-picker"
+ class="ztzf-date-picker"
v-model="timeArr"
type="daterange"
:value-format="timeFormat"
@@ -13,69 +22,142 @@
end-placeholder="结束日期"
@change="timeChange"
/>
- </div>
- <el-select style="width: 100%" v-model="params.device_sn" placeholder="机巢" filterable clearable @change="getList">
- <el-option v-for="item in deviceList" :label="item.nickname" :value="item.device_sn" :key="item.device_sn" />
- </el-select>
- <el-select v-model="params.word_order_type" placeholder="工单类型" filterable clearable @change="getList">
- <el-option v-for="item in workOrderType" :label="item.dictValue" :value="item.dictKey" :key="item.dictKey" />
- </el-select>
- <div class="statusList">
- <div v-for="item in statusList" @click="statusClick(item)" :class="{ active: item.active }">
- <div>{{ item.name }}</div>
- <div>{{ item.num || 0 }}</div>
- </div>
- </div>
+ <el-select
+ :teleported="false"
+ class="ztzf-select"
+ :style="{ width: pxToRem(174) }"
+ v-model="params.device_sn"
+ placeholder="机巢"
+ filterable
+ clearable
+ @change="getList"
+ >
+ <el-option v-for="item in deviceList" :label="item.nickname" :value="item.device_sn" :key="item.device_sn" />
+ </el-select>
- <el-checkbox-group v-model="params.eventKeys" @change="getList">
- <el-checkbox
- v-for="item in eventList"
- :label="item.name + ' ' + item.value"
- :value="item.status"
- :key="item.dictKey"
- />
- </el-checkbox-group>
+ <el-select
+ :teleported="false"
+ class="ztzf-select"
+ :style="{ width: pxToRem(174) }"
+ v-model="params.word_order_type"
+ placeholder="工单类型"
+ filterable
+ clearable
+ @change="getList"
+ >
+ <el-option v-for="item in workOrderType" :label="item.dictValue" :value="item.dictKey" :key="item.dictKey" />
+ </el-select>
- <div class="eventList">
- <div class="eventListItem" v-for="item in list">
- <img class="eventListItemImg"
- :src="item.photo_url ?
- item.photo_url.substring(0, item.photo_url.lastIndexOf('.')) + '_small' +
- item.photo_url.substring(item.photo_url.lastIndexOf('.'))
- : ''"
- alt=""
- />
- <div class="eventListItemText">
- <div class="eventListItemName">{{ item.event_name }}</div>
- <div @click="positioning(item)">定位</div>
- <div class="eventListItemTime">{{ item.create_time }}</div>
+ <div class="statusList">
+ <div
+ class="statusItem"
+ v-for="item in isMore ? statusList : statusList.filter(i => i.few)"
+ @click="statusClick(item)"
+ :class="{ active: item.active }"
+ >
+ <img class="statusItemImg" :src="item.img" alt="" />
+ <div class="statusItemInfo">
+ <div class="statusItemName">{{ item.name }}</div>
+ <div class="statusItemNum" :style="{ color: item.color }">{{ item.num || 0 }}</div>
+ </div>
</div>
</div>
- </div>
- <el-pagination
- background
- v-model:current-page="params.current"
- v-model:page-size="params.size"
- layout="total, prev, pager, next"
- :total="total"
- @change="pageChange"
- />
+ <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>
+ <span class="eventListItemCheckboxNum">({{ item.value }})</span>
+ </template>
+ </el-checkbox>
+ </el-checkbox-group>
+
+ <div class="eventList">
+ <div class="eventListItem" v-for="item in list">
+ <img class="eventListItemImg" :src="getSmallImg(item.photo_url)" alt="" @click="getFindImgHistory(item)" />
+ <div class="eventListItemPosition" :title="item.address" @click="positioning(item)">
+ <img :src="positioningImg" alt="" title="点击定位" />
+ <!-- <div class="address">{{ item.address }}</div> -->
+ </div>
+ <div class="eventListItemText">
+ <div class="eventListItemName">{{ item.event_name }}</div>
+ <div class="eventListItemTime">{{ dayjs(item.create_time).format('MM/DD HH:mm') }}</div>
+ </div>
+ </div>
+ </div>
+
+ <div class="pagination">
+ <el-pagination
+ class="ztzf-pagination"
+ background
+ v-model:current-page="params.current"
+ v-model:page-size="params.size"
+ layout="total, prev, pager, next"
+ :total="total"
+ @change="pageChange"
+ />
+ </div>
+ </div>
+ </div>
+ <div class="image-list" v-if="isShowBigImg" :style="{ right: isMore ? pxToRem(838) : pxToRem(460) }">
+ <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 class="card-content">
+ <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
+ class="active"
+ 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>
</div>
</template>
<script setup>
-import UserOperate from '@/components/UserOperate.vue';
+import status0Img from '@/assets/images/home/eventOverviewDetail/status0.png'
+import status1Img from '@/assets/images/home/eventOverviewDetail/status1.png'
+import status2Img from '@/assets/images/home/eventOverviewDetail/status2.png'
+import status3Img from '@/assets/images/home/eventOverviewDetail/status3.png'
+import status4Img from '@/assets/images/home/eventOverviewDetail/status4.png'
+import status5Img from '@/assets/images/home/eventOverviewDetail/status5.png'
+import positioningImg from '@/assets/images/home/eventOverviewDetail/positioning.png'
+import leftArrowImg from '@/assets/images/home/eventOverviewDetail/leftArrow.png'
+import rightArrowImg from '@/assets/images/home/eventOverviewDetail/rightArrow.png'
+
import dayjs from 'dayjs'
import { selectDevicePage } from '@/api/home/machineNest'
import { getMultipleDictionary } from '@/api/system/dictbiz'
-import { getEvenNum, getEventPage, getEventStatusNum, getEventTrend } 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'
+import { useStore } from 'vuex'
+const store = useStore()
+// const eventTimeRange = computed(() => store.state.home.eventTimeRange)
const timeFormat = 'YYYY-MM-DD HH:mm:ss'
const today = dayjs().format(timeFormat)
-const oneWeekAgo = dayjs().subtract(7, 'day').format(timeFormat)
-const timeArr = ref([oneWeekAgo, today])
+// const oneWeekAgo = dayjs().subtract(7, 'day').format(timeFormat)
+// const timeArr = ref([oneWeekAgo, today])
+const startOfWeek = dayjs().startOf('week').add(1, 'day').format(timeFormat)
+const endOfWeek = dayjs().endOf('week').add(1, 'day').format(timeFormat)
+const timeArr = ref([startOfWeek, endOfWeek])
const deviceList = ref([])
const total = ref(0)
@@ -85,10 +167,24 @@
device_sn: undefined,
word_order_type: undefined,
status: undefined,
- eventKeys: [],
+ event_keys: [],
current: 1,
- size: 10,
+ size: 8,
})
+
+const getSmallImg = url => {
+ return url ? url.substring(0, url.lastIndexOf('.')) + '_small' + url.substring(url.lastIndexOf('.')) : ''
+}
+
+const isMore = ref(false)
+const leftArrowFun = () => {
+ isMore.value = !isMore.value
+ params.value.size = isMore.value ? 16 : 8
+ params.value.current = 1
+ // 下半部分隐藏 右侧隐藏
+ store.commit('setHideBottomIcon', !isMore.value)
+ getList()
+}
const statusClick = row => {
params.value.status = row.id || undefined
@@ -111,19 +207,35 @@
workOrderType.value = res.data.data?.['WORK_ORDER_TYPE'] || []
})
}
-const { flyTo } = cesiumOperation();
-const positioning = (row) =>{
+const { flyTo } = cesiumOperation()
+const longitudeOffset = ref(0)
+const positioning = row => {
const longitude = Number(row.longitude)
const latitude = Number(row.latitude)
- flyTo({ longitude, latitude }, 1, 1000);
+ flyTo({ longitude: longitude, latitude: latitude + 0.0008 }, 1, 1000)
}
// 事件状态+数量
-const statusList = ref([])
+const statusList = ref([
+ { 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 = () => {
const [start_date, end_date] = timeArr.value
getEventStatusNum({ start_date, end_date }).then(res => {
- statusList.value = (res.data?.data || []).map(i => ({ ...i, active: false }))
+ const list = res.data?.data || []
+ statusList.value = statusList.value.map(item => {
+ const find = list.find(item1 => item.id === item1.id) || {}
+ return {
+ ...item,
+ ...find,
+ }
+ })
statusList.value[0].active = true
})
}
@@ -141,11 +253,13 @@
const [start_date, end_date] = timeArr.value
params.value.start_date = start_date
params.value.end_date = end_date
+ // 提交数据,更新聚合
+ store.commit('setEventTimeRang', timeArr.value)
// 重置
getEventStatusNumFun()
getEventList()
params.value.status = undefined
- params.value.eventKeys = undefined
+ params.value.event_keys = undefined
getList()
}
@@ -156,12 +270,59 @@
const list = ref([])
const getList = () => {
- getEventPage(params.value).then(res => {
+ const pageParams = {
+ current: params.value.current,
+ size: params.value.size,
+ }
+ getEventPage(params.value, pageParams).then(res => {
const resData = res.data.data
list.value = resData?.records || []
total.value = resData.total
})
}
+const isShowBigImg = ref(false)
+const imageList = ref([])
+const clickImgSrc = ref('')
+const selectedImgIndex = ref(0)
+// 点击图片放大 显示详细信息
+const getFindImgHistory = item => {
+ // 下半部分隐藏 右侧隐藏
+ isShowBigImg.value = true
+ store.commit('setHideBottomIcon', false)
+ findImgHistory(item.id).then(res => {
+ if (res.data.code !== 0) return
+ imageList.value = res.data.data
+ clickImgSrc.value = res.data.data[0]?.url
+ })
+ positioning(item)
+}
+// 点击周期
+const clickWeekTime = (item, index) => {
+ clickImgSrc.value = item.url
+ selectedImgIndex.value = index
+}
+
+const getDateRange = unit => {
+ if (unit === 'today') {
+ return [dayjs().format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')]
+ }
+ return [dayjs().startOf(unit).format('YYYY-MM-DD HH:mm:ss'), dayjs().endOf(unit).format('YYYY-MM-DD HH:mm:ss')]
+}
+
+// 监听事件时间范围变化
+watch(
+ () => store.state.home.eventTimeType,
+ newVal => {
+ timeArr.value = getDateRange(newVal)
+ const [start_date, end_date] = getDateRange(newVal)
+ params.value.start_date = start_date
+ params.value.end_date = end_date
+ getEventStatusNumFun()
+ getEventList()
+ getList()
+ },
+ { immediate: false, deep: true }
+)
onMounted(() => {
getDeviceList()
@@ -174,40 +335,342 @@
<style scoped lang="scss">
.event-overviewdetail-right {
position: absolute;
- right: 29px;
+ right: 36px;
top: 122px;
- // color: black;
display: flex;
flex-direction: column;
- align-items: center;
- height: 900px;
- width: 400px;
- background: white;
+ align-items: end;
+ height: 922px;
+ width: 405px;
font-size: 18px;
+ z-index: 10;
- .statusList {
- display: flex;
- flex-wrap: wrap;
+ &.isMore {
+ width: 808px;
- .active {
- background: #19ad8d;
+ .content {
+ width: 792px;
+ padding-left: 44px;
}
}
- .eventList {
+ .content {
+ width: 390px;
+ height: 877px;
+ 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 13px 0 11px;
+ gap: 16px;
- .eventListItem {
- .eventListItemImg {
- width: 120px;
- height: 100px;
+ .leftArrow {
+ position: absolute;
+ left: -11px;
+ top: 50%;
+ transform: translateY(-50%);
+ 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;
+ 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 98%,
+ #259dff 98%,
+ #259dff 98%
+ );
+ }
+
+ .statusItemImg {
+ width: 34px;
+ height: 34px;
+ margin-right: 1px;
+ }
+
+ .statusItemInfo {
+ .statusItemName {
+ // width: 59px;
+ height: 17px;
+ font-family: Segoe UI, Segoe UI;
+ font-weight: 400;
+ font-size: 14px;
+ color: #ffffff;
+ line-height: 17px;
+ text-align: left;
+ font-style: normal;
+ text-transform: none;
+ margin-bottom: 4px;
+ }
+
+ .statusItemNum {
+ width: 32px;
+ height: 16px;
+ font-family: Segoe UI, Segoe UI;
+ font-weight: bold;
+ font-size: 16px;
+ color: #ffd509;
+ line-height: 16px;
+ text-align: left;
+ font-style: normal;
+ text-transform: none;
+ }
+ }
+ }
+ }
+
+ .el-checkbox-group {
+ :deep() {
+ .el-checkbox {
+ height: 20px;
+ margin-right: 10px;
+ }
+
+ .el-checkbox__inner {
+ background: transparent;
+ width: 18px;
+ height: 18px;
+ border: 1px solid #3194ef;
+ }
+
+ .el-checkbox__label {
+ font-family: Segoe UI, Segoe UI;
+ font-weight: 400;
+ font-size: 14px;
+ color: #ffffff;
+ line-height: 17px;
+
+ .eventListItemCheckboxNum {
+ color: #ffa500;
+ }
+ }
+ }
+ }
+
+ .eventList {
+ width: 100%;
+ display: flex;
+ flex-wrap: wrap;
+ // justify-content: space-between;
+ gap: 20px 10px;
+
+ .eventListItem {
+ width: 175px;
+ height: 140px;
+ position: relative;
+ cursor: pointer;
+
+ .eventListItemImg {
+ width: 174px;
+ height: 116px;
+ border-radius: 4px 4px 4px 4px;
+ margin-bottom: 7px;
+ }
+
+ .eventListItemPosition {
+ position: absolute;
+ right: 0;
+ top: 116px;
+ width: 174px;
+ height: 20px;
+ transform: translateY(-100%);
+ background: rgba(22, 22, 22, 0.68);
+ border-radius: 0 0 4px 4px;
+ font-family: Segoe UI, Segoe UI;
+ font-weight: 400;
+ font-size: 12px;
+ line-height: 17px;
+ color: #51a8ff;
+ cursor: pointer;
+ padding-right: 5px;
+ display: flex;
+ justify-content: end;
+
+ img {
+ margin-right: 5px;
+ }
+
+ .address {
+ display: inline-block;
+ width: 60px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ }
+
+ .eventListItemText {
+ display: flex;
+ justify-content: space-between;
+ font-family: Segoe UI, Segoe UI;
+ font-weight: 400;
+ font-size: 14px;
+ color: #ffffff;
+ line-height: 17px;
+
+ .eventListItemTime {
+ font-family: Segoe UI, Segoe UI;
+ font-weight: 400;
+ font-size: 14px;
+ color: #96a3cc;
+ line-height: 17px;
+ }
+ }
+ }
+ }
+ }
+}
+
+.pagination {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+}
+
+.image-list {
+ position: absolute;
+ top: 148px;
+
+ right: 460px;
+
+ width: 632px;
+ height: 476px;
+ border: solid;
+ background: #0f1929;
+ z-index: 1;
+
+ border: solid 2px transparent;
+ border-radius: 20px;
+ background-image: linear-gradient(#fff, #fff), linear-gradient(180deg, rgba(81, 168, 255, 1), rgba(189, 228, 255, 1));
+ background-origin: border-box;
+ background-clip: content-box, border-box;
+
+ overflow: hidden;
+ .title {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ text-align: right;
+ top: 0;
+ right: 0;
+ width: 45px;
+ height: 44px;
+ background: rgba(0, 0, 0, 0.5);
+ border-radius: 0px 20px 0px 8px;
+
+ img {
+ width: 10.55px;
+ height: 10.55px;
+ cursor: pointer;
+ }
+ }
+
+ .content {
+ img {
+ width: 100%;
+ height: 100%;
+ border-radius: 10px 10px 10px 10px;
+ }
+ }
+
+ .card {
+ position: absolute;
+ bottom: 0px;
+ width: 100%;
+ height: 67px;
+ background: rgba(0, 0, 0, 0.42);
+ border-radius: 0px 0px 20px 20px;
+ padding: 0px 6px 0px 29px;
+
+ color: #d5d5d5;
+ font-size: 14px;
+
+ .card-content {
+ display: flex;
+ justify-content: space-between;
+
+ position: absolute;
+ left: 29px;
+ width: calc(100% - 29px - 6px);
+ height: 100%;
+
+ & > div {
+ position: relative;
}
- .eventListItemText {
+ .time-top {
+ margin-top: 10px;
+ line-height: 1;
+ text-align: center;
+ cursor: pointer;
+ }
+
+ .active {
+ font-weight: 400;
+ color: #ffffff;
+ }
+
+ .time-point {
display: flex;
- justify-content: space-between;
- font-size: 16px;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ top: 28px;
+ left: 50%;
+ width: 18px;
+ height: 18px;
+ z-index: 1;
+ transform: translate(-50%, 0);
+
+ img {
+ width: 11.2px;
+ height: 11.2px;
+ }
+
+ img.active {
+ width: 16.89px;
+ height: 16.89px;
+ }
+ }
+
+ .time-bottom {
+ margin-top: 20px;
+ }
+
+ .time-line {
+ position: absolute;
+ top: 35px;
+ width: 100%;
+ width: 595px;
+ border-radius: 0px 0px 0px 0px;
+ border: 1px solid rgba(237, 237, 237, 0.6);
+ z-index: 0;
}
}
}
--
Gitblit v1.9.3