main.js 12 KB

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