Commit Graph
7 Commits
Author SHA1 Message Date
tamakyi eb35abb7f2 专题页的迷雾按专题圈的区域收口
以前专题的中心/半径只用来定视图,迷雾图层一直是全局的;管理页那句
「迷雾由地图按视野自动呈现,不需要单独圈选」其实是把「没做」写成了
「不用做」。现在专题圈了区域时,迷雾只在那个圆内显示。

做法是给迷雾单独一个 pane(zIndex 250,底图 200 之上)再对该 pane 做
clip-path: circle()——不能直接裁 tilePane,底图也在里面,会把地图一起挖空。

两个坑:
- 圆心必须先 project() 到底图坐标系(与 fitCircle 一致),否则整体偏移;
- 裁剪圆的注册必须排在 applyFit() 之后:视图未定时 latLngToContainerPoint()
  会抛「Set map center and zoom first.」,把后续图层添加一起打断——实测
  表现是 pane 建好了、迷雾瓦片一张都不出来,而且不报错。

迷雾是累积快照、没有时间维度,所以只按区域收口,不按专题的时间范围收口。
守卫 TestTopicFogIsClippedToArea 钉住两端与注册顺序。
2026-10-10 10:41:27 +08:00
tamakyi cd69efe8f1 日历改中文、修掉头部重叠;统计页那两张体量悬殊的卡不再并排
用户反馈:日历「空间显示有点异常」且是英文、和项目割裂;类型分布与一天中的分布仍是一左一右、
右边下面一大片空白。两件事的根因都不是表面看到的那个。

一、日历英文
- `flatpickr.localize(l10ns.zh)` 原先只写在三个后台页的 whenReady 里;上一批把 flatpickr 放到
  公共页(筛选区)之后就漏了 ⇒ 日历全是 Sun/Mon/January…
- 修法:移到 datetime-input.js 的 attachPicker 里(localizeOnce(),全局只调一次),
  三个后台页那三行重复调用删掉。

二、日历头部重叠(就是用户说的「空间异常」)
- 月份下拉被撑满整行、压在年份输入上。根因是**站点全局的 input/select 样式扫进了日历内部**:
  那条规则带 width:100%、内边距、边框与 16px 控件字号,而日历内部的
  `input.numInput`(type=number)与 `select.flatpickr-monthDropdown-months` 都躲不开。
- ⚠️ 第一版修法(在后面补一条 `.flatpickr-calendar input{...}` 对冲)**是错的**:全局选择器带
  10 个 :not([type=…])、特异性 (0,10,1),普通对冲压不过,实测年份框仍是站点样式。
  正确做法是在**全局规则里排除** `input…:not(.numInput)` / `select:not(.flatpickr-monthDropdown-months)`,
  `input:focus` 的焦点环同理(否则年份框上套一圈主色光圈)。
- 实测:星期「周日 周一 …」、月份「十月」、月份与年份 overlap=0、无 JS 报错。

三、统计页排版
- `align-items: start` 只消掉了卡内空白,消不掉并排本身的空:类型分布 1411px 与
  一天中的分布 256px 并排,右侧下面必然空一片。改成单列(`<div class="grid">`),
  两张卡各占整行 1080px —— 24 根柱终于有宽度可用,列表也像「城市排行」那样横铺。

回归:./scripts/verify.sh PASS=349 FAIL=0 SKIP=0;JS 单测 45/45;移动端 390 溢出全 0;
桌面 1440 与改前一致(−15 是滚动条宽)。
2026-10-10 09:45:32 +08:00
tamakyi b69b827d6e 日期框换成自控输入(原生 date 会吞位)+ 气温图桌面端铺满 + 同行卡片不再被拉伸
三件事都由用户实测反馈,前两件先复现再动手。

一、日期框:敲 20260606 变成 202606/06(用户要「永远解决」)
- **实测复现**:写了个真实按键工具(CDP Input.dispatchKeyEvent 每字符带 text;
  技能里的 `--press` 只给 Enter 带 text,数字敲不进去)。在 /stats 的「起始日期」上敲 20260606:
  敲之前 `INPUT|date|`、attached=false;敲完显示 `202606/06`、`el.value` 是**空**(非法)—— 截图为证。
- **根因**:筛选区的起止日期是原生 `<input type="date">`,而挂载代码只写了
  `querySelectorAll('input[type=datetime-local]')` ⇒ **type=date 从没人管**。
  Chrome 的年段允许超过 4 位数字(年份上限 275760),8 位被切成 年=202606 + 月=06。
  原生分段状态读不到、`setSelectionRange` 对 date 类输入直接抛 ⇒ 修不了,只能换控件
  (用户也说了「如果当前控件无法实现就换别的」)。
- **做法**:`datetime-input.js` 加「只日期」模式(`SPEC.date`:年/月/日三段,输出 `Y-m-d`),
  并提供**统一入口 `attachAll(root)`** 按 `el.type` 分派;`attach` 里先把控件换成 `text`
  (引导会写 `2026-06-` 这种半成品,而原生控件对非法值一律置空)。
  `datetime-input.js` 改为**无条件引入**(公共页筛选区也要用;flatpickr 仍按需加载 ——
  没有它时只挂输入引导、不给日历,省 60 多 KB),挂载在 body 末尾**立刻**跑一次
  (别只等 DOMContentLoaded,否则会先露出原生框再变文本框)。三个后台页改用 `attachAll`,
  顺带覆盖行程筛选的 `mfrom/mto`(date 类走 `enableTime:false`,实测无时间选择器)。
- **验证**:真实按键敲 20260606 → `value="2026-06-06"`;端到端 `from=2025-08-01&to=2025-08-31`
  筛出 **186 次**,与月度图峰值月(186)完全吻合(排除「解析成空导致恒 0」)。
  门禁 `TestDateInputsGoThroughAttachAll`:模板里再出现按 type 挑的选择器即红(做过变异验证);
  JS 单测补 11 条逐键模拟(45/45)。

二、逐月平均气温图在桌面端很小
- 量出来的:10 个月固定 36px 宽,只占 1042px 里的 **396px**,右边 600 多像素全空。
- 窄屏保持「固定 36px + 横滚」(挤在一起月份标签会糊),宽屏改 `flex: 1 1 36px; max-width: 96px`
  并把轨道从 84px 加到 130px、字号提到 `--fs-sm`。

三、类型分布与一天中的分布同行高度不齐
- grid 默认 `align-items: stretch`,把 256px 的「一天中的分布」拉到与 1411px 的「类型分布」一样高,
  卡片内部留一大片空白。改成 `.grid { align-items: start }`。

回归:./scripts/verify.sh **PASS=349 FAIL=0 SKIP=0**;移动端 390 / 桌面 1440 溢出与改前一致。

⚠️ 两个验证纪律(都写进 details 三十二):
- 验收跑着的时候别并发跑测试/变异实验(两次踩到,其中一次变异正好被验收抓到,那轮结果作废)。
- **变异验证「内嵌文件」(templates/static)之后必须 `go clean -cache`**:`//go:embed` 的内容
  在「改坏→还原」后,构建缓存会继续给出变异期间编译的那份 —— 实测同一个测试
  `go test ./internal/web/` 绿、`go test ./...` 红,`go clean -testcache` 不管用。
2026-10-09 18:29:55 +08:00
tamakyi 4015ddf373 时间框跳段 + 弹窗不再脏地址栏 + 统计脚本做成后台开关
时间框(flatpickr allowInput 的手输体验)
- flatpickr 把 <input type=datetime-local> 就地改成 type=text,原生分段编辑器被替换掉;
  allowInput 又是「整串解析」语义:实测 parseDate('2026') 只出年份、'202666' 才出月份,
  于是「年份很长才跳下一位」;'20260606' 还会被静默错解成 2030-12-06 且不报错。
- 新增 static/js/datetime-input.js:自定义 parseDate(纯数字只收 4/6/8/12/14 位,
  歧义与非法日期一律拒)+ 输入引导(段满即补分隔符,敲完 4 位年份立刻跳月份位)。
  按标准格式不做自动补零、不前滚;越界值原样保留交报错,不静默改成合法值。
- 三处页面(编辑/照片/专题)共用 attachPicker,配置与原先一致,模板净减 5 行。

弹窗
- window.prompt 会把提示文本与默认值写进地址栏并留进历史(confirm/alert 无此问题)。
- 新增 static/js/prompt-box.js 替代:原生 <dialog>.showModal(),遮罩/Esc/焦点齐全,
  旧浏览器降级成页面顶部一条。已换 report.html 复制链接兜底与 edit.html 活动改名。
- 门禁 no_prompt_test.go:静态扫模板禁止 prompt(,并钉住 JS 与 CSS 都在。

统计脚本
- 原来只能改 conf/app.ini(要重启),现在后台「站点设置」可开关 + 填写,默认关闭。
- cleanTrackScript 挡住注入面:开闭 <script> 标签数不配平(提前闭合会让页面散架)、
  src 的 javascript:/data: 伪协议、超长截断。注意不能用「出现 </script 就拒」当规则——
  百度统计、Umami 贴的就是完整 HTML,正常用法会被挡死。

门禁
- datetime-input.test.js:34 条断言(node 直跑,无依赖)。
- TestCleanTrackScript:逐条边界 + 定义性不变量(任何输入都不得产出含 </script 的非空结果)。
- 三项均做过变异验证,改坏实现都会被对应测试抓到。

实测:真实站点逐键 2→20→202→2026-→2026-06-→2026-06-06T;
统计脚本六个场景(默认关/只填不开/开+URL/后台与登录页不挂/危险输入/关掉恢复)全部符合预期。
全量 internal/web 204 例 0 skip,其余包全绿,gofmt 干净。
2026-10-08 18:27:59 +08:00
tamakyi 9e01923244 宽表在窄屏真的不横滑了:堆叠判据退回媒体查询,后台三张表补上
真机反馈「手机上还是要左右滑」,两个根因:

1. 上一版把堆叠判据写成了 @container。它按卡片自己的宽度判断更准,但要
   iOS 16 / Chrome 105 才支持——旧手机把整块规则当不认识的东西丢掉,表格
   完全不堆叠、退化成横滑 328~388px,比改之前还糟。改回 @media,阈值从
   620 抬到 800:卡片内容宽 ≈ 视口 − 93,最宽的表 min-width 700,视口 793
   以上才放得下,620 那档会让 621~792 两头不靠。

2. /admin/edit 的地点/到访/行程三张表压根没加 tb-stack。它们默认折叠在
   data-card 里,探针在默认态量到的是 display:none,前两轮审计都没扫到。

顺带修掉三处被这次改动顶出来的问题:
- 宽表卡片不放 g2:/stats /report 有几张表被塞进半宽卡片,视口 1440 时
  卡片只有 494px,桌面端照样要横滑 100+px。改成整行(只动含表的那些网格,
  「推荐 & 踩雷」「类型分布 + 一天中的分布」这类没有表的仍保持两列)。
- 操作格的 inline white-space:nowrap 会继承进行内编辑表单,堆叠态下
  「已选:#403 …」那一行不换行、把卡片顶破。挪成 .ops 类,窄屏放开。
- 行内编辑表单的 min-width 改成 --efw 变量(inline 的 min-width 压不过
  CSS 覆盖),堆叠态置 0 让它自然铺满。

导航装不下时右缘渐隐一下,提示还能往右滑;滑到末端自动收掉。用 mask 而不是
盖一层渐变伪元素——伪元素会把链接文字一起遮住。

回归:tb_stack_test.go 补 /admin/edit(12 张表),表头为空的列(如末尾操作格)
不再要求 data-label;新增 wide_table_layout_test.go 守住「宽表卡片必须整行」+
「凡被 .tw 包住的表必须带 tb-stack」+「堆叠规则必须在 max-width≥792 的 @media 里」。
2026-09-19 02:04:03 +08:00
tamakyi 7236c7a9d5 窄屏宽表不再横向滚动:改成一屏一行的「字段名 + 值」
移动端有 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)。
2026-09-18 22:24:12 +08:00
tamakyi b327bc1230 first release 2026-09-18 13:05:49 +08:00