Files
laoyang 2f7dc6ca23 v63:卡片配色 / 日历本靠右 / 地图题图 / 设置页清理 / 公共标签颜色 / 令牌下线
- 卡片右上角按钮改用「来自哪个模块」的主题色:HomeCards 登记表新增 mod 字段
  与 module(),首页从登记表取色(原来是模板里硬编码 in_array(['agenda','tasks'])
  白名单,新加带按钮的卡片会默默变灰)
- 首页日程把日历本放到色块右侧:.ag-ev 改弹性行,「时间+标题」包进
  .ag-ev-main(flex:1 1 auto; min-width:0),日历本作右侧兄弟。
  原来 display:block 会把日历本顶到第二行,色块一矮就完全看不见
- 旅程地图显示题图:服务端把 media_url(cover_key) 塞进地图数据,
  地图卡片左侧 40x40 题图(object-fit:cover),没有题图不留灰框
- 系统设置第一块改叫「系统标语」;删掉「首页上那一行小字」提示、
  「不是全家的统一口号」说明、「上次结构升级有步骤失败了」整框;
  运行环境删「排错时看这一块」与「亲属连线」那一行(功能与数据未动)
- 公共标签:说明文字全删;列表与编辑合并成一行(色块+名字+N人+箭头+编辑);
  person_groups 加 color 列(Schema addColumn,老库可升);点「编辑」弹框
  改名字与颜色、点「完成」提交;下面那个独立编辑列表撤掉。删除挪进弹框
- 个人设置删掉「手动签发接口令牌」整块;settings/api_token 路由保留但挡下提交
  (只删界面会留下知道地址就能用的后门);令牌只由登录后自动签发,
  设备管理卡保留。apiTokens/apiPlain/apiLabel/apiBase 四个变量一并撤掉
2026-10-19 17:27:37 +08:00

80 lines
4.9 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 旅程**地图视图**的主体(v54 用户 2026-10-16 第 3 条)。
*
* 用户原话:「你去读一下 TripLog 的代码,在旅程这个模块,**可以在地图上显示旅程数据**。
* 1. 先读一下它之前那个代码是怎么实现的,**在我们的旅程模块也实现一下**。」
*
* ── TripLog 那套是怎么做的(读了它的 `templates/activities/index.php`)──
* · 用**高德 JS API**(`AMap.Map` + `AMap.Marker`);
* · 每个活动一枚标记;标记的 `content` 是自绘的"小卡片"(封面图 + 标题 + 地点),
* 同城/邻近的卡片会**环形扇开**+画引线,避免叠在一起;
* · `map.setFitView()` 自动框住所有点,但**上限 11 级**(不然只有一趟时会被
* 一路放大到街道级,那是导航视角不是"足迹"视角)。
*
* ── 本仓怎么落地(同一套思路,但数据源更规整)──
* · 坐标来源:`Trip::attachSpots()` —— 旅程下所有节点的 from/to 坐标**取重心**;
* 没有坐标就退到城市(内置离线城市表,**不发网络请求**,见那里的说明)。
* · 每趟旅程一枚标记,点它进 `trips/show`。
* · 🔴 v63(用户 2026-10-19 第 3 条):「旅程地图模式,应该显示旅程的题图。」
* ⇒ 卡片左侧加一枚**题图小方图**(`trip_details.cover_key`,与列表页同一个来源、
* 同一套 `media_url()` 出口)。没有题图就只显示文字,不留灰框。
* ⚠️ URL 在**服务端**算好塞进 JSON:`media_url()` 依赖站点路径与代理前缀
* (见那个函数的说明),端上拼不出来。
* · 视野上限同样 11 级、贴合全部标记。
*
* ⚠️ **合规**:地图用高德(腾讯/高德/百度/天地图是合规白名单内),
* 绝不用 Google/OSM 等境外瓦片。key 走本仓既有配置(`App\Geo::jsConfig()`),
* 由 `layout.php` 的 `fb-amap` 按需加载 —— 本页不自己拼 SDK 地址。
* ⚠️ 容器必须有**固定高度**(这里是 `.trip-map` 的 CSS 高度):
* 高德地图在"高度为 0 的容器"里渲染出来是空白,这是最常见的坑。
* ⚠️ 没有坐标的旅程**不画**(数据里说了 `trip_spot=false`);
* 若**一个点都没有**,不渲染地图容器,直接给一句说明(免得用户对着白框发呆)。
*
* 变量:$rows(Trip::all + attachDerived + attachSpots 之后)、$total
*/
$mapPoints = [];
foreach ((array)($rows ?? []) as $row) {
if (empty($row['trip_spot'])) {
continue;
}
$mapPoints[] = [
'id' => (int)$row['id'],
'title' => (string)$row['title'],
'lng' => (float)$row['trip_lng'],
'lat' => (float)$row['trip_lat'],
'when' => \App\Trip::activitySpan($row['starts_at'] ?? null, $row['ends_at'] ?? null),
'city' => (string)($row['city'] ?? ''),
'url' => url('trips/show', ['id' => (int)$row['id']]),
// 🔴 v63 第 3 条:题图。⚠️ 用 `media_url()` 而不是直接拼 storage 路径 ——
// 图片统一走 media.php 代理(桶不必开公共读),且**必须带版本号**,
// 否则换了题图缓存里还是老图。
'cover' => !empty($row['cover_key']) ? media_url((string)$row['cover_key']) : '',
];
}
?>
<?php if (!$mapPoints): ?>
<?php /* 一个坐标都没有 —— 如实说清楚"为什么没有",而不是给个空地图。
常见原因:行程里没填出发/到达地,或填了但(当时没配高德)没解析出坐标。 */ ?>
<div class="card card-pad empty" id="tripMapEmpty">
<b>还没有能在地图上显示的旅程</b>
地图要靠行程里的**出发地 / 到达地**(有坐标或能认出城市)。
去某趟旅程里加一段行程、把出发到达填上,它就会出现在这里。
</div>
<?php else: ?>
<?php /* 🔴 高度写在内联 style 上不够稳(有的主题会覆盖),
所以主要靠 `.trip-map` 的 CSS;这里只在**无 JS** 时兜一个提示。 */ ?>
<div class="trip-map-wrap">
<div class="trip-map" id="tripMapCanvas"
data-points="<?= e(json_encode($mapPoints, JSON_UNESCAPED_UNICODE | JSON_HEX_APOS | JSON_HEX_QUOT)) ?>">
<noscript><p class="trip-map-fallback">地图需要 JavaScript;用左侧的「列表」看旅程。</p></noscript>
</div>
<?php if (count($mapPoints) < (int)($total ?? 0)): ?>
<?php /* 有旅程不在图上 —— 说清楚,免得用户以为"少了几趟"。 */ ?>
<p class="small muted trip-map-hint">
有 <?= (int)($total ?? 0) - count($mapPoints) ?> 趟旅程没有可用位置(行程里没填出发/到达,或认不出城市),
没有画在地图上 —— 它们在「列表」里照常显示。
</p>
<?php endif; ?>
</div>
<?php endif; ?>