diff --git a/frontend/src/pages/xray/RoutingTab.vue b/frontend/src/pages/xray/RoutingTab.vue
new file mode 100644
index 00000000..8687bec5
--- /dev/null
+++ b/frontend/src/pages/xray/RoutingTab.vue
@@ -0,0 +1,401 @@
+
+
+
+
+
+
+ Add rule
+
+
+
+
+
+
+
+
{{ index + 1 }}
+
+
+
+
+
+
+
+ Edit
+
+
+ Move up
+
+
+ Move down
+
+
+ Delete
+
+
+
+
+
+
+
+
+
+
+
+
+ IP
+ {{ csv(record.sourceIP)[0] }}
+ +{{ csv(record.sourceIP).length - 1 }}
+
+
+
+
+ Port
+ {{ csv(record.sourcePort)[0] }}
+ +{{ csv(record.sourcePort).length - 1 }}
+
+
+
+
+ VLESS
+ {{ csv(record.vlessRoute)[0] }}
+ +{{ csv(record.vlessRoute).length - 1 }}
+
+
+
—
+
+
+
+
+
+
+
+
+ L4
+ {{ csv(record.network)[0] }}
+ +{{ csv(record.network).length - 1 }}
+
+
+
+
+ Protocol
+ {{ csv(record.protocol)[0] }}
+ +{{ csv(record.protocol).length - 1 }}
+
+
+
+
+ Attrs
+ {{ csv(record.attrs)[0] }}
+
+
+
—
+
+
+
+
+
+
+
+
+ IP
+ {{ csv(record.ip)[0] }}
+ +{{ csv(record.ip).length - 1 }}
+
+
+
+
+ Domain
+ {{ csv(record.domain)[0] }}
+ +{{ csv(record.domain).length - 1 }}
+
+
+
+
+ Port
+ {{ csv(record.port)[0] }}
+ +{{ csv(record.port).length - 1 }}
+
+
+
—
+
+
+
+
+
+
+
+
+ Tag
+ {{ csv(record.inboundTag)[0] }}
+ +{{ csv(record.inboundTag).length - 1 }}
+
+
+
+
+ User
+ {{ csv(record.user)[0] }}
+ +{{ csv(record.user).length - 1 }}
+
+
+
—
+
+
+
+
+
+
+
+
+
{{ record.outboundTag }}
+
+
+
+
{{ record.balancerTag }}
+
+
—
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/pages/xray/RuleFormModal.vue b/frontend/src/pages/xray/RuleFormModal.vue
new file mode 100644
index 00000000..0f10ac47
--- /dev/null
+++ b/frontend/src/pages/xray/RuleFormModal.vue
@@ -0,0 +1,254 @@
+
+
+
+
+
+
+
+
+ Source IPs
+
+
+
+
+
+
+
+
+ Source port
+
+
+
+
+
+
+
+
+ VLESS route
+
+
+
+
+
+
+
+ {{ n || '(any)' }}
+
+
+
+
+
+ {{ p }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ idx + 1 }}
+
+
+
+
+
+
+
+
+
+
+ IP
+
+
+
+
+
+
+ Domain
+
+
+
+
+
+
+ User
+
+
+
+
+
+
+ Port
+
+
+
+
+
+
+ {{ t }}
+
+
+
+
+
+ {{ t || '(none)' }}
+
+
+
+
+
+
+ Balancer tag
+
+
+
+ {{ t || '(none)' }}
+
+
+
+
+
+
+
diff --git a/frontend/src/pages/xray/XrayPage.vue b/frontend/src/pages/xray/XrayPage.vue
index 71ddb73e..e9888e8e 100644
--- a/frontend/src/pages/xray/XrayPage.vue
+++ b/frontend/src/pages/xray/XrayPage.vue
@@ -16,6 +16,7 @@ import { useMediaQuery } from '@/composables/useMediaQuery.js';
import { message } from 'ant-design-vue';
import AppSidebar from '@/components/AppSidebar.vue';
import BasicsTab from './BasicsTab.vue';
+import RoutingTab from './RoutingTab.vue';
import { useXraySetting } from './useXraySetting.js';
// Phase 6-i: scaffold + advanced JSON tab. Other tabs (Basics, Routing,
@@ -36,6 +37,8 @@ const {
xraySetting,
templateSettings,
outboundTestUrl,
+ inboundTags,
+ clientReverseTags,
restartResult,
saveAll,
restartXray,
@@ -140,7 +143,12 @@ function confirmRestart() {
Routing
-
+