mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 12:44:22 +00:00
feat(clients): add Reverse tag field for VLESS-attached clients
Mirrors the Flow field's pattern: a Reverse tag input appears in the
Add/Edit Client modal whenever at least one selected inbound is VLESS
or PortFallback. The value rides over the wire as
client.reverse = { tag: '...' } so it lands directly in model.Client's
*ClientReverse field; an empty value omits the reverse key entirely.
On edit the field is hydrated from props.client.reverse?.tag, and the
showReverseTag watcher clears the field if the user drops the last
VLESS-like inbound from the selection.
This commit is contained in:
parent
e9fce827ac
commit
cfd8cc3cbb
1 changed files with 40 additions and 11 deletions
|
|
@ -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() {
|
|||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row v-if="showFlow" :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="Flow">
|
||||
<a-select v-model:value="form.flow">
|
||||
<a-select-option value="">none</a-select-option>
|
||||
<a-select-option v-for="k in FLOW_OPTIONS" :key="k" :value="k">{{ k }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item :label="t('pages.clients.totalGB') || 'Total (GB, 0 = unlimited)'">
|
||||
|
|
@ -295,6 +308,22 @@ async function onSubmit() {
|
|||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row v-if="showFlow || showReverseTag" :gutter="16">
|
||||
<a-col v-if="showFlow" :span="12">
|
||||
<a-form-item label="Flow">
|
||||
<a-select v-model:value="form.flow">
|
||||
<a-select-option value="">none</a-select-option>
|
||||
<a-select-option v-for="k in FLOW_OPTIONS" :key="k" :value="k">{{ k }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="showReverseTag" :span="12">
|
||||
<a-form-item label="Reverse tag">
|
||||
<a-input v-model:value="form.reverseTag" placeholder="Optional reverse tag" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item :label="t('pages.clients.comment') || 'Comment'">
|
||||
<a-input v-model:value="form.comment" />
|
||||
</a-form-item>
|
||||
|
|
|
|||
Loading…
Reference in a new issue