lex-xin пре 3 година
родитељ
комит
b6f048257a
4 измењених фајлова са 144 додато и 20 уклоњено
  1. 97 0
      src/helpers/native-message.ts
  2. 18 20
      src/helpers/request.ts
  3. 29 0
      src/helpers/utils.ts
  4. 0 0
      src/helpers/validate.ts

+ 97 - 0
src/helpers/native-message.ts

@@ -0,0 +1,97 @@
+import { browser, getRandomKey } from '/src/helpers/utils';
+
+export interface IPostMessage {
+  api: string;
+  content?: any;
+}
+
+/**
+ * 劫持postMessage
+ */
+
+const originalPostMessage = window.postMessage;
+
+window.postMessage = (message: IPostMessage) => {
+  // console.log('通过劫持', message)
+  originalPostMessage(message, '*');
+};
+
+/**
+ *
+ * 目前已支持API
+ *
+ * openWebView
+ *
+ */
+
+type CallBack = (evt?: IPostMessage) => void;
+
+const loop = () => {};
+
+const calls: { [key: string]: CallBack } = {};
+
+const browserInfo = browser();
+
+if (browserInfo.isApp) {
+  window.addEventListener('message', evt => {
+    try {
+      const data = evt.data
+        ? typeof evt.data === 'object'
+          ? evt.data
+          : JSON.parse(evt.data)
+        : {};
+      const uuid = data.content?.uuid || data.uuid;
+      try {
+        if (data.content) {
+          data.content = JSON.parse(data.content);
+        }
+      } catch (error) {}
+      if (data?.content?.uuid) {
+        console.log('data', data);
+      }
+      if (!uuid) {
+        const keys = Object.keys(calls).filter(
+          key => key.indexOf(data.api) === 0
+        );
+        for (const key of keys) {
+          const callback = calls[key] || loop;
+          callback(data);
+        }
+        return;
+      }
+      const callid = data.content?.uuid || data.uuid || data.api + data.uuid;
+      const callback = calls[callid] || loop;
+      callback(data);
+    } catch (error) {
+      console.error('通信消息解析错误', error);
+    }
+  });
+}
+
+const instance: any =
+  (window as any).DAYA || (window as any).webkit?.messageHandlers?.DAYA;
+
+export const postMessage = (data: IPostMessage, callback?: CallBack) => {
+  if (browserInfo.isApp) {
+    const uuid = getRandomKey();
+    calls[uuid] = callback || loop;
+    data.content = data.content ? { ...data.content, uuid } : { uuid };
+    instance.postMessage(JSON.stringify(data));
+    console.log('send:', JSON.stringify(data));
+  }
+};
+
+export const listenerMessage = (api: string, callback: CallBack) => {
+  if (browserInfo.isApp) {
+    const uuid = api + getRandomKey();
+    calls[uuid] = callback || loop;
+  }
+};
+
+export const promisefiyPostMessage = (
+  data: IPostMessage
+): Promise<IPostMessage | undefined> => {
+  return new Promise(resolve => {
+    postMessage(data, res => resolve(res));
+  });
+};

+ 18 - 20
helpers/request.ts → src/helpers/request.ts

@@ -1,8 +1,8 @@
 import { extend } from 'umi-request';
 import { Toast } from 'vant';
 import cleanDeep from 'clean-deep';
-import { browser } from '/src/helpers/utils';
-import ApiRouter from '/src/api-router';
+import { browser } from '@/helpers/utils';
+import { postMessage } from './native-message';
 
 export interface SearchInitParams {
   rows?: string | number;
@@ -11,7 +11,7 @@ export interface SearchInitParams {
 
 export interface InitSearchRespones {
   data: {
-    rows: any[],
+    rows: any[];
     [key: string]: any
   };
   [key: string]: any
@@ -24,16 +24,16 @@ const request = extend({
   timeout: 10000
 });
 
-request.use(async (ctx, next) => {
-  const { url, options } = ctx.req
-  const prefix = options.prefix || '';
-  const baseUrl: string = url.replace(prefix, '') || '';
-  const linkUrl: string = (ApiRouter as any)[baseUrl];
-  if (linkUrl) {
-    ctx.req.url = prefix + linkUrl;
-  }
-  await next();
-})
+// request.use(async (ctx, next) => {
+//   const { url, options } = ctx.req
+//   const prefix = options.prefix || '';
+//   const baseUrl: string = url.replace(prefix, '') || '';
+//   const linkUrl: string = (ApiRouter as any)[baseUrl];
+//   if (linkUrl) {
+//     ctx.req.url = prefix + linkUrl;
+//   }
+//   await next();
+// })
 
 request.interceptors.request.use(
   (url, options: any) => {
@@ -82,14 +82,12 @@ request.interceptors.response.use(
       if (!(data.code === 403 || data.code === 401)) {
         Toast(msg);
       }
-      const browserInfo = browser()
+      const browserInfo = browser();
       if (data.code === 403 && browserInfo.isApp && !isOpenLogin) {
-        if (browserInfo.android) {
-          (window as any).DAYA.postMessage(JSON.stringify({ api: 'login' }));
-        } else if (browserInfo.iPhone) {
-          (window as any).webkit.messageHandlers.DAYA.postMessage(
-            JSON.stringify({ api: 'login' })
-          );
+        if (browserInfo.isApp) {
+          postMessage({
+            api: 'login'
+          });
         }
       }
       throw new Error(msg);

+ 29 - 0
src/helpers/utils.ts

@@ -0,0 +1,29 @@
+export const browser = () => {
+  const u = navigator.userAgent;
+  //   app = navigator.appVersion;
+  return {
+    trident: u.indexOf('Trident') > -1, //IE内核
+    presto: u.indexOf('Presto') > -1, //opera内核
+    webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
+    gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
+    mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
+    ios: !!u.match(/Mac OS X/), //ios终端
+    // ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
+    android: u.indexOf('DAYAAPPA') > -1 || u.indexOf('Adr') > -1, //android终端
+    iPhone: u.indexOf('DAYAAPPI') > -1, //是否为iPhone或者QQHD浏览器
+    isApp:
+      u.indexOf('DAYAAPPI') > -1 ||
+      u.indexOf('DAYAAPPA') > -1 ||
+      u.indexOf('Adr') > -1,
+    iPad: u.indexOf('iPad') > -1, //是否iPad
+    webApp: u.indexOf('Safari') == -1, //是否web应该程序,没有头部与底部
+    weixin: u.indexOf('MicroMessenger') > -1, //是否微信 (2015-01-22新增)
+    huawei: !!u.match(/huawei/i) || !!u.match(/honor/i),
+    xiaomi: !!u.match(/mi\s/i) || !!u.match(/redmi/i) || !!u.match(/mix/i)
+  };
+};
+
+export const getRandomKey = () => {
+  const key = '' + new Date().getTime() + Math.floor(Math.random() * 1000000);
+  return key;
+}

+ 0 - 0
helpers/validate.ts → src/helpers/validate.ts