From 98ff0df343bd4e5d2d5e138a02c6db2b7fa9696b Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Tue, 27 Jan 2026 10:23:03 +0800
Subject: [PATCH] feat:角色权限弹窗配置页面,调整

---
 applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue |  209 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 207 insertions(+), 2 deletions(-)

diff --git a/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue b/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue
index f59947f..65c2764 100644
--- a/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue
+++ b/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue
@@ -1,13 +1,218 @@
 <template>
-	<div>
+	<div class="left-container" :class="{ collapsed: collapsedModel }">
+		<div class="wrapper">
+			<TitleTemplate>异常情况告警</TitleTemplate>
 
+			<div class="category-container">
+				<div class="category-item" v-for="(item, ind) in categoryList" :key="ind"
+					@click="activeIdModel = item.id" :class="{ active: activeIdModel === item.id }">
+					{{ item.name }}
+					<span class="badge" v-if="item.badge">{{ item.badge }}</span>
+				</div>
+			</div>
+
+			<div class="content">
+				<component :is="currentComponent" />
+			</div>
+		</div>
+
+		<div class="collapse-btn" @click="toggleCollapse">
+			<span class="arrow" :class="collapsedModel ? 'right' : 'left'"></span>
+		</div>
 	</div>
 </template>
 
 <script setup>
+import TitleTemplate from './templateComponents/TitleTemplate.vue'
+import RealWarning from './RealWarning.vue'
+import EquipmentWarning from './EquipmentWarning.vue'
+import HistoryWarning from './HistoryWarning.vue'
+import { alarmStatisticsApi } from '@/api/dataCockpit'
+import { onMounted } from 'vue'
 
+const props = defineProps({
+	activeId: {
+		type: Number,
+		default: 1
+	},
+	collapsed: {
+		type: Boolean,
+		default: false
+	}
+})
+
+const emit = defineEmits(['update:activeId', 'update:collapsed'])
+
+const activeIdModel = computed({
+	get: () => props.activeId,
+	set: (val) => emit('update:activeId', val)
+})
+
+const collapsedModel = computed({
+	get: () => props.collapsed,
+	set: (val) => emit('update:collapsed', val)
+})
+
+const categoryList = ref([
+	{
+		id: 1,
+		name: '实时告警',
+		badge: 0,
+		component: RealWarning
+	},
+	{
+		id: 2,
+		name: '设备告警',
+		badge: 0,
+		component: EquipmentWarning
+	},
+	{
+		id: 3,
+		name: '历史告警',
+		badge: 0,
+		component: HistoryWarning
+	}
+])
+
+const currentComponent = computed(() => {
+	return categoryList.value.find(i => i.id === activeIdModel.value)?.component
+})
+
+const toggleCollapse = () => {
+	collapsedModel.value = !collapsedModel.value
+}
+
+const updateBadges = async () => {
+	const res = await alarmStatisticsApi()
+	const data = res?.data?.data || {}
+	const realTotal = data.realTimeAlarmCount ?? 0
+	const historyTotal = data.historyAlarmCount ?? 0
+	const deviceTotal = data.deviceAlarmCount ?? 0
+	categoryList.value = categoryList.value.map((item) => {
+		if (item.id === 1) return { ...item, badge: realTotal }
+		if (item.id === 2) return { ...item, badge: deviceTotal }
+		if (item.id === 3) return { ...item, badge: historyTotal }
+		return item
+	})
+}
+
+onMounted(() => {
+	updateBadges()
+})
 </script>
 
 <style lang="scss" scoped>
+.left-container {
+	position: relative;
+	transition: transform 0.3s ease-in-out;
 
-</style>
\ No newline at end of file
+	&.collapsed {
+		transform: translateX(calc(-100% - 17px - 32px));
+	}
+}
+
+.collapse-btn {
+	position: absolute;
+	bottom: 454px;
+	left: 300px;
+	cursor: pointer;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	color: #fff;
+	z-index: 10;
+	transform: translateY(50%);
+
+	.arrow {
+		width: 36px;
+		height: 36px;
+		background: url('@/assets/images/dataCockpit/left-btn.png') center / 100% 100% no-repeat;
+	}
+
+	&:hover {
+		background: rgba(40, 79, 227, 0.6);
+	}
+}
+
+.category-container {
+	position: relative;
+	display: flex;
+	justify-content: space-between;
+
+	&::after {
+		content: '';
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		height: 1px;
+		background: #333355;
+	}
+
+	.category-item {
+		position: relative;
+		width: 0;
+		flex: 1;
+		margin-left: 26px;
+		height: 68px;
+		line-height: 68px;
+
+		font-family: Source Code Pro, Source Code Pro;
+		font-weight: 400;
+		font-size: 14px;
+		color: #86909C;
+		text-align: center;
+		font-style: normal;
+		text-transform: none;
+		cursor: pointer;
+
+		&:first-child {
+			margin-left: 0;
+		}
+
+		&.active {
+			font-weight: normal;
+			color: #FFFFFF;
+		}
+
+		&::after {
+			content: '';
+			position: absolute;
+			left: 0;
+			bottom: 0;
+			width: 100%;
+			height: 0;
+		}
+
+		&.active::after {
+			height: 3px;
+			background: #284FE3;
+			box-shadow: 0px 3px 2px 0px rgba(15, 89, 255, 0.1), 0px 7px 5px 0px rgba(15, 89, 255, 0.15), 0px 13px 10px 0px rgba(15, 89, 255, 0.18), 0px 22px 18px 0px rgba(15, 89, 255, 0.21), 0px 42px 33px 0px rgba(15, 89, 255, 0.26), 0px 100px 80px 0px rgba(15, 89, 255, 0.36);
+			border-radius: 5px 5px 0px 0px;
+			z-index: 9;
+		}
+
+		.badge {
+			position: absolute;
+			top: 16px;
+			right: -4px;
+			min-width: 18px;
+			line-height: 18px;
+			font-size: 12px;
+			color: #FFFFFF;
+			background: #FF3B30;
+			border-radius: 50%;
+			text-align: center;
+			box-shadow: 0px 2px 6px rgba(255, 59, 48, 0.6);
+			pointer-events: none;
+		}
+	}
+}
+
+.content {
+	height: 0;
+	flex: 1;
+	margin-top: 20px;
+	overflow: hidden;
+}
+</style>

--
Gitblit v1.9.3