解决登录显示、首页显示bug
This commit is contained in:
325
utils/merchantAuth.uts
Normal file
325
utils/merchantAuth.uts
Normal file
@@ -0,0 +1,325 @@
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
import { HOME_REDIRECT } from '@/ak/config.uts'
|
||||
import { AkReq } from '@/uni_modules/ak-req/index.uts'
|
||||
import { getCurrentUser, logout, state } from '@/utils/store.uts'
|
||||
import type { UserProfile } from '@/types/mall-types.uts'
|
||||
|
||||
export type MerchantInfo = {
|
||||
id: string
|
||||
merchant_id: string
|
||||
shop_name: string
|
||||
shop_logo: string
|
||||
shop_banner: string
|
||||
description: string
|
||||
contact_name: string
|
||||
contact_phone: string
|
||||
status: number | null
|
||||
}
|
||||
|
||||
export type MerchantAuthOptions = {
|
||||
redirectOnFail?: boolean
|
||||
toastOnFail?: boolean
|
||||
redirect?: string
|
||||
message?: string
|
||||
}
|
||||
|
||||
export type MerchantAuthResult = {
|
||||
ok: boolean
|
||||
message: string
|
||||
userInfo: UserProfile | null
|
||||
merchantInfo: MerchantInfo | null
|
||||
}
|
||||
|
||||
const MERCHANT_LOGIN_PATH = '/pages/user/login?mode=merchant'
|
||||
const MERCHANT_HOME_PATH = HOME_REDIRECT !== '' ? HOME_REDIRECT : '/pages/mall/merchant/index'
|
||||
|
||||
let redirectingToMerchantLogin = false
|
||||
|
||||
function hasText(value: string | null): boolean {
|
||||
return value != null && value !== ''
|
||||
}
|
||||
|
||||
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 isMerchantRoute(route: string): boolean {
|
||||
return route.startsWith('/pages/mall/merchant/')
|
||||
}
|
||||
|
||||
function shouldShowToast(enabled: boolean | null): boolean {
|
||||
return enabled == null || enabled === true
|
||||
}
|
||||
|
||||
function shouldRedirect(enabled: boolean | null): boolean {
|
||||
return enabled == null || enabled === true
|
||||
}
|
||||
|
||||
function buildMerchantInfo(raw: UTSJSONObject): MerchantInfo {
|
||||
return {
|
||||
id: raw.getString('id') ?? '',
|
||||
merchant_id: raw.getString('merchant_id') ?? '',
|
||||
shop_name: raw.getString('shop_name') ?? '',
|
||||
shop_logo: raw.getString('shop_logo') ?? '',
|
||||
shop_banner: raw.getString('shop_banner') ?? '',
|
||||
description: raw.getString('description') ?? '',
|
||||
contact_name: raw.getString('contact_name') ?? '',
|
||||
contact_phone: raw.getString('contact_phone') ?? '',
|
||||
status: raw.getNumber('status')
|
||||
}
|
||||
}
|
||||
|
||||
function persistMerchantInfo(info: MerchantInfo): void {
|
||||
const payload = new UTSJSONObject()
|
||||
payload.set('id', info.id)
|
||||
payload.set('merchant_id', info.merchant_id)
|
||||
payload.set('shop_name', info.shop_name)
|
||||
payload.set('shop_logo', info.shop_logo)
|
||||
payload.set('shop_banner', info.shop_banner)
|
||||
payload.set('description', info.description)
|
||||
payload.set('contact_name', info.contact_name)
|
||||
payload.set('contact_phone', info.contact_phone)
|
||||
if (info.status != null) {
|
||||
payload.set('status', info.status)
|
||||
}
|
||||
uni.setStorageSync('merchant_info', JSON.stringify(payload))
|
||||
if (hasText(info.merchant_id)) {
|
||||
uni.setStorageSync('merchant_id', info.merchant_id)
|
||||
} else {
|
||||
uni.removeStorageSync('merchant_id')
|
||||
}
|
||||
}
|
||||
|
||||
function buildFailureResult(message: string, userInfo: UserProfile | null = null): MerchantAuthResult {
|
||||
return {
|
||||
ok: false,
|
||||
message,
|
||||
userInfo,
|
||||
merchantInfo: null
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchMerchantInfoByUserId(userId: string): Promise<MerchantInfo | null> {
|
||||
let response = await supa
|
||||
.from('ml_shops')
|
||||
.select('id, merchant_id, shop_name, shop_logo, shop_banner, description, contact_name, contact_phone, status')
|
||||
.eq('merchant_id', userId)
|
||||
.limit(1)
|
||||
.execute()
|
||||
|
||||
if (response.error == null && response.data != null) {
|
||||
const rows = response.data as Array<UTSJSONObject>
|
||||
if (rows.length > 0) {
|
||||
return buildMerchantInfo(rows[0])
|
||||
}
|
||||
}
|
||||
|
||||
response = await supa
|
||||
.from('ml_shops')
|
||||
.select('id, merchant_id, shop_name, shop_logo, shop_banner, description, contact_name, contact_phone, status')
|
||||
.eq('id', userId)
|
||||
.limit(1)
|
||||
.execute()
|
||||
|
||||
if (response.error == null && response.data != null) {
|
||||
const rows = response.data as Array<UTSJSONObject>
|
||||
if (rows.length > 0) {
|
||||
return buildMerchantInfo(rows[0])
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function getRedirectTarget(explicitRedirect: string | null): string {
|
||||
if (hasText(explicitRedirect)) {
|
||||
return explicitRedirect as string
|
||||
}
|
||||
const currentRoute = getCurrentRoute()
|
||||
if (hasText(currentRoute) && currentRoute !== '/pages/user/login') {
|
||||
return currentRoute
|
||||
}
|
||||
return MERCHANT_HOME_PATH
|
||||
}
|
||||
|
||||
function handleFailure(message: string, options?: MerchantAuthOptions, userInfo: UserProfile | null = null): MerchantAuthResult {
|
||||
clearAuth()
|
||||
if (shouldShowToast(options?.toastOnFail ?? null) && hasText(message)) {
|
||||
uni.showToast({ title: message, icon: 'none' })
|
||||
}
|
||||
if (shouldRedirect(options?.redirectOnFail ?? null)) {
|
||||
redirectToMerchantLogin(getRedirectTarget(options?.redirect ?? null))
|
||||
}
|
||||
return buildFailureResult(message, userInfo)
|
||||
}
|
||||
|
||||
export function getToken(): string {
|
||||
const token = AkReq.getToken()
|
||||
return token != null ? token : ''
|
||||
}
|
||||
|
||||
export async function getUserInfo(): Promise<UserProfile | null> {
|
||||
try {
|
||||
const profile = state.userProfile
|
||||
if (profile != null && hasText(profile.id ?? null)) {
|
||||
return profile as UserProfile
|
||||
}
|
||||
} catch (e) {}
|
||||
return await getCurrentUser()
|
||||
}
|
||||
|
||||
export function getMerchantInfo(): MerchantInfo | null {
|
||||
try {
|
||||
const raw = uni.getStorageSync('merchant_info') as string | null
|
||||
if (hasText(raw)) {
|
||||
const parsed = JSON.parse(raw as string) as UTSJSONObject
|
||||
return buildMerchantInfo(parsed)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[merchantAuth] 读取 merchant_info 失败:', e)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function setMerchantInfo(info: MerchantInfo): void {
|
||||
persistMerchantInfo(info)
|
||||
}
|
||||
|
||||
export function isLoggedIn(): boolean {
|
||||
try {
|
||||
const session = supa.getSession()
|
||||
const hasSession = session != null && session.user != null
|
||||
const storedId = uni.getStorageSync('user_id') as string | null
|
||||
const hasStoredId = hasText(storedId)
|
||||
return hasSession || hasStoredId
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function isMerchantRole(userInfo: UserProfile | null): boolean {
|
||||
if (userInfo == null) {
|
||||
return false
|
||||
}
|
||||
const role = userInfo.role != null ? userInfo.role : ''
|
||||
return role === 'merchant'
|
||||
}
|
||||
|
||||
export async function checkMerchantAccount(userInfo: UserProfile): Promise<MerchantInfo | null> {
|
||||
const userId = userInfo.id != null ? userInfo.id : ''
|
||||
if (!hasText(userId)) {
|
||||
return null
|
||||
}
|
||||
try {
|
||||
return await fetchMerchantInfoByUserId(userId)
|
||||
} catch (e) {
|
||||
console.error('[merchantAuth] 查询商家信息失败:', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function clearAuth(): void {
|
||||
try {
|
||||
AkReq.clearToken()
|
||||
} catch (e) {}
|
||||
uni.removeStorageSync('user_id')
|
||||
uni.removeStorageSync('merchant_id')
|
||||
uni.removeStorageSync('merchant_info')
|
||||
uni.removeStorageSync('merchant_idx_cache')
|
||||
try {
|
||||
logout()
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export function redirectToMerchantLogin(redirect?: string): void {
|
||||
const currentRoute = getCurrentRoute()
|
||||
if (currentRoute === '/pages/user/login') {
|
||||
return
|
||||
}
|
||||
if (redirectingToMerchantLogin) {
|
||||
return
|
||||
}
|
||||
redirectingToMerchantLogin = true
|
||||
let targetUrl = MERCHANT_LOGIN_PATH
|
||||
const redirectTarget = getRedirectTarget(redirect != null ? redirect : null)
|
||||
if (hasText(redirectTarget)) {
|
||||
targetUrl = `${MERCHANT_LOGIN_PATH}&redirect=${encodeURIComponent(redirectTarget)}`
|
||||
}
|
||||
uni.reLaunch({
|
||||
url: targetUrl,
|
||||
complete: () => {
|
||||
setTimeout(() => {
|
||||
redirectingToMerchantLogin = false
|
||||
}, 300)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function goMerchantHome(): void {
|
||||
uni.reLaunch({ url: MERCHANT_HOME_PATH })
|
||||
}
|
||||
|
||||
export async function requireMerchantAuth(options?: MerchantAuthOptions): Promise<MerchantAuthResult> {
|
||||
const currentRoute = getCurrentRoute()
|
||||
if (currentRoute === '/pages/user/login') {
|
||||
return {
|
||||
ok: true,
|
||||
message: '',
|
||||
userInfo: null,
|
||||
merchantInfo: null
|
||||
}
|
||||
}
|
||||
|
||||
if (!isLoggedIn()) {
|
||||
return handleFailure(options?.message ?? '请先登录商家账号', options)
|
||||
}
|
||||
|
||||
const userInfo = await getUserInfo()
|
||||
if (userInfo == null || !hasText(userInfo.id ?? null)) {
|
||||
return handleFailure('登录状态已失效,请重新登录', options)
|
||||
}
|
||||
|
||||
if (!isMerchantRole(userInfo)) {
|
||||
const message = options?.message != null && options.message !== ''
|
||||
? options.message
|
||||
: '当前账号不是商家账号'
|
||||
return handleFailure(message, options, userInfo)
|
||||
}
|
||||
|
||||
const merchantInfo = await checkMerchantAccount(userInfo)
|
||||
if (merchantInfo == null) {
|
||||
return handleFailure('当前账号未绑定商家信息', options, userInfo)
|
||||
}
|
||||
|
||||
if (merchantInfo.status != null) {
|
||||
if (merchantInfo.status === 0) {
|
||||
return handleFailure('当前商家信息待审核', options, userInfo)
|
||||
}
|
||||
if (merchantInfo.status !== 1) {
|
||||
return handleFailure('当前商家状态异常,暂不可登录', options, userInfo)
|
||||
}
|
||||
}
|
||||
|
||||
persistMerchantInfo(merchantInfo)
|
||||
return {
|
||||
ok: true,
|
||||
message: '',
|
||||
userInfo,
|
||||
merchantInfo
|
||||
}
|
||||
}
|
||||
|
||||
export function isCurrentMerchantPage(): boolean {
|
||||
return isMerchantRoute(getCurrentRoute())
|
||||
}
|
||||
Reference in New Issue
Block a user