A:简化样式;划分组件职责

This commit is contained in:
jimmy committed 2025-07-08 14:46:18 +08:00
1 parent 60fd29876e
commit 1211208189
3 files changed
+155 -83

No files matched your search

@@ -44,14 +44,8 @@
<div class="resize-handle-hover-h"></div>
</div>
<!-- 时间轴事件流 -->
<EventTimeline
:height="timelineHeight"
:events="events"
:isPaused="isTimelinePaused"
@pause="isTimelinePaused = !isTimelinePaused"
@clear="handleClearEvents"
/>
<!-- 时间轴事件流 - 现在更简洁了 -->
<EventTimeline :height="timelineHeight" />
</div>
</template>
@@ -66,6 +60,7 @@ import { ResponseModel, SubscriptionInfo, SubscriptionProcessInfo } from '@/type
import { httpClient } from '@/utils/http'
import { useWebSocketStore } from '@/stores/websocketStore'
import { useProcessStore } from '@/stores/processInfo'
import ConnectionsTable1 from '@/views/MonitorView/components/ConnectionsTable1.vue'
const webSocketStore = useWebSocketStore()
@@ -76,6 +71,10 @@ const { selectedApp } = storeToRefs(applicationStore)
const processStore = useProcessStore()
const { processInfos } = storeToRefs(processStore)
// 订阅进程信息
processStore.subscribe()
// Props - 只保留必要的布局相关属性
@@ -142,19 +141,6 @@ const filteredConnections = computed(() => {
return connections
})
// 模拟事件数据 - 将来可以从pinia获取
const events = computed(() => [
{
id: 1,
time: new Date().toLocaleTimeString(),
type: 'connection',
eventType: '连接建立',
description: 'chrome.exe → google.com:443',
},
// ... 更多事件数据
])
// Timeline拖拽逻辑
const startTimelineResize = (event: MouseEvent) => {
event.preventDefault()
@@ -209,16 +195,10 @@ const handleRefresh = () => {
processStore.refresh?.()
}
const handleClearEvents = () => {
console.log('清空事件')
}
// 监听选中应用的变化
watch(selectedApp, (newVal, oldVal) => {
// 进行更新,先把原始数据清空
processStore.clear()
// 重置展开状态
expandedProcesses.value = []
// 清空搜索
searchQuery.value = ''
@@ -1563,32 +1563,6 @@ const handleDisconnect = (connection: ConnectionInfo) => {
color: var(--text-muted);
}
/* 动画 */
.sticky-slide-enter-active,
.sticky-slide-leave-active {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.sticky-slide-enter-from {
opacity: 0;
transform: translateY(-20px);
}
.sticky-slide-leave-to {
opacity: 0;
transform: translateY(-10px);
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
/* CSS 变量定义 */
:root {
--bg-primary: #ffffff;
@@ -1743,4 +1717,10 @@ const handleDisconnect = (connection: ConnectionInfo) => {
:deep(.n-virtual-list__content)::-webkit-scrollbar-thumb:active {
background: var(--scrollbar-thumb-bg-active);
}
/* 加入滚动条动画 */
:deep(.v-vl-visible-items){
/*transition: transform 0.1s ease-out;*/
}
</style>
@@ -11,11 +11,11 @@
size="small"
:type="isPaused ? 'info' : 'warning'"
ghost
@click="$emit('pause')"
@click="handleTogglePause"
>
{{ isPaused ? '继续' : '暂停' }}
</n-button>
<n-button size="small" ghost @click="$emit('clear')">清空</n-button>
<n-button size="small" ghost @click="handleClearEvents">清空</n-button>
</div>
</div>
@@ -50,44 +50,156 @@
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { NButton } from 'naive-ui'
import { useProcessStore } from '@/stores/processInfo'
import { storeToRefs } from 'pinia'
// Props
// 只保留高度控制
const props = defineProps<{
height: number
events: Array<{
id: number
time: string
type: 'info' | 'warning' | 'success' | 'error'
eventType: string
description: string
}>
isPaused: boolean
}>()
// Emits
const emit = defineEmits<{
pause: []
clear: []
}>()
// 使用 Process Store
const processStore = useProcessStore()
const { processInfos } = storeToRefs(processStore)
// 组件内部状态管理
const isPaused = ref(false)
const internalEvents = ref<Array<{
id: number
time: string
type: 'info' | 'warning' | 'success' | 'error'
eventType: string
description: string
timestamp: number
}>>([])
// 显示的事件(添加动画标记)
const displayEvents = ref(props.events.map(e => ({ ...e, isNew: false })))
const displayEvents = ref(internalEvents.value.map(e => ({ ...e, isNew: false })))
// 监听事件变化,标记新事件
watch(() => props.events, (newEvents, oldEvents) => {
if (!props.isPaused) {
const oldIds = new Set(oldEvents?.map(e => e.id) || [])
displayEvents.value = newEvents.map(e => ({
...e,
isNew: !oldIds.has(e.id)
}))
// 500ms后移除新事件标记
setTimeout(() => {
displayEvents.value = displayEvents.value.map(e => ({ ...e, isNew: false }))
}, 500)
// 从 processInfos 派生事件数据
const events = computed(() => {
if (isPaused.value) {
return internalEvents.value // 暂停时返回内部缓存的事件
}
return internalEvents.value
})
// 添加事件的内部方法
const addEvent = (event: {
time: string
type: 'info' | 'warning' | 'success' | 'error'
eventType: string
description: string
}) => {
if (isPaused.value) return
const newEvent = {
...event,
id: Date.now() + Math.random(),
timestamp: Date.now()
}
internalEvents.value.unshift(newEvent)
// 限制最大事件数量
if (internalEvents.value.length > 1000) {
internalEvents.value = internalEvents.value.slice(0, 1000)
}
}
// 监听 processInfos 变化,自动生成事件
watch(processInfos, (newProcessInfos, oldProcessInfos) => {
if (!oldProcessInfos || oldProcessInfos.length === 0 || isPaused.value) return
const now = new Date().toLocaleTimeString()
newProcessInfos.forEach(newProcess => {
const oldProcess = oldProcessInfos.find(p => p.processId === newProcess.processId)
if (!oldProcess) {
// 新进程
addEvent({
time: now,
type: 'info',
eventType: '进程启动',
description: `${newProcess.processName} (PID: ${newProcess.processId})`
})
} else {
// 检测连接变化
const newConnections = newProcess.connections.filter(newConn =>
!oldProcess.connections.some(oldConn =>
oldConn.localEndpoint.address === newConn.localEndpoint.address &&
oldConn.localEndpoint.port === newConn.localEndpoint.port &&
oldConn.remoteEndpoint.address === newConn.remoteEndpoint.address &&
oldConn.remoteEndpoint.port === newConn.remoteEndpoint.port
)
)
newConnections.forEach(conn => {
addEvent({
time: now,
type: 'success',
eventType: '连接建立',
description: `${newProcess.processName} → ${conn.remoteEndpoint.address}:${conn.remoteEndpoint.port}`
})
})
// 检测连接断开
const closedConnections = oldProcess.connections.filter(oldConn =>
!newProcess.connections.some(newConn =>
oldConn.localEndpoint.address === newConn.localEndpoint.address &&
oldConn.localEndpoint.port === newConn.localEndpoint.port &&
oldConn.remoteEndpoint.address === newConn.remoteEndpoint.address &&
oldConn.remoteEndpoint.port === newConn.remoteEndpoint.port
)
)
closedConnections.forEach(conn => {
addEvent({
time: now,
type: 'warning',
eventType: '连接断开',
description: `${newProcess.processName} ✗ ${conn.remoteEndpoint.address}:${conn.remoteEndpoint.port}`
})
})
}
})
// 检测进程结束
oldProcessInfos.forEach(oldProcess => {
if (!newProcessInfos.find(p => p.processId === oldProcess.processId)) {
addEvent({
time: now,
type: 'error',
eventType: '进程结束',
description: `${oldProcess.processName} (PID: ${oldProcess.processId})`
})
}
})
}, { deep: true })
// 监听内部事件变化,标记新事件
watch(internalEvents, (newEvents, oldEvents) => {
const oldIds = new Set(oldEvents?.map(e => e.id) || [])
displayEvents.value = newEvents.map(e => ({
...e,
isNew: !oldIds.has(e.id)
}))
// 500ms后移除新事件标记
setTimeout(() => {
displayEvents.value = displayEvents.value.map(e => ({ ...e, isNew: false }))
}, 500)
}, { deep: true })
// 事件处理函数
const handleTogglePause = () => {
isPaused.value = !isPaused.value
}
const handleClearEvents = () => {
internalEvents.value = []
}
</script>
<style scoped>