解决登录显示、首页显示bug

This commit is contained in:
2026-05-19 11:06:46 +08:00
parent 2f7e097e6c
commit 00a859c551
181 changed files with 55329 additions and 998 deletions

325
utils/merchantAuth.uts Normal file
View 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())
}