feat(clients): add Reset Traffic, QR Code, Info actions + Online/Remaining columns
The Clients page table gains:
- Online column — green/grey tag driven by /panel/api/inbounds/onlines,
polled every 10s.
- Remaining column — bytes-remaining tag, coloured green/orange/red
against quota, purple infinity when unlimited.
- Action icons per row: QR, Info, Reset traffic, Edit, Delete.
ClientInfoModal shows the full client detail (uuid/password/auth,
traffic ↑/↓ + remaining + all-time, expiry absolute + relative,
attached inbounds chip list, online + last-online).
ClientQrModal fetches links for the client's subId via
/panel/api/inbounds/getSubLinks/:subId and renders each one through
the existing QrPanel component.
Reset Traffic confirms then calls the existing per-inbound endpoint
on the client's first attached inbound (the traffic row is keyed on
email globally, so any attached inbound resets the shared counter).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:12 +00:00
|
|
|
import { onMounted, onUnmounted, ref, shallowRef } from 'vue';
|
2026-05-17 05:28:55 +00:00
|
|
|
import { HttpUtil } from '@/utils';
|
|
|
|
|
|
|
|
|
|
const JSON_HEADERS = { headers: { 'Content-Type': 'application/json' } };
|
feat(clients): add Reset Traffic, QR Code, Info actions + Online/Remaining columns
The Clients page table gains:
- Online column — green/grey tag driven by /panel/api/inbounds/onlines,
polled every 10s.
- Remaining column — bytes-remaining tag, coloured green/orange/red
against quota, purple infinity when unlimited.
- Action icons per row: QR, Info, Reset traffic, Edit, Delete.
ClientInfoModal shows the full client detail (uuid/password/auth,
traffic ↑/↓ + remaining + all-time, expiry absolute + relative,
attached inbounds chip list, online + last-online).
ClientQrModal fetches links for the client's subId via
/panel/api/inbounds/getSubLinks/:subId and renders each one through
the existing QrPanel component.
Reset Traffic confirms then calls the existing per-inbound endpoint
on the client's first attached inbound (the traffic row is keyed on
email globally, so any attached inbound resets the shared counter).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:12 +00:00
|
|
|
const ONLINES_POLL_MS = 10000;
|
2026-05-17 05:28:55 +00:00
|
|
|
|
|
|
|
|
export function useClients() {
|
|
|
|
|
const clients = shallowRef([]);
|
|
|
|
|
const inbounds = shallowRef([]);
|
feat(clients): add Reset Traffic, QR Code, Info actions + Online/Remaining columns
The Clients page table gains:
- Online column — green/grey tag driven by /panel/api/inbounds/onlines,
polled every 10s.
- Remaining column — bytes-remaining tag, coloured green/orange/red
against quota, purple infinity when unlimited.
- Action icons per row: QR, Info, Reset traffic, Edit, Delete.
ClientInfoModal shows the full client detail (uuid/password/auth,
traffic ↑/↓ + remaining + all-time, expiry absolute + relative,
attached inbounds chip list, online + last-online).
ClientQrModal fetches links for the client's subId via
/panel/api/inbounds/getSubLinks/:subId and renders each one through
the existing QrPanel component.
Reset Traffic confirms then calls the existing per-inbound endpoint
on the client's first attached inbound (the traffic row is keyed on
email globally, so any attached inbound resets the shared counter).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:12 +00:00
|
|
|
const onlines = ref([]);
|
2026-05-17 05:28:55 +00:00
|
|
|
const loading = ref(false);
|
|
|
|
|
const fetched = ref(false);
|
feat(clients): add Reset Traffic, QR Code, Info actions + Online/Remaining columns
The Clients page table gains:
- Online column — green/grey tag driven by /panel/api/inbounds/onlines,
polled every 10s.
- Remaining column — bytes-remaining tag, coloured green/orange/red
against quota, purple infinity when unlimited.
- Action icons per row: QR, Info, Reset traffic, Edit, Delete.
ClientInfoModal shows the full client detail (uuid/password/auth,
traffic ↑/↓ + remaining + all-time, expiry absolute + relative,
attached inbounds chip list, online + last-online).
ClientQrModal fetches links for the client's subId via
/panel/api/inbounds/getSubLinks/:subId and renders each one through
the existing QrPanel component.
Reset Traffic confirms then calls the existing per-inbound endpoint
on the client's first attached inbound (the traffic row is keyed on
email globally, so any attached inbound resets the shared counter).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:12 +00:00
|
|
|
let onlinesTimer = null;
|
2026-05-17 05:28:55 +00:00
|
|
|
|
|
|
|
|
async function refresh() {
|
|
|
|
|
loading.value = true;
|
|
|
|
|
try {
|
|
|
|
|
const [clientsMsg, inboundsMsg] = await Promise.all([
|
|
|
|
|
HttpUtil.get('/panel/api/clients/list'),
|
|
|
|
|
HttpUtil.get('/panel/api/inbounds/list'),
|
|
|
|
|
]);
|
|
|
|
|
if (clientsMsg?.success) {
|
|
|
|
|
clients.value = Array.isArray(clientsMsg.obj) ? clientsMsg.obj : [];
|
|
|
|
|
}
|
|
|
|
|
if (inboundsMsg?.success) {
|
|
|
|
|
inbounds.value = Array.isArray(inboundsMsg.obj) ? inboundsMsg.obj : [];
|
|
|
|
|
}
|
|
|
|
|
fetched.value = true;
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
feat(clients): add Reset Traffic, QR Code, Info actions + Online/Remaining columns
The Clients page table gains:
- Online column — green/grey tag driven by /panel/api/inbounds/onlines,
polled every 10s.
- Remaining column — bytes-remaining tag, coloured green/orange/red
against quota, purple infinity when unlimited.
- Action icons per row: QR, Info, Reset traffic, Edit, Delete.
ClientInfoModal shows the full client detail (uuid/password/auth,
traffic ↑/↓ + remaining + all-time, expiry absolute + relative,
attached inbounds chip list, online + last-online).
ClientQrModal fetches links for the client's subId via
/panel/api/inbounds/getSubLinks/:subId and renders each one through
the existing QrPanel component.
Reset Traffic confirms then calls the existing per-inbound endpoint
on the client's first attached inbound (the traffic row is keyed on
email globally, so any attached inbound resets the shared counter).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:12 +00:00
|
|
|
async function refreshOnlines() {
|
|
|
|
|
const msg = await HttpUtil.post('/panel/api/inbounds/onlines');
|
|
|
|
|
if (msg?.success) {
|
|
|
|
|
onlines.value = Array.isArray(msg.obj) ? msg.obj : [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 05:28:55 +00:00
|
|
|
async function create(payload) {
|
|
|
|
|
const msg = await HttpUtil.post('/panel/api/clients/add', payload, JSON_HEADERS);
|
|
|
|
|
if (msg?.success) await refresh();
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function update(id, client) {
|
|
|
|
|
const msg = await HttpUtil.post(`/panel/api/clients/update/${id}`, client, JSON_HEADERS);
|
|
|
|
|
if (msg?.success) await refresh();
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function remove(id, keepTraffic = false) {
|
|
|
|
|
const url = keepTraffic
|
|
|
|
|
? `/panel/api/clients/del/${id}?keepTraffic=1`
|
|
|
|
|
: `/panel/api/clients/del/${id}`;
|
|
|
|
|
const msg = await HttpUtil.post(url);
|
|
|
|
|
if (msg?.success) await refresh();
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function attach(id, inboundIds) {
|
|
|
|
|
const msg = await HttpUtil.post(`/panel/api/clients/${id}/attach`, { inboundIds }, JSON_HEADERS);
|
|
|
|
|
if (msg?.success) await refresh();
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function detach(id, inboundIds) {
|
|
|
|
|
const msg = await HttpUtil.post(`/panel/api/clients/${id}/detach`, { inboundIds }, JSON_HEADERS);
|
|
|
|
|
if (msg?.success) await refresh();
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
feat(clients): add Reset Traffic, QR Code, Info actions + Online/Remaining columns
The Clients page table gains:
- Online column — green/grey tag driven by /panel/api/inbounds/onlines,
polled every 10s.
- Remaining column — bytes-remaining tag, coloured green/orange/red
against quota, purple infinity when unlimited.
- Action icons per row: QR, Info, Reset traffic, Edit, Delete.
ClientInfoModal shows the full client detail (uuid/password/auth,
traffic ↑/↓ + remaining + all-time, expiry absolute + relative,
attached inbounds chip list, online + last-online).
ClientQrModal fetches links for the client's subId via
/panel/api/inbounds/getSubLinks/:subId and renders each one through
the existing QrPanel component.
Reset Traffic confirms then calls the existing per-inbound endpoint
on the client's first attached inbound (the traffic row is keyed on
email globally, so any attached inbound resets the shared counter).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:12 +00:00
|
|
|
async function resetTraffic(client) {
|
|
|
|
|
const ibIds = Array.isArray(client?.inboundIds) ? client.inboundIds : [];
|
|
|
|
|
if (!client?.email || ibIds.length === 0) return null;
|
|
|
|
|
const url = `/panel/api/inbounds/${ibIds[0]}/resetClientTraffic/${encodeURIComponent(client.email)}`;
|
|
|
|
|
const msg = await HttpUtil.post(url);
|
|
|
|
|
if (msg?.success) await refresh();
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
await refresh();
|
|
|
|
|
refreshOnlines();
|
|
|
|
|
onlinesTimer = setInterval(refreshOnlines, ONLINES_POLL_MS);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
if (onlinesTimer) clearInterval(onlinesTimer);
|
|
|
|
|
});
|
2026-05-17 05:28:55 +00:00
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
clients,
|
|
|
|
|
inbounds,
|
feat(clients): add Reset Traffic, QR Code, Info actions + Online/Remaining columns
The Clients page table gains:
- Online column — green/grey tag driven by /panel/api/inbounds/onlines,
polled every 10s.
- Remaining column — bytes-remaining tag, coloured green/orange/red
against quota, purple infinity when unlimited.
- Action icons per row: QR, Info, Reset traffic, Edit, Delete.
ClientInfoModal shows the full client detail (uuid/password/auth,
traffic ↑/↓ + remaining + all-time, expiry absolute + relative,
attached inbounds chip list, online + last-online).
ClientQrModal fetches links for the client's subId via
/panel/api/inbounds/getSubLinks/:subId and renders each one through
the existing QrPanel component.
Reset Traffic confirms then calls the existing per-inbound endpoint
on the client's first attached inbound (the traffic row is keyed on
email globally, so any attached inbound resets the shared counter).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:12 +00:00
|
|
|
onlines,
|
2026-05-17 05:28:55 +00:00
|
|
|
loading,
|
|
|
|
|
fetched,
|
|
|
|
|
refresh,
|
feat(clients): add Reset Traffic, QR Code, Info actions + Online/Remaining columns
The Clients page table gains:
- Online column — green/grey tag driven by /panel/api/inbounds/onlines,
polled every 10s.
- Remaining column — bytes-remaining tag, coloured green/orange/red
against quota, purple infinity when unlimited.
- Action icons per row: QR, Info, Reset traffic, Edit, Delete.
ClientInfoModal shows the full client detail (uuid/password/auth,
traffic ↑/↓ + remaining + all-time, expiry absolute + relative,
attached inbounds chip list, online + last-online).
ClientQrModal fetches links for the client's subId via
/panel/api/inbounds/getSubLinks/:subId and renders each one through
the existing QrPanel component.
Reset Traffic confirms then calls the existing per-inbound endpoint
on the client's first attached inbound (the traffic row is keyed on
email globally, so any attached inbound resets the shared counter).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:12 +00:00
|
|
|
refreshOnlines,
|
2026-05-17 05:28:55 +00:00
|
|
|
create,
|
|
|
|
|
update,
|
|
|
|
|
remove,
|
|
|
|
|
attach,
|
|
|
|
|
detach,
|
feat(clients): add Reset Traffic, QR Code, Info actions + Online/Remaining columns
The Clients page table gains:
- Online column — green/grey tag driven by /panel/api/inbounds/onlines,
polled every 10s.
- Remaining column — bytes-remaining tag, coloured green/orange/red
against quota, purple infinity when unlimited.
- Action icons per row: QR, Info, Reset traffic, Edit, Delete.
ClientInfoModal shows the full client detail (uuid/password/auth,
traffic ↑/↓ + remaining + all-time, expiry absolute + relative,
attached inbounds chip list, online + last-online).
ClientQrModal fetches links for the client's subId via
/panel/api/inbounds/getSubLinks/:subId and renders each one through
the existing QrPanel component.
Reset Traffic confirms then calls the existing per-inbound endpoint
on the client's first attached inbound (the traffic row is keyed on
email globally, so any attached inbound resets the shared counter).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:12 +00:00
|
|
|
resetTraffic,
|
2026-05-17 05:28:55 +00:00
|
|
|
};
|
|
|
|
|
}
|