{{define "clientsBulkModal"}} <a-modal id="client-bulk-modal" v-model="clientsBulkModal.visible" :title="clientsBulkModal.title" @ok="clientsBulkModal.ok" :confirm-loading="clientsBulkModal.confirmLoading" :closable="true" :mask-closable="false" :class="themeSwitcher.darkCardClass" :ok-text="clientsBulkModal.okText" cancel-text='{{ i18n "close" }}'> <a-form layout="inline"> <a-form-item label='{{ i18n "pages.client.method" }}'> <a-select v-model="clientsBulkModal.emailMethod" buttonStyle="solid" style="width: 350px" :dropdown-class-name="themeSwitcher.darkCardClass"> <a-select-option :value="0">Random</a-select-option> <a-select-option :value="1">Random+Prefix</a-select-option> <a-select-option :value="2">Random+Prefix+Num</a-select-option> <a-select-option :value="3">Random+Prefix+Num+Postfix</a-select-option> <a-select-option :value="4">Prefix+Num+Postfix [ BE CAREFUL! ]</a-select-option> </a-select> </a-form-item><br /> <a-form-item v-if="clientsBulkModal.emailMethod>1"> <span slot="label">{{ i18n "pages.client.first" }}</span> <a-input-number v-model="clientsBulkModal.firstNum" :min="1"></a-input-number> </a-form-item> <a-form-item v-if="clientsBulkModal.emailMethod>1"> <span slot="label">{{ i18n "pages.client.last" }}</span> <a-input-number v-model="clientsBulkModal.lastNum" :min="clientsBulkModal.firstNum"></a-input-number> </a-form-item> <a-form-item v-if="clientsBulkModal.emailMethod>0"> <span slot="label">{{ i18n "pages.client.prefix" }}</span> <a-input v-model="clientsBulkModal.emailPrefix" style="width: 120px"></a-input> </a-form-item> <a-form-item v-if="clientsBulkModal.emailMethod>2"> <span slot="label">{{ i18n "pages.client.postfix" }}</span> <a-input v-model="clientsBulkModal.emailPostfix" style="width: 120px"></a-input> </a-form-item> <a-form-item v-if="clientsBulkModal.emailMethod < 2"> <span slot="label">{{ i18n "pages.client.clientCount" }}</span> <a-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number> </a-form-item> <a-form-item v-if="app.subSettings.enable"> <span slot="label"> Subscription <a-tooltip> <template slot="title"> <span>{{ i18n "pages.inbounds.subscriptionDesc" }}</span> </template> <a-icon type="question-circle" theme="filled"></a-icon> </a-tooltip> </span> <a-input v-model.trim="clientsBulkModal.subId"></a-input> </a-form-item> <a-form-item v-if="app.tgBotEnable"> <span slot="label"> Telegram ID <a-tooltip> <template slot="title"> <span>{{ i18n "pages.inbounds.telegramDesc" }}</span> </template> <a-icon type="question-circle" theme="filled"></a-icon> </a-tooltip> </span> <a-input v-model.trim="clientsBulkModal.tgId"></a-input> </a-form-item> <br> <a-form-item> <span slot="label"> <span>{{ i18n "pages.inbounds.IPLimit" }}</span> <a-tooltip> <template slot="title"> <span>{{ i18n "pages.inbounds.IPLimitDesc" }}</span> </template> <a-icon type="question-circle" theme="filled"></a-icon> </a-tooltip> </span> <a-input-number v-model="clientsBulkModal.limitIp" min="0"></a-input-number> </a-form-item> <br> <a-form-item v-if="clientsBulkModal.inbound.xtls" label="Flow"> <a-select v-model="clientsBulkModal.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.darkCardClass"> <a-select-option value="">{{ i18n "none" }}</a-select-option> <a-select-option v-for="key in XTLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option> </a-select> </a-form-item> <a-form-item v-if="clientsBulkModal.inbound.canEnableTlsFlow()" label="Flow" layout="inline"> <a-select v-model="clientsBulkModal.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.darkCardClass"> <a-select-option value="" selected>{{ i18n "none" }}</a-select-option> <a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option> </a-select> </a-form-item> <a-form-item> <span slot="label"> <span>{{ i18n "pages.inbounds.totalFlow" }}</span> (GB) <a-tooltip> <template slot="title"> 0 <span>{{ i18n "pages.inbounds.meansNoLimit" }}</span> </template> <a-icon type="question-circle" theme="filled"></a-icon> </a-tooltip> </span> <a-input-number v-model="clientsBulkModal.totalGB" :min="0"></a-input-number> </a-form-item> <br> <a-form-item label='{{ i18n "pages.client.delayedStart" }}'> <a-switch v-model="clientsBulkModal.delayedStart" @click="clientsBulkModal.expiryTime=0"></a-switch> </a-form-item> <br> <a-form-item label='{{ i18n "pages.client.expireDays" }}' v-if="clientsBulkModal.delayedStart"> <a-input-number v-model="delayedExpireDays" :min="0"></a-input-number> </a-form-item> <a-form-item v-else> <span slot="label"> <span>{{ i18n "pages.inbounds.expireDate" }}</span> <a-tooltip> <template slot="title"> <span>{{ i18n "pages.inbounds.leaveBlankToNeverExpire" }}</span> </template> <a-icon type="question-circle" theme="filled"></a-icon> </a-tooltip> </span> <a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss" :dropdown-class-name="themeSwitcher.darkCardClass" v-model="clientsBulkModal.expiryTime" style="width: 300px;"></a-date-picker> </a-form-item> </a-form> </a-modal> <script> const clientsBulkModal = { visible: false, confirmLoading: false, title: '', okText: '', confirm: null, dbInbound: new DBInbound(), inbound: new Inbound(), quantity: 1, totalGB: 0, limitIp: 0, expiryTime: '', emailMethod: 0, firstNum: 1, lastNum: 1, emailPrefix: "", emailPostfix: "", subId: "", tgId: "", flow: "", delayedStart: false, ok() { clients = []; method = clientsBulkModal.emailMethod; if (method > 1) { start = clientsBulkModal.firstNum; end = clientsBulkModal.lastNum + 1; } else { start = 0; end = clientsBulkModal.quantity; } prefix = (method > 0 && clientsBulkModal.emailPrefix.length > 0) ? clientsBulkModal.emailPrefix : ""; useNum = (method > 1); postfix = (method > 2 && clientsBulkModal.emailPostfix.length > 0) ? clientsBulkModal.emailPostfix : ""; for (let i = start; i < end; i++) { newClient = clientsBulkModal.newClient(clientsBulkModal.dbInbound.protocol); if (method == 4) newClient.email = ""; newClient.email += useNum ? prefix + i.toString() + postfix : prefix + postfix; if (clientsBulkModal.subId.length > 0) newClient.subId = clientsBulkModal.subId; if (clientsBulkModal.tgId.length > 0) newClient.tgId = clientsBulkModal.tgId; newClient.limitIp = clientsBulkModal.limitIp; newClient._totalGB = clientsBulkModal.totalGB; newClient._expiryTime = clientsBulkModal.expiryTime; if (clientsBulkModal.inbound.canEnableTlsFlow()) { newClient.flow = clientsBulkModal.flow; } if (clientsBulkModal.inbound.xtls) { newClient.flow = clientsBulkModal.flow; } clients.push(newClient); } ObjectUtil.execute(clientsBulkModal.confirm, clients, clientsBulkModal.dbInbound.id); }, show({ title = '', okText = '{{ i18n "sure" }}', dbInbound = null, confirm = (inbound, dbInbound) => { } }) { this.visible = true; this.title = title; this.okText = okText; this.confirm = confirm; this.quantity = 1; this.totalGB = 0; this.expiryTime = 0; this.emailMethod = 0; this.limitIp = 0; this.firstNum = 1; this.lastNum = 1; this.emailPrefix = ""; this.emailPostfix = ""; this.subId = ""; this.tgId = ""; this.flow = ""; this.dbInbound = new DBInbound(dbInbound); this.inbound = dbInbound.toInbound(); this.delayedStart = false; }, newClient(protocol) { switch (protocol) { case Protocols.VMESS: return new Inbound.VmessSettings.Vmess(); case Protocols.VLESS: return new Inbound.VLESSSettings.VLESS(); case Protocols.TROJAN: return new Inbound.TrojanSettings.Trojan(); case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings.Shadowsocks(clientsBulkModal.inbound.settings.shadowsockses[0].method); default: return null; } }, close() { clientsBulkModal.visible = false; clientsBulkModal.loading(false); }, loading(loading) { clientsBulkModal.confirmLoading = loading; }, }; const clientsBulkModalApp = new Vue({ delimiters: ['[[', ']]'], el: '#client-bulk-modal', data: { clientsBulkModal, get inbound() { return this.clientsBulkModal.inbound; }, get delayedExpireDays() { return this.clientsBulkModal.expiryTime < 0 ? this.clientsBulkModal.expiryTime / -86400000 : 0; }, set delayedExpireDays(days) { this.clientsBulkModal.expiryTime = -86400000 * days; }, }, }); </script> {{end}}