main.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. import { createApp } from 'vue';
  2. import App from './App.vue';
  3. import router from './router';
  4. import store from './store';
  5. import Vant from 'vant';
  6. import { ConfigProvider } from 'vant';
  7. import 'vant/lib/index.css';
  8. import './styles/app.less';
  9. import './styles/font.less';
  10. import http from './plugins/http';
  11. import colors from './plugins/colors';
  12. // import ElementUI from 'element-ui';
  13. // import 'element-ui/lib/theme-chalk/index.css';
  14. import PageTitle from './components/PageTitle';
  15. import LikeButton from './components/LikeButton.vue';
  16. import Driver from './components/Driver.vue';
  17. import common from './mixins/common';
  18. import VueClipboard from 'vue-clipboard2';
  19. import queryString from 'query-string';
  20. import PageBar from './components/PageBar';
  21. import eruda from 'eruda';
  22. import mitt from 'mitt';
  23. import dayjs from 'dayjs';
  24. import relativeTime from 'dayjs/plugin/relativeTime';
  25. import calendar from 'dayjs/plugin/calendar';
  26. import duration from 'dayjs/plugin/duration';
  27. import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
  28. import customParseFormat from 'dayjs/plugin/customParseFormat';
  29. import { Toast, Dialog } from 'vant';
  30. const appHeight = () => {
  31. const doc = document.documentElement;
  32. doc.style.setProperty('--app-height', `${window.innerHeight}px`);
  33. };
  34. window.addEventListener('resize', appHeight);
  35. appHeight();
  36. Toast.setDefaultOptions('loading', { duration: 0 });
  37. require('dayjs/locale/zh-cn');
  38. const emitter = mitt();
  39. dayjs.locale('zh-cn');
  40. dayjs.extend(relativeTime);
  41. dayjs.extend(calendar);
  42. dayjs.extend(duration);
  43. dayjs.extend(isSameOrBefore);
  44. dayjs.extend(customParseFormat);
  45. let showConsole = localStorage.getItem('showConsole');
  46. if (showConsole && parseInt(showConsole) > new Date().getTime()) {
  47. eruda.init();
  48. store.commit('setShowConsole', true);
  49. }
  50. store.commit('setFirstUrl', location.href);
  51. import ImgContent from './components/ImgContent.vue';
  52. const app = createApp(App)
  53. .use(Vant)
  54. .use(http)
  55. .use(colors)
  56. // .use(ElementUI)
  57. .use(ConfigProvider)
  58. .use(VueClipboard)
  59. .mixin(common)
  60. .component('page-title', PageTitle)
  61. .component('like-button', LikeButton)
  62. .component('driver', Driver)
  63. .component('van-image', ImgContent)
  64. .component('page-bar', PageBar)
  65. .use(store)
  66. .use(router);
  67. app.config.globalProperties.emitter = emitter;
  68. app.config.globalProperties.dayjs = dayjs;
  69. let query = queryString.parse(location.search);
  70. if (query.code) {
  71. http.http.post('/user/code2openId', { code: query.code }).then(res => {
  72. localStorage.setItem('openId', res);
  73. });
  74. } else {
  75. if (/micromessenger/i.test(navigator.userAgent) && !/localhost|(192\.168)/i.test(location.host)) {
  76. // document.location.replace(location.origin + '/wx/redirect?redirectUrl=' + location.href);
  77. }
  78. }
  79. store.dispatch('getTime');
  80. if (query.invitor) {
  81. store.commit('setInvitor', query.invitor);
  82. if (query.id) {
  83. store.commit('setProductId', query.id);
  84. }
  85. }
  86. if (query.from) {
  87. store.commit('setFrom', query.from);
  88. }
  89. if (query.inviteCode) {
  90. store.commit('setInviteCode', query.inviteCode);
  91. }
  92. if (query.review === 'true' || query.review === true) {
  93. store.commit('setReview', true);
  94. }
  95. if (query.reviewPay === 'true' || query.reviewPay === true || sessionStorage.getItem('reviewPay')) {
  96. store.commit('setReviewPay', true);
  97. sessionStorage.setItem('reviewPay', true);
  98. }
  99. if (query.hopeMarket === 'true' || query.hopeMarket === true || sessionStorage.getItem('hopeMarket')) {
  100. store.commit('setHopeMarket', true);
  101. sessionStorage.setItem('hopeMarket', true);
  102. }
  103. const style = document.documentElement.style;
  104. style.setProperty('--safe-top', 'env(safe-area-inset-top)');
  105. style.setProperty('--safe-bottom', 'env(safe-area-inset-bottom)');
  106. style.setProperty('--safe-left', 'env(safe-area-inset-left)');
  107. style.setProperty('--safe-right', 'env(safe-area-inset-right)');
  108. const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
  109. const loadSplash = (onload, onerror) =>
  110. new Promise((resolve, reject) => {
  111. let isHide = false;
  112. function hideSplash() {
  113. if (isHide) return;
  114. isHide = true;
  115. splash.style.opacity = 0;
  116. setTimeout(() => {
  117. document.body.removeChild(splash);
  118. }, 800);
  119. resolve();
  120. }
  121. const splash = document.createElement('img');
  122. splash.className = 'splash-screen';
  123. splash.onload = () => {
  124. console.log('splash onload');
  125. onload && onload();
  126. setTimeout(() => {
  127. hideSplash();
  128. }, 2000);
  129. };
  130. splash.onerror = () => {
  131. hideSplash();
  132. onerror && onerror();
  133. };
  134. setTimeout(() => {
  135. hideSplash();
  136. }, 5000);
  137. splash.src = 'https://cdn.raex.vip/splash.jpg';
  138. document.body.append(splash);
  139. });
  140. if (navigator.userAgent.includes('#cordova#')) {
  141. document.addEventListener(
  142. 'deviceready',
  143. function () {
  144. StatusBar.overlaysWebView(true);
  145. function mountApp() {
  146. window.$vm = app.mount('#app');
  147. http.http
  148. .get('/appVersion/checkUpdate', {
  149. platform: window.cordova.platformId,
  150. version: navigator.appInfo.version
  151. })
  152. .then(res => {
  153. if (res.needUpdate) {
  154. window.$vm.$dialog.alert({
  155. message: '检测到新版本,请下载更新',
  156. confirmButtonText: '下载更新',
  157. beforeClose(action, done) {
  158. console.log(action);
  159. location.href = 'http://download.raex.vip';
  160. }
  161. });
  162. }
  163. });
  164. }
  165. loadSplash(
  166. () => {
  167. setTimeout(() => {
  168. navigator.splashscreen.hide();
  169. }, 100);
  170. mountApp();
  171. },
  172. () => {
  173. navigator.splashscreen.hide();
  174. mountApp();
  175. }
  176. ).then(res => {
  177. StatusBar.overlaysWebView(false);
  178. StatusBar.backgroundColorByHexString('#F5F7FA');
  179. StatusBar.styleDefault();
  180. });
  181. if ('ios' === window.cordova.platformId) {
  182. style.setProperty('--safe-top', 'env(safe-area-inset-top)');
  183. style.setProperty('--safe-bottom', 'env(safe-area-inset-bottom)');
  184. style.setProperty('--safe-left', 'env(safe-area-inset-left)');
  185. style.setProperty('--safe-right', 'env(safe-area-inset-right)');
  186. } else {
  187. if (window.AndroidNotch) {
  188. window.AndroidNotch.getInsetTop(
  189. px => {
  190. style.setProperty('--safe-top', px + 'px');
  191. },
  192. err => console.error('Failed to get insets top:', err)
  193. );
  194. window.AndroidNotch.getInsetRight(
  195. px => {
  196. style.setProperty('--safe-right', px + 'px');
  197. },
  198. err => console.error('Failed to get insets right:', err)
  199. );
  200. window.AndroidNotch.getInsetBottom(
  201. px => {
  202. style.setProperty('--safe-bottom', px + 'px');
  203. },
  204. err => console.error('Failed to get insets bottom:', err)
  205. );
  206. window.AndroidNotch.getInsetLeft(
  207. px => {
  208. style.setProperty('--safe-left', px + 'px');
  209. },
  210. err => console.error('Failed to get insets left:', err)
  211. );
  212. }
  213. }
  214. let t = 0;
  215. document.addEventListener(
  216. 'backbutton',
  217. e => {
  218. if (window.$vm.$route.matched.find(i => i.name === 'index')) {
  219. e.preventDefault();
  220. let t1 = new Date().getTime();
  221. console.log(t1 - t);
  222. if (t1 - t < 1000) {
  223. navigator.app.exitApp();
  224. } else {
  225. t = t1;
  226. window.$vm.$toast('再按一次退出');
  227. }
  228. } else {
  229. window.$vm.$router.go(-1);
  230. }
  231. },
  232. false
  233. );
  234. if ('ios' === window.cordova.platformId) {
  235. window.store.register({
  236. id: '358',
  237. alias: '358',
  238. type: window.store.CONSUMABLE
  239. });
  240. window.store.error(function (error) {
  241. console.log('ERROR ' + error.code + ': ' + error.message);
  242. });
  243. window.store
  244. .when('358')
  245. .updated(product => {
  246. emitter.emit('iapEvent', { event: 'updated', product });
  247. })
  248. .requested(product => {
  249. emitter.emit('iapEvent', { event: 'requested', product });
  250. })
  251. .initiated(product => {
  252. emitter.emit('iapEvent', { event: 'initiated', product });
  253. })
  254. .cancelled(product => {
  255. emitter.emit('iapEvent', { event: 'cancelled', product });
  256. })
  257. .approved(product => {
  258. product.finish();
  259. emitter.emit('iapEvent', { event: 'approved', product });
  260. })
  261. .verified(product => {
  262. emitter.emit('iapEvent', { event: 'verified', product });
  263. })
  264. .finished(product => {
  265. emitter.emit('iapEvent', { event: 'finished', product });
  266. });
  267. window.store.refresh();
  268. }
  269. },
  270. false
  271. );
  272. } else {
  273. loadSplash().then(res => {
  274. window.$vm = app.mount('#app');
  275. });
  276. }