路线地图/节点卡片/详情按出行方式显示不同图标(批 19)
出行方式(飞机/火车/游船/自驾/地铁…)原本在路线地图标记、节点卡片交通行、
节点详情「出行方式」行一律显示节点类型图标(赶路节点恒为 🚗),易让人误解。
- TravelModeController 新增 MODE_ICONS(mode_type → emoji 映射)
- ActivityController::show() 两路查询 LEFT JOIN travel_modes 取 mode_type,注入 modeIcons
- 路线地图标记 / 卡片交通行 / 详情出行方式行:优先用出行方式图标,
未选出行方式时回退节点类型图标
This commit is contained in:
@@ -314,18 +314,22 @@ class ActivityController
|
|||||||
exit('活动不存在');
|
exit('活动不存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $db->prepare('SELECT tn.*, nt.name AS node_type_name, nt.icon AS node_type_icon
|
$stmt = $db->prepare('SELECT tn.*, nt.name AS node_type_name, nt.icon AS node_type_icon,
|
||||||
|
tm.mode_type AS travel_mode_type
|
||||||
FROM trip_nodes tn
|
FROM trip_nodes tn
|
||||||
LEFT JOIN node_types nt ON nt.id = tn.node_type_id
|
LEFT JOIN node_types nt ON nt.id = tn.node_type_id
|
||||||
|
LEFT JOIN travel_modes tm ON tm.id = tn.travel_mode_id
|
||||||
WHERE tn.activity_id = ? AND tn.node_category = "plan"
|
WHERE tn.activity_id = ? AND tn.node_category = "plan"
|
||||||
ORDER BY tn.start_time ASC');
|
ORDER BY tn.start_time ASC');
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id]);
|
||||||
$planNodes = $stmt->fetchAll();
|
$planNodes = $stmt->fetchAll();
|
||||||
$this->attachCounts($db, $planNodes);
|
$this->attachCounts($db, $planNodes);
|
||||||
|
|
||||||
$stmt = $db->prepare('SELECT tn.*, nt.name AS node_type_name, nt.icon AS node_type_icon
|
$stmt = $db->prepare('SELECT tn.*, nt.name AS node_type_name, nt.icon AS node_type_icon,
|
||||||
|
tm.mode_type AS travel_mode_type
|
||||||
FROM trip_nodes tn
|
FROM trip_nodes tn
|
||||||
LEFT JOIN node_types nt ON nt.id = tn.node_type_id
|
LEFT JOIN node_types nt ON nt.id = tn.node_type_id
|
||||||
|
LEFT JOIN travel_modes tm ON tm.id = tn.travel_mode_id
|
||||||
WHERE tn.activity_id = ? AND tn.node_category = "reality"
|
WHERE tn.activity_id = ? AND tn.node_category = "reality"
|
||||||
ORDER BY tn.start_time ASC');
|
ORDER BY tn.start_time ASC');
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id]);
|
||||||
@@ -352,6 +356,8 @@ class ActivityController
|
|||||||
'nodeMembers' => $nodeMembers,
|
'nodeMembers' => $nodeMembers,
|
||||||
// 路线地图:每个执行节点第一张图片附件 id(圆形标记用),一条 GROUP BY 防止 N+1
|
// 路线地图:每个执行节点第一张图片附件 id(圆形标记用),一条 GROUP BY 防止 N+1
|
||||||
'nodeFirstImage' => Attachments::firstImageIdsForNodes(array_column($realityNodes, 'id')),
|
'nodeFirstImage' => Attachments::firstImageIdsForNodes(array_column($realityNodes, 'id')),
|
||||||
|
// 批 19:路线地图标记图标按出行方式映射(回退节点类型图标)
|
||||||
|
'modeIcons' => TravelModeController::MODE_ICONS,
|
||||||
'expenseSummary' => Expenses::summaryForActivity($id),
|
'expenseSummary' => Expenses::summaryForActivity($id),
|
||||||
'commentTree' => Comments::tree(Comments::TARGET_ACTIVITY, $id),
|
'commentTree' => Comments::tree(Comments::TARGET_ACTIVITY, $id),
|
||||||
'pageTitle' => $activity['title'],
|
'pageTitle' => $activity['title'],
|
||||||
|
|||||||
@@ -316,6 +316,8 @@ class NodeController
|
|||||||
'travel_mode_label' => $travelModeLabel,
|
'travel_mode_label' => $travelModeLabel,
|
||||||
'travel_mode_type' => $travelModeType,
|
'travel_mode_type' => $travelModeType,
|
||||||
]),
|
]),
|
||||||
|
// 批 19:出行方式图标映射,节点详情「出行方式」行前展示
|
||||||
|
'modeIcons' => TravelModeController::MODE_ICONS,
|
||||||
'attachmentCount' => $attachmentCount,
|
'attachmentCount' => $attachmentCount,
|
||||||
'attachments' => $nodeAttachments,
|
'attachments' => $nodeAttachments,
|
||||||
'members' => Members::forNode($nodeId),
|
'members' => Members::forNode($nodeId),
|
||||||
|
|||||||
@@ -22,6 +22,25 @@ class TravelModeController
|
|||||||
'other' => '其他',
|
'other' => '其他',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出行方式 → 地图/卡片上的图标(emoji)。
|
||||||
|
* 自驾两类仍用 🚗(本来就是开车);其余按交通工具区分,
|
||||||
|
* 避免路线地图上「一律汽车」让人误解(批 19)。未列入的 mode_type 回退到节点类型图标。
|
||||||
|
*/
|
||||||
|
public const MODE_ICONS = [
|
||||||
|
'drive_own' => '🚗',
|
||||||
|
'drive_rental' => '🚙',
|
||||||
|
'train' => '🚄',
|
||||||
|
'plane' => '✈️',
|
||||||
|
'bus' => '🚌',
|
||||||
|
'subway' => '🚇',
|
||||||
|
'taxi' => '🚕',
|
||||||
|
'bike' => '🚲',
|
||||||
|
'walk' => '🚶',
|
||||||
|
'ship' => '🚢',
|
||||||
|
'other' => '🔀',
|
||||||
|
];
|
||||||
|
|
||||||
public function index(): void
|
public function index(): void
|
||||||
{
|
{
|
||||||
$this->requireLogin();
|
$this->requireLogin();
|
||||||
|
|||||||
@@ -66,8 +66,15 @@ if ($cardCategory === 'plan') {
|
|||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
/* 批 19:交通行图标跟着「出行方式」走(飞机/火车/游船…),不再一律 🚄。
|
||||||
|
没选出行方式时回退到 🚄,保持旧行为。 */
|
||||||
|
$modeIcons = $modeIcons ?? [];
|
||||||
|
$tModeType = (string)($n['travel_mode_type'] ?? '');
|
||||||
|
$tIcon = $modeIcons[$tModeType] ?? '🚄';
|
||||||
|
?>
|
||||||
<?php if (!empty($transportParts)): ?>
|
<?php if (!empty($transportParts)): ?>
|
||||||
<div class="node-transport">🚄 <?= e(implode(' · ', $transportParts)) ?></div>
|
<div class="node-transport"><?= e($tIcon) ?> <?= e(implode(' · ', $transportParts)) ?></div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if ($st === 'cancelled' && !empty($n['cancel_reason'])): ?>
|
<?php if ($st === 'cancelled' && !empty($n['cancel_reason'])): ?>
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
查不到就保持缺省,不硬造位置。AMap 2.0 已由 layout.php 全局加载。 */
|
查不到就保持缺省,不硬造位置。AMap 2.0 已由 layout.php 全局加载。 */
|
||||||
$routeNodes = [];
|
$routeNodes = [];
|
||||||
$nodeFirstImage = $nodeFirstImage ?? [];
|
$nodeFirstImage = $nodeFirstImage ?? [];
|
||||||
|
$modeIcons = $modeIcons ?? []; // 批 19:出行方式→图标映射,由控制器注入
|
||||||
foreach (($realityNodes ?? []) as $rn) {
|
foreach (($realityNodes ?? []) as $rn) {
|
||||||
$s = json_decode_field($rn['start_location'] ?? null);
|
$s = json_decode_field($rn['start_location'] ?? null);
|
||||||
$e = json_decode_field($rn['end_location'] ?? null);
|
$e = json_decode_field($rn['end_location'] ?? null);
|
||||||
@@ -53,10 +54,17 @@ foreach (($realityNodes ?? []) as $rn) {
|
|||||||
continue; // 坐标和地名一个都没有的节点不上地图
|
continue; // 坐标和地名一个都没有的节点不上地图
|
||||||
}
|
}
|
||||||
$imgId = (int)($nodeFirstImage[(int)$rn['id']] ?? 0);
|
$imgId = (int)($nodeFirstImage[(int)$rn['id']] ?? 0);
|
||||||
|
// 批 19:标记图标优先用「出行方式」的图标;没选出行方式时回退到节点类型图标
|
||||||
|
//(赶路节点没选方式 → 仍是 🚗;选了飞机/火车/游船等 → 显示对应交通工具图标,不再一律汽车)。
|
||||||
|
$rnModeType = (string)($rn['travel_mode_type'] ?? '');
|
||||||
|
$rnIcon = ($rnModeType !== '' && isset($modeIcons[$rnModeType]))
|
||||||
|
? $modeIcons[$rnModeType]
|
||||||
|
: (string)($rn['node_type_icon'] ?: '📍');
|
||||||
|
|
||||||
$routeNodes[] = [
|
$routeNodes[] = [
|
||||||
'id' => (int)$rn['id'],
|
'id' => (int)$rn['id'],
|
||||||
'title' => (string)($rn['title'] ?: '(无标题节点)'),
|
'title' => (string)($rn['title'] ?: '(无标题节点)'),
|
||||||
'icon' => (string)($rn['node_type_icon'] ?: '📍'),
|
'icon' => $rnIcon,
|
||||||
'img' => $imgId > 0 ? media_att($imgId) : '',
|
'img' => $imgId > 0 ? media_att($imgId) : '',
|
||||||
'url' => url('nodes/show', ['id' => (int)$rn['id']]),
|
'url' => url('nodes/show', ['id' => (int)$rn['id']]),
|
||||||
'sname' => $sname, // 出发地名:没有坐标时交给高德地理编码兜底
|
'sname' => $sname, // 出发地名:没有坐标时交给高德地理编码兜底
|
||||||
|
|||||||
@@ -87,7 +87,12 @@ if (!empty($node['duration_minutes'])) {
|
|||||||
<?php if (!empty($node['travel_mode_label'])): ?>
|
<?php if (!empty($node['travel_mode_label'])): ?>
|
||||||
<div class="detail-item">
|
<div class="detail-item">
|
||||||
<span class="detail-label">出行方式</span>
|
<span class="detail-label">出行方式</span>
|
||||||
<span class="detail-value"><?= e($node['travel_mode_label']) ?></span>
|
<?php
|
||||||
|
/* 批 19:行前加一个出行方式图标(飞机/火车/游船…),更直观 */
|
||||||
|
$modeIcons = $modeIcons ?? [];
|
||||||
|
$tIcon = $modeIcons[(string)($node['travel_mode_type'] ?? '')] ?? '';
|
||||||
|
?>
|
||||||
|
<span class="detail-value"><?= e($tIcon) ?> <?= e($node['travel_mode_label']) ?></span>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php if (!empty($transportParts)): ?>
|
<?php if (!empty($transportParts)): ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user