解决登录显示、首页显示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

View File

@@ -147,6 +147,9 @@ import { onLoad } from '@dcloudio/uni-app'
import supa from '@/components/supadb/aksupainstance.uts'
import { IS_TEST_MODE, PUSH_SERVER_URL } from '@/ak/config.uts'
import { getCurrentUser, logout, setIsLoggedIn, setUserProfile } from '@/utils/store.uts'
import { checkMerchantAccount, clearAuth, goMerchantHome, isMerchantRole, requireMerchantAuth, setMerchantInfo } from '@/utils/merchantAuth.uts'
import { clearDeliveryAuth, goDeliveryHome, requireDeliveryAuth, saveDeliverySession } from '@/utils/deliveryAuth.uts'
import { loginDelivery } from '@/services/deliveryService.uts'
import type { UserProfile } from '@/types/mall-types.uts'
import { AkReq } from '@/uni_modules/ak-req/index.uts'
@@ -207,6 +210,20 @@ const isMerchantMode = (): boolean => {
return loginMode.value === 'merchant'
}
const isDeliveryMode = (): boolean => {
return loginMode.value === 'delivery'
}
const goTargetHome = (): void => {
if (isDeliveryMode()) {
goDeliveryHome()
} else if (isMerchantMode()) {
goMerchantHome()
} else {
goConsumerHome()
}
}
onLoad((opts) => {
if (opts != null) {
const optsObj = opts as UTSJSONObject
@@ -215,6 +232,9 @@ onLoad((opts) => {
if (parsedMode === 'merchant') {
loginMode.value = 'merchant'
uni.setNavigationBarTitle({ title: '商家登录' })
} else if (parsedMode === 'delivery') {
loginMode.value = 'delivery'
uni.setNavigationBarTitle({ title: '服务人员登录' })
} else {
loginMode.value = 'consumer'
uni.setNavigationBarTitle({ title: '用户登录' })
@@ -234,7 +254,7 @@ const checkUserAccess = async (uid: string, rawEmail: string): Promise<UTSJSONOb
const obj = arr[0]
const role = obj.getString('role') ?? ''
const id = obj.getString('id') ?? ''
const allowed = isMerchantMode() ? (role === 'merchant' || role === 'admin') : (role === 'consumer' || role === 'customer')
const allowed = isMerchantMode() ? (role === 'merchant') : (role === 'consumer' || role === 'customer')
if (allowed && id !== '') {
return { id, role } as UTSJSONObject
}
@@ -262,7 +282,7 @@ const checkUserAccess = async (uid: string, rawEmail: string): Promise<UTSJSONOb
} catch (e) {
if (e instanceof Error && e.message === 'NOT_REGISTERED') {
if (isMerchantMode()) {
throw new Error('该账户不是商家/管理员,或数据库中不存在该账户')
throw new Error('该账户不是商家账号,或数据库中不存在该账户')
}
throw new Error('该账户不是消费者,或数据库中不存在该账户')
}
@@ -282,20 +302,16 @@ const goConsumerHome = (): void => {
uni.reLaunch({ url: '/pages/main/index' })
}
const goTargetHome = (): void => {
if (isMerchantMode()) {
uni.reLaunch({ url: '/pages/mall/merchant/index' })
} else {
goConsumerHome()
}
}
const isTabBarPage = (url: string): boolean => {
return url === '/pages/main/index'
|| url === '/pages/main/category'
|| url === '/pages/main/messages'
|| url === '/pages/main/cart'
|| url === '/pages/main/profile'
|| url === '/pages/mall/delivery/home/index'
|| url === '/pages/mall/delivery/orders/index'
|| url === '/pages/mall/delivery/messages/index'
|| url === '/pages/mall/delivery/profile/index'
}
const navigateToRedirect = (redirect: string): void => {
@@ -313,20 +329,41 @@ const navigateToRedirect = (redirect: string): void => {
uni.redirectTo({ url: target })
}
const checkLoginStatus = (): void => {
const redirectAfterMount = (redirect: string): void => {
setTimeout(() => {
if (redirect !== '') {
navigateToRedirect(redirect)
} else {
goTargetHome()
}
}, 80)
}
const checkLoginStatus = async (): Promise<void> => {
try {
const sessionInfo = supa.getSession()
const storedId = uni.getStorageSync('user_id')
const hasSession = sessionInfo != null && sessionInfo.user != null
const hasStorage = storedId != null && (storedId as string) !== ''
if (isDeliveryMode()) {
const authResult = await requireDeliveryAuth({ redirectOnFail: false, toastOnFail: false })
if (!authResult.ok) {
return
}
const redirect = redirectPath.value
redirectAfterMount(redirect)
return
}
if (hasSession && hasStorage) {
if (isMerchantMode()) {
const authResult = await requireMerchantAuth({ redirectOnFail: false, toastOnFail: false })
if (!authResult.ok) {
return
}
}
const redirect = redirectPath.value
console.log('检测到已有会话, 执行重定向...')
if (redirect !== '') {
navigateToRedirect(redirect)
} else {
goTargetHome()
}
redirectAfterMount(redirect)
}
} catch (e) {
console.error('检查登录状态失败:', e)
@@ -363,7 +400,10 @@ onMounted(() => {
isDefault: account.value === TEST_ACCOUNT
})
if (isMerchantMode()) {
if (isDeliveryMode()) {
account.value = ''
password.value = ''
} else if (isMerchantMode()) {
account.value = TEST_ACCOUNT
password.value = TEST_PASSWORD
}
@@ -437,8 +477,52 @@ const getCode = async () => {
const handleLogin = async () => {
if (!validateAccount()) return
if (isDeliveryMode()) {
if (loginType.value !== 0) {
uni.showToast({ title: '服务人员端暂不支持短信登录', icon: 'none' })
return
}
if (!validatePassword()) return
if (!account.value.includes('@')) {
uni.showToast({ title: '请使用真实邮箱账号登录', icon: 'none' })
return
}
isLoading.value = true
try {
clearAuth()
clearDeliveryAuth()
const result = await loginDelivery({ account: account.value.trim(), password: password.value.trim() })
saveDeliverySession(result.token, result.userInfo, result.deliveryInfo)
const authResult = await requireDeliveryAuth({ redirectOnFail: false, toastOnFail: false })
if (!authResult.ok) {
clearDeliveryAuth()
throw new Error(authResult.message != '' ? authResult.message : '服务人员登录失败')
}
uni.showToast({ title: '登录成功', icon: 'success' })
setTimeout(() => {
const redirect = redirectPath.value
if (redirect !== '') {
navigateToRedirect(redirect)
} else {
goTargetHome()
}
}, 300)
} catch (err) {
let msg = '登录失败,请重试'
try {
const e = err as Error
if (e.message != null && e.message.trim() !== '') msg = e.message
} catch (e2) {}
uni.showToast({ title: msg, icon: 'none' })
} finally {
isLoading.value = false
}
return
}
// 特殊账号处理:仅在测试模式下保留直登逻辑,生产环境强制校验角色
if (IS_TEST_MODE && account.value === 'admin' && password.value === 'admin') {
if (!isMerchantMode() && IS_TEST_MODE && account.value === 'admin' && password.value === 'admin') {
setIsLoggedIn(true)
const adminProfile = {
id: 'admin',
@@ -466,35 +550,6 @@ const handleLogin = async () => {
return
}
// 演示模式:测试账号直接走本地 bypass不请求后端WeChat MP 禁止 HTTP/裸 IP 请求)
if (IS_TEST_MODE && isMerchantMode() && account.value === TEST_ACCOUNT && password.value === TEST_PASSWORD) {
console.log('[LoginBypass] merchant test bypass hit')
setIsLoggedIn(true)
const demoProfile = {
id: isMerchantMode() ? 'demo-merchant-001' : 'demo-consumer-001',
username: isMerchantMode() ? '演示机构' : '演示用户',
email: TEST_ACCOUNT,
gender: 'unknown',
birthday: '',
height_cm: 0,
weight_kg: 0,
bio: isMerchantMode() ? '医养服务演示机构' : '医养服务演示用户',
avatar_url: '/static/logo.png',
preferred_language: 'zh-CN',
role: isMerchantMode() ? 'merchant' : 'consumer',
school_id: '',
grade_id: '',
class_id: ''
} as UserProfile
setUserProfile(demoProfile)
uni.setStorageSync('user_id', demoProfile.id ?? '')
uni.showToast({ title: '登录成功', icon: 'success' })
setTimeout(() => {
goTargetHome()
}, 500)
return
}
if (loginType.value === 0) {
if (!validatePassword()) return
} else {
@@ -503,7 +558,7 @@ const handleLogin = async () => {
isLoading.value = true
try {
logout()
clearAuth()
if (loginType.value === 0) {
const isEmail = account.value.includes('@')
@@ -540,17 +595,13 @@ const handleLogin = async () => {
const accessData = await checkUserAccess(sessionUid, account.value)
if (accessData == null) {
await supa.signOut()
logout()
clearAuth()
throw new Error(isMerchantMode() ? '该账户无商家端权限' : '该账户无消费者权限')
}
const currRole = accessData.getString('role')
if (isMerchantMode()) {
if (currRole !== 'merchant') {
uni.removeStorageSync('merchant_id')
}
} else {
if (!isMerchantMode()) {
uni.removeStorageSync('merchant_id')
uni.removeStorageSync('merchant_info')
}
} else {
uni.showToast({ title: '手机号密码登录功能开发中', icon: 'none' })
@@ -562,13 +613,39 @@ const handleLogin = async () => {
}
// 更新 store 中的用户资料
let profile: UserProfile | null = null
try {
const profile = await getCurrentUser()
profile = await getCurrentUser()
console.log('fetch profile success:', profile)
} catch (e) {
console.error('获取用户信息失败(忽略):', e)
}
if (isMerchantMode()) {
if (profile == null || !isMerchantRole(profile)) {
clearAuth()
throw new Error('当前账号不是商家账号')
}
const merchantInfo = await checkMerchantAccount(profile)
if (merchantInfo == null) {
clearAuth()
throw new Error('当前账号未绑定商家信息')
}
if (merchantInfo.status === 0) {
clearAuth()
throw new Error('当前商家信息待审核')
}
if (merchantInfo.status != null && merchantInfo.status !== 1) {
clearAuth()
throw new Error('当前商家状态异常,暂不可登录')
}
setMerchantInfo(merchantInfo)
}
// 已移除对 shared storage user_id 的依赖
const currentSession = supa.getSession()
@@ -627,8 +704,14 @@ const handleLogin = async () => {
}
const navigateToRegister = (): void => {
let url = '/pages/user/register'
if (isDeliveryMode()) {
url = '/pages/user/register?mode=delivery'
} else if (isMerchantMode()) {
url = '/pages/user/register?mode=merchant'
}
uni.navigateTo({
url: '/pages/user/register'
url
})
}
const handleTutorial = () => uni.showToast({ title: '扫码教程开发中', icon: 'none' })