bridge.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. (function (window) {
  2. 'use strict';
  3. /**
  4. * ColorMapRun JSBridge SDK (Compatible Version)
  5. * 用于 H5 页面与 Flutter App 进行交互
  6. * 兼容性说明:
  7. * - 优先检测 uni.webView 标准通道
  8. * - 降级适配旧版 App 的 action:// 协议拦截和 window.share_wx 注入对象
  9. */
  10. var Bridge = {
  11. version: '1.0.2',
  12. /**
  13. * 内部核心发送方法
  14. */
  15. _post: function (action, data) {
  16. data = data || {};
  17. console.log('[Bridge] Call:', action, data);
  18. // 1. 优先尝试标准 uni 通道 (新版 App)
  19. if (window.uni && window.uni.postMessage) {
  20. window.uni.postMessage({
  21. data: {
  22. action: action,
  23. data: data
  24. }
  25. });
  26. return;
  27. }
  28. // 2. 降级适配 (旧版 App)
  29. this._fallback(action, data);
  30. },
  31. /**
  32. * 旧版 App 适配逻辑
  33. */
  34. _fallback: function (action, data) {
  35. var url = '';
  36. switch (action) {
  37. case 'back':
  38. // 尝试关闭页面或返回
  39. window.history.back();
  40. break;
  41. case 'toHome':
  42. // 协议: action://to_home/
  43. url = 'action://to_home/';
  44. break;
  45. case 'toLogin':
  46. // 协议: action://to_login/
  47. url = 'action://to_login/';
  48. break;
  49. case 'openMap':
  50. // 协议: action://to_map_app?title=xxx&latitude=xxx&longitude=xxx
  51. url = 'action://to_map_app?title=' + encodeURIComponent(data.name || '') +
  52. '&latitude=' + data.latitude +
  53. '&longitude=' + data.longitude;
  54. break;
  55. case 'openMatch':
  56. // 协议: action://to_detail/?id=xxx&matchType=xxx
  57. url = 'action://to_detail/?id=' + data.id +
  58. '&matchType=' + (data.type || 1);
  59. break;
  60. case 'openActivityList':
  61. // 协议: action://to_activity_list/?id=xxx&mapName=xxx
  62. url = 'action://to_activity_list/?id=' + data.id +
  63. '&mapName=' + encodeURIComponent(data.mapName || '');
  64. break;
  65. case 'shareWx':
  66. // 旧版使用注入对象 share_wx
  67. if (window.share_wx && window.share_wx.postMessage) {
  68. window.share_wx.postMessage(JSON.stringify(data));
  69. } else {
  70. console.error('[Bridge] share_wx injection not found');
  71. alert('微信分享功能不可用(环境不支持)');
  72. }
  73. return; // shareWx 不需要走 URL 拦截
  74. case 'launchWxMini':
  75. // 旧版使用注入对象 wx_launch_mini
  76. if (window.wx_launch_mini && window.wx_launch_mini.postMessage) {
  77. window.wx_launch_mini.postMessage(JSON.stringify(data));
  78. } else {
  79. console.error('[Bridge] wx_launch_mini injection not found');
  80. }
  81. return;
  82. case 'saveImage':
  83. // 旧版使用注入对象 save_base64
  84. if (window.save_base64 && window.save_base64.postMessage) {
  85. window.save_base64.postMessage(data.base64);
  86. } else {
  87. console.error('[Bridge] save_base64 injection not found');
  88. }
  89. return;
  90. default:
  91. console.warn('[Bridge] No legacy fallback for action:', action);
  92. }
  93. if (url) {
  94. console.log('[Bridge] Legacy URL jump:', url);
  95. // 触发 URL 拦截
  96. window.location.href = url;
  97. }
  98. },
  99. // ==============================
  100. // 公开 API
  101. // ==============================
  102. back: function () {
  103. this._post('back');
  104. },
  105. toHome: function() {
  106. this._post('toHome');
  107. },
  108. toLogin: function() {
  109. this._post('toLogin');
  110. },
  111. setTitle: function (title) {
  112. this._post('setTitle', { title: title });
  113. },
  114. openMap: function (latitude, longitude, name) {
  115. this._post('openMap', {
  116. latitude: latitude,
  117. longitude: longitude,
  118. name: name
  119. });
  120. },
  121. openMatch: function (id, type) {
  122. this._post('openMatch', {
  123. id: id,
  124. type: type
  125. });
  126. },
  127. openActivityList: function(id, mapName) {
  128. this._post('openActivityList', {
  129. id: id,
  130. mapName: mapName
  131. });
  132. },
  133. shareWx: function (options) {
  134. this._post('shareWx', options);
  135. },
  136. launchWxMini: function (username, path) {
  137. this._post('launchWxMini', { username: username, path: path });
  138. },
  139. saveImage: function (base64Str) {
  140. this._post('saveImage', { base64: base64Str });
  141. },
  142. getToken: function () {
  143. this._post('getToken');
  144. },
  145. _tokenCallback: null,
  146. onToken: function(callback) {
  147. this._tokenCallback = callback;
  148. },
  149. receiveToken: function(token) {
  150. console.log('[Bridge] Received token:', token);
  151. if (this._tokenCallback) {
  152. this._tokenCallback(token);
  153. }
  154. }
  155. };
  156. window.Bridge = Bridge;
  157. })(window);