新增车辆运维 OTA 工作台前端。
支持包管理、车辆同步、任务与自定义文件下发,并按 ops.ota* 对齐可写权限。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import http from './http'
|
||||
import type {
|
||||
OtaJob,
|
||||
OtaPackageInfo,
|
||||
OtaSettings,
|
||||
OtaTarget,
|
||||
OtaVehicleRow
|
||||
} from '@/types/ota'
|
||||
|
||||
export async function getOtaSettings(): Promise<OtaSettings> {
|
||||
const { data } = await http.get<OtaSettings>('/ota/settings')
|
||||
return data
|
||||
}
|
||||
|
||||
export async function putOtaSettings(settings: OtaSettings): Promise<OtaSettings> {
|
||||
const { data } = await http.put<OtaSettings>('/ota/settings', settings)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getOtaTarget(): Promise<{ target: OtaTarget | null; summary?: Record<string, string> }> {
|
||||
const { data } = await http.get<{ target: OtaTarget | null; summary?: Record<string, string> }>('/ota/target')
|
||||
return data
|
||||
}
|
||||
|
||||
export async function listOtaPackages(): Promise<OtaPackageInfo[]> {
|
||||
const { data } = await http.get<OtaPackageInfo[]>('/ota/packages')
|
||||
return data
|
||||
}
|
||||
|
||||
export async function activateOtaPackage(id: string, name?: string): Promise<OtaTarget> {
|
||||
const { data } = await http.post<OtaTarget>(`/ota/packages/${encodeURIComponent(id)}/activate`, null, {
|
||||
params: name ? { name } : undefined
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
export async function deleteOtaPackage(id: string): Promise<void> {
|
||||
await http.delete(`/ota/packages/${encodeURIComponent(id)}`)
|
||||
}
|
||||
|
||||
export async function pullOtaPackage(carId: string): Promise<OtaPackageInfo> {
|
||||
const { data } = await http.post<OtaPackageInfo>('/ota/packages/pull', { carId }, { timeout: 120000 })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function uploadOtaPackage(file: File): Promise<OtaPackageInfo> {
|
||||
const form = new FormData()
|
||||
form.append('file', file)
|
||||
const { data } = await http.post<OtaPackageInfo>('/ota/packages/upload', form, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
timeout: 300000
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
export async function listOtaVehicles(latency?: boolean): Promise<OtaVehicleRow[]> {
|
||||
const { data } = await http.get<OtaVehicleRow[]>('/ota/vehicles', {
|
||||
params: latency === undefined ? undefined : { latency },
|
||||
timeout: 60000
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
export async function listOtaJobs(take = 100): Promise<OtaJob[]> {
|
||||
const { data } = await http.get<OtaJob[]>('/ota/jobs', { params: { take } })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getOtaJob(id: string): Promise<OtaJob> {
|
||||
const { data } = await http.get<OtaJob>(`/ota/jobs/${encodeURIComponent(id)}`)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function createOtaSyncJob(body: {
|
||||
carIds: string[]
|
||||
components?: string[]
|
||||
requireLatencyCheck?: boolean
|
||||
}): Promise<OtaJob> {
|
||||
const { data } = await http.post<OtaJob>('/ota/jobs', body)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function cancelOtaJob(id: string): Promise<void> {
|
||||
await http.post(`/ota/jobs/${encodeURIComponent(id)}/cancel`)
|
||||
}
|
||||
|
||||
export async function retryOtaJob(id: string): Promise<OtaJob> {
|
||||
const { data } = await http.post<OtaJob>(`/ota/jobs/${encodeURIComponent(id)}/retry`)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getOtaConfig(carId: string, app: string): Promise<{ json: string }> {
|
||||
const { data } = await http.get<{ json: string }>(`/ota/config/${encodeURIComponent(carId)}/${encodeURIComponent(app)}`)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function pushOtaConfig(body: {
|
||||
carIds: string[]
|
||||
app: string
|
||||
json: string
|
||||
requireLatencyCheck?: boolean
|
||||
}): Promise<OtaJob> {
|
||||
const { data } = await http.post<OtaJob>('/ota/config/push', body)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function pushOtaCustomFile(opts: {
|
||||
carIds: string[]
|
||||
remotePath: string
|
||||
restartOps: number[]
|
||||
files: File[]
|
||||
}): Promise<OtaJob> {
|
||||
const form = new FormData()
|
||||
form.append('carIds', JSON.stringify(opts.carIds))
|
||||
form.append('remotePath', opts.remotePath)
|
||||
form.append('restartOps', JSON.stringify(opts.restartOps.length ? opts.restartOps : [-1]))
|
||||
for (const f of opts.files) form.append('files', f)
|
||||
const { data } = await http.post<OtaJob>('/ota/custom-file', form, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
timeout: 300000
|
||||
})
|
||||
return data
|
||||
}
|
||||
Reference in New Issue
Block a user