import { ref } from 'vue'; import { storeToRefs } from 'pinia' import { onLoad, onShow } from "@dcloudio/uni-app"; import routes from '@/routes'; import useAccount from '@/store/account'; import { triggerPromise } from '@/utils'; /** * 页面校验登录hook * hook逻辑 * 1. 根据routes配置判断当前页面是否需要登录 * 2. 如果需要登录,则判断是否已经登录,如果没有登录则跳转到登录页面 * 3. 如果已经登录,则触发onLoad事件 * 4. 如果页面需要登录,则登录成功后跳转到当前页面 * @returns */ export default function useGuard() { const { account } = storeToRefs(useAccount()); const { login } = useAccount(); const { resolve, promise } = triggerPromise(); const onShowEvents = ref([]); const options = ref({}) const onShowOptions = ref({}) function toLoginPage(options, path) { const params = Object.keys(options).map(key => `${key}=${options[key]}`).join('&'); const redirectUrl = encodeURIComponent(`${path}?${params}`); uni.redirectTo({ url: `/pages/login/login?redirect=${redirectUrl}` }) } async function useLoad(fn) { await promise; fn(options.value); } async function triggleShowEvents() { await promise; if (account.value && account.value.openid) { onShowEvents.value.forEach(fn => fn(onShowOptions.value)) } } function useShow(fn) { onShowEvents.value.push(fn) } onLoad(async opts => { options.value = { ...opts }; const pages = getCurrentPages(); const page = pages[pages.length - 1]; const route = routes.find(i => page && i.path === page.route); const requireLogin = route && route.meta && route.meta.login; if (requireLogin && !account.value) { await login() console.log('login success') console.log(account.value) if (account.value) { resolve() } else { return toLoginPage(opts, page.route); } } resolve() }) onShow(opts => { console.log('onShow') onShowOptions.value = { ...opts }; triggleShowEvents() }) return { useLoad, useShow } }