diff --git a/client/mobile/api.ts b/client/mobile/api.ts index 08dee14..c6ff6d1 100644 --- a/client/mobile/api.ts +++ b/client/mobile/api.ts @@ -40,7 +40,7 @@ interface AuthResponse { // 定义Auth API接口类型 interface AuthAPIType { - login: (username: string, password: string) => Promise; + login: (username: string, password: string, latitude?: number, longitude?: number) => Promise; register: (username: string, email: string, password: string) => Promise; logout: () => Promise; getCurrentUser: () => Promise; @@ -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; diff --git a/client/mobile/hooks.tsx b/client/mobile/hooks.tsx index cb0b021..9b4e1ee 100644 --- a/client/mobile/hooks.tsx +++ b/client/mobile/hooks.tsx @@ -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; // 保存到状态和本地存储 diff --git a/client/mobile/pages_login.tsx b/client/mobile/pages_login.tsx index d10b33c..ade9ac8 100644 --- a/client/mobile/pages_login.tsx +++ b/client/mobile/pages_login.tsx @@ -25,10 +25,37 @@ const LoginPage: React.FC = () => { setError(null); try { - await login(username, password); + // 获取地理位置 + const position = await new Promise((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); } diff --git a/client/share/types.ts b/client/share/types.ts index a9349c5..9f42d02 100644 --- a/client/share/types.ts +++ b/client/share/types.ts @@ -48,7 +48,7 @@ export interface MenuItem { export interface AuthContextType { user: User | null; token: string | null; - login: (username: string, password: string) => Promise; + login: (username: string, password: string, latitude?: number, longitude?: number) => Promise; logout: () => Promise; isAuthenticated: boolean; isLoading: boolean; diff --git a/server/routes_auth.ts b/server/routes_auth.ts index 0051422..edb23fa 100644 --- a/server/routes_auth.ts +++ b/server/routes_auth.ts @@ -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 }) }