A:调整构建
This commit is contained in:
1 parent
4d60f349df
commit
59367c7880
15 files changed
+156
-54
No files matched your search
@@ -5,7 +5,8 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p type-check \"build-only {@}\" --",
|
||||
"build": "vite build",
|
||||
"build-with-types": "run-p type-check \"build-only {@}\" --",
|
||||
"preview": "vite preview",
|
||||
"test:unit": "vitest",
|
||||
"build-only": "vite build",
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ref, onMounted, provide } from 'vue'
|
||||
import { NButton } from 'naive-ui'
|
||||
import { NConfigProvider, NGlobalStyle, NMessageProvider, NLoadingBarProvider, NDialogProvider } from 'naive-ui'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
import NetworkConnectionPanel1 from '@/components/NetworkConnectionPanel1.vue'
|
||||
import NetworkConnectionPanel2 from '@/components/NetworkConnectionPanel2.vue'
|
||||
import MainLayout from './layouts/MainLayout.vue'
|
||||
|
||||
const router = useRouter()
|
||||
@@ -30,7 +30,7 @@ const route = useRoute()
|
||||
// 子路由列表
|
||||
const subRouteLists: subRouteList = []
|
||||
// 遍历路由page列表进行路由渲染
|
||||
Object.keys(routes).map((path) => {
|
||||
Object.keys(routes).map((path: string) => {
|
||||
if ('.vue' === PathUtils.extname(path).trim()) {
|
||||
const fileName = PathUtils.basename(path).split('.')[0]
|
||||
const s = StringUtils.toCustomCase(fileName).toLowerCase().split('-')[0]
|
||||
@@ -88,12 +88,13 @@ const navPosition = ref({ x: 10, y: 10 }) // 默认位置
|
||||
const dragOffset = ref({ x: 0, y: 0 })
|
||||
|
||||
// 拖拽相关函数
|
||||
function startDrag(event) {
|
||||
function startDrag(event: MouseEvent) {
|
||||
if (event.target.closest('.drag-handle')) {
|
||||
isDragging.value = true
|
||||
|
||||
// 计算鼠标与元素左上角的偏移量
|
||||
const navElement = navRef.value
|
||||
if (!navElement) return
|
||||
const rect = navElement.getBoundingClientRect()
|
||||
dragOffset.value = {
|
||||
x: event.clientX - rect.left,
|
||||
@@ -105,7 +106,7 @@ function startDrag(event) {
|
||||
}
|
||||
}
|
||||
|
||||
function onDrag(event) {
|
||||
function onDrag(event: MouseEvent) {
|
||||
if (isDragging.value) {
|
||||
// 计算新位置
|
||||
navPosition.value = {
|
||||
|
||||
@@ -17,11 +17,11 @@ const bridge = CSharpBridgeV2.getBridge()
|
||||
|
||||
const useWebSocket = useWebSocketStore()
|
||||
|
||||
const newVar = (data) => {
|
||||
logN.warning('后端返回的参数', module.name, data)
|
||||
module.result = JSON.stringify(data, null, 2)
|
||||
const newVar = (data: any) => {
|
||||
logN.warning('后端返回的参数', modules.value[0]?.name, data)
|
||||
modules.value[0].result = JSON.stringify(data, null, 2)
|
||||
|
||||
useWebSocket.unsubscribe(module.name)
|
||||
useWebSocket.unsubscribe(modules.value[0]?.name)
|
||||
}
|
||||
/**
|
||||
* 指令触发
|
||||
@@ -36,12 +36,12 @@ const invokeCommand = async (module: CommandType) => {
|
||||
useWebSocket.send(module.name)
|
||||
} else {
|
||||
try {
|
||||
bridge.send(module.name, params, (data) => {
|
||||
bridge?.send(module.name, params, (data: any) => {
|
||||
logN.warning('后端返回的参数', module.name, data)
|
||||
module.result = JSON.stringify(data, null, 2)
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(err)
|
||||
console.error(error)
|
||||
module.result = `Error: ${error}`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,8 +223,8 @@ import {
|
||||
NButton,
|
||||
NIcon,
|
||||
NSpace,
|
||||
FormInst,
|
||||
FormRules,
|
||||
type FormInst,
|
||||
type FormRules,
|
||||
useMessage,
|
||||
} from 'naive-ui'
|
||||
import {
|
||||
|
||||
@@ -200,9 +200,9 @@ const loadRule = async () => {
|
||||
if (loadedRule) {
|
||||
rule.value = loadedRule
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
// 忽略取消错误
|
||||
if (error.name !== 'AbortError' && !error.message?.includes('Cancel')) {
|
||||
if (error?.name !== 'AbortError' && !error?.message?.includes('Cancel')) {
|
||||
console.error('加载规则失败:', error)
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -69,14 +69,14 @@ const tabConfig = [
|
||||
]
|
||||
|
||||
// 根据当前路由设置激活的Tab
|
||||
const activeTab = ref(route.name || 'monitor')
|
||||
const activeTab = ref(String(route.name) || 'monitor')
|
||||
|
||||
// 监听路由变化,同步Tab状态
|
||||
watch(
|
||||
() => route.name,
|
||||
(newRouteName) => {
|
||||
if (newRouteName) {
|
||||
activeTab.value = newRouteName
|
||||
activeTab.value = String(newRouteName)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { MessagePayload } from '@/correspond/IBridge'
|
||||
import CSharpBridge from '@/correspond/CSharpBridge'
|
||||
import TauriBridge from '@/correspond/TauriBridge'
|
||||
import type { MessagePayload } from '@/correspond/IBridge'
|
||||
import { CSharpBridge } from '@/correspond/CSharpBridge'
|
||||
import { TauriBridge } from '@/correspond/TauriBridge'
|
||||
|
||||
type MessagePayload<T> = {
|
||||
interface BridgeMessagePayload<T = any> {
|
||||
channel: string
|
||||
payload: T
|
||||
}
|
||||
@@ -11,12 +11,13 @@ class CSharpBridgeV2 {
|
||||
private static CSBridge: CSharpBridgeV2 | null = null
|
||||
|
||||
static getBridge(): CSharpBridgeV2 | null {
|
||||
if (CSharpBridgeV2.CSBridge === null || CSharpBridgeV2.CSBridge.CSBridge === undefined) {
|
||||
if (CSharpBridgeV2.CSBridge === null) {
|
||||
if (window.chrome && window.chrome.webview) {
|
||||
// window.chrome.webview.postMessage("hello");
|
||||
CSharpBridgeV2.CSBridge = new CSharpBridgeV2()
|
||||
window.externalFunctions.__BRIDGE_LISTEN__ = CSharpBridgeV2.CSBridge.bridgeInvoke
|
||||
window.externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__ = new Map()
|
||||
;(window as any).externalFunctions = (window as any).externalFunctions || {}
|
||||
;(window as any).externalFunctions.__BRIDGE_LISTEN__ = CSharpBridgeV2.CSBridge.bridgeInvoke
|
||||
;(window as any).externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__ = new Map()
|
||||
} else {
|
||||
console.error('Not running in WebView2 environment')
|
||||
}
|
||||
@@ -25,10 +26,10 @@ class CSharpBridgeV2 {
|
||||
}
|
||||
|
||||
bridgeInvoke(channel: string, json: string) {
|
||||
const bridgeListenFunctions = window.externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__
|
||||
const bridgeListenFunctions = (window as any).externalFunctions?.__BRIDGE_LISTEN__FUNCTIONS__
|
||||
const listeners = bridgeListenFunctions.get(channel)
|
||||
if (listeners) {
|
||||
listeners.forEach((listener) => {
|
||||
listeners.forEach((listener: any) => {
|
||||
try {
|
||||
listener.callback(json)
|
||||
if (listener.once && CSharpBridgeV2.CSBridge) {
|
||||
@@ -42,23 +43,25 @@ class CSharpBridgeV2 {
|
||||
}
|
||||
|
||||
// 发送消息到后端
|
||||
send<T, V>(channel: string, data?: T | null = null, callback: ((data: V) => void) | null = null) {
|
||||
const obj: MessagePayload = {
|
||||
send<T, V>(channel: string, data: T | null = null, callback: ((data: V) => void) | null = null) {
|
||||
const obj: BridgeMessagePayload<T> = {
|
||||
channel,
|
||||
payload: data,
|
||||
}
|
||||
if (callback !== null && callback !== undefined) {
|
||||
this.listen(channel, callback, true)
|
||||
}
|
||||
window.chrome.webview.postMessage(obj)
|
||||
if (window.chrome?.webview) {
|
||||
window.chrome.webview.postMessage(obj)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听后端消息
|
||||
*/
|
||||
listen<V>(channel: string, callback: (data: V) => void, once: boolean = false) {
|
||||
const bridgeListenFunctions = window.externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__
|
||||
if (!bridgeListenFunctions.has(channel)) {
|
||||
const bridgeListenFunctions = (window as any).externalFunctions?.__BRIDGE_LISTEN__FUNCTIONS__
|
||||
if (!bridgeListenFunctions?.has(channel)) {
|
||||
bridgeListenFunctions.set(channel, new Set())
|
||||
}
|
||||
|
||||
@@ -70,12 +73,12 @@ class CSharpBridgeV2 {
|
||||
|
||||
// 移除指定通道的所有监听器
|
||||
off(channel: string) {
|
||||
window.externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__.delete(channel)
|
||||
;(window as any).externalFunctions?.__BRIDGE_LISTEN__FUNCTIONS__?.delete(channel)
|
||||
}
|
||||
|
||||
// 移除特定监听器
|
||||
removeListen(channel: string, listener: unknown) {
|
||||
const bridgeListenFunctions = window.externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__
|
||||
const bridgeListenFunctions = (window as any).externalFunctions?.__BRIDGE_LISTEN__FUNCTIONS__
|
||||
const channelListeners = bridgeListenFunctions.get(channel)
|
||||
if (channelListeners) {
|
||||
// 需要类型转换以匹配存储的监听器类型
|
||||
@@ -89,3 +92,14 @@ class CSharpBridgeV2 {
|
||||
}
|
||||
|
||||
export default CSharpBridgeV2
|
||||
|
||||
// 扩展 Window 接口
|
||||
declare global {
|
||||
interface Window {
|
||||
chrome?: {
|
||||
webview?: {
|
||||
postMessage: (data: any) => void
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,15 +4,8 @@ import {
|
||||
type RouteComponent,
|
||||
type RouteRecordRaw,
|
||||
} from 'vue-router'
|
||||
import HomeView from '../views/HomeView.vue'
|
||||
import DevIndex from '@/views/dev/DevIndex.vue'
|
||||
import StringUtils from '@/utils/stringUtils'
|
||||
import PathUtils from '@/utils/pathUtils'
|
||||
import NotFound from '@/views/NotFoundView.vue'
|
||||
import AboutView from '@/views/AboutView.vue'
|
||||
import FirewallView from '@/views/FirewallView.vue'
|
||||
import AnalyseView from '@/views/AnalyseView/AnalyseView.vue'
|
||||
import MonitorView from '@/views/MonitorView/index.vue'
|
||||
|
||||
// 导入所有 .vue 文件
|
||||
const routes = import.meta.glob('@/views/dev/**/*.vue')
|
||||
@@ -51,11 +44,11 @@ const router = createRouter({
|
||||
{
|
||||
path: '/home',
|
||||
name: 'home',
|
||||
component: HomeView,
|
||||
component: () => import('../views/HomeView.vue'),
|
||||
children: [
|
||||
{
|
||||
path: '/', // 捕获所有其他路径
|
||||
component: NotFound, // 任何其他路径都跳转到默认页面
|
||||
component: () => import('@/views/NotFoundView.vue'), // 任何其他路径都跳转到默认页面
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -63,39 +56,39 @@ const router = createRouter({
|
||||
{
|
||||
path: '/monitor',
|
||||
name: 'monitor',
|
||||
component: MonitorView,
|
||||
component: () => import('@/views/MonitorView/index.vue'),
|
||||
meta: { layout: 'main' },
|
||||
},
|
||||
// 防火墙
|
||||
{
|
||||
path: '/firewall',
|
||||
name: 'firewall',
|
||||
component: FirewallView,
|
||||
component: () => import('@/views/FirewallView.vue'),
|
||||
meta: { layout: 'main' },
|
||||
},
|
||||
// 网络分析
|
||||
{
|
||||
path: '/analyse',
|
||||
name: 'analyse',
|
||||
component: AnalyseView,
|
||||
component: () => import('@/views/AnalyseView/AnalyseView.vue'),
|
||||
meta: { layout: 'main' },
|
||||
},
|
||||
|
||||
{
|
||||
path: '/dev',
|
||||
name: 'dev',
|
||||
component: DevIndex,
|
||||
component: () => import('@/views/dev/DevIndex.vue'),
|
||||
children: [...devPageViews],
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
component: AboutView,
|
||||
component: () => import('@/views/AboutView.vue'),
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*', // 通配符路由
|
||||
name: 'NotFound',
|
||||
component: NotFound,
|
||||
component: () => import('@/views/NotFoundView.vue'),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -164,3 +164,18 @@ export interface FirewallStatistics {
|
||||
topApplications: string[]
|
||||
topPorts: string[]
|
||||
}
|
||||
|
||||
// 显示用的规则类型(简化版本)
|
||||
export interface DisplayRule {
|
||||
id: string
|
||||
name: string
|
||||
description?: string
|
||||
enabled: boolean
|
||||
direction: RuleDirection
|
||||
action: RuleAction
|
||||
program: string
|
||||
protocol: string
|
||||
port: string
|
||||
profiles: string[]
|
||||
grouping?: string
|
||||
}
|
||||
@@ -20,6 +20,7 @@ export interface FirewallRuleShow {
|
||||
protocol: string
|
||||
port: string
|
||||
profiles: string[]
|
||||
grouping?: string
|
||||
}
|
||||
|
||||
export interface FirewallRuleResponse {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||
"exclude": ["src/**/__tests__/*"],
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
|
||||
"paths": {
|
||||
|
||||
@@ -29,9 +29,10 @@
|
||||
// 加载 Node 和 Vite 类型声明
|
||||
"types": [
|
||||
"vite/client",
|
||||
"node",
|
||||
"element-plus/global"
|
||||
]
|
||||
"node"
|
||||
],
|
||||
"skipLibCheck": true,
|
||||
"verbatimModuleSyntax": false
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"eslint.config.*"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"composite": true,
|
||||
"noEmit": false,
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||
|
||||
"module": "ESNext",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"include": ["src/**/__tests__/*", "env.d.ts"],
|
||||
"exclude": [],
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
|
||||
|
||||
"lib": [],
|
||||
|
||||
@@ -26,10 +26,14 @@ export default defineConfig(({ mode }) => {
|
||||
'useLoadingBar'
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
// 生成类型声明文件
|
||||
dts: true
|
||||
}),
|
||||
Components({
|
||||
resolvers: [NaiveUiResolver()]
|
||||
resolvers: [NaiveUiResolver()],
|
||||
// 生成类型声明文件
|
||||
dts: true
|
||||
})
|
||||
],
|
||||
// 防止 Vite 掩盖 Rust 错误
|
||||
@@ -42,6 +46,75 @@ export default defineConfig(({ mode }) => {
|
||||
},
|
||||
},
|
||||
build: {
|
||||
// 打包优化配置
|
||||
rollupOptions: {
|
||||
output: {
|
||||
// 手动分割 chunks
|
||||
manualChunks: (id) => {
|
||||
// node_modules 中的第三方库
|
||||
if (id.includes('node_modules')) {
|
||||
// Vue 生态
|
||||
if (id.includes('vue') || id.includes('vue-router') || id.includes('pinia')) {
|
||||
return 'vue-vendor'
|
||||
}
|
||||
// UI 库
|
||||
if (id.includes('naive-ui')) {
|
||||
return 'ui-vendor'
|
||||
}
|
||||
// 图表相关
|
||||
if (id.includes('echarts') || id.includes('vue-echarts')) {
|
||||
return 'charts-vendor'
|
||||
}
|
||||
// 图标库
|
||||
if (id.includes('@vicons') || id.includes('vicons')) {
|
||||
return 'icons-vendor'
|
||||
}
|
||||
// 其他第三方库
|
||||
if (id.includes('axios') || id.includes('lodash') || id.includes('gsap') || id.includes('pako')) {
|
||||
return 'utils-vendor'
|
||||
}
|
||||
// 其他 node_modules
|
||||
return 'vendor'
|
||||
}
|
||||
// 业务代码分割
|
||||
if (id.includes('src/views')) {
|
||||
return 'views'
|
||||
}
|
||||
if (id.includes('src/components')) {
|
||||
return 'components'
|
||||
}
|
||||
},
|
||||
// 资产文件名称策略
|
||||
assetFileNames: (assetInfo) => {
|
||||
const info = assetInfo.name.split('.')
|
||||
const ext = info[info.length - 1]
|
||||
if (/\.(png|jpe?g|gif|svg|webp|ico)$/.test(assetInfo.name)) {
|
||||
return 'assets/images/[name].[hash][extname]'
|
||||
} else if (/\.(woff2?|eot|ttf|otf)$/.test(assetInfo.name)) {
|
||||
return 'assets/fonts/[name].[hash][extname]'
|
||||
}
|
||||
return `assets/[ext]/[name].[hash][extname]`
|
||||
},
|
||||
// 入口文件名称
|
||||
entryFileNames: 'assets/js/[name].[hash].js',
|
||||
// chunk 文件名称
|
||||
chunkFileNames: 'assets/js/[name].[hash].js'
|
||||
}
|
||||
},
|
||||
// 压缩配置
|
||||
minify: 'esbuild',
|
||||
// 移除控制台输出
|
||||
esbuild: {
|
||||
drop: ['console', 'debugger']
|
||||
},
|
||||
// 警告阈值
|
||||
chunkSizeWarningLimit: 1000,
|
||||
// CSS 代码分割
|
||||
cssCodeSplit: true,
|
||||
// 生成 source map
|
||||
sourcemap: false,
|
||||
// 资产内联阈值
|
||||
assetsInlineLimit: 4096
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
|
||||
Reference in new issue
Block a user