client_modal.html 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. {{define "clientsModal"}}
  2. <a-modal id="client-modal" v-model="clientModal.visible" :title="clientModal.title" @ok="clientModal.ok"
  3. :confirm-loading="clientModal.confirmLoading" :closable="true" :mask-closable="false"
  4. :class="themeSwitcher.currentTheme"
  5. :ok-text="clientModal.okText" cancel-text='{{ i18n "close" }}'>
  6. <template v-if="isEdit">
  7. <a-tag v-if="isExpiry || isTrafficExhausted" color="red" style="margin-bottom: 10px;display: block;text-align: center;">Account is (Expired|Traffic Ended) And Disabled</a-tag>
  8. </template>
  9. {{template "form/client"}}
  10. </a-modal>
  11. <script>
  12. const clientModal = {
  13. visible: false,
  14. confirmLoading: false,
  15. title: '',
  16. okText: '',
  17. group: {
  18. isGroup: false,
  19. currentClient: null,
  20. inbounds: [],
  21. clients: [],
  22. },
  23. dbInbound: new DBInbound(),
  24. inbound: new Inbound(),
  25. clients: [],
  26. clientStats: [],
  27. oldClientId: "",
  28. index: null,
  29. clientIps: null,
  30. delayedStart: false,
  31. ok() {
  32. if (clientModal.isEdit) {
  33. ObjectUtil.execute(clientModal.confirm, clientModalApp.client, clientModal.dbInbound.id, clientModal.oldClientId);
  34. } else {
  35. if (clientModal.group.isGroup) {
  36. const currentClient = clientModal.group.currentClient;
  37. clientModal.group.clients.forEach((client, index) => {
  38. const { email, limitIp, totalGB, expiryTime, reset, enable, subId, tgId, flow } = currentClient;
  39. client.email = `${email}-${index + 1}`;
  40. client.limitIp = limitIp;
  41. client.totalGB = totalGB;
  42. client.expiryTime = expiryTime;
  43. client.reset = reset;
  44. client.enable = enable;
  45. if (subId) {
  46. client.subId = subId;
  47. }
  48. if (tgId) {
  49. client.tgId = tgId;
  50. }
  51. if (flow) {
  52. client.flow = flow;
  53. }
  54. });
  55. ObjectUtil.execute(clientModal.confirm, clientModal.group.clients, clientModal.group.inbounds);
  56. } else {
  57. ObjectUtil.execute(clientModal.confirm, clientModalApp.client, clientModal.dbInbound.id);
  58. }
  59. }
  60. },
  61. show({ title = '', okText = '{{ i18n "sure" }}', index = null, dbInbound = null, confirm = () => { }, isEdit = false }) {
  62. this.group = {
  63. isGroup: false,
  64. currentClient: null,
  65. inbounds: [],
  66. clients: [],
  67. }
  68. this.visible = true;
  69. this.title = title;
  70. this.okText = okText;
  71. this.isEdit = isEdit;
  72. if (Array.isArray(dbInbound)) {
  73. this.group.isGroup = true;
  74. dbInbound.forEach((dbInboundItem) => {
  75. this.showProcess(dbInboundItem);
  76. this.group.inbounds.push(dbInboundItem.id)
  77. this.group.clients.push(this.clients[this.index])
  78. })
  79. this.group.currentClient = this.clients[this.index]
  80. } else {
  81. this.showProcess(dbInbound, index);
  82. if (isEdit) {
  83. if (this.clients[index].expiryTime < 0) {
  84. this.delayedStart = true;
  85. }
  86. this.oldClientId = this.getClientId(dbInbound.protocol, clients[index]);
  87. } else {
  88. this.addClient(this.inbound.protocol, this.clients);
  89. }
  90. }
  91. this.clientStats = this.dbInbound.clientStats.find(row => row.email === this.clients[this.index].email);
  92. this.confirm = confirm;
  93. },
  94. showProcess(dbInbound, index = null) {
  95. this.dbInbound = new DBInbound(dbInbound);
  96. this.inbound = dbInbound.toInbound();
  97. this.clients = this.inbound.clients;
  98. this.index = index === null ? this.clients.length : index;
  99. this.delayedStart = false;
  100. this.addClient(this.inbound.protocol, this.clients);
  101. },
  102. getClientId(protocol, client) {
  103. switch (protocol) {
  104. case Protocols.TROJAN: return client.password;
  105. case Protocols.SHADOWSOCKS: return client.email;
  106. default: return client.id;
  107. }
  108. },
  109. addClient(protocol, clients) {
  110. switch (protocol) {
  111. case Protocols.VMESS: return clients.push(new Inbound.VmessSettings.Vmess());
  112. case Protocols.VLESS: return clients.push(new Inbound.VLESSSettings.VLESS());
  113. case Protocols.TROJAN: return clients.push(new Inbound.TrojanSettings.Trojan());
  114. case Protocols.SHADOWSOCKS: return clients.push(new Inbound.ShadowsocksSettings.Shadowsocks(clients[0].method));
  115. default: return null;
  116. }
  117. },
  118. close() {
  119. clientModal.visible = false;
  120. clientModal.loading(false);
  121. },
  122. loading(loading) {
  123. clientModal.confirmLoading = loading;
  124. },
  125. };
  126. const clientModalApp = new Vue({
  127. delimiters: ['[[', ']]'],
  128. el: '#client-modal',
  129. data: {
  130. clientModal,
  131. get inbound() {
  132. return this.clientModal.inbound;
  133. },
  134. get client() {
  135. return this.clientModal.clients[this.clientModal.index];
  136. },
  137. get clientStats() {
  138. return this.clientModal.clientStats;
  139. },
  140. get isEdit() {
  141. return this.clientModal.isEdit;
  142. },
  143. get isGroup() {
  144. return this.clientModal.group.isGroup;
  145. },
  146. get datepicker() {
  147. return app.datepicker;
  148. },
  149. get isTrafficExhausted() {
  150. if (!clientStats) return false
  151. if (clientStats.total <= 0) return false
  152. if (clientStats.up + clientStats.down < clientStats.total) return false
  153. return true
  154. },
  155. get isExpiry() {
  156. return this.clientModal.isEdit && this.client.expiryTime >0 ? (this.client.expiryTime < new Date().getTime()) : false;
  157. },
  158. get delayedStart() {
  159. return this.clientModal.delayedStart;
  160. },
  161. set delayedStart(value) {
  162. this.clientModal.delayedStart = value;
  163. },
  164. get delayedExpireDays() {
  165. return this.client && this.client.expiryTime < 0 ? this.client.expiryTime / -86400000 : 0;
  166. },
  167. set delayedExpireDays(days) {
  168. this.client.expiryTime = -86400000 * days;
  169. },
  170. },
  171. methods: {
  172. async getDBClientIps(email) {
  173. const msg = await HttpUtil.post(`/panel/inbound/clientIps/${email}`);
  174. if (!msg.success) {
  175. document.getElementById("clientIPs").value = msg.obj;
  176. return;
  177. }
  178. let ips = msg.obj;
  179. if (typeof ips === 'string' && ips.startsWith('[') && ips.endsWith(']')) {
  180. try {
  181. ips = JSON.parse(ips);
  182. ips = Array.isArray(ips) ? ips.join("\n") : ips;
  183. } catch (e) {
  184. console.error('Error parsing JSON:', e);
  185. }
  186. }
  187. document.getElementById("clientIPs").value = ips;
  188. },
  189. async clearDBClientIps(email) {
  190. try {
  191. const msg = await HttpUtil.post(`/panel/inbound/clearClientIps/${email}`);
  192. if (!msg.success) {
  193. return;
  194. }
  195. document.getElementById("clientIPs").value = "";
  196. } catch (error) {
  197. }
  198. },
  199. resetClientTraffic(email, dbInboundId, iconElement) {
  200. this.$confirm({
  201. title: '{{ i18n "pages.inbounds.resetTraffic"}}',
  202. content: '{{ i18n "pages.inbounds.resetTrafficContent"}}',
  203. class: themeSwitcher.currentTheme,
  204. okText: '{{ i18n "reset"}}',
  205. cancelText: '{{ i18n "cancel"}}',
  206. onOk: async () => {
  207. iconElement.disabled = true;
  208. const msg = await HttpUtil.postWithModal('/panel/inbound/' + dbInboundId + '/resetClientTraffic/' + email);
  209. if (msg.success) {
  210. this.clientModal.clientStats.up = 0;
  211. this.clientModal.clientStats.down = 0;
  212. }
  213. iconElement.disabled = false;
  214. },
  215. })
  216. },
  217. },
  218. });
  219. </script>
  220. {{end}}