import { createApp, h, render } from "vue"; import App from "./App.vue"; import { createRouter, createWebHashHistory } from "vue-router"; import { routes } from "./router"; import less from "less"; import "./styles/ch.less"; import BaseSkeleton from './components/BaseSkeleton.vue'; import { showToast, showLoadingToast, showSuccessToast, showFailToast, showNotify, showDialog, showConfirmDialog, showImagePreview, closeToast } from "vant"; import "vant/es/notify/style"; import "vant/es/dialog/style"; import "vant/es/toast/style"; import "vant/es/image-preview/style"; import "vant/es/calendar/style"; const app = createApp(App); import VueQr from "vue-qr"; app.component("VueQr", VueQr); const router = createRouter({ history: createWebHashHistory(), routes, scrollBehavior(to, from, savedPosition) { if (to.meta.cache && savedPosition) { return savedPosition; } return { top: 0 }; } }); // 全局变量:标识是否正在页面切换 let isPageChanging = false; // 全局变量:存储当前页面路径 let currentPath = ''; router.beforeEach((to, from, next) => { abortAll(); // 标记开始页面切换 isPageChanging = true; next(); }); router.afterEach((to, from) => { // 更新当前页面路径 currentPath = to.fullPath; // 页面切换完成后,延迟重置标志,给首次请求留出时间 setTimeout(() => { isPageChanging = false; }, 300); }); // 暴露标志供 http.js 使用 window.__isPageChanging = () => isPageChanging; window.__currentPath = () => currentPath; app.use(router); import pinia from './stores'; import { useDatadicStore } from './stores/datadic'; import { useUserStore } from './stores/user'; app.use(pinia); const datadicStore = useDatadicStore() const userStore = useUserStore() // 全局前置守卫 // router.beforeEach((to, from, next) => { // if (to.meta.noLogin) { // return next(); // } // const isLogin = userStore.isLogin; // if (!isLogin) { // return next({ name: 'Login', query: { redirect: to.fullPath } }); // } // next(); // }); app.config.globalProperties.$datadic = { get: (code) => datadicStore.fetch(code), getContent: async (code) => { const item = await datadicStore.fetch(code) return item ? item.contents : '' }, } app.config.globalProperties.$userInfo = userStore.getUserInfo; app.config.globalProperties.$showDialog = showDialog; app.config.globalProperties.$showConfirmDialog = showConfirmDialog; app.config.globalProperties.$showNotify = showNotify; app.config.globalProperties.$showToast = showToast; app.config.globalProperties.$showLoadingToast = showLoadingToast; app.config.globalProperties.$showSuccessToast = showSuccessToast; app.config.globalProperties.$showFailToast = showFailToast; app.config.globalProperties.$closeToast = closeToast; app.config.globalProperties.$showImagePreview = showImagePreview; app.config.globalProperties.$toMoney = (e, label, length = 2) => { const num = parseFloat(e).toFixed(length); const [a, b] = num.split('.'); return `${a}.<${label}>${b}`; }; app.config.globalProperties.$autoToast = (val, msg, type = 'Fail', isThrow = true) => { if (val) { app.config.globalProperties[`$show${type}Toast`](msg); if (isThrow) throw msg; } }; let skeleton; app.config.globalProperties.$showSkeleton = () => { if (!skeleton) skeleton = h(BaseSkeleton); render(skeleton, document.body); if (!document.body.contains(skeleton.el)) document.body.appendChild(skeleton.el); }; app.config.globalProperties.$closeSkeleton = () => { if (skeleton && document.body.contains(skeleton.el)) document.body.removeChild(skeleton.el); }; window.addEventListener('showSkeleton', app.config.globalProperties.$showSkeleton); window.addEventListener('closeSkeleton', app.config.globalProperties.$closeSkeleton); app.config.globalProperties.$navigate = (e) => { if (window.__wxjs_environment === 'miniprogram') { const index = e.indexOf('?'); let query = ''; if (index > -1) query = e.slice(index); const data = router.resolve({ path: e }); wx.miniProgram.navigateTo({ url: `/pages/webview/webview?url=${encodeURIComponent(`${location.origin}/${data.href}${query}`)}`, }); } else { router.push(e); } }; app.config.globalProperties.$ls = { set: (e, obj) => { localStorage.setItem(e, obj); }, get: (e) => { return localStorage.getItem(e); }, remove: (e) => { localStorage.removeItem(e); } }; app.config.globalProperties.$ss = { set: (e, obj) => { sessionStorage.setItem(e, obj); }, get: (e) => { return sessionStorage.getItem(e); }, remove: (e) => { sessionStorage.removeItem(e); } }; import ObjectHelper from './utils/ObjectHelper'; import date from './utils/date'; app.config.globalProperties.$conf = { apiUrl: import.meta.env.VITE_API_URL, ossUrl: import.meta.env.VITE_OSS_URL, }; app.config.globalProperties.$date = date; app.config.globalProperties.$copyText = (e) => { return ObjectHelper.Copy(e) }; app.config.globalProperties.$getRule = (e) => { return ObjectHelper.getRule(e) }; app.config.globalProperties.$groupBy = (e, key) => { return ObjectHelper.groupBy(e, key) }; app.config.globalProperties.$unsigned = (e) => { return e > 0 ? e : 0 }; app.config.globalProperties.$truncate = (e, p, a) => { return `${e.substring(0, p)}...${e.substring(e.length - a)}`; }; app.config.globalProperties.$trunc = (e, p) => { const tp = Math.pow(10, p); return Math.trunc(e * tp) / tp; }; app.config.globalProperties.$valid = (field, msg) => { if (!field) { app.config.globalProperties.$showFailToast(msg); return false; } return true; }; app.config.globalProperties.$token = (e) => { const token = localStorage.getItem(e === 'token' ? 'member_token' : e).split('.'); return { header: JSON.parse(atob(token[0])), payload: JSON.parse(atob(token[1])), } }; app.config.globalProperties.$file = (e) => { if (!e) return '/img/img-avatar-default.png'; if (typeof e !== 'string') return '/img/img-avatar-default.png'; if (e.startsWith('http://') || e.startsWith('https://')) return e; else return import.meta.env.VITE_OSS_URL + e; }; app.config.globalProperties.$openUrl = (e) => { window.open(e); }; app.config.globalProperties.$refresh = () => { window.location.replace('#/refresh?key=' + app.config.globalProperties.$route.name) }; app.config.globalProperties.$verify = (permissions, module, type) => { return permissions.indexOf(`${module}:${type}`) > -1; }; app.config.globalProperties.$substring = (e, begin, end) => { if (typeof e !== 'string') { return ''; } return e.length > end ? e.substring(begin, end) + "..." : e; } app.config.globalProperties.$fileSize = (e) => { let level = 0; while (e >= 1024 && level < 4) { e /= 1024; level++; } return `${e.toFixed(2)}${['B', 'KB', 'MB', 'GB'][level]}`; }; app.config.globalProperties.$compressFiles = (files) => { const fileArray = Array.isArray(files) ? files : [files]; const promises = fileArray.map(file => { return new Promise((resolve, reject) => { if (!(file instanceof File)) { return reject(new Error('Invalid file type')); } imageConversion.compressAccurately(file, 400) .then(res => { res = new File([res], file.name, { type: res.type, lastModified: Date.now() }); resolve(res); }) .catch(err => { console.error('压缩失败', err); reject(err); }); }); }); return Promise.all(promises); }; app.config.globalProperties.$uploadFiles = (files, uploadUrl) => { let fd = new FormData(); files.forEach(x => { fd.append('file', x.file, x.file.name); }); return new Promise((resolve, reject) => { fetch(`${import.meta.env.VITE_API_URL}${uploadUrl}`, { method: 'POST', headers: { 'Authorization': `Bearer ${localStorage.getItem('member_token')}`, }, body: fd, }).then(rep => { rep.json().then(data => { if (data.errcode) { reject(data); } else { //上传成功 resolve(data); } }).catch(err => { reject({ message: '上传失败' }); }); }).catch(err => { reject(err); }); }); } // enum import enums from './utils/enums'; Object.getOwnPropertyNames(enums).forEach(x => { app.config.globalProperties[`${x}`] = enums[x]; }); import geo from './utils/geo'; app.config.globalProperties.$geo = geo; app.config.globalProperties.$distance = (e) => { if (e < 1) return `${e * 1000}m`; return `${e}km`; }; app.config.globalProperties.$goIndex = () => { if (window.__wxjs_environment == 'miniprogram') { wx.miniProgram.reLaunch({ url: `/pages/index/index`, }); } else { location.replace('#/'); setTimeout(() => { location.reload(); }, 100); } } app.config.globalProperties.$CheckStates = [{ label: '待审核', color: 'primary' }, { label: '已通过', color: 'success' }, { label: '已拒绝', color: 'danger' }]; app.config.globalProperties.$goService = () => { if (app.config.globalProperties.$isWechatMini()) { wx.miniProgram.navigateTo({ url: `/pages/service/service`, }); } else { app.config.globalProperties.$navigate('/Service'); } }; app.config.globalProperties.$isWechat = () => { return navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger' }; app.config.globalProperties.$isWechatMini = () => { return window.__wxjs_environment == 'miniprogram' }; app.config.globalProperties.$openLocation = (lon, lat, name = '', address = '') => { if (wx && app.config.globalProperties.$isWechat()) wx.openLocation({ longitude: lon, latitude: lat, name: name, address: address, scale: 18, }); else window.open(`http://api.map.baidu.com/marker?location=${lat},${lon}&coord_type=gcj02&title=${name}&content=${address}&output=html`); }; // app.config.globalProperties.$isLogin = () => { // if (!localStorage.getItem('token')) // return false; // const token = app.config.globalProperties.$token('token'); // return token.header.exp > Date.now() && (window.__wxjs_environment != 'miniprogram' || localStorage.getItem('miniopenid')); // } app.config.globalProperties.$validPhone = (e) => { return /^1(3|4|5|6|7|8|9)\d{9}$/.test(e); } app.config.globalProperties.$validIdCard = (idCard) => { const reg18 = /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/; return reg18.test(idCard); } app.config.globalProperties.$getShareLink = () => { const query = app.config.globalProperties.$route.query; const recommend = localStorage.getItem('cellphone'); const params = Object.keys(query).filter(x => x != 'RecommendCode').map(x => { return `${x}=${query[x]}`; }); params.push(`RecommendCode=${recommend}`); return `${location.href.split('?')[0]}?${params.join('&')}`; } // CH import { post, get, put, del, request, postForm, abortAll } from './api/http'; import { isLogin, formatGMT } from './api/user'; app.config.globalProperties.$post = post; app.config.globalProperties.$get = get; app.config.globalProperties.$put = put; app.config.globalProperties.$del = del; app.config.globalProperties.$request = request; app.config.globalProperties.$postForm = postForm; app.config.globalProperties.$isLogin = isLogin; app.config.globalProperties.$formatGMT = formatGMT; app.config.globalProperties.$formatCellphone = (e) => { if (!e || e.length !== 11) return e; return e.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2'); }; app.mount("#app");