diff --git a/frontend/src/pages/clients/ClientFormModal.vue b/frontend/src/pages/clients/ClientFormModal.vue
index ef6ae622..3547ad8c 100644
--- a/frontend/src/pages/clients/ClientFormModal.vue
+++ b/frontend/src/pages/clients/ClientFormModal.vue
@@ -33,6 +33,7 @@ function emptyForm() {
password: '',
auth: '',
flow: '',
+ reverseTag: '',
totalGB: 0,
expiryTime: null,
limitIp: 0,
@@ -56,6 +57,7 @@ watch(
form.password = props.client.password || '';
form.auth = props.client.auth || '';
form.flow = props.client.flow || '';
+ form.reverseTag = props.client.reverse?.tag || '';
form.totalGB = bytesToGB(props.client.totalGB || 0);
form.expiryTime = props.client.expiryTime ? dayjs(props.client.expiryTime) : null;
form.limitIp = props.client.limitIp || 0;
@@ -110,6 +112,24 @@ watch(showFlow, (next) => {
if (!next) form.flow = '';
});
+const vlessLikeIds = computed(() => {
+ const ids = new Set();
+ for (const row of props.inbounds || []) {
+ if (row && (row.protocol === 'vless' || row.protocol === 'portfallback')) {
+ ids.add(row.id);
+ }
+ }
+ return ids;
+});
+
+const showReverseTag = computed(() =>
+ (form.inboundIds || []).some((id) => vlessLikeIds.value.has(id)),
+);
+
+watch(showReverseTag, (next) => {
+ if (!next) form.reverseTag = '';
+});
+
const clientIps = ref([]);
const ipsLoading = ref(false);
const ipsClearing = ref(false);
@@ -184,6 +204,10 @@ async function onSubmit() {
comment: form.comment,
enable: !!form.enable,
};
+ const reverseTag = showReverseTag.value ? (form.reverseTag || '').trim() : '';
+ if (reverseTag) {
+ clientPayload.reverse = { tag: reverseTag };
+ }
submitting.value = true;
try {
@@ -271,17 +295,6 @@ async function onSubmit() {
-
-
-
-
- none
- {{ k }}
-
-
-
-
-
@@ -295,6 +308,22 @@ async function onSubmit() {
+
+
+
+
+ none
+ {{ k }}
+
+
+
+
+
+
+
+
+
+