Przeglądaj źródła

优化 AIO platform 功能调用

cc12458 1 miesiąc temu
rodzic
commit
3c7cc7ba04

+ 1 - 0
.gitignore

@@ -31,3 +31,4 @@ coverage
 
 components.d.ts
 auto-imports.d.ts
+six.aio-**.zip

+ 21 - 0
@types/bridge.d.ts

@@ -7,6 +7,14 @@ interface HandSummary {
 
 type HandKeys = 'chen' | 'chi' | 'fu' | 'hua' | 'kong' | 'ruan' | 'shi' | 'shu' | 'xi' | 'xian';
 
+interface ScanData {
+  code: string;
+  state: number;
+  type: number;
+}
+
+type ScanEvent = CustomEvent<{code: number, data?: ScanData, message?: string}>;
+
 export class Bridge extends EventTarget {
   public static getInstance(): Bridge;
 
@@ -28,4 +36,17 @@ export class Bridge extends EventTarget {
 
   public static print(): Promise<void>;
   public static print(params: { url?: string }): Promise<void>;
+
+  /**
+   * 监听扫码事件
+   * @param type 事件类型 'scan'
+   * @param listener 事件回调,参数为 ScanEvent
+   * @param options
+   */
+  addEventListener(type: 'scan', listener: (event: ScanEvent) => void, options?: boolean | AddEventListenerOptions): void;
 }
+
+export interface globalAIO {
+  scan(value: string): number;
+  print(value: string): void;
+}

+ 5 - 0
@types/global.d.ts

@@ -6,6 +6,11 @@ declare global {
   interface Window {
     /* six-aio 设备注入 */
     bridge: InstanceType<typeof import('./bridge').Bridge>;
+    /**
+     * webview 设备注入的 全局对象(历史遗留)
+     * @deprecated 使用 bridge
+     */
+    AIO: Partial<import('./bridge').globalAIO>;
   }
 
   /**

+ 50 - 46
src/loader/bridge.loader.ts

@@ -1,56 +1,60 @@
 import { processMethod, scanAccountMethod } from '@/request/api';
 import router                               from '@/router';
 
-import type { RouteLocation } from 'vue-router';
-
-
-export interface globalAIO {
-  scan(value: string): number;
-  print(value: string): void;
+import { platformIsAIO } from '@/platform';
+
+export function waitFor(condition: () => boolean | Promise<boolean>, timeout: number = 300 * 1000) {
+  const start = Date.now();
+  const { promise, resolve, reject } = Promise.withResolvers<void>();
+  const check = async () => {
+    try {
+      if (await condition()) resolve();
+      else if (timeout && Date.now() - start >= timeout) reject({ message: 'waitForBridge timeout' });
+      else requestAnimationFrame(check);
+    } catch (e) {
+      reject(e);
+    }
+  };
+  return check().then(
+    () => promise,
+    () => promise
+  );
 }
 
-declare var window: Window & typeof globalThis & { AIO: globalAIO };
-
-
 export default function bridgeLoader(): DEV.Loader {
-  async function scan(value: string, route?: RouteLocation) {
-    const { Toast } = await import(`@/platform/toast.ui`);
-    const toast = Toast.loading(100, { message: '加载中' });
-    const data = await scanAccountMethod(value).catch(() => {});
+  window.AIO ??= {};
+  window.AIO.scan ??= (value) => {
+    if (!value) return -1;
+    const event = new CustomEvent('scan', { detail: { code: value, state: 0, type: -1 } });
+    Bridge.getInstance().dispatchEvent(event);
+    return 0;
+  };
+  window.AIO.print ??= (value) => {
+    (window as any).sixWisdom.printPdfByUrl(value);
+  };
 
-    if ( data ) {
-      const path = data?.path ?? (
-        route?.path === '/screen' ? await processMethod() : route?.path
-      );
-      const key = Date.now();
-      sessionStorage.setItem(`scan_${ key }`, JSON.stringify(data));
-      await router.replace({ path, query: { scan: key } });
-      Toast.success('扫码成功');
+  return async function () {
+    if (platformIsAIO()) {
+      await waitFor(() => window.bridge != null);
+      Bridge.getInstance().addEventListener('scan', async ({ detail }) => {
+        if (detail.code !== 0 || detail.data?.code == null) return;
+        const route = unref(router.currentRoute);
+        if (route.meta?.scan) {
+          const { Toast } = await import(`@/platform/toast.ui`);
+          const toast = Toast.loading(100, { message: '加载中' });
+          const data = await scanAccountMethod(detail.data.code).catch(() => {});
+
+          if (data) {
+            const path = data?.path ?? (route?.path === '/screen' ? await processMethod() : route?.path);
+            const key = Date.now();
+            sessionStorage.setItem(`scan_${key}`, JSON.stringify(data));
+            await router.replace({ path, query: { scan: key } });
+            Toast.success('扫码成功');
+          }
+
+          toast.close();
+        } else import(`@/platform/notify.ui`).then(({ Notify }) => { Notify.warning(`请返回首页后,再进行扫码!`); });
+      });
     }
-    toast.close();
-  }
-
-
-  return async function() {
-    window.AIO ??= {} as globalAIO;
-
-    window.AIO.scan = (value) => {
-      if ( !value ) return -1;
-
-      const route = unref(router.currentRoute);
-
-      if ( !route.meta?.scan ) {
-        import(`@/platform/notify.ui`).then(({ Notify }) => { Notify.warning(`请返回首页后,再进行扫码!`); });
-        return 1;
-      }
-      scan(value, route);
-      return 0;
-    };
-
-    window.AIO.print = (value) => {
-      (
-        window as any
-      ).sixWisdom.printPdfByUrl(value);
-    };
   };
 }

+ 1 - 1
src/modules/report/report.page.vue

@@ -55,7 +55,7 @@ async function print() {
     try {
       await Bridge.print({ url });
     } catch (e) {
-      (window as any).sixWisdom.printPdfByUrl(url);
+      window.AIO?.print?.(url)
     }
     Toast.success(`开始打印`);
     Toast.success(`开始打印`);

+ 1 - 1
src/platform/index.ts

@@ -4,7 +4,7 @@ import { getURLSearchParams } from '@/tools';
 const userAgent = navigator.userAgent;
 
 export function platformIsAIO() {
-  return /aio\/\w+/i.test(userAgent);
+  return /Six\/applet \(AIO;.+\)/i.test(userAgent) || /aio\/\w+/i.test(userAgent);
 }
 
 export function getSerialNumberSync() {