U:调整index中函数分布

This commit is contained in:
jimmy committed 2025-07-07 15:50:46 +08:00
1 parent e737713ef5
commit 60fd29876e
3 files changed
+100 -153

No files matched your search

@@ -107,14 +107,23 @@
<script setup lang="ts">
import { ref, computed } from 'vue'
import { storeToRefs } from 'pinia'
import TrafficChart from './components/TrafficChart.vue'
// 假设我们有一个连接状态的store,将来可以添加
// import { useConnectionStore } from '@/stores/connection'
// Props
// Props - 只保留布局相关的
const props = defineProps<{
width: number
selectedConnection: any | null
}>()
// 从store获取选中的连接 - 将来可以从pinia获取
// const connectionStore = useConnectionStore()
// const { selectedConnection } = storeToRefs(connectionStore)
// 临时使用ref,将来替换为store
const selectedConnection = ref<any>(null)
// 状态文本映射
const getStatusText = (status: string) => {
const statusMap: Record<string, string> = {
@@ -129,11 +138,11 @@ const getStatusText = (status: string) => {
// 流量数据
const trafficData = computed(() => {
if (!props.selectedConnection) {
if (!selectedConnection.value) {
return { upload: '0 B', download: '0 B', total: '0 B' }
}
// 模拟数据
// 模拟数据 - 将来可以从store或API获取真实数据
return {
upload: '1.2 MB',
download: '5.8 MB',
@@ -143,9 +152,20 @@ const trafficData = computed(() => {
// 图表数据
const chartData = computed(() => {
// 生成模拟的流量图表数据
// 生成模拟的流量图表数据 - 将来可以从store获取真实数据
return Array.from({ length: 20 }, () => Math.random() * 100)
})
// 提供一个方法让外部组件设置选中的连接(过渡期使用)
// 将来可以移除,直接通过store管理
const setSelectedConnection = (connection: any) => {
selectedConnection.value = connection
}
// 暴露方法给父组件(如果需要的话)
defineExpose({
setSelectedConnection
})
</script>
<style scoped>
@@ -11,8 +11,7 @@
<div class="header-actions">
<div class="search-area">
<n-input
:value="searchQuery"
@update:value="$emit('update:searchQuery', $event)"
v-model:value="searchQuery"
placeholder="搜索连接、域名或IP..."
size="medium"
>
@@ -61,17 +60,13 @@ import { ref, computed, onMounted, watch, onUnmounted, nextTick } from 'vue'
import { NButton, NInput, NIcon } from 'naive-ui'
import { SearchOutline } from '@vicons/ionicons5'
import EventTimeline from './components/EventTimeline.vue'
import { FlashOutline } from '@vicons/ionicons5'
import { useApplicationStore } from '@/stores/application'
import { storeToRefs } from 'pinia'
import { ResponseModel, SubscriptionInfo, SubscriptionProcessInfo } from '@/types/response'
import { httpClient } from '@/utils/http'
import { useWebSocketStore } from '@/stores/websocketStore'
import { useProcessStore } from '@/stores/processInfo'
import { ApplicationType } from '@/types/infoModel'
import ConnectionsTable1 from '@/views/MonitorView/components/ConnectionsTable1.vue'
import ConnectionsTable from '@/views/MonitorView/components/ConnectionsTable.vue'
import UnifiedConnectionsList from '@/views/MonitorView/components/UnifiedConnectionsList.vue'
const webSocketStore = useWebSocketStore()
const { isOpen } = storeToRefs(webSocketStore)
@@ -83,10 +78,15 @@ const processStore = useProcessStore()
const { processInfos } = storeToRefs(processStore)
processStore.subscribe()
// Props - 只保留必要的布局相关属性
const props = defineProps<{
width?: number // 可选的宽度,如果父组件需要控制
}>()
// 组件引用
const mainViewRef = ref<HTMLElement>()
// 布局尺寸控制
// 内部管理的布局尺寸
const headerHeight = ref(80)
const timelineHeight = ref(200)
const mainViewHeight = ref(600)
@@ -106,6 +106,11 @@ const timelineResizing = ref<{
startHeight: 0,
})
// 内部管理的状态
const searchQuery = ref('')
const isTimelinePaused = ref(false)
const expandedProcesses = ref<number[]>([])
// 计算ConnectionsTable1的可用高度
const connectionsTableHeight = computed(() => {
const totalHeight = mainViewHeight.value
@@ -113,6 +118,43 @@ const connectionsTableHeight = computed(() => {
return `${Math.max(200, totalHeight - usedHeight)}px`
})
// 过滤后的连接数据
const filteredConnections = computed(() => {
const connections = processInfos.value || []
// 如果有搜索条件,进行过滤
if (searchQuery.value) {
const query = searchQuery.value.toLowerCase()
return connections.filter(process => {
// 搜索进程名
if (process.processName.toLowerCase().includes(query)) {
return true
}
// 搜索连接信息
return process.connections.some(conn =>
conn.localEndpoint.address.includes(query) ||
conn.remoteEndpoint.address.includes(query) ||
conn.localEndpoint.port.toString().includes(query) ||
conn.remoteEndpoint.port.toString().includes(query)
)
})
}
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()
@@ -157,39 +199,28 @@ const updateMainViewHeight = () => {
}
}
// 展开的进程ID列表
const expandedProcesses = ref<number[]>([])
// 事件处理函数
const handleFilter = () => {
console.log('打开过滤器')
}
// 过滤后的连接数据
const filteredConnections = computed(() => {
const connections = processInfos.value || []
const handleRefresh = () => {
console.log('刷新数据')
processStore.refresh?.()
}
// 如果有搜索条件,进行过滤
if (props.searchQuery) {
const query = props.searchQuery.toLowerCase()
return connections.filter(process => {
// 搜索进程名
if (process.processName.toLowerCase().includes(query)) {
return true
}
// 搜索连接信息
return process.connections.some(conn =>
conn.localEndpoint.address.includes(query) ||
conn.remoteEndpoint.address.includes(query) ||
conn.localEndpoint.port.toString().includes(query) ||
conn.remoteEndpoint.port.toString().includes(query)
)
})
}
return connections
})
const handleClearEvents = () => {
console.log('清空事件')
}
// 监听选中应用的变化
watch(selectedApp, (newVal, oldVal) => {
// 进行更新,先把原始数据清空
processStore.clear()
// 重置展开状态
expandedProcesses.value = []
// 清空搜索
searchQuery.value = ''
console.log(newVal.id, '==========')
})
@@ -208,7 +239,6 @@ onMounted(() => {
[isOpen, selectedApp],
([newValue, newValue1]) => {
if (newValue && newValue1 && newValue1.processIds && newValue1.processIds.length > 0) {
// ApplicationType
// 发送请求【请求订阅软件列表】
const subAppInfo: SubscriptionProcessInfo = {
subscriptionType: 'ProcessInfo',
@@ -251,40 +281,6 @@ onUnmounted(() => {
console.error('取消订阅进程信息失败:', err)
})
})
// Props - 移除不再需要的height相关props
const props = defineProps<{
searchQuery: string
connections: Array<unknown>
events: Array<unknown>
}>()
// Emits - 移除resize相关emit
const emit = defineEmits<{
'update:searchQuery': [value: string]
selectConnection: [connection: unknown]
}>()
// Local state
const isMonitoring = ref(true)
const isTimelinePaused = ref(false)
// 处理过滤
const handleFilter = () => {
console.log('打开过滤器')
}
// 处理刷新
const handleRefresh = () => {
console.log('刷新数据')
// 可以在这里触发数据重新加载
processStore.refresh?.()
}
// 清空事件
const handleClearEvents = () => {
console.log('清空事件')
}
</script>
<style scoped>
@@ -392,7 +388,6 @@ const handleClearEvents = () => {
}
/* 响应式设计 */
/* 中等屏幕:隐藏标题和副标题 */
@media (max-width: 1200px) {
.header-info {
display: none;
@@ -407,7 +402,6 @@ const handleClearEvents = () => {
}
}
/* 小屏幕:搜索框开始使用弹性布局 */
@media (max-width: 900px) {
.main-header {
padding: 0 16px;
@@ -432,7 +426,6 @@ const handleClearEvents = () => {
}
}
/* 超小屏幕:进一步优化 */
@media (max-width: 600px) {
.main-header {
padding: 0 12px;
@@ -458,7 +451,6 @@ const handleClearEvents = () => {
}
}
/* 超窄屏幕:只保留搜索框 */
@media (max-width: 480px) {
.filter-buttons {
display: none;
@@ -14,16 +14,7 @@
<!-- 中间主视图区域 -->
<div class="main-panel-wrapper">
<MonitorMainPanel
:headerHeight="mainHeaderHeight"
:timelineHeight="timelineHeight"
:searchQuery="searchQuery"
:connections="mockConnections"
:events="mockEvents"
@update:searchQuery="searchQuery = $event"
@resizeTimeline="startResize('timeline', $event)"
@selectConnection="handleConnectionSelect"
/>
<MonitorMainPanel :width="mainPanelWidth" />
</div>
<!-- 右侧分割线 -->
@@ -33,10 +24,7 @@
<!-- 右侧检查器面板 -->
<div class="inspector-wrapper" :style="{ width: inspectorWidth + 'px' }">
<MonitorInspector
:width="inspectorWidth"
:selectedConnection="selectedConnection"
/>
<MonitorInspector :width="inspectorWidth" />
</div>
</div>
</div>
@@ -47,7 +35,7 @@ defineOptions({
name: 'MonitorView',
})
import { ref, onMounted, onUnmounted, provide } from 'vue'
import { ref, computed, onMounted, onUnmounted } from 'vue'
import MonitorSidebar from './MonitorSidebar.vue'
import MonitorMainPanel from './MonitorMainPanel.vue'
import MonitorInspector from './MonitorInspector.vue'
@@ -55,83 +43,43 @@ import MonitorInspector from './MonitorInspector.vue'
// 布局尺寸控制
const sidebarWidth = ref(400)
const inspectorWidth = ref(350)
const timelineHeight = ref(200)
const mainHeaderHeight = ref(80)
// 调整分割条范围限制
const MIN_SIDEBAR_WIDTH = 200
const MAX_SIDEBAR_WIDTH = 600
const MIN_INSPECTOR_WIDTH = 250
const MAX_INSPECTOR_WIDTH = 650
const MIN_TIMELINE_HEIGHT = 100
const MAX_TIMELINE_HEIGHT = 800
// 响应式数据
const searchQuery = ref('')
const selectedConnection = ref<any>(null)
const mockConnections = ref([
{
id: 1,
process: 'chrome.exe',
localAddress: '192.168.1.100',
remoteAddress: 'google.com',
status: 'established',
traffic: '542 KB/s',
},
// ... 更多连接数据
])
const mockEvents = ref([
{
id: 1,
time: new Date().toLocaleTimeString(),
type: 'connection',
eventType: '连接建立',
description: 'chrome.exe → google.com:443',
},
// ... 更多事件数据
])
// 提供布局配置给子组件
provide('layoutConfig', {
sidebarWidth,
inspectorWidth,
timelineHeight,
mainHeaderHeight,
// 计算主面板的可用宽度
const mainPanelWidth = computed(() => {
// 这里可以根据需要计算,如果不需要传递具体宽度,可以移除这个computed
return window.innerWidth - sidebarWidth.value - inspectorWidth.value - 8 // 8px为分割线宽度
})
// 拖拽状态
const resizing = ref<{
type: 'sidebar' | 'inspector' | 'timeline' | null
type: 'sidebar' | 'inspector' | null
startX: number
startY: number
startWidth: number
startHeight: number
}>({
type: null,
startX: 0,
startY: 0,
startWidth: 0,
startHeight: 0,
})
// 开始拖拽
const startResize = (type: 'sidebar' | 'inspector' | 'timeline', event: MouseEvent) => {
const startResize = (type: 'sidebar' | 'inspector', event: MouseEvent) => {
event.preventDefault()
resizing.value = {
type,
startX: event.clientX,
startY: event.clientY,
startWidth:
type === 'sidebar' ? sidebarWidth.value : type === 'inspector' ? inspectorWidth.value : 0,
startHeight: type === 'timeline' ? timelineHeight.value : 0,
startWidth: type === 'sidebar' ? sidebarWidth.value : inspectorWidth.value,
}
document.addEventListener('mousemove', handleResize)
document.addEventListener('mouseup', stopResize)
document.body.style.cursor = type === 'timeline' ? 'row-resize' : 'col-resize'
document.body.style.cursor = 'col-resize'
document.body.style.userSelect = 'none'
}
@@ -139,7 +87,7 @@ const startResize = (type: 'sidebar' | 'inspector' | 'timeline', event: MouseEve
const handleResize = (event: MouseEvent) => {
if (!resizing.value.type) return
const { type, startX, startY, startWidth, startHeight } = resizing.value
const { type, startX, startWidth } = resizing.value
if (type === 'sidebar') {
const deltaX = event.clientX - startX
@@ -152,13 +100,6 @@ const handleResize = (event: MouseEvent) => {
Math.max(MIN_INSPECTOR_WIDTH, startWidth + deltaX),
)
inspectorWidth.value = newWidth
} else if (type === 'timeline') {
const deltaY = startY - event.clientY
const newHeight = Math.min(
MAX_TIMELINE_HEIGHT,
Math.max(MIN_TIMELINE_HEIGHT, startHeight + deltaY),
)
timelineHeight.value = newHeight
}
}
@@ -171,16 +112,10 @@ const stopResize = () => {
document.body.style.userSelect = ''
}
// 处理连接选中
const handleConnectionSelect = (connection: any) => {
selectedConnection.value = connection
}
// 重置布局
const resetLayout = () => {
sidebarWidth.value = 400
inspectorWidth.value = 350
timelineHeight.value = 200
}
// 键盘快捷键