109 lines
3.3 KiB
TypeScript
109 lines
3.3 KiB
TypeScript
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<string, string> = {
|
||
'Content-Type': 'application/json',
|
||
...(options?.headers as Record<string, string> || {}),
|
||
}
|
||
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<Asset | null> {
|
||
try {
|
||
const data = await assetsFetch(`/assets/${id}`)
|
||
return data.asset || data
|
||
} catch {
|
||
return null
|
||
}
|
||
}
|
||
|
||
export async function getAssetByIp(ip: string): Promise<Asset | null> {
|
||
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<Asset[]> {
|
||
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
|
||
}
|