import { mockConfigs, mockProxies } from './mock' import { mockOn, mocked, request } from './request' import type { ProxyImportResult, ProxyInfo, ProxyInput } from '@/types/api' export function listProxies(): Promise<{ items: ProxyInfo[] }> { if (mockOn) return mocked({ items: mockProxies }) return request('/proxies') } /** mock 端复刻后端自动命名:留空生成 {type}-{host}:{port},冲突加序号 */ function mockAutoName(body: ProxyInput): string { const base = `${body.type}-${body.host}:${body.port}` let name = base for (let i = 2; mockProxies.some((p) => p.name === name); i++) name = `${base}-${i}` return name } function mockCreate(body: ProxyInput): ProxyInfo { const created: ProxyInfo = { id: Math.max(0, ...mockProxies.map((p) => p.id)) + 1, name: body.name?.trim() || mockAutoName(body), type: body.type, host: body.host, port: body.port, username: body.username ?? '', passwordSet: !!body.password, country: '', city: '', geoAt: '', usedBy: 0, createdAt: new Date().toISOString(), } mockProxies.push(created) return created } export function createProxy(body: ProxyInput): Promise { if (mockOn) return mocked(mockCreate(body)) return request('/proxies', { method: 'POST', body }) } export function updateProxy(id: number, body: ProxyInput): Promise { if (mockOn) { const found = mockProxies.find((p) => p.id === id) if (!found) return Promise.reject(new Error('代理不存在')) Object.assign(found, body, { name: body.name?.trim() || found.name, passwordSet: body.password ? true : found.passwordSet, }) return mocked({ ...found }) } return request(`/proxies/${id}`, { method: 'PUT', body }) } export function deleteProxy(id: number): Promise { if (mockOn) { const i = mockProxies.findIndex((p) => p.id === id) if (i >= 0) mockProxies.splice(i, 1) return mocked(undefined) } return request(`/proxies/${id}`, { method: 'DELETE' }) } /** 批量导入:每行 scheme://[user:pass@]host:port 或 host:port[:user:pass] */ export function importProxies(text: string): Promise { if (mockOn) { const created = text .split('\n') .map((l) => l.trim()) .filter((l) => l && !l.startsWith('#')) .map((l) => { const m = /^(?:(socks5|http|https):\/\/)?(?:[^@]+@)?([^:@/]+):(\d+)/.exec(l) return m ? mockCreate({ type: m[1] ?? 'socks5', host: m[2], port: Number(m[3]) }) : null }) .filter((p): p is ProxyInfo => !!p) return mocked({ created, failed: [] }) } return request('/proxies/import', { method: 'POST', body: { text } }) } /** 代理侧设置关联租户全集:选中即关联(含从其他代理改挂),未选中即解除 */ export function setProxyTenants(id: number, ociConfigIds: number[]): Promise<{ usedBy: number }> { if (mockOn) { const found = mockProxies.find((p) => p.id === id) if (!found) return Promise.reject(new Error('代理不存在')) for (const c of mockConfigs) { if (ociConfigIds.includes(c.id)) Object.assign(c, { proxyId: id, proxyName: found.name }) else if (c.proxyId === id) Object.assign(c, { proxyId: null, proxyName: '' }) } // 改挂会影响其他代理的引用数,全量重算保持一致 for (const p of mockProxies) p.usedBy = mockConfigs.filter((c) => c.proxyId === p.id).length return mocked({ usedBy: found.usedBy }) } return request(`/proxies/${id}/tenants`, { method: 'PUT', body: { ociConfigIds } }) } /** 手动重测出口地区,同步返回最新视图 */ export function probeProxy(id: number): Promise { if (mockOn) { const found = mockProxies.find((p) => p.id === id) if (!found) return Promise.reject(new Error('代理不存在')) Object.assign(found, { country: '日本', city: '大阪市', geoAt: new Date().toISOString() }) return mocked({ ...found }) } return request(`/proxies/${id}/probe`, { method: 'POST' }) }