// entry/src/main/ets/utils/LiveViewUtil.ets import { liveViewManager } from '@kit.LiveViewKit'; import { Want, wantAgent, WantAgent } from '@kit.AbilityKit'; import { FlightData, LiveDataService, PilotData, ApiResponse } from './LiveDataService'; import { hilog } from '@kit.PerformanceAnalysisKit'; import deviceInfo from '@ohos.deviceInfo'; import { http } from '@kit.NetworkKit'; // Push Kit相关类型定义 interface ClickAction { actionType: number; action: string; } interface RichProgress { type: number; nodeIcons: string[]; indicatorIcon: string; progress: number; indicatorType: number; color: string; bgColor: string; } interface CapsuleData { type: number; status: number; icon: string; bgColor: string; // Push Kit格式 backgroundColor: string; // 本地API格式 title: string; content: string; // 显式声明必填 } // Push Kit专用的胶囊数据接口 interface PushKitCapsuleData { type: number; status: number; icon: string; bgColor: string; // Push Kit要求的字段名 title: string; content?: string; // 可选字段 } // JWT令牌响应接口 interface JwtTokenResponse { token?: string; } interface ContentTextItem { text: string; foregroundColor?: string; } interface NotificationData { type: number; contentTitle: string; contentText: Array; clickAction: ClickAction; richProgress: RichProgress; largeIcon: string; // 添加largeIcon字段 keywords?: Record; // 修改为可选的对象类型 } interface ActivityData { notificationData: NotificationData; capsuleData: PushKitCapsuleData; // 使用Push Kit专用接口 } // PHP接口响应接口 interface PhpApiResponse { success?: boolean; error?: string; code?: string | number; msg?: string; } // PHP接口请求数据接口 interface StartLiveViewRequestData { token: string; flight_data: FlightData; activity_id: number; authorization: string; } interface UpdateLiveViewRequestData { token: string; flight_data: FlightData; activity_id: number; authorization: string; } interface EndLiveViewRequestData { token: string; activity_id: number; authorization: string; } const DOMAIN = 0x0000; /** * 实况窗控制器类,负责管理实况窗的整个生命周期 */ export class LiveViewController { private static selectedPilot: PilotData | null = null; private static deviceId: string = ''; private static wantAgentInstance: WantAgent | null = null; private static readonly TEMPLATE_ID = 'flight_live_view_template'; // 模板ID private static activityId: number = 0; // 实况活动ID // 添加PHP接口URL private static readonly START_LIVE_VIEW_PUSH_API = 'https://system.ldpfly.cn/hmos/startLiveViewPush.php'; private static readonly UPDATE_LIVE_VIEW_PUSH_API = 'https://system.ldpfly.cn/hmos/updateLiveViewPush.php'; private static readonly END_LIVE_VIEW_PUSH_API = 'https://system.ldpfly.cn/hmos/endLiveViewPush.php'; private static readonly ONLINE_PILOTS_API = 'https://system.ldpfly.cn/hmos/OnlinePilots.php'; // 使用OnlinePilots.php /** * 设置选中的飞行员 * @param pilot 选中的飞行员数据 */ public static setSelectedPilot(pilot: PilotData): void { LiveViewController.selectedPilot = pilot; // 获取设备ID LiveViewController.deviceId = deviceInfo.productModel || 'unknown_device'; hilog.info(DOMAIN, 'LiveViewController', `Selected pilot: ${pilot.callsign}, Device ID: ${LiveViewController.deviceId}`); } /** * 设置实况活动ID * @param id 实况活动ID */ public static setActivityId(id: number): void { LiveViewController.activityId = id; } /** * 获取设备ID * @returns string 设备ID */ public static getDeviceId(): string { hilog.info(DOMAIN, 'LiveViewController', `Getting device ID: ${LiveViewController.deviceId}`); return LiveViewController.deviceId; } /** * 启动实况窗 * @returns Promise - 启动结果 */ public static async startLiveView(): Promise { hilog.info(DOMAIN, 'LiveViewController', 'Starting live view'); if (!LiveViewController.selectedPilot) { const errorMsg = "请先选择一个飞行员"; hilog.error(DOMAIN, 'LiveViewController', errorMsg); throw new Error(errorMsg); } // 校验实况窗开关是否打开 if (!await LiveViewController.isLiveViewEnabled()) { const errorMsg = "Live view is disabled."; hilog.error(DOMAIN, 'LiveViewController', errorMsg); throw new Error(errorMsg); } // 构建WantAgent await LiveViewController.buildWantAgent(); // 转换选中的飞行员数据为航班数据格式 const flightData = LiveViewController.convertPilotToFlightData(LiveViewController.selectedPilot); hilog.info(DOMAIN, 'LiveViewController', `Converted flight data: ${JSON.stringify(flightData)}`); // 获取设备ID const deviceId = LiveViewController.getDeviceId(); if (!deviceId) { throw new Error("设备ID获取失败"); } // 获取Push Token let pushToken: string; try { pushToken = await LiveDataService.fetchPushToken(deviceId); if (!pushToken) { throw new Error("未能获取到推送令牌"); } } catch (tokenError) { hilog.error(DOMAIN, 'LiveViewController', `获取Push Token失败: ${tokenError.message}`); throw new Error("获取推送令牌失败: " + tokenError.message); } // 获取JWT令牌 let authorization: string; try { authorization = await LiveViewController.getAuthorizationToken(); if (!authorization) { throw new Error("未能获取到授权令牌"); } } catch (authError) { hilog.error(DOMAIN, 'LiveViewController', `获取JWT令牌失败: ${authError.message}`); throw new Error("获取授权令牌失败: " + authError.message); } // 生成activityId LiveViewController.activityId = parseInt(Date.now().toString().slice(-9)); // 通过Push Kit启动实况窗 await LiveViewController.startRemoteLiveViewViaPushKit( pushToken, flightData, LiveViewController.activityId, authorization ); // 创建本地实况窗 hilog.info(DOMAIN, 'LiveViewController', 'Creating local live view'); return await LiveDataService.createRemoteLiveView(LiveViewController.deviceId, flightData); } /** * 更新实况窗 * @returns Promise - 更新结果 */ public static async updateLiveView(): Promise { hilog.info(DOMAIN, 'LiveViewController', 'Updating live view'); if (!LiveViewController.selectedPilot) { const errorMsg = "没有选中的飞行员"; hilog.error(DOMAIN, 'LiveViewController', errorMsg); throw new Error(errorMsg); } // 从OnlinePilots.php重新获取最新的航班数据 hilog.info(DOMAIN, 'LiveViewController', 'Fetching latest flight data from OnlinePilots.php'); const flightData = await LiveViewController.fetchFlightDataFromOnlinePilots(); hilog.info(DOMAIN, 'LiveViewController', `Fetched flight data: ${JSON.stringify(flightData)}`); // 获取设备ID const deviceId = LiveViewController.getDeviceId(); if (!deviceId) { throw new Error("设备ID获取失败"); } // 获取Push Token let pushToken: string; try { pushToken = await LiveDataService.fetchPushToken(deviceId); if (!pushToken) { throw new Error("未能获取到推送令牌"); } } catch (tokenError) { hilog.error(DOMAIN, 'LiveViewController', `获取Push Token失败: ${tokenError.message}`); throw new Error("获取推送令牌失败: " + tokenError.message); } // 获取JWT令牌 let authorization: string; try { authorization = await LiveViewController.getAuthorizationToken(); if (!authorization) { throw new Error("未能获取到授权令牌"); } } catch (authError) { hilog.error(DOMAIN, 'LiveViewController', `获取JWT令牌失败: ${authError.message}`); throw new Error("获取授权令牌失败: " + authError.message); } // 通过Push Kit更新实况窗 await LiveViewController.updateRemoteLiveViewViaPushKit( pushToken, flightData, LiveViewController.activityId, authorization ); return await LiveDataService.updateRemoteLiveView(LiveViewController.deviceId, flightData); } /** * 结束实况窗 * @returns Promise - 结束结果 */ public static async endLiveView(): Promise { hilog.info(DOMAIN, 'LiveViewController', 'Ending live view'); if (!LiveViewController.deviceId) { const errorMsg = "设备ID未获取"; hilog.error(DOMAIN, 'LiveViewController', errorMsg); throw new Error(errorMsg); } // 获取设备ID const deviceId = LiveViewController.getDeviceId(); if (!deviceId) { throw new Error("设备ID获取失败"); } // 获取Push Token let pushToken: string; try { pushToken = await LiveDataService.fetchPushToken(deviceId); if (!pushToken) { throw new Error("未能获取到推送令牌"); } } catch (tokenError) { hilog.error(DOMAIN, 'LiveViewController', `获取Push Token失败: ${tokenError.message}`); throw new Error("获取推送令牌失败: " + tokenError.message); } // 获取JWT令牌 let authorization: string; try { authorization = await LiveViewController.getAuthorizationToken(); if (!authorization) { throw new Error("未能获取到授权令牌"); } } catch (authError) { hilog.error(DOMAIN, 'LiveViewController', `获取JWT令牌失败: ${authError.message}`); throw new Error("获取授权令牌失败: " + authError.message); } // 通过Push Kit结束实况窗 await LiveViewController.endRemoteLiveViewViaPushKit( pushToken, LiveViewController.activityId, authorization ); // 清理WantAgent if (LiveViewController.wantAgentInstance) { try { hilog.info(DOMAIN, 'LiveViewController', 'Cancelling wantAgent'); await wantAgent.cancel(LiveViewController.wantAgentInstance); LiveViewController.wantAgentInstance = null; hilog.info(DOMAIN, 'LiveViewController', 'WantAgent cancelled successfully'); } catch (error) { hilog.error(DOMAIN, 'LiveViewController', `Failed to cancel wantAgent: ${error.message}`); } } // 结束本地实况窗 try { await LiveViewController.stopLiveView(); hilog.info(DOMAIN, 'LiveViewController', 'Local live view stopped successfully'); } catch (error) { hilog.error(DOMAIN, 'LiveViewController', `Failed to stop local live view: ${error.message}`); } hilog.info(DOMAIN, 'LiveViewController', 'Ending remote live view'); return await LiveDataService.endRemoteLiveView(LiveViewController.deviceId); } /** * 将飞行员数据转换为航班数据格式 * @param pilot 飞行员数据 * @returns FlightData 航班数据 */ public static convertPilotToFlightData(pilot: PilotData): FlightData { hilog.info(DOMAIN, 'LiveViewController', `Converting pilot to flight data: ${pilot.callsign}`); const flightData: FlightData = { flightNumber: pilot.callsign, altitude: pilot.altitude, speed: pilot.groundSpeed, origin: pilot.departureAirport || "未知", // 防止空字符串 destination: pilot.destinationAirport || "未知", // 防止空字符串 originName: "出发机场", // 固定显示 destinationName: "到达机场", // 固定显示 statusCode: 1, statusText: "飞行中" }; hilog.info(DOMAIN, 'LiveViewController', `Converted flight data: ${JSON.stringify(flightData)}`); return flightData; } /** * 校验实况窗功能是否启用 * @returns boolean - 是否启用 */ private static async isLiveViewEnabled(): Promise { try { hilog.info(DOMAIN, 'LiveViewController', 'Checking if live view is enabled'); const enabled = await liveViewManager.isLiveViewEnabled(); hilog.info(DOMAIN, 'LiveViewController', `Live view enabled status: ${enabled}`); return enabled; } catch (error) { hilog.error(DOMAIN, 'LiveViewController', `Failed to check live view status: ${error.message}`); return false; } } /** * 构建点击动作WantAgent * @returns Want - 点击后的跳转意图 */ public static async buildWantAgent(): Promise { try { hilog.info(DOMAIN, 'LiveViewController', 'Building WantAgent'); const wantAgentInfo: wantAgent.WantAgentInfo = { wants: [ { bundleName: 'com.example.ldpflyefb', // 应用实际bundleName abilityName: 'EntryAbility', moduleName: 'entry', parameters: { targetPage: 'map', flightNo: LiveViewController.selectedPilot?.callsign || '', departure: LiveViewController.selectedPilot?.departureAirport || '', destination: LiveViewController.selectedPilot?.destinationAirport || '' } } as Want ], operationType: wantAgent.OperationType.START_ABILITY, requestCode: 0, wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] }; hilog.info(DOMAIN, 'LiveViewController', `WantAgent info: ${JSON.stringify(wantAgentInfo)}`); LiveViewController.wantAgentInstance = await wantAgent.getWantAgent(wantAgentInfo); hilog.info(DOMAIN, 'LiveViewController', 'WantAgent created successfully'); } catch (error) { hilog.error(DOMAIN, 'LiveViewController', `Failed to create WantAgent: ${error.message}`); throw new Error(`WantAgent创建失败: ${error.message}`); } } /** * 获取WantAgent实例 * @returns WantAgent实例 */ public static getWantAgent(): WantAgent | null { hilog.info(DOMAIN, 'LiveViewController', `Getting WantAgent instance: ${LiveViewController.wantAgentInstance !== null}`); return LiveViewController.wantAgentInstance; } /** * 构建实况胶囊数据(本地API格式) * @param flightData 航班数据 * @returns capsuleData 实况胶囊数据 */ public static buildCapsuleData(flightData: FlightData): CapsuleData { hilog.info(DOMAIN, 'LiveViewController', `Building capsule data for flight: ${flightData.flightNumber}`); // 提供默认值而不是抛出错误 const speed = flightData.speed || 0; const altitude = flightData.altitude || 0; const capsuleData: CapsuleData = { //实况胶囊数据显示 type: 1, status: 1, icon: "icon.png", //实况胶囊左侧图标定义,你爹地默认使用LDP FLY的图标 bgColor: "#FF0A59F7", // Push Kit格式 backgroundColor: "#FF0A59F7", // 本地API格式 title: "飞行中", // 固定显示"飞行中" content: flightData.flightNumber // 显示航班号 }; hilog.info(DOMAIN, 'LiveViewController', `Built capsule data: ${JSON.stringify(capsuleData)}`); return capsuleData; } /** * 转换胶囊数据为Push Kit格式 * @param capsule 本地胶囊数据 * @returns PushKitCapsuleData Push Kit格式的胶囊数据 */ private static convertCapsuleForPushKit(capsule: CapsuleData): PushKitCapsuleData { hilog.info(DOMAIN, 'LiveViewController', 'Converting capsule data for Push Kit'); // 验证数据完整性 if (!capsule || !capsule.type || !capsule.status || capsule.icon === undefined || !capsule.bgColor || !capsule.title) { const errorMsg = "胶囊数据不完整"; hilog.error(DOMAIN, 'LiveViewController', `${errorMsg}. Capsule data: ${JSON.stringify(capsule)}`); throw new Error(errorMsg); } // 验证胶囊类型 if (capsule.type !== 1 && capsule.type !== 2) { const errorMsg = "胶囊类型必须为1或2"; hilog.error(DOMAIN, 'LiveViewController', `${errorMsg}. Type: ${capsule.type}`); throw new Error(errorMsg); } // 验证背景颜色格式 if (!/^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(capsule.bgColor)) { const errorMsg = "背景颜色格式必须为#RRGGBB或#AARRGGBB"; hilog.error(DOMAIN, 'LiveViewController', `${errorMsg}. Color: ${capsule.bgColor}`); throw new Error(errorMsg); } const pushKitCapsuleData: PushKitCapsuleData = { type: capsule.type, status: capsule.status, icon: capsule.icon || "flight_icon.png", // 提供默认图标 bgColor: capsule.bgColor, // 字段名转换 title: capsule.title, content: capsule.content // 可选字段 }; hilog.info(DOMAIN, 'LiveViewController', `Converted PushKit capsule data: ${JSON.stringify(pushKitCapsuleData)}`); return pushKitCapsuleData; } /** * 通过PHP接口启动实况窗 * @param token Push Token * @param flightData 航班数据 * @param activityId 实况活动ID * @param authorization JWT授权令牌 */ public static async startRemoteLiveViewViaPushKit(token: string, flightData: FlightData, activityId: number, authorization: string): Promise { try { hilog.info(DOMAIN, 'LiveViewController', `Starting remote live view via PHP API. Activity ID: ${activityId}`); const httpRequest = http.createHttp(); const requestData: StartLiveViewRequestData = { token: token, flight_data: flightData, activity_id: activityId, authorization: authorization }; hilog.info(DOMAIN, 'LiveViewController', `Request data: ${JSON.stringify(requestData)}`); const response = await httpRequest.request( LiveViewController.START_LIVE_VIEW_PUSH_API, { method: http.RequestMethod.POST, header: { 'Content-Type': 'application/json' }, extraData: JSON.stringify(requestData) } ); hilog.info(DOMAIN, 'LiveViewController', `Start remote live view via PHP API response code: ${response.responseCode}`); hilog.info(DOMAIN, 'LiveViewController', `Start remote live view via PHP API response: ${response.result}`); const responseText = response.result as string; const responseJson = JSON.parse(responseText) as PhpApiResponse; hilog.info(DOMAIN, 'LiveViewController', `Parsed response: ${JSON.stringify(responseJson)}`); // 修复错误判断逻辑:将"80000000"视为成功响应 if ((responseJson.success === false) || (responseJson.code && responseJson.code !== "80000000" && responseJson.code !== "200" && responseJson.code !== 200)) { const errorMsg = `PHP API Error: ${responseJson.msg || responseJson.error || responseJson.code}`; hilog.error(DOMAIN, 'LiveViewController', errorMsg); throw new Error(errorMsg); } hilog.info(DOMAIN, 'LiveViewController', 'Remote live view started successfully via PHP API'); } catch (error) { const err = error as Error; hilog.error(DOMAIN, 'LiveViewController', `Failed to start remote live view via PHP API: ${err.message}`); hilog.error(DOMAIN, 'LiveViewController', `Stack trace: ${err.stack}`); throw new Error(`通过PHP接口启动实况窗失败: ${err.message}`); } } /** * 通过PHP接口更新实况窗 * @param token Push Token * @param flightData 航班数据 * @param activityId 实况活动ID * @param authorization JWT授权令牌 */ public static async updateRemoteLiveViewViaPushKit(token: string, flightData: FlightData, activityId: number, authorization: string): Promise { try { hilog.info(DOMAIN, 'LiveViewController', `Updating remote live view via PHP API. Activity ID: ${activityId}`); const httpRequest = http.createHttp(); const requestData: UpdateLiveViewRequestData = { token: token, flight_data: flightData, activity_id: activityId, authorization: authorization }; hilog.info(DOMAIN, 'LiveViewController', `Request data: ${JSON.stringify(requestData)}`); const response = await httpRequest.request( LiveViewController.UPDATE_LIVE_VIEW_PUSH_API, { method: http.RequestMethod.POST, header: { 'Content-Type': 'application/json' }, extraData: JSON.stringify(requestData) } ); hilog.info(DOMAIN, 'LiveViewController', `Update remote live view via PHP API response code: ${response.responseCode}`); hilog.info(DOMAIN, 'LiveViewController', `Update remote live view via PHP API response: ${response.result}`); const responseText = response.result as string; const responseJson = JSON.parse(responseText) as PhpApiResponse; hilog.info(DOMAIN, 'LiveViewController', `Parsed response: ${JSON.stringify(responseJson)}`); // 修复错误判断逻辑:将"80000000"视为成功响应 if ((responseJson.success === false) || (responseJson.code && responseJson.code !== "80000000" && responseJson.code !== "200" && responseJson.code !== 200)) { const errorMsg = `PHP API Error: ${responseJson.msg || responseJson.error || responseJson.code}`; hilog.error(DOMAIN, 'LiveViewController', errorMsg); throw new Error(errorMsg); } hilog.info(DOMAIN, 'LiveViewController', 'Remote live view updated successfully via PHP API'); } catch (error) { const err = error as Error; hilog.error(DOMAIN, 'LiveViewController', `Failed to update remote live view via PHP API: ${err.message}`); hilog.error(DOMAIN, 'LiveViewController', `Stack trace: ${err.stack}`); throw new Error(`通过PHP接口更新实况窗失败: ${err.message}`); } } /** * 通过PHP接口结束实况窗 * @param token Push Token * @param activityId 实况活动ID * @param authorization JWT授权令牌 */ public static async endRemoteLiveViewViaPushKit(token: string, activityId: number, authorization: string): Promise { try { hilog.info(DOMAIN, 'LiveViewController', `Ending remote live view via PHP API. Activity ID: ${activityId}`); const httpRequest = http.createHttp(); const requestData: EndLiveViewRequestData = { token: token, activity_id: activityId, authorization: authorization }; hilog.info(DOMAIN, 'LiveViewController', `Request data: ${JSON.stringify(requestData)}`); const response = await httpRequest.request( LiveViewController.END_LIVE_VIEW_PUSH_API, { method: http.RequestMethod.POST, header: { 'Content-Type': 'application/json' }, extraData: JSON.stringify(requestData) } ); hilog.info(DOMAIN, 'LiveViewController', `End remote live view via PHP API response code: ${response.responseCode}`); hilog.info(DOMAIN, 'LiveViewController', `End remote live view via PHP API response: ${response.result}`); const responseText = response.result as string; const responseJson = JSON.parse(responseText) as PhpApiResponse; hilog.info(DOMAIN, 'LiveViewController', `Parsed response: ${JSON.stringify(responseJson)}`); // 修复错误判断逻辑:将"80000000"视为成功响应 if ((responseJson.success === false) || (responseJson.code && responseJson.code !== "80000000" && responseJson.code !== "200" && responseJson.code !== 200)) { const errorMsg = `PHP API Error: ${responseJson.msg || responseJson.error || responseJson.code}`; hilog.error(DOMAIN, 'LiveViewController', errorMsg); throw new Error(errorMsg); } hilog.info(DOMAIN, 'LiveViewController', 'Remote live view ended successfully via PHP API'); } catch (error) { const err = error as Error; hilog.error(DOMAIN, 'LiveViewController', `Failed to end remote live view via PHP API: ${err.message}`); hilog.error(DOMAIN, 'LiveViewController', `Stack trace: ${err.stack}`); throw new Error(`通过PHP接口结束实况窗失败: ${err.message}`); } } /** * 构建本地实况窗视图 * @returns Promise 实况窗对象 */ private static async buildLocalLiveView(flightData: FlightData): Promise { // 获取WantAgent实例 const wantAgent: WantAgent | null = LiveViewController.getWantAgent(); if (!wantAgent) { throw new Error("WantAgent未初始化"); } return { id: 0, event: "FLIGHT", liveViewData: { primary: { title: flightData.flightNumber, // 只显示航班号 content: [ { text: "高度 " }, { text: `${flightData.altitude}`, textColor: "#FF0A59F7" }, { text: " ft" }, { text: " | " }, { text: "速度 " }, { text: `${flightData.speed}`, textColor: "#FF0A59F7" }, { text: " kts" }, ], keepTime: 15, backgroundType: liveViewManager.BackgroundType.SYS_BACKGROUND_FLIGHT_SUNSET, clickAction: wantAgent, layoutData: { layoutType: liveViewManager.LayoutType.LAYOUT_TYPE_FLIGHT, spaceIcon: "flight_icon1.png", firstTitle: flightData.origin || "未知", // 防止空字符串导致参数错误 firstContent: flightData.originName || "出发机场", lastTitle: flightData.destination || "未知", // 防止空字符串导致参数错误 lastContent: flightData.destinationName || "到达机场", additionalText: "数据来源于FSD服务器,仅供参考 | LDP FLY空天模拟飞行平台", } }, // 添加实况胶囊数据 - 修改为新的显示格式 capsule: { type: 1, status: 1, icon: "icon.png", backgroundColor: "#FF0A59F7", title: "飞行中", // 固定显示"飞行中" content: flightData.flightNumber // 显示航班号 } } }; } /** * 更新本地实况窗 * @returns Promise 更新结果 */ public static async updateLocalLiveView(): Promise { // 校验实况窗开关是否打开 if (!await LiveViewController.isLiveViewEnabled()) { throw new Error("Live view is disabled."); } if (!LiveViewController.selectedPilot) { throw new Error("没有选中的飞行员"); } // 转换选中的飞行员数据为航班数据格式 const flightData = LiveViewController.convertPilotToFlightData(LiveViewController.selectedPilot); // 构建实况窗视图 const liveView = await LiveViewController.buildLocalLiveView(flightData); // 更新实况窗 return await liveViewManager.updateLiveView(liveView); } /** * 结束本地实况窗 * @returns Promise 结束结果 */ public static async stopLiveView(): Promise { // 校验实况窗开关是否打开 if (!await LiveViewController.isLiveViewEnabled()) { throw new Error("Live view is disabled."); } if (!LiveViewController.selectedPilot) { throw new Error("没有选中的飞行员"); } // 转换选中的飞行员数据为航班数据格式 const flightData = LiveViewController.convertPilotToFlightData(LiveViewController.selectedPilot); // 修改实况窗内容为结束状态 const liveView = await LiveViewController.buildLocalLiveView(flightData); liveView.liveViewData.primary.title = `${flightData.flightNumber} 已到达`; liveView.liveViewData.primary.content = [ { text: '航班已安全降落,' }, { text: '感谢您的飞行' } ]; liveView.liveViewData.primary.layoutData = { layoutType: liveViewManager.LayoutType.LAYOUT_TYPE_FLIGHT, spaceIcon: "flight_icon1.png", firstTitle: flightData.origin || "未知", // 防止空字符串导致参数错误 firstContent: flightData.originName || "出发机场", lastTitle: flightData.destination || "未知", // 防止空字符串导致参数错误 lastContent: flightData.destinationName || "到达机场", additionalText: "数据来源于FSD服务器,仅供参考 | LDP FLY空天模拟飞行平台", }; liveView.liveViewData.capsule = { type: 1, status: 1, icon: "icon.png", backgroundColor: "#FF0A59F7", title: `${flightData.flightNumber} 已到达` }; // 结束实况窗 return await liveViewManager.stopLiveView(liveView); } /** * 获取JWT授权令牌 * @returns Promise JWT令牌 */ private static async getAuthorizationToken(): Promise { try { const httpRequest = http.createHttp(); const response = await httpRequest.request( 'https://system.ldpfly.cn/hmos/getJwtToken.php', { method: http.RequestMethod.GET, header: { 'Content-Type': 'application/json' } } ); // 检查HTTP状态码 if (response.responseCode !== 200) { throw new Error(`HTTP Error: ${response.responseCode}`); } const resultText = response.result as string; // 检查返回内容是否为HTML(错误页面) if (resultText.trim().startsWith(' 航班数据 */ private static async fetchFlightDataFromOnlinePilots(): Promise { try { // 获取所有在线飞行员数据 const onlinePilots = await LiveDataService.fetchOnlinePilots(); // 查找与当前选中飞行员匹配的数据 const selectedPilotCallsign = LiveViewController.selectedPilot?.callsign; const matchingPilot = onlinePilots.find(pilot => pilot.callsign === selectedPilotCallsign); if (matchingPilot) { // 将PilotData转换为FlightData return LiveViewController.convertPilotToFlightData(matchingPilot); } else { // 如果未找到匹配的飞行员,抛出错误 throw new Error(`未找到呼号为 ${selectedPilotCallsign} 的飞行员数据`); } } catch (error) { const err = error as Error; hilog.error(DOMAIN, 'LiveViewController', `获取航班数据失败: ${err.message}`); throw new Error('获取航班数据失败: ' + err.message); } } }