import { Subject } from 'rxjs'; import httpRequest from '../services/httpRequest'; import { KTJOrg, Measurement, RailType, SaveMeasureDTO, SettingDTO, StationItem, } from '../services/apiTypes'; import { MobileDatagram, SyncProgress } from '../services/mobileWsType'; declare global { interface Window { WebViewJavascriptBridge: { callHandler: ( name: string, args: Record, callback: (res: string) => void ) => void; registerHandler: ( name: string, func: (data: string, callback: (res: string) => void) => void ) => void; }; WVJBCallbacks: Array<(bridge: typeof window.WebViewJavascriptBridge) => void>; SyncBridgeJS: { call: (methodName: string, param: string) => string; }; } } declare global { interface Window { ReactNativeWebView: { postMessage: (arg: string) => void }; bridgeFunc: Record; bridgeCall: (func: string, param: string) => void; } } export function setupWebViewJavascriptBridge( callback: (bridge: typeof window.WebViewJavascriptBridge) => void ) { if (window.WebViewJavascriptBridge) { return callback(window.WebViewJavascriptBridge); } if (/android/i.test(navigator.userAgent)) { document.addEventListener( 'WebViewJavascriptBridgeReady', function () { callback(window.WebViewJavascriptBridge); }, false ); } else { if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; WVJBIframe.src = 'https://__bridge_loaded__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function () { document.documentElement.removeChild(WVJBIframe); }, 0); } } export type BridgeBaseResult = { success: boolean; data: T; message: string; }; type ShowModelParam = Partial<{ title: string; // 非必填,但 title 和 content 至少要填一个 content: string; // 非必填,但 title 和 content 至少要填一个 contentAlignCenter: boolean; // 内容文本水平居中? 默认 false, 居左 showCancel: boolean; // 默认 true cancelText: string; //默认 '取消' // cancelColor: string; // 默认'#333333' confirmText: string; // 默认 '确定' // confirmColor: string; // 默认 APP主题色 }>; // 是否运行在 原生APP 的 WebView 中 export const appWebview = navigator.userAgent.includes('iFlyTop-mobile'); const bridgeSub = new Subject(); export const bridgeOb = bridgeSub.asObservable(); export function emitBridgeEvent(event: MobileDatagram) { bridgeSub.next(event); } export function registerBridgeFunc() { // window.bridgeFunc = { // peripheralStatus: (param: string) => { // bridgeSub.next({ func: 'peripheralStatus', data: JSON.parse(param) }); // }, // }; // window.bridgeCall = (func, param) => { // const res = window.bridgeFunc[func].call(null, param); // console.log('res:', res); // }; // const jsFuncs = ['funcInJs']; // jsFuncs.forEach((funcName) => { // window.WebViewJavascriptBridge.registerHandler(funcName, (data, callback) => { // bridgeSub.next({ func: funcName, data: JSON.parse(data) }); // callback(JSON.stringify({ success: true })); // }); // }); } export default class Bridge { static register(name: string, func: (data: string, callback: (res: string) => void) => void) { if (appWebview) { window.WebViewJavascriptBridge.registerHandler(name, func); } } static showModal(param: ShowModelParam) { if (appWebview) { return new Promise<'confirm' | 'cancel'>((resolve) => { window.WebViewJavascriptBridge.callHandler('showModal', param, (res) => { resolve(res as 'confirm' | 'cancel'); }); }); } else { return Promise.resolve('confirm' as const); } } static startMeasure() { if (appWebview) { return new Promise((resolve) => { // window.WebViewJavascriptBridge.callHandler('startMeasure', {}, (res) => { // resolve(JSON.parse(res)); // }); const res = window.SyncBridgeJS.call('startMeasure', ''); resolve(JSON.parse(res)); }); } else { return httpRequest({ url: '/api/measure/start', method: 'POST' }); } } static getUploadedRecords(param: { lastId?: number; size: number }) { if (appWebview) { return new Promise>((resolve) => { const res = window.SyncBridgeJS.call('getUploadedRecords', JSON.stringify(param)); resolve(JSON.parse(res)); }); } else { return httpRequest>({ url: '/api/mobile/getUploadedRecords', method: 'GET', params: param, }); } } static getUnuploadRecords(param: { lastId?: number; size: number }) { if (appWebview) { return new Promise>((resolve) => { const res = window.SyncBridgeJS.call('getUnuploadRecords', JSON.stringify(param)); resolve(JSON.parse(res)); }); } else { return httpRequest>({ url: '/api/mobile/getUnuploadRecords', method: 'GET', params: param, }); } } static searchHistoryRecords(param: { keyword: string }) { if (appWebview) { return new Promise>((resolve) => { const res = window.SyncBridgeJS.call('searchHistoryRecords', JSON.stringify(param)); resolve(JSON.parse(res)); }); } else { return httpRequest>({ url: '/api/mobile/searchHistoryRecords', method: 'GET', params: param, }); } } static getMeasurementDetail(param: { id: number }) { if (appWebview) { return new Promise>((resolve) => { const res = window.SyncBridgeJS.call('getMeasurementDetail', JSON.stringify(param)); resolve(JSON.parse(res)); }); } else { return httpRequest>({ url: '/api/record/detail', method: 'POST', params: param, }); } } static scanPeripherals() { return httpRequest({ url: '/api/ble/list/start', method: 'POST', params: {}, }); } static stopScanPeripherals() { return httpRequest({ url: '/api/ble/list/stop', method: 'POST', params: {}, }); } static connectPeripheral(params: { mac: string }) { return httpRequest({ url: '/api/ble/connect', method: 'POST', params, }); } static disconnectPeripheral() { return httpRequest({ url: '/api/ble/disconnect', method: 'POST', params: {}, }); } static getConfig() { return httpRequest>({ url: '/api/system/config', method: 'POST', params: {}, }); } static saveConfig(params: SettingDTO) { return httpRequest({ url: '/api/system/config/save', method: 'POST', params, }); } static getSyncTaskList(params: { pageNum: number; size: number }) { return httpRequest>({ url: '/api/sync/list', method: 'POST', params, }); } static addSyncTask(params: { ids: number[] }) { return httpRequest({ url: '/api/sync/add', method: 'POST', params, }); } static getSyncProcess() { return httpRequest>({ url: '/api/sync/progress', method: 'POST', params: {}, }); } static clearSyncList() { return httpRequest({ url: '/api/sync/empty-all', method: 'POST', params: {}, }); } static clearFinishedSync() { return httpRequest({ url: '/api/sync/empty-finish', method: 'POST', params: {}, }); } static retryFailureSync() { return httpRequest({ url: '/api/sync/re-fail', method: 'POST', params: {}, }); } static getRecordList(params: { pageNum: number; size: number }) { return httpRequest }>>( { url: '/api/record/list', method: 'POST', params, } ); } static getRecordDetail(params: { id: number }) { return httpRequest>({ url: '/api/record/detail', method: 'POST', params, }); } static deleteRecords(params: { ids: number[] }) { return httpRequest({ url: '/api/record/delete', method: 'POST', params, }); } static uploadRecords(params: { ids: number[] }) { return httpRequest({ url: '/api/sync/add', method: 'POST', params, }); } static getBasicTrackList() { return httpRequest>({ url: '/api/basic/track-list', method: 'POST', params: {}, }); } static getTrackPoint(params: { code: string }) { return httpRequest>({ url: '/api/basic/track/get-by-code', method: 'POST', params, }); } static saveMeasure(params: SaveMeasureDTO) { console.log('保存测量 入参:', params); return httpRequest({ url: '/api/measure/save', method: 'POST', params, }); } static getOrgTree() { return httpRequest>({ url: '/api/basic/org', method: 'POST', params: {}, }); } static getStationList(params: { tljCode: string; gwdCode: string; xmCode: string }) { return httpRequest>({ url: '/api/basic/station', method: 'POST', params, }); } static needSyncBaseData() { return httpRequest>({ url: '/api/basic/ktj/check', method: 'POST', params: {}, }); } static syncBaseData() { return httpRequest({ url: '/api/basic/ktj/update', method: 'POST', params: {}, }); } }