mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-07-01 12:32:09 +00:00
add group user with the same subscription id to all inbounds (#1650)
This commit is contained in:
parent
e7ce8c8ddb
commit
5c695ca652
13 changed files with 196 additions and 48 deletions
|
@ -83,6 +83,41 @@ class HttpUtil {
|
||||||
}
|
}
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async jsonPost(url, data) {
|
||||||
|
let msg;
|
||||||
|
try {
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
};
|
||||||
|
const resp = await fetch(url, requestOptions);
|
||||||
|
const response = await resp.json();
|
||||||
|
|
||||||
|
msg = this._respToMsg({data : response});
|
||||||
|
} catch (e) {
|
||||||
|
msg = new Msg(false, e.toString());
|
||||||
|
}
|
||||||
|
this._handleMsg(msg);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async postWithModalJson(url, data, modal) {
|
||||||
|
if (modal) {
|
||||||
|
modal.loading(true);
|
||||||
|
}
|
||||||
|
const msg = await this.jsonPost(url, data);
|
||||||
|
if (modal) {
|
||||||
|
modal.loading(false);
|
||||||
|
if (msg instanceof Msg && msg.success) {
|
||||||
|
modal.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PromiseUtil {
|
class PromiseUtil {
|
||||||
|
|
|
@ -159,24 +159,31 @@ func (a *InboundController) clearClientIps(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *InboundController) addInboundClient(c *gin.Context) {
|
func (a *InboundController) addInboundClient(c *gin.Context) {
|
||||||
data := &model.Inbound{}
|
var requestData []model.Inbound
|
||||||
err := c.ShouldBind(data)
|
|
||||||
if err != nil {
|
|
||||||
jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
needRestart := true
|
err := c.ShouldBindJSON(&requestData)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
needRestart := true
|
||||||
|
|
||||||
|
for _, data := range requestData {
|
||||||
|
|
||||||
|
needRestart, err = a.inboundService.AddInboundClient(&data)
|
||||||
|
if err != nil {
|
||||||
|
jsonMsg(c, "Something went wrong!", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonMsg(c, "Client(s) added", nil)
|
||||||
|
if err == nil && needRestart {
|
||||||
|
a.xrayService.SetToNeedRestart()
|
||||||
|
}
|
||||||
|
|
||||||
needRestart, err = a.inboundService.AddInboundClient(data)
|
|
||||||
if err != nil {
|
|
||||||
jsonMsg(c, "Something went wrong!", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
jsonMsg(c, "Client(s) added", nil)
|
|
||||||
if err == nil && needRestart {
|
|
||||||
a.xrayService.SetToNeedRestart()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *InboundController) delInboundClient(c *gin.Context) {
|
func (a *InboundController) delInboundClient(c *gin.Context) {
|
||||||
|
|
|
@ -11,10 +11,12 @@
|
||||||
<a-divider>Subscription</a-divider>
|
<a-divider>Subscription</a-divider>
|
||||||
<div class="qr-bg"><canvas @click="copyToClipboard('qrCode-sub',genSubLink(qrModal.client.subId))" id="qrCode-sub" style="width: 100%; height: 100%;"></canvas></div>
|
<div class="qr-bg"><canvas @click="copyToClipboard('qrCode-sub',genSubLink(qrModal.client.subId))" id="qrCode-sub" style="width: 100%; height: 100%;"></canvas></div>
|
||||||
</template>
|
</template>
|
||||||
<a-divider>{{ i18n "pages.inbounds.client" }}</a-divider>
|
<a-divider v-if="!isJustSub">{{ i18n "pages.inbounds.client" }}</a-divider>
|
||||||
<template v-for="(row, index) in qrModal.qrcodes">
|
<template v-if="!isJustSub">
|
||||||
<a-tag color="green" style="margin: 10px 0; display: block; text-align: center;">[[ row.remark ]]</a-tag>
|
<template v-for="(row, index) in qrModal.qrcodes">
|
||||||
<div class="qr-bg"><canvas @click="copyToClipboard('qrCode-'+index, row.link)" :id="'qrCode-'+index" style="width: 100%; height: 100%;"></canvas></div>
|
<a-tag color="green" style="margin: 10px 0; display: block; text-align: center;">[[ row.remark ]]</a-tag>
|
||||||
|
<div class="qr-bg"><canvas @click="copyToClipboard('qrCode-'+index, row.link)" :id="'qrCode-'+index" style="width: 100%; height: 100%;"></canvas></div>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
|
@ -27,12 +29,14 @@
|
||||||
qrcodes: [],
|
qrcodes: [],
|
||||||
clipboard: null,
|
clipboard: null,
|
||||||
visible: false,
|
visible: false,
|
||||||
|
isJustSub: false,
|
||||||
subId: '',
|
subId: '',
|
||||||
show: function (title = '', dbInbound, client) {
|
show: function (title = '', dbInbound, client, isJustSub = false) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.dbInbound = dbInbound;
|
this.dbInbound = dbInbound;
|
||||||
this.inbound = dbInbound.toInbound();
|
this.inbound = dbInbound.toInbound();
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
this.isJustSub = isJustSub;
|
||||||
this.subId = '';
|
this.subId = '';
|
||||||
this.qrcodes = [];
|
this.qrcodes = [];
|
||||||
this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, client).forEach(l => {
|
this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, client).forEach(l => {
|
||||||
|
@ -53,6 +57,9 @@
|
||||||
el: '#qrcode-modal',
|
el: '#qrcode-modal',
|
||||||
data: {
|
data: {
|
||||||
qrModal: qrModal,
|
qrModal: qrModal,
|
||||||
|
get isJustSub(){
|
||||||
|
return qrModal.isJustSub
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
copyToClipboard(elmentId, content) {
|
copyToClipboard(elmentId, content) {
|
||||||
|
|
|
@ -15,7 +15,12 @@
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
title: '',
|
title: '',
|
||||||
okText: '',
|
okText: '',
|
||||||
isEdit: false,
|
group: {
|
||||||
|
isGroup: false,
|
||||||
|
currentClient: null,
|
||||||
|
inbounds: [],
|
||||||
|
clients: [],
|
||||||
|
},
|
||||||
dbInbound: new DBInbound(),
|
dbInbound: new DBInbound(),
|
||||||
inbound: new Inbound(),
|
inbound: new Inbound(),
|
||||||
clients: [],
|
clients: [],
|
||||||
|
@ -28,30 +33,76 @@
|
||||||
if (clientModal.isEdit) {
|
if (clientModal.isEdit) {
|
||||||
ObjectUtil.execute(clientModal.confirm, clientModalApp.client, clientModal.dbInbound.id, clientModal.oldClientId);
|
ObjectUtil.execute(clientModal.confirm, clientModalApp.client, clientModal.dbInbound.id, clientModal.oldClientId);
|
||||||
} else {
|
} else {
|
||||||
ObjectUtil.execute(clientModal.confirm, clientModalApp.client, clientModal.dbInbound.id);
|
if (clientModal.group.isGroup) {
|
||||||
|
const currentClient = clientModal.group.currentClient;
|
||||||
|
|
||||||
|
clientModal.group.clients.forEach((client, index) => {
|
||||||
|
const { email, limitIp, totalGB, expiryTime, reset, enable, subId, tgId, flow } = currentClient;
|
||||||
|
|
||||||
|
client.email = `${email}-${index + 1}`;
|
||||||
|
client.limitIp = limitIp;
|
||||||
|
client.totalGB = totalGB;
|
||||||
|
client.expiryTime = expiryTime;
|
||||||
|
client.reset = reset;
|
||||||
|
client.enable = enable;
|
||||||
|
|
||||||
|
if (subId) {
|
||||||
|
client.subId = subId;
|
||||||
|
}
|
||||||
|
if (tgId) {
|
||||||
|
client.tgId = tgId;
|
||||||
|
}
|
||||||
|
if (flow) {
|
||||||
|
client.flow = flow;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ObjectUtil.execute(clientModal.confirm, clientModal.group.clients, clientModal.group.inbounds);
|
||||||
|
} else {
|
||||||
|
ObjectUtil.execute(clientModal.confirm, clientModalApp.client, clientModal.dbInbound.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
show({ title = '', okText = '{{ i18n "sure" }}', index = null, dbInbound = null, confirm = () => { }, isEdit = false }) {
|
show({ title = '', okText = '{{ i18n "sure" }}', index = null, dbInbound = null, confirm = () => { }, isEdit = false }) {
|
||||||
|
this.group = {
|
||||||
|
isGroup: false,
|
||||||
|
currentClient: null,
|
||||||
|
inbounds: [],
|
||||||
|
clients: [],
|
||||||
|
}
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.okText = okText;
|
this.okText = okText;
|
||||||
this.isEdit = isEdit;
|
this.isEdit = isEdit;
|
||||||
|
if (Array.isArray(dbInbound)) {
|
||||||
|
this.group.isGroup = true;
|
||||||
|
dbInbound.forEach((dbInboundItem) => {
|
||||||
|
this.showProcess(dbInboundItem);
|
||||||
|
this.group.inbounds.push(dbInboundItem.id)
|
||||||
|
this.group.clients.push(this.clients[this.index])
|
||||||
|
})
|
||||||
|
this.group.currentClient = this.clients[this.index]
|
||||||
|
} else {
|
||||||
|
this.showProcess(dbInbound, index);
|
||||||
|
if (isEdit) {
|
||||||
|
if (this.clients[index].expiryTime < 0) {
|
||||||
|
this.delayedStart = true;
|
||||||
|
}
|
||||||
|
this.oldClientId = this.getClientId(dbInbound.protocol, clients[index]);
|
||||||
|
} else {
|
||||||
|
this.addClient(this.inbound.protocol, this.clients);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.clientStats = this.dbInbound.clientStats.find(row => row.email === this.clients[this.index].email);
|
||||||
|
this.confirm = confirm;
|
||||||
|
},
|
||||||
|
showProcess(dbInbound, index = null) {
|
||||||
this.dbInbound = new DBInbound(dbInbound);
|
this.dbInbound = new DBInbound(dbInbound);
|
||||||
this.inbound = dbInbound.toInbound();
|
this.inbound = dbInbound.toInbound();
|
||||||
this.clients = this.inbound.clients;
|
this.clients = this.inbound.clients;
|
||||||
this.index = index === null ? this.clients.length : index;
|
this.index = index === null ? this.clients.length : index;
|
||||||
this.delayedStart = false;
|
this.delayedStart = false;
|
||||||
if (isEdit) {
|
this.addClient(this.inbound.protocol, this.clients);
|
||||||
if (this.clients[index].expiryTime < 0) {
|
},
|
||||||
this.delayedStart = true;
|
|
||||||
}
|
|
||||||
this.oldClientId = this.getClientId(dbInbound.protocol, clients[index]);
|
|
||||||
} else {
|
|
||||||
this.addClient(this.inbound.protocol, this.clients);
|
|
||||||
}
|
|
||||||
this.clientStats = this.dbInbound.clientStats.find(row => row.email === this.clients[this.index].email);
|
|
||||||
this.confirm = confirm;
|
|
||||||
},
|
|
||||||
getClientId(protocol, client) {
|
getClientId(protocol, client) {
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case Protocols.TROJAN: return client.password;
|
case Protocols.TROJAN: return client.password;
|
||||||
|
@ -94,6 +145,9 @@
|
||||||
get isEdit() {
|
get isEdit() {
|
||||||
return this.clientModal.isEdit;
|
return this.clientModal.isEdit;
|
||||||
},
|
},
|
||||||
|
get isGroup() {
|
||||||
|
return this.clientModal.group.isGroup;
|
||||||
|
},
|
||||||
get datepicker() {
|
get datepicker() {
|
||||||
return app.datepicker;
|
return app.datepicker;
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</template>
|
</template>
|
||||||
<a-input v-model.trim="client.email"></a-input>
|
<a-input v-model.trim="client.email"></a-input>
|
||||||
</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) && !isGroup">
|
||||||
<template slot="label">
|
<template slot="label">
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
</template>
|
</template>
|
||||||
<a-input v-model.trim="client.password"></a-input>
|
<a-input v-model.trim="client.password"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="inbound.protocol === Protocols.VMESS || inbound.protocol === Protocols.VLESS">
|
<a-form-item v-if="(inbound.protocol === Protocols.VMESS || inbound.protocol === Protocols.VLESS) && !isGroup">
|
||||||
<template slot="label">
|
<template slot="label">
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
okText: '{{ i18n "sure" }}',
|
okText: '{{ i18n "sure" }}',
|
||||||
isEdit: false,
|
isEdit: false,
|
||||||
|
isGroup: false,
|
||||||
confirm: null,
|
confirm: null,
|
||||||
inbound: new Inbound(),
|
inbound: new Inbound(),
|
||||||
dbInbound: new DBInbound(),
|
dbInbound: new DBInbound(),
|
||||||
|
@ -60,6 +61,9 @@
|
||||||
get isEdit() {
|
get isEdit() {
|
||||||
return inModal.isEdit;
|
return inModal.isEdit;
|
||||||
},
|
},
|
||||||
|
get isGroup() {
|
||||||
|
return inModal.isGroup;
|
||||||
|
},
|
||||||
get client() {
|
get client() {
|
||||||
return inModal.inbound.clients[0];
|
return inModal.inbound.clients[0];
|
||||||
},
|
},
|
||||||
|
|
|
@ -145,6 +145,10 @@
|
||||||
<a-icon type="rest"></a-icon>
|
<a-icon type="rest"></a-icon>
|
||||||
{{ i18n "pages.inbounds.delDepletedClients" }}
|
{{ i18n "pages.inbounds.delDepletedClients" }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
|
<a-menu-item v-if="subSettings.enable && dbInbounds.length > 0" key="addGroupClient">
|
||||||
|
<a-icon type="usergroup-add"></a-icon>
|
||||||
|
{{ i18n "pages.client.groupAdd"}}
|
||||||
|
</a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -285,7 +289,7 @@
|
||||||
<p v-for="clientEmail in clientCount[dbInbound.id].online">[[ clientEmail ]]</p>
|
<p v-for="clientEmail in clientCount[dbInbound.id].online">[[ clientEmail ]]</p>
|
||||||
</template>
|
</template>
|
||||||
<a-tag style="margin:0; padding: 0 2px;" color="blue" v-if="clientCount[dbInbound.id].online.length">[[ clientCount[dbInbound.id].online.length ]]</a-tag>
|
<a-tag style="margin:0; padding: 0 2px;" color="blue" v-if="clientCount[dbInbound.id].online.length">[[ clientCount[dbInbound.id].online.length ]]</a-tag>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template slot="traffic" slot-scope="text, dbInbound">
|
<template slot="traffic" slot-scope="text, dbInbound">
|
||||||
|
@ -339,7 +343,7 @@
|
||||||
<a-tag style="margin:0;" color="blue">[[ dbInbound.toInbound().stream.network ]]</a-tag>
|
<a-tag style="margin:0;" color="blue">[[ dbInbound.toInbound().stream.network ]]</a-tag>
|
||||||
<a-tag style="margin:0;" v-if="dbInbound.toInbound().stream.isTls" color="green">tls</a-tag>
|
<a-tag style="margin:0;" v-if="dbInbound.toInbound().stream.isTls" color="green">tls</a-tag>
|
||||||
<a-tag style="margin:0;" v-if="dbInbound.toInbound().stream.isReality" color="green">reality</a-tag>
|
<a-tag style="margin:0;" v-if="dbInbound.toInbound().stream.isReality" color="green">reality</a-tag>
|
||||||
</template>
|
</template>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -373,7 +377,7 @@
|
||||||
<p v-for="clientEmail in clientCount[dbInbound.id].online">[[ clientEmail ]]</p>
|
<p v-for="clientEmail in clientCount[dbInbound.id].online">[[ clientEmail ]]</p>
|
||||||
</template>
|
</template>
|
||||||
<a-tag style="margin:0; padding: 0 2px;" color="green" v-if="clientCount[dbInbound.id].online.length">[[ clientCount[dbInbound.id].online.length ]]</a-tag>
|
<a-tag style="margin:0; padding: 0 2px;" color="green" v-if="clientCount[dbInbound.id].online.length">[[ clientCount[dbInbound.id].online.length ]]</a-tag>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -740,6 +744,9 @@
|
||||||
case "delDepletedClients":
|
case "delDepletedClients":
|
||||||
this.delDepletedClients(-1)
|
this.delDepletedClients(-1)
|
||||||
break;
|
break;
|
||||||
|
case "addGroupClient":
|
||||||
|
this.openGroupAddClient()
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clickAction(action, dbInbound) {
|
clickAction(action, dbInbound) {
|
||||||
|
@ -883,6 +890,20 @@
|
||||||
|
|
||||||
await this.submit(`/panel/inbound/update/${dbInbound.id}`, data, inModal);
|
await this.submit(`/panel/inbound/update/${dbInbound.id}`, data, inModal);
|
||||||
},
|
},
|
||||||
|
openGroupAddClient() {
|
||||||
|
clientModal.show({
|
||||||
|
title: '{{ i18n "pages.client.groupAdd"}}',
|
||||||
|
okText: '{{ i18n "pages.client.submitAdd"}}',
|
||||||
|
dbInbound: this.dbInbounds,
|
||||||
|
confirm: async (clients, dbInboundIds) => {
|
||||||
|
clientModal.loading();
|
||||||
|
await this.addGroupClient(clients, dbInboundIds);
|
||||||
|
clientModal.close();
|
||||||
|
await this.showQrcode(dbInboundIds[0],clients[0], true)
|
||||||
|
},
|
||||||
|
isEdit: false
|
||||||
|
});
|
||||||
|
},
|
||||||
openAddClient(dbInboundId) {
|
openAddClient(dbInboundId) {
|
||||||
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
||||||
clientModal.show({
|
clientModal.show({
|
||||||
|
@ -893,6 +914,7 @@
|
||||||
clientModal.loading();
|
clientModal.loading();
|
||||||
await this.addClient(clients, dbInboundId);
|
await this.addClient(clients, dbInboundId);
|
||||||
clientModal.close();
|
clientModal.close();
|
||||||
|
await this.showQrcode(dbInboundId,clients)
|
||||||
},
|
},
|
||||||
isEdit: false
|
isEdit: false
|
||||||
});
|
});
|
||||||
|
@ -936,11 +958,24 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async addClient(clients, dbInboundId) {
|
async addClient(clients, dbInboundId) {
|
||||||
const data = {
|
const data = [{
|
||||||
id: dbInboundId,
|
id: dbInboundId,
|
||||||
settings: '{"clients": [' + clients.toString() + ']}',
|
settings: '{"clients": [' + clients.toString() + ']}',
|
||||||
};
|
}];
|
||||||
await this.submit(`/panel/inbound/addClient`, data);
|
|
||||||
|
await this.submit(`/panel/inbound/addClient`, data, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
async addGroupClient(clients, dbInboundIds) {
|
||||||
|
const data = []
|
||||||
|
dbInboundIds.forEach((dbInboundId, index) => {
|
||||||
|
data.push({
|
||||||
|
id: dbInboundId,
|
||||||
|
settings: '{"clients": [' + clients[index].toString() + ']}',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
await this.submit(`/panel/inbound/addClient`, data, true)
|
||||||
},
|
},
|
||||||
async updateClient(client, dbInboundId, clientId) {
|
async updateClient(client, dbInboundId, clientId) {
|
||||||
const data = {
|
const data = {
|
||||||
|
@ -1001,8 +1036,8 @@
|
||||||
checkFallback(dbInbound) {
|
checkFallback(dbInbound) {
|
||||||
newDbInbound = new DBInbound(dbInbound);
|
newDbInbound = new DBInbound(dbInbound);
|
||||||
if (dbInbound.listen.startsWith("@")){
|
if (dbInbound.listen.startsWith("@")){
|
||||||
rootInbound = this.inbounds.find((i) =>
|
rootInbound = this.inbounds.find((i) =>
|
||||||
i.isTcp &&
|
i.isTcp &&
|
||||||
['trojan','vless'].includes(i.protocol) &&
|
['trojan','vless'].includes(i.protocol) &&
|
||||||
i.settings.fallbacks.find(f => f.dest === dbInbound.listen)
|
i.settings.fallbacks.find(f => f.dest === dbInbound.listen)
|
||||||
);
|
);
|
||||||
|
@ -1018,10 +1053,10 @@
|
||||||
}
|
}
|
||||||
return newDbInbound;
|
return newDbInbound;
|
||||||
},
|
},
|
||||||
showQrcode(dbInboundId, client) {
|
showQrcode(dbInboundId, client, isJustSub = false) {
|
||||||
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
||||||
newDbInbound = this.checkFallback(dbInbound);
|
newDbInbound = this.checkFallback(dbInbound);
|
||||||
qrModal.show('{{ i18n "qrCode"}}', newDbInbound, client);
|
qrModal.show('{{ i18n "qrCode"}}', newDbInbound, client, isJustSub);
|
||||||
},
|
},
|
||||||
showInfo(dbInboundId, client) {
|
showInfo(dbInboundId, client) {
|
||||||
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
||||||
|
@ -1050,8 +1085,8 @@
|
||||||
await this.updateClient(clients[index], dbInboundId, clientId);
|
await this.updateClient(clients[index], dbInboundId, clientId);
|
||||||
this.loading(false);
|
this.loading(false);
|
||||||
},
|
},
|
||||||
async submit(url, data) {
|
async submit(url, data, isJson = false) {
|
||||||
const msg = await HttpUtil.postWithModal(url, data);
|
const msg = isJson ? await HttpUtil.postWithModalJson(url, data) : await HttpUtil.postWithModal(url, data);
|
||||||
if (msg.success) {
|
if (msg.success) {
|
||||||
await this.getDBInbounds();
|
await this.getDBInbounds();
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,6 +184,7 @@
|
||||||
|
|
||||||
[pages.client]
|
[pages.client]
|
||||||
"add" = "Add Client"
|
"add" = "Add Client"
|
||||||
|
"groupAdd" = "Add subscription user"
|
||||||
"edit" = "Edit Client"
|
"edit" = "Edit Client"
|
||||||
"submitAdd" = "Add Client"
|
"submitAdd" = "Add Client"
|
||||||
"submitEdit" = "Save Changes"
|
"submitEdit" = "Save Changes"
|
||||||
|
|
|
@ -184,6 +184,7 @@
|
||||||
|
|
||||||
[pages.client]
|
[pages.client]
|
||||||
"add" = "Agregar Cliente"
|
"add" = "Agregar Cliente"
|
||||||
|
"groupAdd" = "Agregar usuario de suscripción"
|
||||||
"edit" = "Editar Cliente"
|
"edit" = "Editar Cliente"
|
||||||
"submitAdd" = "Agregar Cliente"
|
"submitAdd" = "Agregar Cliente"
|
||||||
"submitEdit" = "Guardar Cambios"
|
"submitEdit" = "Guardar Cambios"
|
||||||
|
|
|
@ -184,6 +184,7 @@
|
||||||
|
|
||||||
[pages.client]
|
[pages.client]
|
||||||
"add" = "کاربر جدید"
|
"add" = "کاربر جدید"
|
||||||
|
"groupAdd" = "کاربر جدید سابسکریپشن"
|
||||||
"edit" = "ویرایش کاربر"
|
"edit" = "ویرایش کاربر"
|
||||||
"submitAdd" = "اضافه کردن"
|
"submitAdd" = "اضافه کردن"
|
||||||
"submitEdit" = "ذخیره تغییرات"
|
"submitEdit" = "ذخیره تغییرات"
|
||||||
|
|
|
@ -184,6 +184,7 @@
|
||||||
|
|
||||||
[pages.client]
|
[pages.client]
|
||||||
"add" = "Добавить пользователя"
|
"add" = "Добавить пользователя"
|
||||||
|
"groupAdd" = "Добавить пользователя подписки"
|
||||||
"edit" = "Редактировать пользователя"
|
"edit" = "Редактировать пользователя"
|
||||||
"submitAdd" = "Добавить пользователя"
|
"submitAdd" = "Добавить пользователя"
|
||||||
"submitEdit" = "Сохранить изменения"
|
"submitEdit" = "Сохранить изменения"
|
||||||
|
|
|
@ -184,6 +184,7 @@
|
||||||
|
|
||||||
[pages.client]
|
[pages.client]
|
||||||
"add" = "Thêm người dùng"
|
"add" = "Thêm người dùng"
|
||||||
|
"groupAdd" = "Thêm người dùng đăng ký"
|
||||||
"edit" = "Chỉnh sửa người dùng"
|
"edit" = "Chỉnh sửa người dùng"
|
||||||
"submitAdd" = "Thêm"
|
"submitAdd" = "Thêm"
|
||||||
"submitEdit" = "Lưu thay đổi"
|
"submitEdit" = "Lưu thay đổi"
|
||||||
|
|
|
@ -184,6 +184,7 @@
|
||||||
|
|
||||||
[pages.client]
|
[pages.client]
|
||||||
"add" = "添加客户端"
|
"add" = "添加客户端"
|
||||||
|
"groupAdd" = "添加订阅用户"
|
||||||
"edit" = "编辑客户端"
|
"edit" = "编辑客户端"
|
||||||
"submitAdd" = "添加客户端"
|
"submitAdd" = "添加客户端"
|
||||||
"submitEdit" = "保存修改"
|
"submitEdit" = "保存修改"
|
||||||
|
|
Loading…
Reference in a new issue