const ASSETS_API_URL = process.env.ASSETS_API_URL || 'http://localhost:5177/api' const ASSETS_API_KEY = process.env.ASSETS_API_KEY || '' export interface Asset { id: number node_name: string serial_number: string device_type: string business_ip: string | null hdm_ip: string | null manufacturer: string device_model: string status: string } async function assetsFetch(path: string, options?: RequestInit) { const headers: Record = { 'Content-Type': 'application/json', ...(options?.headers as Record || {}), } if (ASSETS_API_KEY) headers['Authorization'] = `Bearer ${ASSETS_API_KEY}` const res = await fetch(`${ASSETS_API_URL}${path}`, { ...options, headers }) if (!res.ok) { const text = await res.text().catch(() => '') throw new Error(`Assets API error: ${res.status} ${text}`) } return res.json() } export async function getAssets(params?: { page?: number pageSize?: number search?: string device_type?: string region?: string status?: string }) { const query = new URLSearchParams() if (params?.page) query.set('page', String(params.page)) if (params?.pageSize) query.set('pageSize', String(params.pageSize)) if (params?.search) query.set('search', params.search) if (params?.device_type) query.set('filter_device_type', params.device_type) if (params?.region) query.set('filter_region', params.region) if (params?.status) query.set('filter_status', params.status) const qs = query.toString() return assetsFetch(`/assets${qs ? `?${qs}` : ''}`) } export async function getAssetById(id: number): Promise { try { const data = await assetsFetch(`/assets/${id}`) return data.asset || data } catch { return null } } export async function getAssetByIp(ip: string): Promise { try { const data = await assetsFetch(`/assets?search=${encodeURIComponent(ip)}&pageSize=50`) if (data.data && data.data.length > 0) { for (const asset of data.data) { if (asset.business_ip === ip || asset.hdm_ip === ip) return asset } } return null } catch { return null } } export async function getAssetHistory(ip: string) { try { const data = await assetsFetch(`/assets/history?ip=${encodeURIComponent(ip)}`) return data.records || [] } catch { return [] } } // 设备类型常量(assets-ai 中 device_type 字段取值) export const DEVICE_TYPE_GPU = 'GPU服务器' export const DEVICE_TYPE_STORAGE = '存储服务器' // 获取所有"腾讯使用"状态的设备,支持按设备类型筛选 export async function getActiveDevices(deviceType?: string): Promise { const PAGE_SIZE = 200 const MAX_PAGES = 20 // 安全上限:20×200=4000台 const allAssets: Asset[] = [] for (let page = 1; page <= MAX_PAGES; page++) { const query = new URLSearchParams({ page: String(page), pageSize: String(PAGE_SIZE), filter_status: '腾讯使用', }) if (deviceType) query.set('filter_device_type', deviceType) const data = await assetsFetch(`/assets?${query.toString()}`) if (!data.data || !Array.isArray(data.data)) break allAssets.push(...data.data) // 返回量少于 pageSize 说明已到最后一页 if (data.data.length < PAGE_SIZE) break } return allAssets }