mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-07 21:54:10 +00:00
feat: add user email dropdown for inbound clients
This commit is contained in:
parent
2a9d9a0a6b
commit
ec70c4ce07
5 changed files with 45 additions and 3 deletions
|
|
@ -13,7 +13,19 @@
|
||||||
<a-icon type="sync" @click="client.email = RandomUtil.randomLowerAndNum(9)"></a-icon>
|
<a-icon type="sync" @click="client.email = RandomUtil.randomLowerAndNum(9)"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<a-input v-model.trim="client.email"></a-input>
|
<a-select
|
||||||
|
v-model="client.email"
|
||||||
|
mode="combobox"
|
||||||
|
show-search
|
||||||
|
allow-clear
|
||||||
|
:filter-option="filterEmailOption"
|
||||||
|
:dropdown-class-name="themeSwitcher.currentTheme"
|
||||||
|
:not-found-content="emailOptions.length === 0 ? null : undefined"
|
||||||
|
:placeholder='{{ printf "%q" (i18n "pages.inbounds.emailSelectPlaceholder") }}'>
|
||||||
|
<a-select-option v-for="email in emailOptions" :key="email" :value="email">
|
||||||
|
[[ email ]]
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="inbound.protocol === Protocols.TROJAN || inbound.protocol === Protocols.SHADOWSOCKS">
|
<a-form-item v-if="inbound.protocol === Protocols.TROJAN || inbound.protocol === Protocols.SHADOWSOCKS">
|
||||||
<template slot="label">
|
<template slot="label">
|
||||||
|
|
@ -169,4 +181,4 @@
|
||||||
<a-input-number v-model.number="client.reset" :min="0"></a-input-number>
|
<a-input-number v-model.number="client.reset" :min="0"></a-input-number>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
||||||
|
|
@ -741,6 +741,9 @@
|
||||||
showAlert: false,
|
showAlert: false,
|
||||||
ipLimitEnable: false,
|
ipLimitEnable: false,
|
||||||
pageSize: 0,
|
pageSize: 0,
|
||||||
|
isAdmin: {{if .is_admin}}true{{else}}false{{end}},
|
||||||
|
currentUsername: {{ printf "%q" .current_username }},
|
||||||
|
clientEmailOptions: [],
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loading(spinning = true) {
|
loading(spinning = true) {
|
||||||
|
|
@ -798,6 +801,18 @@
|
||||||
this.ipLimitEnable = ipLimitEnable;
|
this.ipLimitEnable = ipLimitEnable;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async getClientEmailOptions() {
|
||||||
|
if (this.isAdmin) {
|
||||||
|
const msg = await HttpUtil.get('/panel/api/users/list');
|
||||||
|
if (msg.success && Array.isArray(msg.obj)) {
|
||||||
|
this.clientEmailOptions = msg.obj
|
||||||
|
.map(user => user?.username || '')
|
||||||
|
.filter(Boolean);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.clientEmailOptions = this.currentUsername ? [this.currentUsername] : [];
|
||||||
|
},
|
||||||
setInbounds(dbInbounds) {
|
setInbounds(dbInbounds) {
|
||||||
this.inbounds.splice(0);
|
this.inbounds.splice(0);
|
||||||
this.dbInbounds.splice(0);
|
this.dbInbounds.splice(0);
|
||||||
|
|
@ -1587,6 +1602,7 @@
|
||||||
}
|
}
|
||||||
this.loading();
|
this.loading();
|
||||||
this.getDefaultSettings();
|
this.getDefaultSettings();
|
||||||
|
this.getClientEmailOptions();
|
||||||
|
|
||||||
// Initial data fetch
|
// Initial data fetch
|
||||||
this.getDBInbounds().then(() => {
|
this.getDBInbounds().then(() => {
|
||||||
|
|
@ -1697,4 +1713,4 @@
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{{ template "page/body_end" .}}
|
{{ template "page/body_end" .}}
|
||||||
|
|
|
||||||
|
|
@ -118,8 +118,20 @@
|
||||||
set delayedExpireDays(days) {
|
set delayedExpireDays(days) {
|
||||||
this.client.expiryTime = -86400000 * days;
|
this.client.expiryTime = -86400000 * days;
|
||||||
},
|
},
|
||||||
|
get emailOptions() {
|
||||||
|
const options = Array.isArray(app.clientEmailOptions) ? [...app.clientEmailOptions] : [];
|
||||||
|
const email = this.client?.email;
|
||||||
|
if (email && !options.includes(email)) {
|
||||||
|
options.unshift(email);
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
filterEmailOption(input, option) {
|
||||||
|
const value = String(option.componentOptions?.propsData?.value || '').toLowerCase();
|
||||||
|
return value.includes(String(input || '').toLowerCase());
|
||||||
|
},
|
||||||
async getDBClientIps(email) {
|
async getDBClientIps(email) {
|
||||||
const msg = await HttpUtil.post(`/panel/api/inbounds/clientIps/${email}`);
|
const msg = await HttpUtil.post(`/panel/api/inbounds/clientIps/${email}`);
|
||||||
if (!msg.success) {
|
if (!msg.success) {
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@
|
||||||
"delDepletedClientsTitle" = "Delete Depleted Clients"
|
"delDepletedClientsTitle" = "Delete Depleted Clients"
|
||||||
"delDepletedClientsContent" = "Are you sure you want to delete all the depleted clients?"
|
"delDepletedClientsContent" = "Are you sure you want to delete all the depleted clients?"
|
||||||
"email" = "Email"
|
"email" = "Email"
|
||||||
|
"emailSelectPlaceholder" = "Type an email or select a user from the list"
|
||||||
"emailDesc" = "Please provide a unique email address."
|
"emailDesc" = "Please provide a unique email address."
|
||||||
"IPLimit" = "IP Limit"
|
"IPLimit" = "IP Limit"
|
||||||
"IPLimitDesc" = "Disables inbound if the count exceeds the set value. (0 = disable)"
|
"IPLimitDesc" = "Disables inbound if the count exceeds the set value. (0 = disable)"
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@
|
||||||
"delDepletedClientsTitle" = "删除流量耗尽的客户端"
|
"delDepletedClientsTitle" = "删除流量耗尽的客户端"
|
||||||
"delDepletedClientsContent" = "确定要删除所有流量耗尽的客户端吗?"
|
"delDepletedClientsContent" = "确定要删除所有流量耗尽的客户端吗?"
|
||||||
"email" = "电子邮件"
|
"email" = "电子邮件"
|
||||||
|
"emailSelectPlaceholder" = "可输入邮箱,也可从用户列表中选择"
|
||||||
"emailDesc" = "电子邮件必须完全唯一"
|
"emailDesc" = "电子邮件必须完全唯一"
|
||||||
"IPLimit" = "IP 限制"
|
"IPLimit" = "IP 限制"
|
||||||
"IPLimitDesc" = "如果数量超过设置值,则禁用入站流量。(0 = 禁用)"
|
"IPLimitDesc" = "如果数量超过设置值,则禁用入站流量。(0 = 禁用)"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue