A:缺失文件

This commit is contained in:
jimmy committed 2025-07-30 14:31:06 +08:00
1 parent 8b43fdb11e
commit e265261fa0
3 files changed
+454

No files matched your search

+208
View File
@@ -0,0 +1,208 @@
/**
* 防火墙API服务
*/
import { httpClient } from '@/utils/http'
import type { ApiResponse } from '@/types/http'
import type {
FirewallRule,
CreateRuleRequest,
UpdateRuleRequest,
RuleFilter,
FirewallStatus,
FirewallStatistics,
FirewallRulesResponse,
DisplayRule,
} from '@/types/firewall'
import { RuleDirection, RuleAction, ProtocolType } from '@/types/firewall'
class FirewallApiService {
private readonly baseUrl = '/firewall'
/**
* 获取防火墙规则列表(支持分页和筛选)
*/
async getRules(filter?: RuleFilter): Promise<FirewallRulesResponse> {
const params: Record<string, string> = {}
if (filter) {
if (filter.name) params.name = filter.name
if (filter.direction) params.direction = filter.direction.toString()
if (typeof filter.enabled === 'boolean') params.enabled = filter.enabled.toString()
if (filter.protocol) params.protocol = filter.protocol.toString()
if (filter.action) params.action = filter.action.toString()
if (filter.application) params.application = filter.application
if (filter.port) params.port = filter.port
if (typeof filter.start === 'number') params.start = filter.start.toString()
if (typeof filter.limit === 'number') params.limit = filter.limit.toString()
}
const response = await httpClient.get<FirewallRulesResponse>(`${this.baseUrl}/rules`, params)
return response.data!
}
/**
* 创建防火墙规则
*/
async createRule(rule: CreateRuleRequest): Promise<void> {
await httpClient.post(`${this.baseUrl}/rules`, rule)
}
/**
* 更新防火墙规则
*/
async updateRule(rule: UpdateRuleRequest): Promise<void> {
await httpClient.put(`${this.baseUrl}/rules`, rule)
}
/**
* 删除防火墙规则
*/
async deleteRule(ruleName: string): Promise<void> {
await httpClient.delete(`${this.baseUrl}/rules`, { name: ruleName })
}
/**
* 获取防火墙状态
*/
async getStatus(): Promise<FirewallStatus> {
const response = await httpClient.get<FirewallStatus>(`${this.baseUrl}/status`)
return response.data!
}
/**
* 获取防火墙统计信息
*/
async getStatistics(): Promise<FirewallStatistics> {
const response = await httpClient.get<FirewallStatistics>(`${this.baseUrl}/statistics`)
return response.data!
}
/**
* 转换后端规则数据为前端显示格式
*/
convertToDisplayRule(rule: FirewallRule): DisplayRule {
// 将Profile枚举转换为字符串数组
const profiles: string[] = []
if ((rule.profiles & 1) === 1) profiles.push('域') // Domain
if ((rule.profiles & 2) === 2) profiles.push('专用') // Private
if ((rule.profiles & 4) === 4) profiles.push('公用') // Public
let direction
if (rule.direction === null || rule.direction === undefined) {
direction = RuleDirection.None
} else {
direction = rule.direction === RuleDirection.Inbound ? 'inbound' : 'outbound'
}
return {
id: rule.name, // 使用规则名称作为ID
name: rule.name,
description: rule.description,
enabled: rule.enabled,
direction: direction,
action: rule.action === RuleAction.Allow ? 'allow' : 'block',
program: rule.applicationName || rule.serviceName || '任意',
protocol: this.getProtocolDisplayName(rule.protocol),
port: rule.localPorts || rule.remotePorts || '任意',
profiles,
}
}
/**
* 转换前端显示规则为后端创建请求格式
*/
convertToCreateRequest(displayRule: DisplayRule): CreateRuleRequest {
// 将配置文件字符串数组转换为枚举值
let profiles = 0
displayRule.profiles.forEach((profile) => {
switch (profile) {
case '域':
profiles |= 1
break // Domain
case '专用':
profiles |= 2
break // Private
case '公用':
profiles |= 4
break // Public
}
})
return {
name: displayRule.name,
description: displayRule.description,
direction:
displayRule.direction === 'inbound' ? RuleDirection.Inbound : RuleDirection.Outbound,
action: displayRule.action === 'allow' ? RuleAction.Allow : RuleAction.Block,
enabled: displayRule.enabled,
applicationName: displayRule.program !== '任意' ? displayRule.program : '',
protocol: this.getProtocolTypeFromName(displayRule.protocol),
localPorts: displayRule.port !== '任意' ? displayRule.port : '',
profiles: profiles || 7, // 默认All (Domain | Private | Public)
localAddresses: '*',
remoteAddresses: '*',
}
}
/**
* 获取协议显示名称
*/
private getProtocolDisplayName(protocol: ProtocolType): string {
switch (protocol) {
case ProtocolType.TCP:
return 'TCP'
case ProtocolType.UDP:
return 'UDP'
case ProtocolType.ICMPV4:
return 'ICMP'
case ProtocolType.ICMPv6:
return 'ICMPv6'
case ProtocolType.Any:
return '任意'
default:
return '其他'
}
}
/**
* 从显示名称获取协议类型枚举
*/
private getProtocolTypeFromName(protocolName: string): ProtocolType {
switch (protocolName.toUpperCase()) {
case 'TCP':
return ProtocolType.TCP
case 'UDP':
return ProtocolType.UDP
case 'ICMP':
return ProtocolType.ICMPV4
case 'ICMPV6':
return ProtocolType.ICMPv6
case '任意':
return ProtocolType.Any
default:
return ProtocolType.Any
}
}
/**
* 批量操作规则(启用/禁用/删除)
*/
async batchUpdateRules(
ruleNames: string[],
operation: 'enable' | 'disable' | 'delete',
): Promise<void> {
const promises = ruleNames.map(async (name) => {
switch (operation) {
case 'enable':
return this.updateRule({ currentName: name, enabled: true })
case 'disable':
return this.updateRule({ currentName: name, enabled: false })
case 'delete':
return this.deleteRule(name)
}
})
await Promise.all(promises)
}
}
export const firewallApi = new FirewallApiService()
+193
View File
@@ -0,0 +1,193 @@
/**
* 防火墙相关类型定义
*/
// 防火墙配置文件类型
export enum FirewallProfile {
Domain = 1,
Private = 2,
Public = 4,
All = Domain | Private | Public,
}
// 防火墙规则方向
export enum RuleDirection {
Inbound = 1,
Outbound = 2,
None = -1,
}
// 防火墙规则动作
export enum RuleAction {
Allow = 1,
Block = 0,
}
// 协议类型
export enum ProtocolType {
Any = 256,
ICMPV4 = 1,
IGMP = 2,
TCP = 6,
UDP = 17,
IPv6 = 41,
IPv6Route = 43,
IPv6Frag = 44,
GRE = 47,
ICMPv6 = 58,
IPv6NoNxt = 59,
IPv6Opts = 60,
VRRP = 112,
PGM = 113,
L2TP = 115,
}
// 防火墙规则详细信息
export interface FirewallRule {
name: string
description: string
applicationName: string
serviceName: string
protocol: ProtocolType
localPorts: string
remotePorts: string
localAddresses: string
remoteAddresses: string
icmpTypesAndCodes: string
direction: RuleDirection
enabled: boolean
profiles: FirewallProfile
edgeTraversal: boolean
action: RuleAction
grouping: string
interfaceTypes: string
interfaces: string[]
creationDate?: string
modificationDate?: string
edgeTraversalAllowed: boolean
looseSourceMapping: boolean
localOnlyMapping: boolean
remoteMachineAuthorizationList: string
remoteUserAuthorizationList: string
embeddedContext: string
flags: number
secureFlags: boolean
}
// 创建防火墙规则的请求
export interface CreateRuleRequest {
name: string
description?: string
applicationName?: string
serviceName?: string
protocol?: ProtocolType
localPorts?: string
remotePorts?: string
localAddresses?: string
remoteAddresses?: string
icmpTypesAndCodes?: string
direction: RuleDirection
enabled?: boolean
profiles?: FirewallProfile
action?: RuleAction
grouping?: string
interfaceTypes?: string
interfaces?: string[]
edgeTraversal?: boolean
edgeTraversalAllowed?: boolean
remoteMachineAuthorizationList?: string
remoteUserAuthorizationList?: string
}
// 更新防火墙规则的请求
export interface UpdateRuleRequest {
currentName: string
newName?: string
description?: string
enabled?: boolean
applicationName?: string
serviceName?: string
protocol?: ProtocolType
localPorts?: string
remotePorts?: string
localAddresses?: string
remoteAddresses?: string
profiles?: FirewallProfile
action?: RuleAction
grouping?: string
edgeTraversal?: boolean
}
// 防火墙规则查询过滤器
export interface RuleFilter {
name?: string
direction?: RuleDirection | string
enabled?: boolean
profile?: FirewallProfile
protocol?: ProtocolType | string
action?: RuleAction | string
application?: string
grouping?: string
port?: string
start?: number
limit?: number
}
// 防火墙状态信息
export interface FirewallStatus {
isEnabled: boolean
profileStatuses: Record<string, ProfileStatus>
totalRules: number
enabledRules: number
inboundRules: number
outboundRules: number
lastModified: string
}
// 配置文件状态
export interface ProfileStatus {
profile: FirewallProfile
isEnabled: boolean
blockAllInboundTraffic: boolean
notifyOnListen: boolean
unicastResponsesDisabled: boolean
defaultInboundAction: RuleAction
defaultOutboundAction: RuleAction
}
// 防火墙统计信息
export interface FirewallStatistics {
totalRules: number
enabledRules: number
disabledRules: number
rulesByDirection: Record<string, number>
rulesByProtocol: Record<string, number>
rulesByProfile: Record<string, number>
rulesByAction: Record<string, number>
topApplications: string[]
topPorts: string[]
}
// 防火墙规则查询响应
export interface FirewallRulesResponse {
rules: FirewallRule[]
totalCount: number
startIndex: number
limit: number
hasMore: boolean
}
// 前端显示用的规则接口(兼容现有组件)
export interface DisplayRule {
id: string
name: string
description: string
enabled: boolean
direction: 'inbound' | 'outbound'
action: 'allow' | 'block'
program: string
protocol: string
port: string
profiles: string[]
priority?: number
}
@@ -0,0 +1,53 @@
declare module 'vue-virtual-scroller' {
import { DefineComponent } from 'vue'
export const RecycleScroller: DefineComponent<{
items: any[]
itemSize: number | string
keyField?: string
direction?: 'vertical' | 'horizontal'
listTag?: string
itemTag?: string
listClass?: string | object | any[]
itemClass?: string | object | any[]
gridItems?: number
sizeField?: string
typeField?: string
buffer?: number
pageMode?: boolean
prerender?: number
emitUpdate?: boolean
}>
export const DynamicScroller: DefineComponent<{
items: any[]
minItemSize: number | string
keyField?: string
direction?: 'vertical' | 'horizontal'
listTag?: string
itemTag?: string
listClass?: string | object | any[]
itemClass?: string | object | any[]
buffer?: number
pageMode?: boolean
prerender?: number
emitUpdate?: boolean
}>
export const DynamicScrollerItem: DefineComponent<{
item: any
index: number
active: boolean
sizeDependencies?: any[]
watchData?: boolean
tag?: string
emitResize?: boolean
onResize?: () => void
}>
const plugin: {
install: (app: any, options?: any) => void
}
export default plugin
}