| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- import dayjs, { type Dayjs } from 'dayjs';
- import { ObjectUtil, NumberFormatter, SizeFormatter } from '@/utils';
- import { Protocols } from '@/schemas/primitives';
- export type RawJsonField = string | Record<string, unknown> | unknown[];
- export interface ClientStats {
- email: string;
- up: number;
- down: number;
- total: number;
- expiryTime: number;
- enable?: boolean;
- inboundId?: number;
- reset?: number;
- }
- export interface FallbackParentRef {
- masterId: number;
- path: string;
- }
- export type DBInboundInit = Partial<{
- id: number;
- userId: number;
- up: number;
- down: number;
- total: number;
- remark: string;
- enable: boolean;
- expiryTime: number;
- trafficReset: string;
- lastTrafficResetTime: number;
- listen: string;
- port: number;
- protocol: string;
- settings: RawJsonField;
- streamSettings: RawJsonField;
- tag: string;
- sniffing: RawJsonField;
- clientStats: ClientStats[];
- nodeId: number | null;
- fallbackParent: FallbackParentRef | null;
- }>;
- export function coerceInboundJsonField(value: unknown): Record<string, unknown> {
- if (value == null) return {};
- if (typeof value === 'object' && !Array.isArray(value)) {
- return value as Record<string, unknown>;
- }
- if (typeof value !== 'string') return {};
- const trimmed = value.trim();
- if (trimmed === '') return {};
- try {
- const parsed = JSON.parse(trimmed);
- if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
- return parsed as Record<string, unknown>;
- }
- return {};
- } catch {
- return {};
- }
- }
- export class DBInbound {
- id: number;
- userId: number;
- up: number;
- down: number;
- total: number;
- remark: string;
- enable: boolean;
- expiryTime: number;
- trafficReset: string;
- lastTrafficResetTime: number;
- listen: string;
- port: number;
- protocol: string;
- settings: RawJsonField;
- streamSettings: RawJsonField;
- tag: string;
- sniffing: RawJsonField;
- clientStats: ClientStats[];
- nodeId: number | null;
- fallbackParent: FallbackParentRef | null;
- private _clientStatsMap: Map<string, ClientStats> | null = null;
- constructor(data?: DBInboundInit) {
- this.id = 0;
- this.userId = 0;
- this.up = 0;
- this.down = 0;
- this.total = 0;
- this.remark = "";
- this.enable = true;
- this.expiryTime = 0;
- this.trafficReset = "never";
- this.lastTrafficResetTime = 0;
- this.listen = "";
- this.port = 0;
- this.protocol = "";
- this.settings = "";
- this.streamSettings = "";
- this.tag = "";
- this.sniffing = "";
- this.clientStats = [];
- this.nodeId = null;
- this.fallbackParent = null;
- if (data == null) {
- return;
- }
- ObjectUtil.cloneProps(this, data);
- }
- get totalGB(): number {
- return NumberFormatter.toFixed(this.total / SizeFormatter.ONE_GB, 2);
- }
- set totalGB(gb: number) {
- this.total = NumberFormatter.toFixed(gb * SizeFormatter.ONE_GB, 0);
- }
- get isVMess() {
- return this.protocol === Protocols.VMESS;
- }
- get isVLess() {
- return this.protocol === Protocols.VLESS;
- }
- get isTrojan() {
- return this.protocol === Protocols.TROJAN;
- }
- get isSS() {
- return this.protocol === Protocols.SHADOWSOCKS;
- }
- get isMixed() {
- return this.protocol === Protocols.MIXED;
- }
- get isHTTP() {
- return this.protocol === Protocols.HTTP;
- }
- get isWireguard() {
- return this.protocol === Protocols.WIREGUARD;
- }
- get isHysteria() {
- return this.protocol === Protocols.HYSTERIA;
- }
- get address(): string {
- let address = location.hostname;
- if (!ObjectUtil.isEmpty(this.listen) && this.listen !== "0.0.0.0") {
- address = this.listen;
- }
- return address;
- }
- get _expiryTime(): Dayjs | null {
- if (this.expiryTime === 0) {
- return null;
- }
- return dayjs(this.expiryTime);
- }
- set _expiryTime(t: Dayjs | null | undefined) {
- if (t == null) {
- this.expiryTime = 0;
- } else {
- this.expiryTime = t.valueOf();
- }
- }
- get isExpiry(): boolean {
- return this.expiryTime < new Date().getTime();
- }
- invalidateCache(): void {
- this._clientStatsMap = null;
- }
- getClientStats(email: string): ClientStats | undefined {
- if (!this._clientStatsMap) {
- this._clientStatsMap = new Map();
- if (Array.isArray(this.clientStats)) {
- for (const stats of this.clientStats) {
- if (stats && stats.email) {
- this._clientStatsMap.set(stats.email, stats);
- }
- }
- }
- }
- return this._clientStatsMap.get(email);
- }
- }
|