feat: add user email dropdown for inbound clients

This commit is contained in:
Sora39831 2026-04-04 15:05:37 +08:00
parent 2a9d9a0a6b
commit ec70c4ce07
5 changed files with 45 additions and 3 deletions

View file

@ -13,7 +13,19 @@
<a-icon type="sync" @click="client.email = RandomUtil.randomLowerAndNum(9)"></a-icon>
</a-tooltip>
</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 v-if="inbound.protocol === Protocols.TROJAN || inbound.protocol === Protocols.SHADOWSOCKS">
<template slot="label">
@ -169,4 +181,4 @@
<a-input-number v-model.number="client.reset" :min="0"></a-input-number>
</a-form-item>
</a-form>
{{end}}
{{end}}

View file

@ -741,6 +741,9 @@
showAlert: false,
ipLimitEnable: false,
pageSize: 0,
isAdmin: {{if .is_admin}}true{{else}}false{{end}},
currentUsername: {{ printf "%q" .current_username }},
clientEmailOptions: [],
},
methods: {
loading(spinning = true) {
@ -798,6 +801,18 @@
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) {
this.inbounds.splice(0);
this.dbInbounds.splice(0);
@ -1587,6 +1602,7 @@
}
this.loading();
this.getDefaultSettings();
this.getClientEmailOptions();
// Initial data fetch
this.getDBInbounds().then(() => {
@ -1697,4 +1713,4 @@
},
});
</script>
{{ template "page/body_end" .}}
{{ template "page/body_end" .}}

View file

@ -118,8 +118,20 @@
set delayedExpireDays(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: {
filterEmailOption(input, option) {
const value = String(option.componentOptions?.propsData?.value || '').toLowerCase();
return value.includes(String(input || '').toLowerCase());
},
async getDBClientIps(email) {
const msg = await HttpUtil.post(`/panel/api/inbounds/clientIps/${email}`);
if (!msg.success) {

View file

@ -241,6 +241,7 @@
"delDepletedClientsTitle" = "Delete Depleted Clients"
"delDepletedClientsContent" = "Are you sure you want to delete all the depleted clients?"
"email" = "Email"
"emailSelectPlaceholder" = "Type an email or select a user from the list"
"emailDesc" = "Please provide a unique email address."
"IPLimit" = "IP Limit"
"IPLimitDesc" = "Disables inbound if the count exceeds the set value. (0 = disable)"

View file

@ -241,6 +241,7 @@
"delDepletedClientsTitle" = "删除流量耗尽的客户端"
"delDepletedClientsContent" = "确定要删除所有流量耗尽的客户端吗?"
"email" = "电子邮件"
"emailSelectPlaceholder" = "可输入邮箱,也可从用户列表中选择"
"emailDesc" = "电子邮件必须完全唯一"
"IPLimit" = "IP 限制"
"IPLimitDesc" = "如果数量超过设置值则禁用入站流量。0 = 禁用)"