2026-07-26 14:14:19 +08:00
|
|
|
|
import { ReflectionApiError, reflectionApi } from './reflection'
|
2026-05-31 00:16:16 +08:00
|
|
|
|
|
|
|
|
|
|
export type VehicleMaintenanceMode = 'online' | 'offline' | 'repair' | 'blown'
|
|
|
|
|
|
|
2026-07-26 14:14:19 +08:00
|
|
|
|
/** 地图监控车辆列表快捷动作 */
|
|
|
|
|
|
export type VehicleQuickAction =
|
|
|
|
|
|
| 'online'
|
|
|
|
|
|
| 'offline'
|
|
|
|
|
|
| 'endTask'
|
|
|
|
|
|
| 'disable'
|
|
|
|
|
|
| 'enable'
|
|
|
|
|
|
|
2026-05-31 00:16:16 +08:00
|
|
|
|
const METHOD_MAP: Record<VehicleMaintenanceMode, string> = {
|
|
|
|
|
|
online: 'OnlineCar',
|
|
|
|
|
|
offline: 'OfflineCar',
|
|
|
|
|
|
repair: 'Repair',
|
|
|
|
|
|
blown: 'Blown'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-26 14:14:19 +08:00
|
|
|
|
/** 结束任务:按车型依次尝试(Dummy=ForceStop,Clumsy=ForceStopUI,通用=UIIntercept) */
|
|
|
|
|
|
const END_TASK_METHODS = ['ForceStopUI', 'ForceStop', 'UIIntercept'] as const
|
|
|
|
|
|
|
|
|
|
|
|
const QUICK_METHOD_MAP: Record<Exclude<VehicleQuickAction, 'endTask'>, string> = {
|
|
|
|
|
|
online: 'OnlineCar',
|
|
|
|
|
|
offline: 'OfflineCar',
|
|
|
|
|
|
disable: 'DisableCar',
|
|
|
|
|
|
enable: 'EnableCar'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const VEHICLE_QUICK_ACTIONS: {
|
|
|
|
|
|
value: VehicleQuickAction
|
|
|
|
|
|
label: string
|
|
|
|
|
|
danger?: boolean
|
|
|
|
|
|
confirm: string
|
|
|
|
|
|
}[] = [
|
|
|
|
|
|
{ value: 'online', label: '上线', confirm: '确认将车辆上线?' },
|
|
|
|
|
|
{ value: 'offline', label: '下线', confirm: '确认将车辆下线?下线后不再被任务选中。' },
|
|
|
|
|
|
{ value: 'endTask', label: '结束任务', danger: true, confirm: '确认结束该车当前任务?' },
|
|
|
|
|
|
{ value: 'disable', label: '禁用车辆', danger: true, confirm: '确认禁用该车?禁用后需先启用才能重新上线。' },
|
|
|
|
|
|
{ value: 'enable', label: '启用车辆', confirm: '确认启用该车?启用后仍需上线才能参与调度。' }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
2026-05-31 00:16:16 +08:00
|
|
|
|
export async function setVehicleMaintenance(
|
|
|
|
|
|
carId: number,
|
|
|
|
|
|
mode: VehicleMaintenanceMode
|
|
|
|
|
|
): Promise<boolean> {
|
|
|
|
|
|
const method = METHOD_MAP[mode]
|
|
|
|
|
|
if (!method) return false
|
|
|
|
|
|
try {
|
|
|
|
|
|
await reflectionApi.execute('car', carId, method)
|
|
|
|
|
|
return true
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-26 14:14:19 +08:00
|
|
|
|
async function tryExecuteMethods(carId: number, methods: readonly string[]): Promise<boolean> {
|
|
|
|
|
|
let lastErr: unknown
|
|
|
|
|
|
for (const method of methods) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await reflectionApi.execute('car', carId, method)
|
|
|
|
|
|
return true
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
if (!isUnsupportedMethodError(err)) throw err
|
|
|
|
|
|
lastErr = err
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (lastErr) throw lastErr
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function isUnsupportedMethodError(err: unknown): boolean {
|
|
|
|
|
|
if (err instanceof ReflectionApiError && (err.code === 404 || err.code === 405)) return true
|
|
|
|
|
|
const msg = err instanceof Error ? err.message : String(err)
|
|
|
|
|
|
return /method|not\s*found|unsupported|not\s*supported/i.test(msg)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 执行车辆快捷动作;失败抛错,由调用方提示。 */
|
|
|
|
|
|
export async function executeVehicleQuickAction(
|
|
|
|
|
|
carId: number,
|
|
|
|
|
|
action: VehicleQuickAction
|
|
|
|
|
|
): Promise<void> {
|
|
|
|
|
|
if (!Number.isFinite(carId) || carId <= 0) {
|
|
|
|
|
|
throw new Error('无效车辆 ID')
|
|
|
|
|
|
}
|
|
|
|
|
|
if (action === 'endTask') {
|
|
|
|
|
|
const ok = await tryExecuteMethods(carId, END_TASK_METHODS)
|
|
|
|
|
|
if (!ok) throw new Error('当前车型不支持结束任务')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
const method = QUICK_METHOD_MAP[action]
|
|
|
|
|
|
await reflectionApi.execute('car', carId, method)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-31 00:16:16 +08:00
|
|
|
|
export function openOnboardWeb(url?: string | null, ip?: string | null): void {
|
|
|
|
|
|
const target = url ?? (ip ? `http://${ip}:8081` : null)
|
|
|
|
|
|
if (!target) return
|
|
|
|
|
|
window.open(target, '_blank', 'noopener,noreferrer')
|
|
|
|
|
|
}
|