316 lines
8.6 KiB
Plaintext
316 lines
8.6 KiB
Plaintext
import { AkReq } from '@/uni_modules/ak-req/index.uts'
|
|
import type { UserProfile } from '@/types/mall-types.uts'
|
|
import type { DeliveryInfoType } from '@/types/delivery.uts'
|
|
import { getDeliveryProfileByUserId } from '@/api/delivery.uts'
|
|
import supa from '@/components/supadb/aksupainstance.uts'
|
|
import { getCurrentUser, setIsLoggedIn, setUserProfile } from '@/utils/store.uts'
|
|
|
|
export type DeliveryAuthOptions = {
|
|
redirectOnFail?: boolean
|
|
toastOnFail?: boolean
|
|
redirect?: string
|
|
message?: string
|
|
}
|
|
|
|
export type DeliveryAuthResult = {
|
|
ok: boolean
|
|
message: string
|
|
userInfo: UserProfile | null
|
|
deliveryInfo: DeliveryInfoType | null
|
|
}
|
|
|
|
const DELIVERY_LOGIN_PATH = '/pages/user/login'
|
|
const DELIVERY_LOGIN_TARGET = '/pages/user/login?mode=delivery'
|
|
const DELIVERY_HOME_PATH = '/pages/mall/delivery/home/index'
|
|
const DELIVERY_USER_KEY = 'delivery_user_info'
|
|
const DELIVERY_INFO_KEY = 'delivery_info'
|
|
const DELIVERY_TOKEN_KEY = 'delivery_token'
|
|
const DELIVERY_ROLE_LIST = ['delivery', 'Deliverer', 'deliverer', 'service_staff', 'care_worker'] as Array<string>
|
|
|
|
let redirectingToDeliveryLogin = false
|
|
|
|
function hasText(value: string | null): boolean {
|
|
return value != null && value !== ''
|
|
}
|
|
|
|
function shouldShowToast(enabled: boolean | null): boolean {
|
|
return enabled == null || enabled === true
|
|
}
|
|
|
|
function shouldRedirect(enabled: boolean | null): boolean {
|
|
return enabled == null || enabled === true
|
|
}
|
|
|
|
function getCurrentRoute(): string {
|
|
try {
|
|
const pages = getCurrentPages() as Array<UTSJSONObject>
|
|
if (pages.length === 0) {
|
|
return ''
|
|
}
|
|
const currentPage = pages[pages.length - 1]
|
|
const route = currentPage['route']
|
|
if (route != null) {
|
|
return '/' + route
|
|
}
|
|
} catch (e) {}
|
|
return ''
|
|
}
|
|
|
|
function buildFailureResult(message: string, userInfo: UserProfile | null = null): DeliveryAuthResult {
|
|
return {
|
|
ok: false,
|
|
message,
|
|
userInfo,
|
|
deliveryInfo: null
|
|
}
|
|
}
|
|
|
|
function parseUserInfo(raw: string): UserProfile | null {
|
|
try {
|
|
return JSON.parse(raw) as UserProfile
|
|
} catch (e) {
|
|
return null
|
|
}
|
|
}
|
|
|
|
function parseDeliveryInfo(raw: string): DeliveryInfoType | null {
|
|
try {
|
|
return JSON.parse(raw) as DeliveryInfoType
|
|
} catch (e) {
|
|
return null
|
|
}
|
|
}
|
|
|
|
function persistUserInfo(userInfo: UserProfile): void {
|
|
uni.setStorageSync(DELIVERY_USER_KEY, JSON.stringify(userInfo))
|
|
}
|
|
|
|
function persistDeliveryInfo(info: DeliveryInfoType): void {
|
|
uni.setStorageSync(DELIVERY_INFO_KEY, JSON.stringify(info))
|
|
}
|
|
|
|
export function setDeliveryInfo(info: DeliveryInfoType): void {
|
|
persistDeliveryInfo(info)
|
|
}
|
|
|
|
export function clearDeliveryInfo(): void {
|
|
uni.removeStorageSync(DELIVERY_INFO_KEY)
|
|
}
|
|
|
|
export function saveDeliverySession(token: string, userInfo: UserProfile, deliveryInfo: DeliveryInfoType | null): void {
|
|
AkReq.setToken(token, '', Date.now() + 24 * 60 * 60 * 1000)
|
|
uni.setStorageSync(DELIVERY_TOKEN_KEY, token)
|
|
persistUserInfo(userInfo)
|
|
setIsLoggedIn(true)
|
|
setUserProfile(userInfo)
|
|
if (deliveryInfo != null) {
|
|
persistDeliveryInfo(deliveryInfo)
|
|
} else {
|
|
uni.removeStorageSync(DELIVERY_INFO_KEY)
|
|
}
|
|
}
|
|
|
|
export function getToken(): string {
|
|
const stored = uni.getStorageSync(DELIVERY_TOKEN_KEY) as string | null
|
|
if (stored != null && stored != '') {
|
|
return stored
|
|
}
|
|
const token = AkReq.getToken()
|
|
return token != null ? token : ''
|
|
}
|
|
|
|
export function getUserInfo(): UserProfile | null {
|
|
const raw = uni.getStorageSync(DELIVERY_USER_KEY) as string | null
|
|
if (!hasText(raw)) {
|
|
return null
|
|
}
|
|
return parseUserInfo(raw as string)
|
|
}
|
|
|
|
async function resolveUserInfo(): Promise<UserProfile | null> {
|
|
const cached = getUserInfo()
|
|
if (cached != null) {
|
|
return cached
|
|
}
|
|
try {
|
|
const profile = await getCurrentUser()
|
|
if (profile != null) {
|
|
persistUserInfo(profile)
|
|
}
|
|
return profile
|
|
} catch (e) {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export function getDeliveryInfo(): DeliveryInfoType | null {
|
|
const raw = uni.getStorageSync(DELIVERY_INFO_KEY) as string | null
|
|
if (!hasText(raw)) {
|
|
return null
|
|
}
|
|
return parseDeliveryInfo(raw as string)
|
|
}
|
|
|
|
export function isLoggedIn(): boolean {
|
|
if (hasText(getToken()) && getUserInfo() != null) {
|
|
return true
|
|
}
|
|
try {
|
|
const session = supa.getSession()
|
|
return session != null && session.user != null
|
|
} catch (e) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
export function isDelivererRole(userInfo: UserProfile | null): boolean {
|
|
if (userInfo == null) {
|
|
return false
|
|
}
|
|
const role = userInfo.role != null ? userInfo.role : ''
|
|
for (let i = 0; i < DELIVERY_ROLE_LIST.length; i++) {
|
|
if (role == DELIVERY_ROLE_LIST[i]) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
export async function checkDeliveryAccount(userInfo: UserProfile): Promise<DeliveryInfoType | null> {
|
|
const userId = userInfo.id != null ? userInfo.id : ''
|
|
if (!hasText(userId)) {
|
|
return null
|
|
}
|
|
return await getDeliveryProfileByUserId(userId)
|
|
}
|
|
|
|
export function clearDeliveryAuth(): void {
|
|
try {
|
|
AkReq.clearToken()
|
|
} catch (e) {}
|
|
uni.removeStorageSync(DELIVERY_TOKEN_KEY)
|
|
uni.removeStorageSync(DELIVERY_USER_KEY)
|
|
uni.removeStorageSync('user_id')
|
|
clearDeliveryInfo()
|
|
setIsLoggedIn(false)
|
|
setUserProfile({ username: '', email: '' } as UserProfile)
|
|
}
|
|
|
|
export async function logoutDelivery(): Promise<void> {
|
|
clearDeliveryAuth()
|
|
try {
|
|
await supa.signOut()
|
|
} catch (e) {}
|
|
}
|
|
|
|
function getRedirectTarget(explicitRedirect: string | null): string {
|
|
if (hasText(explicitRedirect)) {
|
|
return explicitRedirect as string
|
|
}
|
|
const currentRoute = getCurrentRoute()
|
|
if (hasText(currentRoute) && currentRoute !== DELIVERY_LOGIN_PATH) {
|
|
return currentRoute
|
|
}
|
|
return DELIVERY_HOME_PATH
|
|
}
|
|
|
|
export function redirectToDeliveryLogin(redirect?: string): void {
|
|
const currentRoute = getCurrentRoute()
|
|
if (currentRoute == DELIVERY_LOGIN_PATH) {
|
|
return
|
|
}
|
|
if (redirectingToDeliveryLogin) {
|
|
return
|
|
}
|
|
redirectingToDeliveryLogin = true
|
|
let targetUrl = DELIVERY_LOGIN_TARGET
|
|
const redirectTarget = getRedirectTarget(redirect != null ? redirect : null)
|
|
if (hasText(redirectTarget)) {
|
|
targetUrl = DELIVERY_LOGIN_TARGET + '&redirect=' + encodeURIComponent(redirectTarget)
|
|
}
|
|
uni.reLaunch({
|
|
url: targetUrl,
|
|
complete: () => {
|
|
setTimeout(() => {
|
|
redirectingToDeliveryLogin = false
|
|
}, 300)
|
|
}
|
|
})
|
|
}
|
|
|
|
export function goDeliveryHome(): void {
|
|
uni.reLaunch({ url: DELIVERY_HOME_PATH })
|
|
}
|
|
|
|
export function isCurrentDeliveryPage(): boolean {
|
|
return getCurrentRoute().startsWith('/pages/mall/delivery/')
|
|
}
|
|
|
|
export function handleDeliveryUnauthorized(message?: string, redirect?: string): void {
|
|
clearDeliveryAuth()
|
|
redirectToDeliveryLogin(redirect)
|
|
if (message != null && message != '') {
|
|
uni.showToast({ title: message, icon: 'none' })
|
|
}
|
|
}
|
|
|
|
function handleFailure(message: string, options?: DeliveryAuthOptions, userInfo: UserProfile | null = null): DeliveryAuthResult {
|
|
clearDeliveryAuth()
|
|
if (shouldShowToast(options?.toastOnFail ?? null) && hasText(message)) {
|
|
uni.showToast({ title: message, icon: 'none' })
|
|
}
|
|
if (shouldRedirect(options?.redirectOnFail ?? null)) {
|
|
redirectToDeliveryLogin(getRedirectTarget(options?.redirect ?? null))
|
|
}
|
|
return buildFailureResult(message, userInfo)
|
|
}
|
|
|
|
export async function requireDeliveryAuth(options?: DeliveryAuthOptions): Promise<DeliveryAuthResult> {
|
|
const currentRoute = getCurrentRoute()
|
|
const onLoginPage = currentRoute == DELIVERY_LOGIN_PATH
|
|
const effectiveOptions: DeliveryAuthOptions = {
|
|
redirectOnFail: onLoginPage ? false : options?.redirectOnFail,
|
|
toastOnFail: options?.toastOnFail,
|
|
redirect: options?.redirect,
|
|
message: options?.message
|
|
}
|
|
|
|
if (!isLoggedIn()) {
|
|
return handleFailure(options?.message != null ? options.message : '请先登录服务人员账号', effectiveOptions)
|
|
}
|
|
|
|
const userInfo = await resolveUserInfo()
|
|
if (userInfo == null) {
|
|
return handleFailure('登录状态已失效,请重新登录', effectiveOptions)
|
|
}
|
|
|
|
if (!isDelivererRole(userInfo)) {
|
|
return handleFailure('当前账号不是上门服务人员账号', effectiveOptions, userInfo)
|
|
}
|
|
|
|
const deliveryInfo = await checkDeliveryAccount(userInfo)
|
|
if (deliveryInfo == null) {
|
|
return handleFailure('当前账号未绑定服务人员档案', effectiveOptions, userInfo)
|
|
}
|
|
|
|
if (deliveryInfo.status == 'disabled' || deliveryInfo.status == 'locked' || deliveryInfo.status == 'suspended') {
|
|
return handleFailure('账号不可接单', effectiveOptions, userInfo)
|
|
}
|
|
|
|
if (deliveryInfo.usesMock && (!hasText(deliveryInfo.organizationId) || !hasText(deliveryInfo.organizationName))) {
|
|
return handleFailure('当前账号未绑定服务机构', effectiveOptions, userInfo)
|
|
}
|
|
|
|
if (deliveryInfo.usesMock && deliveryInfo.certificateStatus == 'expired') {
|
|
return handleFailure('资质已过期,请联系管理员', effectiveOptions, userInfo)
|
|
}
|
|
|
|
persistUserInfo(userInfo)
|
|
persistDeliveryInfo(deliveryInfo)
|
|
return {
|
|
ok: true,
|
|
message: '',
|
|
userInfo,
|
|
deliveryInfo
|
|
}
|
|
} |