A:简化样式;划分组件职责
This commit is contained in:
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>
|
||||
|
||||
Reference in new issue
Block a user