From 4b69ed3b845dc87e466fc440aa2260d7af76bca3 Mon Sep 17 00:00:00 2001 From: kyuuseiryuu Date: Mon, 16 Mar 2026 02:04:06 +0900 Subject: [PATCH] refactor(front-end): switch to web-based map navigation and update layouts - Update `openMapDirection` to `openWebMapRaw` in `utils/front.ts` to open maps in a new browser tab (`_blank`) using raw WGS-84 coordinates. - Adjust URL schemes for Google, AMap, Baidu, Tencent, and Apple Maps to support direct web navigation with `coordinate` parameters. - Update `ClubSummary.tsx` to use `openWebMapRaw` and change the map button label from "Navigation" to "View Location" with a new icon. - Add `padding-bottom` to `AppBar.tsx` in `AppBarLayout.tsx` to accommodate the increased bottom padding required by the updated AppBar styling. - Remove the "Home" FloatButton from `ProfilePage.tsx` and update `routes.tsx` to remove the unused `ActionButtonLayout` import. - Update navigation handlers in `AppBar.tsx` to use `replace: true` for smoother state management without creating new browser history entries. --- src/components/AppBar.tsx | 11 ++++--- src/components/ClubSummary.tsx | 13 +++----- src/components/Layout/AppBarLayout.tsx | 2 +- src/page/ProfilePage.tsx | 4 +-- src/routes.tsx | 2 +- src/utils/front.ts | 45 +++++++++++++++++--------- src/utils/mapUtils.ts | 23 +++++++++++++ 7 files changed, 67 insertions(+), 33 deletions(-) create mode 100644 src/utils/mapUtils.ts diff --git a/src/components/AppBar.tsx b/src/components/AppBar.tsx index 32bdff6..667d897 100644 --- a/src/components/AppBar.tsx +++ b/src/components/AppBar.tsx @@ -1,4 +1,4 @@ -import { CalendarOutlined, HeartOutlined, ScheduleOutlined, SearchOutlined, UserOutlined } from "@ant-design/icons"; +import { HeartOutlined, ScheduleOutlined, SearchOutlined, UserOutlined } from "@ant-design/icons"; import { Button, Flex } from "antd"; import { useNavigate } from "react-router"; import styled from "styled-components"; @@ -12,6 +12,7 @@ const StyledContainer = styled.div` background: #181818; font-size: 16px; padding: 8px; + padding-bottom: 34px; box-sizing: border-box; .ant-btn { padding: 24px; @@ -25,22 +26,22 @@ export const AppBar = () => { )} diff --git a/src/components/Layout/AppBarLayout.tsx b/src/components/Layout/AppBarLayout.tsx index 0be9028..ce2862b 100644 --- a/src/components/Layout/AppBarLayout.tsx +++ b/src/components/Layout/AppBarLayout.tsx @@ -4,7 +4,7 @@ import { AppBar } from "../AppBar"; import styled from "styled-components"; const StyledContainer = styled.div` - padding-bottom: 54px; + padding-bottom: 90px; box-sizing: border-box; `; export const AppBarLayout = () => { diff --git a/src/page/ProfilePage.tsx b/src/page/ProfilePage.tsx index 4cd1a0d..a999fc4 100644 --- a/src/page/ProfilePage.tsx +++ b/src/page/ProfilePage.tsx @@ -1,7 +1,6 @@ import React, { useEffect, useMemo } from "react"; import { Link, useLoaderData, useNavigate } from "react-router"; -import { Avatar, Divider, Flex, FloatButton, Image, Typography } from "antd"; -import { HomeOutlined } from "@ant-design/icons"; +import { Avatar, Divider, Flex, Image, Typography } from "antd"; import { useTitle } from "ahooks"; import type { XCXProfile } from "../types/profile"; import User from "../components/User"; @@ -108,7 +107,6 @@ export default function ProfilePage() { return ( <> - } onClick={() => navigate('/')} /> diff --git a/src/routes.tsx b/src/routes.tsx index 040ea0a..ef8d15a 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -9,7 +9,7 @@ import { CallbackPage } from "./page/Logto/Callback"; import App from "./App"; import { ClubEventsPage } from "./page/ClubEvents"; import { HydrateFallback } from "./components/HydrateFallback"; -import { ActionButtonLayout, AppBarLayout } from './components/Layout'; +import { AppBarLayout } from './components/Layout'; export const route = createBrowserRouter([ { diff --git a/src/utils/front.ts b/src/utils/front.ts index bbc4715..b428df0 100644 --- a/src/utils/front.ts +++ b/src/utils/front.ts @@ -23,44 +23,59 @@ export const isMobile = (): boolean => { }; /** - * 唤起地图导航 - * @param type 地图类型 - * @param location 坐标点 (默认输入为 GCJ-02 坐标) + * 调起 Web 版地图 (直接使用原始坐标,不进行纠偏转换) */ -export const openMapDirection = (type: MapType, location: MapLocation): void => { - const { lat, lng, name = '目的地' } = location; +export const openWebMapRaw = (type: MapType, location: MapLocation): void => { + const { lat, lng, name = 'Location' } = location; const encodedName = encodeURIComponent(name); + let url = ''; switch (type) { case MapType.GOOGLE: /** - * Google Maps Scheme - * saddr: 起点 (为空则默认为当前位置) - * daddr: 终点经纬度 - * directionsmode: 导航模式 (driving, walking, bicycling, transit) + * Google Maps Web API + * 使用 query 参数标注位置 */ - url = `https://www.google.com/maps/dir/?api=1&destination=${lat},${lng}`; + url = `https://www.google.com/maps/search/?api=1&query=${lat},${lng}`; break; case MapType.AMAP: - url = `iosamap://path?sourceApplication=appName&dlat=${lat}&dlon=${lng}&dname=${encodedName}&dev=0&t=0`; + /** + * 高德 Web 标注 + * coordinate=wgs84 声明输入的是原始 GPS 坐标 + * position 参数顺序为 [经度, 纬度] + */ + url = `https://uri.amap.com/marker?position=${lng},${lat}&name=${encodedName}&coordinate=wgs84&callnative=0`; break; case MapType.BAIDU: - url = `baidumap://map/direction?destination=name:${encodedName}|latlng:${lat},${lng}&mode=driving&coord_type=gcj02`; + /** + * 百度 Web 标注 + * coord_type=wgs84 声明输入的是原始 GPS 坐标 + */ + url = `http://api.map.baidu.com/marker?location=${lat},${lng}&title=${encodedName}&content=${encodedName}&coord_type=wgs84&output=html&src=webapp`; break; case MapType.TENCENT: - url = `qqmap://map/routeplan?type=drive&to=${encodedName}&tocoord=${lat},${lng}&referer=myapp`; + /** + * 腾讯 Web 标注 + * 腾讯 Web API 目前对 wgs84 直接支持较弱,通常默认 gcj02, + * 但在 Web 端直接传坐标,系统会尝试解析。 + */ + url = `https://apis.map.qq.com/uri/v1/marker?marker=coord:${lat},${lng};title:${encodedName}&referer=myapp`; break; case MapType.APPLE: - url = `http://maps.apple.com/?daddr=${lat},${lng}&q=${encodedName}`; + /** + * Apple Maps Web + * ll: 经纬度, q: 标注点名称 + */ + url = `https://maps.apple.com/?ll=${lat},${lng}&q=${encodedName}`; break; } if (url) { - window.open(url); + window.open(url, '_blank'); } }; \ No newline at end of file diff --git a/src/utils/mapUtils.ts b/src/utils/mapUtils.ts new file mode 100644 index 0000000..8468c6e --- /dev/null +++ b/src/utils/mapUtils.ts @@ -0,0 +1,23 @@ +import gcoord, { CRSTypes } from 'gcoord'; + +/** + * 判断并转换坐标 + */ +export const getCorrectCoords = (lng: number, lat: number) => { + // gcoord.transform 会自动判断: + // 如果输入坐标在海外,它通常会返回原值(或根据算法处理) + // 但我们可以手动配合它的边界逻辑 + + // 更加显式的判断方法: + // gcoord 内部其实维护了一个边界多边形,你可以直接进行转换测试 + const result = gcoord.transform( + [lng, lat], // 目标坐标 + gcoord.WGS84, // 当前坐标系 + gcoord.GCJ02 // 目标坐标系 + ); + + return { + lng: result[0], + lat: result[1] + }; +}; \ No newline at end of file