更新移动端认证API,新增地理位置参数支持,优化登录逻辑以处理位置获取失败的情况,提升用户体验和代码可维护性。

This commit is contained in:
zyh
2025-04-10 06:55:47 +00:00
parent c4905113d7
commit 52c4e2d187
5 changed files with 44 additions and 10 deletions

View File

@@ -40,7 +40,7 @@ interface AuthResponse {
// 定义Auth API接口类型
interface AuthAPIType {
login: (username: string, password: string) => Promise<AuthLoginResponse>;
login: (username: string, password: string, latitude?: number, longitude?: number) => Promise<AuthLoginResponse>;
register: (username: string, email: string, password: string) => Promise<AuthResponse>;
logout: () => Promise<AuthResponse>;
getCurrentUser: () => Promise<User>;
@@ -54,9 +54,14 @@ interface AuthAPIType {
// Auth相关API
export const AuthAPI: AuthAPIType = {
// 登录API
login: async (username: string, password: string) => {
login: async (username: string, password: string, latitude?: number, longitude?: number) => {
try {
const response = await axios.post(`${API_BASE_URL}/auth/login`, { username, password });
const response = await axios.post(`${API_BASE_URL}/auth/login`, {
username,
password,
latitude,
longitude
});
return response.data;
} catch (error) {
throw error;

View File

@@ -63,9 +63,9 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
// 登录函数
const login = async (username: string, password: string) => {
const login = async (username: string, password: string, latitude?: number, longitude?: number) => {
try {
const response = await AuthAPI.login(username, password);
const response = await AuthAPI.login(username, password, latitude, longitude);
const { token, user } = response;
// 保存到状态和本地存储

View File

@@ -25,10 +25,37 @@ const LoginPage: React.FC = () => {
setError(null);
try {
await login(username, password);
// 获取地理位置
const position = await new Promise<GeolocationPosition>((resolve, reject) => {
if (!navigator.geolocation) {
reject(new Error('浏览器不支持地理位置功能'));
return;
}
navigator.geolocation.getCurrentPosition(
resolve,
(err) => reject(new Error(`获取位置失败: ${err.message}`)),
{ timeout: 5000 }
);
});
const { latitude, longitude } = position.coords;
await login(username, password, latitude, longitude);
navigate('/');
} catch (err) {
setError(handleApiError(err));
// 如果获取位置失败,仍然允许登录但不带位置信息
const error = err instanceof Error ? err : new Error(String(err));
if (error.message.includes('获取位置失败')) {
console.warn('获取位置失败:', err);
try {
await login(username, password);
navigate('/');
} catch (loginErr) {
setError(handleApiError(loginErr));
}
} else {
setError(handleApiError(err));
}
} finally {
setLoading(false);
}

View File

@@ -48,7 +48,7 @@ export interface MenuItem {
export interface AuthContextType {
user: User | null;
token: string | null;
login: (username: string, password: string) => Promise<void>;
login: (username: string, password: string, latitude?: number, longitude?: number) => Promise<void>;
logout: () => Promise<void>;
isAuthenticated: boolean;
isLoading: boolean;

View File

@@ -54,7 +54,7 @@ export function createAuthRoutes(withAuth: WithAuth) {
authRoutes.post('/login', async (c) => {
try {
const auth = c.get('auth')
const { username, password } = await c.req.json()
const { username, password, latitude, longitude } = await c.req.json()
if (!username || !password) {
return c.json({ error: '用户名和密码不能为空' }, 400)
@@ -69,7 +69,9 @@ export function createAuthRoutes(withAuth: WithAuth) {
user_id: result.user.id,
login_time: apiClient.database.fn.now(),
ip_address: c.req.header('x-forwarded-for') || '未知',
user_agent: c.req.header('user-agent') || '未知'
user_agent: c.req.header('user-agent') || '未知',
latitude: latitude || null,
longitude: longitude || null
})
}