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