重构登陆登出
This commit is contained in:
parent
91be186013
commit
31ac817e76
@ -13,9 +13,18 @@ export interface UserInfo {
|
|||||||
user_type: string
|
user_type: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 辅助函数:从cookie字符串中读取指定名称的cookie值
|
||||||
|
function getCookie(name: string): string | null {
|
||||||
|
const value = `; ${document.cookie}`
|
||||||
|
const parts = value.split(`; ${name}=`)
|
||||||
|
if (parts.length === 2) {
|
||||||
|
return parts.pop()?.split(';').shift() || null
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
export function getSessionUser(): string | null {
|
export function getSessionUser(): string | null {
|
||||||
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
const sessionUser = getCookie('user_id')
|
||||||
const sessionUser = cookies.get('user_id')
|
|
||||||
if (!sessionUser || sessionUser === 'Guest') {
|
if (!sessionUser || sessionUser === 'Guest') {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -23,8 +32,34 @@ export function getSessionUser(): string | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getSessionCookie(): string | null {
|
export function getSessionCookie(): string | null {
|
||||||
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
return getCookie('sid')
|
||||||
return cookies.get('sid')
|
}
|
||||||
|
|
||||||
|
// 从cookie中获取用户信息
|
||||||
|
export function getUserInfoFromCookies(): UserInfo | null {
|
||||||
|
const userId = getCookie('user_id')
|
||||||
|
const fullName = getCookie('full_name') || ''
|
||||||
|
const userImage = getCookie('user_image') || ''
|
||||||
|
const systemUser = getCookie('system_user')
|
||||||
|
|
||||||
|
if (!userId || userId === 'Guest') {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析 full_name 为 first_name 和 last_name
|
||||||
|
const nameParts = fullName.split(' ')
|
||||||
|
const firstName = nameParts[0] || ''
|
||||||
|
const lastName = nameParts.slice(1).join(' ') || ''
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: userId,
|
||||||
|
username: userId,
|
||||||
|
email: '',
|
||||||
|
avatar: userImage,
|
||||||
|
first_name: firstName,
|
||||||
|
last_name: lastName,
|
||||||
|
user_type: systemUser === 'yes' ? 'System User' : 'Website User'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查cookie是否过期(通过检查session cookie是否存在)
|
// 检查cookie是否过期(通过检查session cookie是否存在)
|
||||||
@ -34,72 +69,142 @@ export function isCookieExpired(): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const loginApi = async (username: string, password: string): Promise<LoginResponse> => {
|
export const loginApi = async (username: string, password: string): Promise<LoginResponse> => {
|
||||||
const response = await fetch(`/jingrow/login`, {
|
// 使用表单编码格式,匹配后端期望的格式
|
||||||
|
const formData = new URLSearchParams()
|
||||||
|
formData.append('cmd', 'login')
|
||||||
|
formData.append('usr', username)
|
||||||
|
formData.append('pwd', password)
|
||||||
|
|
||||||
|
const response = await fetch(`/api/action/login`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
'Accept': 'application/json'
|
'Accept': 'application/json'
|
||||||
},
|
},
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
body: JSON.stringify({
|
body: formData
|
||||||
username: username,
|
|
||||||
password: password
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const errorData = await response.json().catch(() => ({}))
|
const errorData = await response.json().catch(() => ({}))
|
||||||
throw new Error(errorData.detail || errorData.message || '登录请求失败')
|
throw new Error(errorData.detail || errorData.message || errorData.exc || '登录请求失败')
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
|
|
||||||
if (data.success && data.user) {
|
// 后端登录成功会返回 message: "Logged In" 或 "No App"
|
||||||
return { message: data.message || 'Logged In', user: data.user }
|
// "No App" 表示登录成功但用户类型是 Website User
|
||||||
|
if (response.status === 200 && (data.message === 'Logged In' || data.message === 'No App')) {
|
||||||
|
// 直接从登录响应构建用户信息
|
||||||
|
// 解析 full_name 为 first_name 和 last_name
|
||||||
|
const nameParts = (data.full_name || '').split(' ')
|
||||||
|
const firstName = nameParts[0] || ''
|
||||||
|
const lastName = nameParts.slice(1).join(' ') || ''
|
||||||
|
|
||||||
|
// 使用登录时的用户名作为用户ID和用户名
|
||||||
|
const userInfo: UserInfo = {
|
||||||
|
id: username,
|
||||||
|
username: username,
|
||||||
|
email: '',
|
||||||
|
avatar: '',
|
||||||
|
first_name: firstName,
|
||||||
|
last_name: lastName,
|
||||||
|
user_type: data.message === 'No App' ? 'Website User' : 'System User'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试获取更完整的用户信息(可选,如果失败也不影响登录)
|
||||||
|
try {
|
||||||
|
// 等待一小段时间让session建立
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 200))
|
||||||
|
const detailedUserInfo = await getUserInfoApi()
|
||||||
|
// 如果API返回的用户信息有效(不是Guest),使用它
|
||||||
|
if (detailedUserInfo.id && detailedUserInfo.id !== 'Guest') {
|
||||||
|
return { message: data.message || 'Logged In', user: detailedUserInfo }
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// API调用失败不影响登录,使用基本用户信息
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用从登录响应构建的用户信息
|
||||||
|
return { message: data.message || 'Logged In', user: userInfo }
|
||||||
} else {
|
} else {
|
||||||
throw new Error(data.message || data.detail || '登录失败')
|
throw new Error(data.message || data.detail || data.exc || '登录失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
export const getUserInfoApi = async (): Promise<UserInfo> => {
|
export const getUserInfoApi = async (): Promise<UserInfo> => {
|
||||||
const response = await fetch(`/jingrow/user-info`, {
|
try {
|
||||||
method: 'GET',
|
const response = await fetch(`/api/action/jingrow.realtime.get_user_info`, {
|
||||||
headers: {
|
method: 'GET',
|
||||||
'Accept': 'application/json',
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Accept': 'application/json',
|
||||||
},
|
'Content-Type': 'application/json'
|
||||||
credentials: 'include'
|
},
|
||||||
})
|
credentials: 'include'
|
||||||
|
})
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
// 401或403表示cookie过期或未授权
|
// 401或403表示cookie过期或未授权
|
||||||
if (response.status === 401 || response.status === 403) {
|
if (response.status === 401 || response.status === 403) {
|
||||||
const error = new Error('Cookie已过期,请重新登录')
|
const error = new Error('Cookie已过期,请重新登录')
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
error.status = response.status
|
error.status = response.status
|
||||||
throw error
|
throw error
|
||||||
|
}
|
||||||
|
// 其他错误,尝试从cookie获取
|
||||||
|
const fallbackInfo = getUserInfoFromCookies()
|
||||||
|
if (fallbackInfo) {
|
||||||
|
return fallbackInfo
|
||||||
|
}
|
||||||
|
const errorData = await response.json().catch(() => ({}))
|
||||||
|
throw new Error(errorData.detail || errorData.message || '获取用户信息失败')
|
||||||
}
|
}
|
||||||
const errorData = await response.json().catch(() => ({}))
|
|
||||||
throw new Error(errorData.detail || errorData.message || '获取用户信息失败')
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
|
|
||||||
if (data.success && data.user_info) {
|
// 根据Python代码,用户信息在 message 字段中,如果没有则使用整个 data
|
||||||
return data.user_info
|
const userInfo = data.message || data
|
||||||
} else {
|
|
||||||
throw new Error(data.message || data.detail || '获取用户信息失败')
|
// 格式化用户信息,匹配Python代码的逻辑
|
||||||
|
const formattedUserInfo: UserInfo = {
|
||||||
|
id: userInfo.user || userInfo.name || userInfo.username || '',
|
||||||
|
username: userInfo.user || userInfo.name || userInfo.username || '',
|
||||||
|
email: userInfo.email || '',
|
||||||
|
avatar: userInfo.user_image || '',
|
||||||
|
first_name: userInfo.first_name || '',
|
||||||
|
last_name: userInfo.last_name || '',
|
||||||
|
user_type: userInfo.user_type || 'System User'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果格式化后的用户信息有效,返回它
|
||||||
|
if (formattedUserInfo.id && formattedUserInfo.id !== 'Guest') {
|
||||||
|
return formattedUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果格式化失败,尝试从cookie获取
|
||||||
|
const fallbackInfo = getUserInfoFromCookies()
|
||||||
|
if (fallbackInfo) {
|
||||||
|
return fallbackInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('无法解析用户信息')
|
||||||
|
} catch (error: any) {
|
||||||
|
// 网络错误或其他异常,尝试从cookie获取
|
||||||
|
const fallbackInfo = getUserInfoFromCookies()
|
||||||
|
if (fallbackInfo) {
|
||||||
|
return fallbackInfo
|
||||||
|
}
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 登出
|
// 登出
|
||||||
export const logoutApi = async (): Promise<void> => {
|
export const logoutApi = async (): Promise<void> => {
|
||||||
const response = await fetch(`/jingrow/logout`, {
|
const response = await fetch(`/api/action/logout`, {
|
||||||
method: 'POST',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json'
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
},
|
||||||
credentials: 'include'
|
credentials: 'include'
|
||||||
})
|
})
|
||||||
|
|||||||
@ -14,6 +14,7 @@ const appsDir = path.resolve(currentDir, '..', '..')
|
|||||||
export default defineConfig(({ mode, command }) => {
|
export default defineConfig(({ mode, command }) => {
|
||||||
const env = loadEnv(mode, process.cwd(), '')
|
const env = loadEnv(mode, process.cwd(), '')
|
||||||
const BACKEND_URL = env.VITE_BACKEND_SERVER_URL || 'https://api.jingrow.com'
|
const BACKEND_URL = env.VITE_BACKEND_SERVER_URL || 'https://api.jingrow.com'
|
||||||
|
const JCLOUD_URL = env.VITE_JCLOUD_SERVER_URL || 'https://cloud.jingrow.com'
|
||||||
const FRONTEND_HOST = env.VITE_FRONTEND_HOST || '0.0.0.0'
|
const FRONTEND_HOST = env.VITE_FRONTEND_HOST || '0.0.0.0'
|
||||||
const FRONTEND_PORT = Number(env.VITE_FRONTEND_PORT) || 3100
|
const FRONTEND_PORT = Number(env.VITE_FRONTEND_PORT) || 3100
|
||||||
const ALLOWED_HOSTS = (env.VITE_ALLOWED_HOSTS || '').split(',').map((s) => s.trim()).filter(Boolean)
|
const ALLOWED_HOSTS = (env.VITE_ALLOWED_HOSTS || '').split(',').map((s) => s.trim()).filter(Boolean)
|
||||||
@ -65,12 +66,12 @@ export default defineConfig(({ mode, command }) => {
|
|||||||
},
|
},
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: BACKEND_URL,
|
target: JCLOUD_URL,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: true,
|
secure: true,
|
||||||
},
|
},
|
||||||
'/jingrow': {
|
'/jingrow': {
|
||||||
target: BACKEND_URL,
|
target: JCLOUD_URL,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: true,
|
secure: true,
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user