index.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. // common-page/pages/web-view/index.js
  2. const Parse = getApp().Parse;
  3. const company = getApp().globalData.company;
  4. Page({
  5. /**
  6. * 页面的初始数据
  7. */
  8. data: {
  9. path: "",
  10. currentTitle: "", // 当前标题
  11. },
  12. // 标题轮询定时器
  13. titlePollingTimer: null,
  14. /**
  15. * 生命周期函数--监听页面加载
  16. */
  17. onLoad: function (options) {
  18. // 解码 URL
  19. let path = decodeURIComponent(options.path || '');
  20. console.log('===========================================');
  21. console.log('======= web-view 页面加载 =======');
  22. console.log('原始 options.path:', options.path);
  23. console.log('解码后的 path:', path);
  24. console.log('===========================================');
  25. // 拼接额外参数(避免重复添加已存在的参数)
  26. let hasQuery = path.indexOf('?') !== -1;
  27. let parsm = hasQuery ? '&' : '?';
  28. let params = [];
  29. // 提取 path 中已有的参数
  30. let existingParams = new Set();
  31. if (hasQuery) {
  32. const queryString = path.split('?')[1];
  33. if (queryString) {
  34. queryString.split('&').forEach(param => {
  35. const key = param.split('=')[0];
  36. existingParams.add(key);
  37. });
  38. }
  39. }
  40. // 只添加 path 中不存在的参数
  41. for (const key in options) {
  42. if(key != 'path' && key != 'url' && !existingParams.has(key)){
  43. params.push(key + '=' + options[key]);
  44. }
  45. }
  46. if(params.length > 0) {
  47. parsm = parsm + params.join('&');
  48. path = path + parsm;
  49. }
  50. console.log('最终 web-view URL:', path);
  51. console.log('URL 长度:', path.length);
  52. console.log('===========================================');
  53. this.setData({
  54. path: path
  55. })
  56. // 立即设置标题
  57. const passedStoreName = options.storeName ? decodeURIComponent(options.storeName) : '';
  58. const passedStoreId = options.storeId || '';
  59. if (passedStoreName) {
  60. this.setNavigationTitle(passedStoreName);
  61. }
  62. // 异步加载完整店铺信息(作为备份)
  63. this.loadAndSetStoreTitle(passedStoreId, passedStoreName);
  64. // 启动标题轮询监听
  65. this.startTitlePolling();
  66. },
  67. onReady: function () {
  68. },
  69. onShow: function () {
  70. this.startTitlePolling();
  71. },
  72. onHide: function () {
  73. this.stopTitlePolling();
  74. },
  75. onUnload: function () {
  76. this.stopTitlePolling();
  77. },
  78. /**
  79. * 页面相关事件处理函数--监听用户下拉动作
  80. */
  81. onPullDownRefresh: function () {
  82. },
  83. /**
  84. * 页面上拉触底事件的处理函数
  85. */
  86. onReachBottom: function () {
  87. },
  88. /**
  89. * 用户点击右上角分享
  90. */
  91. onShareAppMessage: function () {
  92. },
  93. /**
  94. * 处理来自 H5 页面的消息
  95. */
  96. handleMessage: function (e) {
  97. try {
  98. const messages = e.detail.data || [];
  99. // 找到最后一个标题更新消息
  100. let lastTitleMessage = null;
  101. for (let i = messages.length - 1; i >= 0; i--) {
  102. const msg = messages[i];
  103. if (msg.type === 'updateTitle' && msg.title) {
  104. lastTitleMessage = msg;
  105. break;
  106. }
  107. }
  108. // 更新标题
  109. if (lastTitleMessage) {
  110. this.setNavigationTitle(lastTitleMessage.title);
  111. }
  112. } catch (error) {
  113. console.error('❌ 处理消息失败:', error);
  114. }
  115. },
  116. /**
  117. * 设置导航栏标题(统一方法)
  118. */
  119. setNavigationTitle: function (title) {
  120. if (!title) {
  121. return;
  122. }
  123. // 若与当前标题一致则跳过,避免频繁触发
  124. if (title === this.data.currentTitle) {
  125. return;
  126. }
  127. // 简单节流:500ms 内重复更新跳过
  128. if (!this._lastTitleUpdateTs) {
  129. this._lastTitleUpdateTs = 0;
  130. }
  131. const now = Date.now();
  132. if (now - this._lastTitleUpdateTs < 500) {
  133. return;
  134. }
  135. this._lastTitleUpdateTs = now;
  136. // 更新当前标题记录
  137. this.setData({
  138. currentTitle: title
  139. });
  140. // 延迟调用微信 API 设置标题,确保页面已准备好
  141. setTimeout(() => {
  142. wx.setNavigationBarTitle({
  143. title: title,
  144. success: () => {
  145. console.log('✅ web-view 标题设置成功:', title);
  146. },
  147. fail: (err) => {
  148. console.warn('⚠️ web-view 标题设置失败(可忽略):', err.errMsg);
  149. // 不影响主流程,静默失败
  150. }
  151. });
  152. }, 100);
  153. },
  154. startTitlePolling: function () {
  155. this.stopTitlePolling();
  156. },
  157. stopTitlePolling: function () {
  158. if (this.titlePollingTimer) {
  159. clearInterval(this.titlePollingTimer);
  160. this.titlePollingTimer = null;
  161. }
  162. },
  163. /**
  164. * 加载店铺信息并设置页面标题
  165. */
  166. loadAndSetStoreTitle: async function (storeId = '', storeName = '') {
  167. try {
  168. let finalTitle = storeName;
  169. if (!finalTitle) {
  170. // 如果没有传入名字,按传入的 storeId 精确查询;再不行按 company 兜底
  171. if (storeId) {
  172. const q = new Parse.Query('ShopStore');
  173. const s = await q.get(storeId);
  174. if (s) {
  175. // 优先使用门店地址,如果没有地址则使用门店名称
  176. const address = s.get('address');
  177. const name = s.get('storeName');
  178. finalTitle = address || name || '';
  179. console.log('📍 web-view 门店信息:', {
  180. id: storeId,
  181. name: name,
  182. address: address,
  183. displayTitle: finalTitle
  184. });
  185. }
  186. }
  187. if (!finalTitle) {
  188. const storeQuery = new Parse.Query('ShopStore');
  189. storeQuery.equalTo('company', company);
  190. storeQuery.ascending('score');
  191. storeQuery.limit(1);
  192. const store = await storeQuery.first();
  193. if (store) {
  194. // 优先使用门店地址,如果没有地址则使用门店名称
  195. const address = store.get('address');
  196. const name = store.get('storeName');
  197. finalTitle = address || name || '';
  198. }
  199. }
  200. }
  201. if (!finalTitle) return;
  202. // 使用统一的设置标题方法
  203. this.setNavigationTitle(finalTitle);
  204. } catch (e) {
  205. console.error('设置 web-view 标题失败:', e);
  206. }
  207. }
  208. })