SEC_Warehouse/utils/auth.js

211 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { AUTH_ENABLED, AUTH_STORAGE_KEYS } from '@/constants/auth'
import { ROUTES, TAB_ROUTES } from '@/constants/routes'
export const LOGIN_PAGE = ROUTES.LOGIN
export const HOME_PAGE = ROUTES.HOME
export const TAB_PAGES = TAB_ROUTES
let hasSetupInterceptors = false
/**
* 规范化路由,保证以 `/` 开头。
*/
function normalizeUrl(url = '') {
if (!url) {
return ''
}
if (url.startsWith('/')) {
return url
}
return `/${url}`
}
/**
* 获取不带 query 的路径。
*/
function getPath(url = '') {
return normalizeUrl(url).split('?')[0]
}
function safeDecode(value = '') {
try {
return decodeURIComponent(value)
} catch (error) {
return value
}
}
/**
* 把页面 options 组装成 query 字符串。
*/
function buildQuery(options = {}) {
const keys = Object.keys(options)
if (!keys.length) {
return ''
}
const query = keys
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(options[key] || '')}`)
.join('&')
return query ? `?${query}` : ''
}
/**
* 获取当前页面完整地址path + query
*/
function getCurrentPageUrl() {
const pages = getCurrentPages()
if (!pages.length) {
return ''
}
const current = pages[pages.length - 1]
const currentPath = current.route ? `/${current.route}` : ''
const currentQuery = current.options ? buildQuery(current.options) : ''
return `${currentPath}${currentQuery}`
}
function isLoginPage(url = '') {
return getPath(url) === LOGIN_PAGE
}
function needLogin(url = '') {
return !isLoginPage(url)
}
export function isAuthEnabled() {
return AUTH_ENABLED
}
export function isTabPage(url = '') {
return TAB_PAGES.includes(getPath(url))
}
export function getToken() {
return uni.getStorageSync(AUTH_STORAGE_KEYS.TOKEN) || ''
}
export function isLoggedIn() {
if (!AUTH_ENABLED) {
return true
}
return Boolean(getToken())
}
export function getUser() {
return uni.getStorageSync(AUTH_STORAGE_KEYS.USER) || null
}
/**
* 保存登录态。
*/
export function setAuth({ token, user } = {}) {
if (token) {
uni.setStorageSync(AUTH_STORAGE_KEYS.TOKEN, token)
}
if (user) {
uni.setStorageSync(AUTH_STORAGE_KEYS.USER, user)
}
}
export function clearAuth() {
uni.removeStorageSync(AUTH_STORAGE_KEYS.TOKEN)
uni.removeStorageSync(AUTH_STORAGE_KEYS.USER)
}
/**
* 跳转到登录页并携带重定向地址。
*/
export function redirectToLogin(targetUrl = '') {
if (!AUTH_ENABLED) {
return
}
const redirect = normalizeUrl(targetUrl || getCurrentPageUrl())
if (isLoginPage(redirect)) {
return
}
const loginUrl = redirect
? `${LOGIN_PAGE}?redirect=${encodeURIComponent(redirect)}`
: LOGIN_PAGE
uni.reLaunch({
url: loginUrl
})
}
/**
* 登录成功后按 redirect 返回目标页。
*/
export function goAfterLogin(redirect = '') {
const target = normalizeUrl(safeDecode(redirect) || HOME_PAGE)
const targetPath = getPath(target)
if (isLoginPage(targetPath)) {
uni.switchTab({
url: HOME_PAGE
})
return
}
if (isTabPage(targetPath)) {
uni.switchTab({
url: targetPath
})
return
}
uni.reLaunch({
url: target
})
}
function guardPage(url = '') {
if (!AUTH_ENABLED) {
return true
}
if (!needLogin(url) || isLoggedIn()) {
return true
}
redirectToLogin(url)
return false
}
/**
* 初始化 uni 路由拦截器,只注册一次。
*/
export function setupAuthInterceptors() {
if (hasSetupInterceptors) {
return
}
const methods = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab']
methods.forEach((method) => {
uni.addInterceptor(method, {
invoke(args) {
return guardPage(args.url)
}
})
})
hasSetupInterceptors = true
}
export function ensureCurrentPageAuth() {
const currentUrl = getCurrentPageUrl()
if (!currentUrl) {
return
}
guardPage(currentUrl)
}