优化LocationMessage组件,添加经纬度格式化功能,生成静态地图预览图URL,改进位置信息展示,增强用户体验和视觉效果。

This commit is contained in:
超级老白兔
2025-11-22 16:15:33 +08:00
parent deac306f69
commit bda57a84e8
2 changed files with 137 additions and 31 deletions

View File

@@ -9,7 +9,7 @@
// 位置消息基础样式
.locationMessage {
max-width: 420px;
width: 420px;
margin: 4px 0;
}
@@ -21,6 +21,8 @@
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
overflow: hidden;
display: flex;
flex-direction: column;
&:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
@@ -33,6 +35,45 @@
}
}
// 地图预览区域
.mapPreview {
position: relative;
width: 100%;
height: 200px;
overflow: hidden;
background: #f5f5f5;
display: flex;
align-items: center;
justify-content: center;
}
.mapImage {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.mapPlaceholder {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
background: #f5f5f5;
color: #999;
font-size: 14px;
gap: 8px;
span:first-child {
font-size: 32px;
}
}
// 位置消息头部
.locationHeader {
display: flex;
@@ -70,6 +111,21 @@
// 位置消息内容
.locationContent {
padding: 12px 16px;
display: flex;
flex-direction: column;
gap: 4px;
}
.roadName {
font-size: 16px;
font-weight: 600;
color: #1a1a1a;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.poiName {
@@ -89,9 +145,8 @@
font-size: 13px;
color: #666;
line-height: 1.5;
margin-bottom: 12px;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
@@ -175,13 +230,17 @@
// 响应式设计
@media (max-width: 768px) {
.locationMessage {
max-width: 280px;
width: 280px;
}
.locationCard {
border-radius: 10px;
}
.mapPreview {
height: 150px;
}
.locationHeader {
padding: 10px 14px 6px;
}
@@ -253,6 +312,15 @@
}
}
.mapPreview {
background: #2a2a2a;
}
.mapPlaceholder {
background: #2a2a2a;
color: #999;
}
.locationHeader {
background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%);
border-bottom-color: #333;

View File

@@ -85,10 +85,36 @@ const LocationMessage: React.FC<LocationMessageProps> = ({ content }) => {
return renderErrorMessage("[位置消息 - 解析失败]");
}
// 生成地图链接
// 格式化经纬度为6位小数
const formatCoordinate = (coord: string): string => {
const num = parseFloat(coord);
if (isNaN(num)) {
return coord; // 如果无法解析,返回原值
}
return num.toFixed(6);
};
// 生成地图链接(用于点击跳转)
const generateMapUrl = (lat: string, lng: string, label: string) => {
const formattedLat = formatCoordinate(lat);
const formattedLng = formatCoordinate(lng);
// 使用腾讯地图链接
return `https://apis.map.qq.com/uri/v1/marker?marker=coord:${lat},${lng};title:${encodeURIComponent(label)}&referer=wechat`;
return `https://apis.map.qq.com/uri/v1/marker?marker=coord:${formattedLng},${formattedLat};title:${encodeURIComponent(label)}&referer=wechat`;
};
// 生成静态地图预览图URL
const generateStaticMapUrl = (
lat: string,
lng: string,
width: number = 420,
height: number = 200,
) => {
const formattedLat = formatCoordinate(lat);
const formattedLng = formatCoordinate(lng);
const key = "7DZBZ-ZSRK3-QJN3W-O5VTV-4E2P6-7GFYX";
const zoom = locationData.scale || "15";
// 腾讯地图静态地图API
return `https://apis.map.qq.com/ws/staticmap/v2/?center=${formattedLng},${formattedLat}&zoom=${zoom}&size=${width}x${height}&markers=${formattedLng},${formattedLat}&key=${key}`;
};
const mapUrl = generateMapUrl(
@@ -97,12 +123,18 @@ const LocationMessage: React.FC<LocationMessageProps> = ({ content }) => {
locationData.label,
);
const staticMapUrl = generateStaticMapUrl(
locationData.y,
locationData.x,
420,
200,
);
// 处理POI信息
const poiName = locationData.poiname || locationData.label;
const poiCategory = locationData.poiCategoryTips
? locationData.poiCategoryTips.split(":")[0]
: "";
const poiPhone = locationData.poiPhone || "";
// 提取道路名称(如果有的话,从label中提取)
const roadName =
locationData.poiname.split(/[(]/)[0] || locationData.label;
const detailAddress = locationData.label;
return (
<div className={styles.locationMessage}>
@@ -110,29 +142,35 @@ const LocationMessage: React.FC<LocationMessageProps> = ({ content }) => {
className={styles.locationCard}
onClick={() => window.open(mapUrl, "_blank")}
>
{/* 位置详情 */}
{/* 地图预览图 */}
<div className={styles.mapPreview}>
<img
src={staticMapUrl}
alt={locationData.label}
className={styles.mapImage}
onError={e => {
// 如果图片加载失败,显示占位符
const target = e.target as HTMLImageElement;
target.style.display = "none";
const placeholder = target.nextElementSibling as HTMLElement;
if (placeholder) {
placeholder.style.display = "flex";
}
}}
/>
<div className={styles.mapPlaceholder}>
<span>📍</span>
<span>...</span>
</div>
</div>
{/* 位置信息 */}
<div className={styles.locationContent}>
{/* POI名称 */}
{poiName && <div className={styles.poiName}>{poiName}</div>}
{/* 道路名称 */}
{roadName && <div className={styles.roadName}>{roadName}</div>}
{/* 详细地址 */}
<div className={styles.locationAddress}>{locationData.label}</div>
{/* POI分类和电话 */}
<div className={styles.locationDetails}>
{poiCategory && (
<div className={styles.poiCategory}>
<span className={styles.categoryIcon}>🏷</span>
{poiCategory}
</div>
)}
{poiPhone && (
<div className={styles.poiPhone}>
<span className={styles.phoneIcon}>📞</span>
{poiPhone}
</div>
)}
</div>
<div className={styles.locationAddress}>{detailAddress}</div>
</div>
</div>
</div>