uni-compat.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. (function() {
  2. window.uni = window.uni || {};
  3. // 1. Network Requests
  4. uni.request = function(options) {
  5. let headers = options.header || {};
  6. let body = undefined;
  7. let url = options.url;
  8. // Handle Content-Type and Body
  9. if (options.method === 'POST') {
  10. if (!headers['Content-Type']) {
  11. headers['Content-Type'] = 'application/json';
  12. }
  13. if (headers['Content-Type'].includes('application/x-www-form-urlencoded')) {
  14. if (options.data) {
  15. body = Object.keys(options.data)
  16. .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(options.data[key])}`)
  17. .join('&');
  18. }
  19. } else {
  20. // Default to JSON
  21. if (options.data) {
  22. body = JSON.stringify(options.data);
  23. }
  24. }
  25. } else if (options.method === 'GET' && options.data) {
  26. // Append query params for GET
  27. const queryString = Object.keys(options.data)
  28. .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(options.data[key])}`)
  29. .join('&');
  30. url += (url.includes('?') ? '&' : '?') + queryString;
  31. }
  32. fetch(url, {
  33. method: options.method || 'GET',
  34. headers: headers,
  35. body: body
  36. })
  37. .then(response => {
  38. // You might want to handle non-200 status codes here if needed,
  39. // but uni.request success callback usually fires even for 4xx/5xx
  40. // with the statusCode in the result.
  41. return response.json().then(data => ({
  42. data: data,
  43. statusCode: response.status,
  44. header: response.headers
  45. })).catch(() => ({
  46. data: null, // or text
  47. statusCode: response.status,
  48. header: response.headers
  49. }));
  50. })
  51. .then(res => {
  52. if (options.success) {
  53. options.success(res);
  54. }
  55. })
  56. .catch(err => {
  57. console.error('uni.request error:', err);
  58. if (options.fail) {
  59. options.fail(err);
  60. }
  61. });
  62. };
  63. // 2. Storage
  64. uni.setStorageSync = function(key, data) {
  65. try {
  66. // uniApp stores data as is, but localStorage only supports strings.
  67. // We wrap it to handle types like numbers or booleans correctly upon retrieval if we wanted to match uni strictly,
  68. // but JSON.stringify is the standard web way.
  69. window.localStorage.setItem(key, JSON.stringify(data));
  70. } catch (e) {
  71. console.error('setStorageSync error', e);
  72. }
  73. };
  74. uni.getStorageSync = function(key) {
  75. try {
  76. const value = window.localStorage.getItem(key);
  77. if (value === null) return ''; // uniApp returns empty string if not found
  78. return JSON.parse(value);
  79. } catch (e) {
  80. return window.localStorage.getItem(key); // Fallback for non-JSON
  81. }
  82. };
  83. uni.setStorage = function(obj) {
  84. try {
  85. uni.setStorageSync(obj.key, obj.data);
  86. if(obj.success) obj.success();
  87. } catch(e) {
  88. if(obj.fail) obj.fail(e);
  89. }
  90. }
  91. uni.getStorage = function(obj) {
  92. try {
  93. const res = uni.getStorageSync(obj.key);
  94. if(obj.success) obj.success({ data: res });
  95. } catch(e) {
  96. if(obj.fail) obj.fail(e);
  97. }
  98. }
  99. uni.removeStorageSync = function(key) {
  100. window.localStorage.removeItem(key);
  101. }
  102. // 3. Interaction
  103. uni.showToast = function(options) {
  104. // Simple alert or console log for now.
  105. // In a real implementation, creating a DOM element for toast is better.
  106. // const title = options.title || '';
  107. // const icon = options.icon || 'none';
  108. // console.log(`[Toast] ${title} (${icon})`);
  109. // // alert(title); // Alert is too intrusive
  110. // Create a simple custom toast
  111. const toast = document.createElement('div');
  112. toast.style.position = 'fixed';
  113. toast.style.top = '50%';
  114. toast.style.left = '50%';
  115. toast.style.transform = 'translate(-50%, -50%)';
  116. toast.style.backgroundColor = 'rgba(0,0,0,0.7)';
  117. toast.style.color = '#fff';
  118. toast.style.padding = '10px 20px';
  119. toast.style.borderRadius = '5px';
  120. toast.style.zIndex = '9999';
  121. toast.innerText = options.title;
  122. document.body.appendChild(toast);
  123. setTimeout(() => {
  124. document.body.removeChild(toast);
  125. }, options.duration || 1500);
  126. };
  127. uni.showLoading = function(options) {
  128. // console.log('[Loading]', options);
  129. }
  130. uni.hideLoading = function() {
  131. // console.log('[HideLoading]');
  132. }
  133. // 4. Navigation
  134. uni.navigateTo = function(options) {
  135. window.location.href = options.url;
  136. };
  137. // 5. System Info
  138. uni.getSystemInfoSync = function() {
  139. return {
  140. appVersion: '1.0.0', // Mock
  141. platform: 'devtools' // Mock
  142. };
  143. };
  144. // 6. Global App Object Mock
  145. window.getApp = function() {
  146. return {
  147. globalData: {
  148. defaultMatchLogo: 'https://orienteering.beswell.com/card/nanning/logo.png' // Placeholder
  149. },
  150. $cardconfigType: 'remote'
  151. };
  152. };
  153. // 7. App Action Helper (Mocking native bridge)
  154. window.appAction = function(url, actType) {
  155. console.log('[appAction]', url);
  156. if (url.startsWith('action://')) {
  157. if (url.includes('to_login')) {
  158. alert('请先登录 (模拟跳转)');
  159. } else if (url.includes('to_home')) {
  160. window.location.href = 'index.html';
  161. } else if (url.includes('to_detail')) {
  162. // Extract ID if possible or just alert
  163. alert('正在进入比赛... (模拟跳转)');
  164. }
  165. } else {
  166. window.location.href = url;
  167. }
  168. };
  169. })();