Skip to content

Commit 2f49d0b

Browse files
committed
feat: 防火墙支持显示端口使用进程
1 parent b541a56 commit 2f49d0b

File tree

3 files changed

+78
-7
lines changed

3 files changed

+78
-7
lines changed

internal/route/http.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ func (route *Http) Register(r *chi.Mux) {
410410
r.Get("/status", route.firewall.GetStatus)
411411
r.Post("/status", route.firewall.UpdateStatus)
412412
r.Get("/rule", route.firewall.GetRules)
413+
r.Get("/rule/port_usage", route.firewall.GetPortUsage)
413414
r.Post("/rule", route.firewall.CreateRule)
414415
r.Delete("/rule", route.firewall.DeleteRule)
415416
r.Get("/ip_rule", route.firewall.GetIPRules)

web/src/api/panel/firewall/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,8 @@ export default {
2525
// 创建防火墙转发规则
2626
createForward: (rule: any): any => http.Post('/firewall/forward', rule),
2727
// 删除防火墙转发规则
28-
deleteForward: (rule: any): any => http.Delete('/firewall/forward', rule)
28+
deleteForward: (rule: any): any => http.Delete('/firewall/forward', rule),
29+
// 获取端口占用进程信息
30+
portUsage: (port: number, protocol: string): any =>
31+
http.Get('/firewall/rule/port_usage', { params: { port, protocol } })
2932
}

web/src/views/firewall/RuleView.vue

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { NButton, NDataTable, NPopconfirm, NTag } from 'naive-ui'
2+
import { NButton, NDataTable, NPopconfirm, NPopover, NSpin, NTag } from 'naive-ui'
33
import { useGettext } from 'vue3-gettext'
44
55
import firewall from '@/api/panel/firewall'
@@ -8,6 +8,23 @@ import CreateModal from '@/views/firewall/CreateModal.vue'
88
const { $gettext } = useGettext()
99
const createModalShow = ref(false)
1010
11+
// 端口进程信息缓存
12+
const portUsageCache = ref<Record<string, any>>({})
13+
const portUsageLoading = ref<Record<string, boolean>>({})
14+
15+
const fetchPortUsage = async (port: number, protocol: string) => {
16+
const key = `${protocol}:${port}`
17+
if (portUsageCache.value[key]) return
18+
portUsageLoading.value[key] = true
19+
try {
20+
const proto = protocol === 'tcp/udp' ? 'tcp' : protocol
21+
const data = await firewall.portUsage(port, proto)
22+
portUsageCache.value[key] = data || []
23+
} finally {
24+
portUsageLoading.value[key] = false
25+
}
26+
}
27+
1128
const columns: any = [
1229
{ type: 'selection', fixed: 'left' },
1330
{
@@ -62,17 +79,67 @@ const columns: any = [
6279
key: 'in_use',
6380
width: 150,
6481
render(row: any): any {
82+
if (!row.in_use) {
83+
return h(NTag, { type: 'default' }, { default: () => $gettext('Not Used') })
84+
}
85+
86+
const key = `${row.protocol}:${row.port_start}`
6587
return h(
66-
NTag,
88+
NPopover,
6789
{
68-
type: row.in_use ? 'success' : 'default'
90+
trigger: 'click',
91+
placement: 'bottom',
92+
onUpdateShow: (show: boolean) => {
93+
if (show) fetchPortUsage(row.port_start, row.protocol)
94+
}
6995
},
7096
{
97+
trigger: () =>
98+
h(
99+
NTag,
100+
{
101+
type: 'success',
102+
style: 'cursor: pointer;'
103+
},
104+
{ default: () => $gettext('In Use') }
105+
),
71106
default: () => {
72-
if (row.in_use) {
73-
return $gettext('In Use')
107+
if (portUsageLoading.value[key]) {
108+
return h(NSpin, { size: 'small', style: 'padding: 12px;' })
109+
}
110+
const processes = portUsageCache.value[key]
111+
if (!processes || processes.length === 0) {
112+
return h('div', { style: 'padding: 4px; color: var(--n-text-color);' }, $gettext('No process information'))
74113
}
75-
return $gettext('Not Used')
114+
return h(
115+
'div',
116+
{ style: 'max-height: 300px; overflow-y: auto;' },
117+
processes.map((p: any, i: number) => {
118+
return h(
119+
'div',
120+
{
121+
style:
122+
i > 0
123+
? 'padding-top: 8px; margin-top: 8px; border-top: 1px solid var(--n-border-color);'
124+
: ''
125+
},
126+
[
127+
h('div', { style: 'font-size: 13px;' }, [
128+
h('span', { style: 'font-weight: bold;' }, `${p.name}`),
129+
h('span', { style: 'margin-left: 8px; opacity: 0.6;' }, `PID: ${p.pid}`)
130+
]),
131+
h(
132+
'div',
133+
{
134+
style:
135+
'font-size: 12px; opacity: 0.8; margin-top: 4px; word-break: break-all; font-family: monospace;'
136+
},
137+
p.command
138+
)
139+
]
140+
)
141+
})
142+
)
76143
}
77144
}
78145
)

0 commit comments

Comments
 (0)