窄屏宽表不再横向滚动:改成一屏一行的「字段名 + 值」

移动端有 7 张表要横滑 300+px 才看得全,滑着还对不上表头(地点库 8 列、统计 3 张、专题详情、
首页天气、后台数据集表与数据说明、专题管理、报告页 2 张)。给这些表加 tb-stack:
窄屏隐藏 thead、每行一屏一块、每格「字段名 + 值」竖排,值多行时用悬挂缩进。

- 字段名取自 td 的 data-label(首格是这行主角,故意不带标签;操作格给「操作」)——
  这样改列顺序也不会串标签,比把名字写进 CSS 的 nth-child 稳。
- 表格结构、链接、表单、按钮一律没动(只是隐藏 thead + 改 display),桌面与平板仍是原表。
- 断点只用 @media (max-width:620px):试过容器查询(能顺手治掉「宽屏里 g2 窄卡片也要横滑」),
  但实测会把 /stats 三个卡片撑高 1300px,太臃肿,不划算。

实测:390/620 十张表需横滑全部为 0、每行每格都有标签;621/700/1440 的横滑量与改动前一致
(桌面零变化);128 个链接/按钮滚动到可见后逐个点测均可点中,无裁切;全站审计 390 站长/访客 +
320 + 1440 溢出全 0、0 JS 报错,小触控与小字数与改动前逐页一致(320 下露外元素 /places 277→2、
/stats 114→12、/admin 46→4,剩下的都是有意的横滑容器)。

新增回归 internal/web/tb_stack_test.go:渲染 7 个页面、逐行核对「每个非首格都有 data-label」
且「格子数 == 表头列数」(变异验证过:去掉一个标签立刻 FAIL)。
This commit is contained in:
tamakyi
2026-09-18 22:24:12 +08:00
parent e8cb94230a
commit 7236c7a9d5
9 changed files with 187 additions and 56 deletions
+37
View File
@@ -1007,3 +1007,40 @@ label.f > span.span-actions { display: flex; align-items: center; justify-conten
.filters-card.collapsed > .panel-fold { margin: 0; border-radius: var(--radius); } .filters-card.collapsed > .panel-fold { margin: 0; border-radius: var(--radius); }
.filters-card.collapsed > :not(.panel-fold) { display: none; } .filters-card.collapsed > :not(.panel-fold) { display: none; }
} }
/* ---------- 窄屏:要横滑的宽表改成一屏一行的「字段 + 值」 ----------
地点库(8 列)、统计、专题、后台这几张表在手机上要横滑 300+px 才看得全,滑着还对不上表头。
窄屏改成每行一块、每格「字段名 + 值」竖排:不用横滑,也不用记「第几列是什么」。
字段名取 td 的 data-label,每行的首格留空当小标题(如地点名),操作格给「操作」。
表格结构与脚本都没动(只是隐藏 thead),链接 / 表单 / 按钮照旧;断点跟其它移动端适配一致
(620px),桌面与平板仍是原来的表格,一行不差。
注:统计页那几张表在宽屏也被放在 g2 的窄卡片里(视口 1440 时卡片只有 494px),仍然要横滑
100+px —— 但那属于桌面版式,真要治得单说;这里先只管移动端(按容器宽度判断会让这些卡片
在宽屏也竖排,实测把 /stats 撑高 1300px,得不偿失)。 */
@media (max-width: 620px) {
.tw > table.tb.tb-stack { min-width: 0; }
.tw > table.tb.tb-stack thead { display: none; }
.tw > table.tb.tb-stack,
.tw > table.tb.tb-stack > tbody,
.tw > table.tb.tb-stack > tbody > tr,
.tw > table.tb.tb-stack > tbody > tr > td { display: block; width: auto; }
.tw > table.tb.tb-stack > tbody > tr {
padding: 9px 11px; border-bottom: 1px solid var(--line-soft);
}
.tw > table.tb.tb-stack > tbody > tr:last-child { border-bottom: 0; }
/* 值用悬挂缩进:标签绝对定位在左边,值换行时对齐到值那一栏,而不是缩到标签下面 */
.tw > table.tb.tb-stack > tbody > tr > td {
position: relative; padding: 2px 0 2px 5.6em; border-bottom: 0;
}
.tw > table.tb.tb-stack > tbody > tr > td::before {
content: attr(data-label); position: absolute; left: 0; top: 2px;
width: 5em; color: var(--text-3); font-size: 12px;
}
/* 首格是这一行的主角(地点名 / 天气 / 方式…):不缩进、字号抬一档当小标题 */
.tw > table.tb.tb-stack > tbody > tr > td:not([data-label]) {
padding-left: 0; margin-bottom: 2px; font-size: 14px;
}
/* 数字列不必再右对齐(现在已经是「标签 + 值」两栏) */
.tw > table.tb.tb-stack td.num { text-align: left; }
}
+94
View File
@@ -0,0 +1,94 @@
package web
import (
"context"
"net/http"
"net/http/httptest"
"regexp"
"strconv"
"strings"
"testing"
)
// TestStackedTablesHaveLabels 守住「窄屏宽表变一屏一行」这条改动的核心不变量:
// 每张打了 tb-stack 的表,窄屏会把表头藏起来、改成「字段名 + 值」竖排,字段名只能取自
// td 的 data-label。少写一个标签,那一格在手机上就是没有名字的裸值——而桌面端一切正常,
// 很难发现(这轮就漏过两次:一张表的中间几行、后台两张表的「状态 / 对访客 / 操作」)。
// 顺带钉住每行格子数 == 表头列数,否则说明模板结构歪了。
//
// ROND_TEST_CONF=conf/app-test.ini ROND_SRC=data/xxx.rondbackup go test ./internal/web -run StackedTables -v
func TestStackedTablesHaveLabels(t *testing.T) {
f := newMovementFixture(t)
var topicID int64
if err := f.pg.QueryRowContext(f.ctx, `SELECT id FROM topics WHERE dataset_id=$1 ORDER BY id LIMIT 1`,
f.dsID).Scan(&topicID); err != nil {
topicID = 0 // 这个数据集没有专题,就少查一页
}
type target struct {
path string
h http.HandlerFunc
admin bool
}
targets := []target{
{"/places", f.srv.placesPage, false},
{"/stats", f.srv.statsPage, false},
{"/", f.srv.home, false},
{"/report", f.srv.reportPage, false},
{"/admin", f.srv.adminHome, true},
{"/admin/topics", f.srv.topicsAdminPage, true},
}
if topicID > 0 {
targets = append(targets, target{"/topics/" + strconv.FormatInt(topicID, 10), f.srv.topicPage, false})
}
tableRe := regexp.MustCompile(`(?s)<table[^>]*class="[^"]*tb-stack[^"]*"[^>]*>.*?</table>`)
rowRe := regexp.MustCompile(`(?s)<tr[^>]*>(.*?)</tr>`)
tdRe := regexp.MustCompile(`(?s)<td([^>]*)>`)
thRe := regexp.MustCompile(`<th[\s>]`)
total := 0
for _, tg := range targets {
ctx := context.Background()
if tg.admin {
ctx = f.ctx // 夹具的 ctx 里已经注入登录态
}
w := httptest.NewRecorder()
tg.h(w, httptest.NewRequest("GET", tg.path, nil).WithContext(ctx))
if w.Code != 200 {
t.Logf("%s 渲染 code=%d,跳过", tg.path, w.Code)
continue
}
for ti, tb := range tableRe.FindAllString(w.Body.String(), -1) {
total++
head := ""
if i, j := strings.Index(tb, "<thead>"), strings.Index(tb, "</thead>"); i >= 0 && j > i {
head = tb[i:j]
}
cols := len(thRe.FindAllString(head, -1))
for ri, row := range rowRe.FindAllString(tb, -1) {
if !strings.Contains(row, "<td") {
continue
}
cells := tdRe.FindAllStringSubmatch(row, -1)
if cols > 0 && len(cells) != cols {
t.Errorf("%s 第 %d 张表第 %d 行有 %d 格,表头 %d 列", tg.path, ti+1, ri+1, len(cells), cols)
}
for ci, c := range cells {
if ci == 0 {
continue // 首格是这一行的主角,故意不带标签
}
if !strings.Contains(c[1], "data-label=") {
t.Errorf("%s 第 %d 张表第 %d 行第 %d 格没有 data-label(窄屏会变成没有名字的裸值)",
tg.path, ti+1, ri+1, ci+1)
}
}
}
}
}
if total == 0 {
t.Fatal("一页 tb-stack 表都没找到:模板里的类名是不是被改掉了")
}
t.Logf("检查了 %d 张 tb-stack 表", total)
}
+14 -14
View File
@@ -108,7 +108,7 @@
<div class="card-sub">同一时刻只有一份数据处于「展示中」状态,主页与地图读取的就是它</div> <div class="card-sub">同一时刻只有一份数据处于「展示中」状态,主页与地图读取的就是它</div>
{{if .Datasets}} {{if .Datasets}}
<div class="tw"> <div class="tw">
<table class="tb"> <table class="tb tb-stack">
<thead> <thead>
<tr><th>文件</th><th>导入时间</th><th class="num">到访</th><th class="num">地点</th><th>数据跨度</th><th>状态</th><th></th></tr> <tr><th>文件</th><th>导入时间</th><th class="num">到访</th><th class="num">地点</th><th>数据跨度</th><th>状态</th><th></th></tr>
</thead> </thead>
@@ -116,18 +116,18 @@
{{range .Datasets}} {{range .Datasets}}
<tr> <tr>
<td><span class="mono">{{trunc .Name 34}}</span></td> <td><span class="mono">{{trunc .Name 34}}</span></td>
<td class="muted">{{dt .UploadedAt}}</td> <td class="muted" data-label="导入时间">{{dt .UploadedAt}}</td>
<td class="num">{{num .Visits}}</td> <td class="num" data-label="到访">{{num .Visits}}</td>
<td class="num">{{num .Places}}</td> <td class="num" data-label="地点">{{num .Places}}</td>
<td class="muted">{{if .First}}{{d .First}} ~ {{d .Last}}{{else}}—{{end}}</td> <td class="muted" data-label="数据跨度">{{if .First}}{{d .First}} ~ {{d .Last}}{{else}}—{{end}}</td>
<td> <td data-label="状态">
{{if and $.Dataset (eq $.Dataset.ID .ID)}} {{if and $.Dataset (eq $.Dataset.ID .ID)}}
<span class="tag">展示中</span> <span class="tag">展示中</span>
{{else}} {{else}}
<span class="muted">未启用</span> <span class="muted">未启用</span>
{{end}} {{end}}
</td> </td>
<td style="white-space:nowrap"> <td data-label="操作" style="white-space:nowrap">
{{if not (and $.Dataset (eq $.Dataset.ID .ID))}} {{if not (and $.Dataset (eq $.Dataset.ID .ID))}}
<form method="post" action="/admin/datasets/{{.ID}}/activate" style="display:inline"> <form method="post" action="/admin/datasets/{{.ID}}/activate" style="display:inline">
<button class="btn sm" type="submit">启用</button> <button class="btn sm" type="submit">启用</button>
@@ -152,15 +152,15 @@
<h2>数据说明</h2> <h2>数据说明</h2>
<div class="card-sub">从备份中读取并转换的字段</div> <div class="card-sub">从备份中读取并转换的字段</div>
<div class="tw"> <div class="tw">
<table class="tb"> <table class="tb tb-stack">
<thead><tr><th>来源表</th><th>内容</th><th>用途</th></tr></thead> <thead><tr><th>来源表</th><th>内容</th><th>用途</th></tr></thead>
<tbody> <tbody>
<tr><td class="mono">ZVISIT</td><td>到访记录(到达 / 离开时间、类型、地点、备注、标签)</td><td>时间线、统计、地图</td></tr> <tr><td class="mono">ZVISIT</td><td data-label="内容">到访记录(到达 / 离开时间、类型、地点、备注、标签)</td><td data-label="用途">时间线、统计、地图</td></tr>
<tr><td class="mono">ZLOCATION</td><td>地点(名称、经纬度、城市、省份、POI 分类)</td><td>地图打点、地点库</td></tr> <tr><td class="mono">ZLOCATION</td><td data-label="内容">地点(名称、经纬度、城市、省份、POI 分类)</td><td data-label="用途">地图打点、地点库</td></tr>
<tr><td class="mono">ZACTIVITY</td><td>自定义类型(颜色、图标、是否家 / 工作)</td><td>类型分布</td></tr> <tr><td class="mono">ZACTIVITY</td><td data-label="内容">自定义类型(颜色、图标、是否家 / 工作)</td><td data-label="用途">类型分布</td></tr>
<tr><td class="mono">ZMOVEMENT</td><td>位移段(交通方式、起止时间)</td><td>出行方式统计</td></tr> <tr><td class="mono">ZMOVEMENT</td><td data-label="内容">位移段(交通方式、起止时间)</td><td data-label="用途">出行方式统计</td></tr>
<tr><td class="mono">ZTAG</td><td>自定义标签及分组</td><td>标签筛选</td></tr> <tr><td class="mono">ZTAG</td><td data-label="内容">自定义标签及分组</td><td data-label="用途">标签筛选</td></tr>
<tr><td class="mono">ZHOURLYWEATHER</td><td>逐小时天气(气温、天气现象、湿度)</td><td>天气足迹</td></tr> <tr><td class="mono">ZHOURLYWEATHER</td><td data-label="内容">逐小时天气(气温、天气现象、湿度)</td><td data-label="用途">天气足迹</td></tr>
</tbody> </tbody>
</table> </table>
</div> </div>
+7 -7
View File
@@ -50,23 +50,23 @@
<div class="card-sub">共 {{len .Topics}} 个;「对访客」一列是展示开关,关掉的专题只有你自己能预览</div> <div class="card-sub">共 {{len .Topics}} 个;「对访客」一列是展示开关,关掉的专题只有你自己能预览</div>
{{if .Topics}} {{if .Topics}}
<div class="tw"> <div class="tw">
<table class="tb"> <table class="tb tb-stack">
<thead><tr><th>标题</th><th>时间范围</th><th class="num">地点</th><th class="num">到访</th><th>区域</th><th>对访客</th><th></th></tr></thead> <thead><tr><th>标题</th><th>时间范围</th><th class="num">地点</th><th class="num">到访</th><th>区域</th><th>对访客</th><th></th></tr></thead>
<tbody> <tbody>
{{range .Topics}} {{range .Topics}}
<tr> <tr>
<td><a href="/topics/{{.ID}}" target="_blank">{{.Title}}</a>{{if .Subtitle}} <span class="muted">· {{.Subtitle}}</span>{{end}}</td> <td><a href="/topics/{{.ID}}" target="_blank">{{.Title}}</a>{{if .Subtitle}} <span class="muted">· {{.Subtitle}}</span>{{end}}</td>
<td class="muted mono">{{.RangeLabel}}</td> <td class="muted mono" data-label="时间范围">{{.RangeLabel}}</td>
<td class="num">{{num .PlaceCount}}</td> <td class="num" data-label="地点">{{num .PlaceCount}}</td>
<td class="num">{{num .VisitCount}}</td> <td class="num" data-label="到访">{{num .VisitCount}}</td>
<td class="muted">{{if .HasArea}}{{printf "%.1f" .RadiusKm}} km 内{{else}}不限{{end}}</td> <td class="muted" data-label="区域">{{if .HasArea}}{{printf "%.1f" .RadiusKm}} km 内{{else}}不限{{end}}</td>
<td> <td data-label="对访客">
<form method="post" action="/admin/topics/toggle" style="display:inline"> <form method="post" action="/admin/topics/toggle" style="display:inline">
<input type="hidden" name="id" value="{{.ID}}"> <input type="hidden" name="id" value="{{.ID}}">
<button class="btn sm {{if .Enabled}}primary{{end}}" type="submit">{{if .Enabled}}展示中{{else}}已隐藏{{end}}</button> <button class="btn sm {{if .Enabled}}primary{{end}}" type="submit">{{if .Enabled}}展示中{{else}}已隐藏{{end}}</button>
</form> </form>
</td> </td>
<td style="white-space:nowrap"> <td data-label="操作" style="white-space:nowrap">
<a class="btn sm" href="/admin/topics?edit={{.ID}}">编辑</a> <a class="btn sm" href="/admin/topics?edit={{.ID}}">编辑</a>
<form method="post" action="/admin/topics/delete" style="display:inline" <form method="post" action="/admin/topics/delete" style="display:inline"
onsubmit="return confirm('删除专题「{{.Title}}」?地点数据不受影响。')"> onsubmit="return confirm('删除专题「{{.Title}}」?地点数据不受影响。')">
+4 -4
View File
@@ -132,15 +132,15 @@
<h2>天气足迹</h2> <h2>天气足迹</h2>
<div class="card-sub">记录期间经历过的天气</div> <div class="card-sub">记录期间经历过的天气</div>
<div class="tw"> <div class="tw">
<table class="tb"> <table class="tb tb-stack">
<thead><tr><th>天气</th><th class="num">记录小时数</th><th class="num">平均气温</th><th class="num">范围</th></tr></thead> <thead><tr><th>天气</th><th class="num">记录小时数</th><th class="num">平均气温</th><th class="num">范围</th></tr></thead>
<tbody> <tbody>
{{range .Weather}} {{range .Weather}}
<tr> <tr>
<td>{{condition .Condition}}</td> <td>{{condition .Condition}}</td>
<td class="num">{{num .Count}}</td> <td class="num" data-label="记录小时数">{{num .Count}}</td>
<td class="num">{{f1 .AvgTemp}} ℃</td> <td class="num" data-label="平均气温">{{f1 .AvgTemp}} ℃</td>
<td class="num">{{f1 .MinTemp}} ~ {{f1 .MaxTemp}} ℃</td> <td class="num" data-label="范围">{{f1 .MinTemp}} ~ {{f1 .MaxTemp}} ℃</td>
</tr> </tr>
{{end}} {{end}}
</tbody> </tbody>
+8 -8
View File
@@ -39,7 +39,7 @@
{{if .Places}} {{if .Places}}
<div class="tw"> <div class="tw">
<table class="tb places-table"> <table class="tb places-table tb-stack">
<thead> <thead>
<tr> <tr>
<th>地点</th><th>城市</th><th>主要类型</th><th>图片</th> <th>地点</th><th>城市</th><th>主要类型</th><th>图片</th>
@@ -57,15 +57,15 @@
{{if eq .Verdict 1}}<span class="tag vote-up">👍 推荐</span>{{else if eq .Verdict -1}}<span class="tag vote-down">👎 踩雷</span>{{end}} {{if eq .Verdict 1}}<span class="tag vote-up">👍 推荐</span>{{else if eq .Verdict -1}}<span class="tag vote-down">👎 踩雷</span>{{end}}
{{if or .Up .Down}}<span class="muted" style="font-size:12px">👍{{.Up}} · 👎{{.Down}}</span>{{end}} {{if or .Up .Down}}<span class="muted" style="font-size:12px">👍{{.Up}} · 👎{{.Down}}</span>{{end}}
</td> </td>
<td class="muted">{{if .City}}{{.City}}{{else}}—{{end}}</td> <td class="muted" data-label="城市">{{if .City}}{{.City}}{{else}}—{{end}}</td>
<td> <td data-label="主要类型">
{{if .TopActivity}}<span class="chip" style="padding:1px 8px"><span class="dot" style="background:{{colorof .TopColor}}"></span>{{.TopActivity}}</span>{{else}}<span class="muted">—</span>{{end}} {{if .TopActivity}}<span class="chip" style="padding:1px 8px"><span class="dot" style="background:{{colorof .TopColor}}"></span>{{.TopActivity}}</span>{{else}}<span class="muted">—</span>{{end}}
</td> </td>
<td>{{if .HasImage}}<span title="有图片">📷</span>{{else}}<span class="muted" title="还没有上传图片">—</span>{{end}}</td> <td data-label="图片">{{if .HasImage}}<span title="有图片">📷</span>{{else}}<span class="muted" title="还没有上传图片">—</span>{{end}}</td>
<td class="num">{{num .VisitCount}}</td> <td class="num" data-label="到访">{{num .VisitCount}}</td>
<td class="num">{{dur .DwellMinutes}}</td> <td class="num" data-label="累计停留">{{dur .DwellMinutes}}</td>
<td class="muted">{{if .FirstAt}}{{d .FirstAt}}{{else}}—{{end}}</td> <td class="muted" data-label="首次">{{if .FirstAt}}{{d .FirstAt}}{{else}}—{{end}}</td>
<td class="muted">{{if .LastAt}}{{d .LastAt}}{{end}}</td> <td class="muted" data-label="最近">{{if .LastAt}}{{d .LastAt}}{{end}}</td>
</tr> </tr>
{{end}} {{end}}
</tbody> </tbody>
+6 -6
View File
@@ -64,11 +64,11 @@
<div class="card-sub">这一年到过纬度最高与最低的地点</div> <div class="card-sub">这一年到过纬度最高与最低的地点</div>
{{if .North}} {{if .North}}
<div class="tw"> <div class="tw">
<table class="tb"> <table class="tb tb-stack">
<thead><tr><th>方位</th><th>地点</th><th class="num">纬度</th></tr></thead> <thead><tr><th>方位</th><th>地点</th><th class="num">纬度</th></tr></thead>
<tbody> <tbody>
<tr><td>最北</td><td>{{.North.Name}}<span class="muted"> · {{.North.City}}</span></td><td class="num">{{f1 .North.Lat}}°N</td></tr> <tr><td>最北</td><td data-label="地点">{{.North.Name}}<span class="muted"> · {{.North.City}}</span></td><td class="num" data-label="纬度">{{f1 .North.Lat}}°N</td></tr>
{{if .South}}<tr><td>最南</td><td>{{.South.Name}}<span class="muted"> · {{.South.City}}</span></td><td class="num">{{f1 .South.Lat}}°N</td>{{end}} {{if .South}}<tr><td>最南</td><td data-label="地点">{{.South.Name}}<span class="muted"> · {{.South.City}}</span></td><td class="num" data-label="纬度">{{f1 .South.Lat}}°N</td>{{end}}
</tbody> </tbody>
</table> </table>
</div> </div>
@@ -81,14 +81,14 @@
<h2>在路上</h2> <h2>在路上</h2>
<div class="card-sub">这一年 {{num .Overview.Movements}} 段行程,共 {{km .Overview.DistanceKm}} km</div> <div class="card-sub">这一年 {{num .Overview.Movements}} 段行程,共 {{km .Overview.DistanceKm}} km</div>
<div class="tw"> <div class="tw">
<table class="tb"> <table class="tb tb-stack">
<thead><tr><th>方式</th><th class="num">次数</th><th class="num">里程</th></tr></thead> <thead><tr><th>方式</th><th class="num">次数</th><th class="num">里程</th></tr></thead>
<tbody> <tbody>
{{range .Transports}} {{range .Transports}}
<tr> <tr>
<td><span class="dot" style="display:inline-block;background:{{colorof .Color}}"></span> {{with icon .Icon}}{{.}} {{end}}{{.Name}}</td> <td><span class="dot" style="display:inline-block;background:{{colorof .Color}}"></span> {{with icon .Icon}}{{.}} {{end}}{{.Name}}</td>
<td class="num">{{num .Count}}</td> <td class="num" data-label="次数">{{num .Count}}</td>
<td class="num">{{km .Distance}} km</td> <td class="num" data-label="里程">{{km .Distance}} km</td>
</tr> </tr>
{{end}} {{end}}
</tbody> </tbody>
+11 -11
View File
@@ -103,15 +103,15 @@
<h2>省级行政区</h2> <h2>省级行政区</h2>
<div class="card-sub">覆盖情况</div> <div class="card-sub">覆盖情况</div>
<div class="tw"> <div class="tw">
<table class="tb"> <table class="tb tb-stack">
<thead><tr><th>省份</th><th class="num">城市</th><th class="num">地点</th><th class="num">到访</th></tr></thead> <thead><tr><th>省份</th><th class="num">城市</th><th class="num">地点</th><th class="num">到访</th></tr></thead>
<tbody> <tbody>
{{range .ProvinceStats}} {{range .ProvinceStats}}
<tr> <tr>
<td>{{.Province}}</td> <td>{{.Province}}</td>
<td class="num">{{num .Cities}}</td> <td class="num" data-label="城市">{{num .Cities}}</td>
<td class="num">{{num .Places}}</td> <td class="num" data-label="地点">{{num .Places}}</td>
<td class="num">{{num .Count}}</td> <td class="num" data-label="到访">{{num .Count}}</td>
</tr> </tr>
{{end}} {{end}}
</tbody> </tbody>
@@ -141,15 +141,15 @@
<div class="card-sub">次数与估算里程</div> <div class="card-sub">次数与估算里程</div>
{{if .Transports}} {{if .Transports}}
<div class="tw"> <div class="tw">
<table class="tb"> <table class="tb tb-stack">
<thead><tr><th>方式</th><th class="num">次数</th><th class="num">里程</th><th class="num">在途时间</th></tr></thead> <thead><tr><th>方式</th><th class="num">次数</th><th class="num">里程</th><th class="num">在途时间</th></tr></thead>
<tbody> <tbody>
{{range .Transports}} {{range .Transports}}
<tr> <tr>
<td><span class="dot" style="display:inline-block;background:{{colorof .Color}}"></span> {{with icon .Icon}}{{.}} {{end}}{{.Name}}</td> <td><span class="dot" style="display:inline-block;background:{{colorof .Color}}"></span> {{with icon .Icon}}{{.}} {{end}}{{.Name}}</td>
<td class="num">{{num .Count}}</td> <td class="num" data-label="次数">{{num .Count}}</td>
<td class="num">{{km .Distance}} km</td> <td class="num" data-label="里程">{{km .Distance}} km</td>
<td class="num">{{dur .DwellMin}}</td> <td class="num" data-label="在途时间">{{dur .DwellMin}}</td>
</tr> </tr>
{{end}} {{end}}
</tbody> </tbody>
@@ -181,14 +181,14 @@
<h2>天气与气温</h2> <h2>天气与气温</h2>
<div class="card-sub">记录期间经历的小时级天气</div> <div class="card-sub">记录期间经历的小时级天气</div>
<div class="tw"> <div class="tw">
<table class="tb"> <table class="tb tb-stack">
<thead><tr><th>天气</th><th class="num">小时数</th><th class="num">平均气温</th></tr></thead> <thead><tr><th>天气</th><th class="num">小时数</th><th class="num">平均气温</th></tr></thead>
<tbody> <tbody>
{{range .Weather}} {{range .Weather}}
<tr> <tr>
<td>{{condition .Condition}}</td> <td>{{condition .Condition}}</td>
<td class="num">{{num .Count}}</td> <td class="num" data-label="小时数">{{num .Count}}</td>
<td class="num">{{f1 .AvgTemp}} ℃</td> <td class="num" data-label="平均气温">{{f1 .AvgTemp}} ℃</td>
</tr> </tr>
{{end}} {{end}}
</tbody> </tbody>
+6 -6
View File
@@ -42,17 +42,17 @@
<div class="card-sub">共 {{num .Topic.PlaceCount}} 个,按到访次数排序</div> <div class="card-sub">共 {{num .Topic.PlaceCount}} 个,按到访次数排序</div>
{{if .Points}} {{if .Points}}
<div class="tw"> <div class="tw">
<table class="tb"> <table class="tb tb-stack">
<thead><tr><th>地点</th><th>城市</th><th>类型</th><th class="num">到访</th><th class="num">停留</th><th>最近一次</th></tr></thead> <thead><tr><th>地点</th><th>城市</th><th>类型</th><th class="num">到访</th><th class="num">停留</th><th>最近一次</th></tr></thead>
<tbody> <tbody>
{{range .Points}} {{range .Points}}
<tr> <tr>
<td>{{if .Name}}{{.Name}}{{else}}<span class="muted">(未命名)</span>{{end}}</td> <td>{{if .Name}}{{.Name}}{{else}}<span class="muted">(未命名)</span>{{end}}</td>
<td class="muted">{{.City}}</td> <td class="muted" data-label="城市">{{.City}}</td>
<td class="muted">{{if .Act}}<span class="dot" style="background:{{colorof .Color}}"></span>{{.Act}}{{end}}</td> <td class="muted" data-label="类型">{{if .Act}}<span class="dot" style="background:{{colorof .Color}}"></span>{{.Act}}{{end}}</td>
<td class="num">{{num .Count}}</td> <td class="num" data-label="到访">{{num .Count}}</td>
<td class="num muted">{{dur .Dwell}}</td> <td class="num muted" data-label="停留">{{dur .Dwell}}</td>
<td class="muted mono">{{.LastAt}}</td> <td class="muted mono" data-label="最近一次">{{.LastAt}}</td>
</tr> </tr>
{{end}} {{end}}
</tbody> </tbody>