feat(after-sale): 处理记录时间线改为「节点 + 状态 + 时间」同一行

原实现把状态与时间竖排在节点右侧的 88px 固定列里,状态文字一长就折行、
时间被挤到第三行,和右侧备注也对不齐。改为节点独占一列,状态与时间包在
head 里紧随其后,处理备注另起一行:

- [节点][处理状态][时间] 一行,状态色仍按工单状态走 --as-accent
- 竖线改挂到条目的 ::before(原来是 aside 的),top 从 12px 调到 14px,
  与加了 4px 上边距的节点底部对齐,绳子依旧穿过每个节且末项不收口
- head 用 flex + baseline + gap:8px,状态过长时时间自然换行而不重叠
- 售后详细弹窗与订单详情弹窗共用同一套标记,两侧同步改

验证:tests/widget-system/ 462 项、tests/admin/ 76 项通过;用 node 分别抽取
两个 JS 里的时间线构造函数跑样例载荷,确认输出为
[节点][状态][时间] + 另起一行的备注;重建 public.css / public.min.css,
diff 仅限时间线规则。未做浏览器视觉验收。
This commit is contained in:
2026-10-09 18:01:16 +08:00
parent 26ce9a5904
commit 039fa6d863
6 changed files with 50 additions and 38 deletions
@@ -524,6 +524,10 @@ test('frontend renders the handling log as a rope-knot timeline', () => {
assert.match(js, /aksrt-after-sale-timeline__status/)
assert.match(js, /aksrt-after-sale-timeline__time/)
assert.match(js, /aksrt-after-sale-timeline__note/)
// [节点][处理状态][时间] 同一行:节点独占一列,状态与时间包在 head 里
assert.match(js, /'<span class="aksrt-after-sale-timeline__knot"><\/span>'/)
assert.match(js, /'<div class="aksrt-after-sale-timeline__head">' \+/)
assert.match(js, /'<div class="aksrt-after-sale-timeline__body">';/)
// 订单详情弹窗:每条工单同样渲染时间线,载荷带上 handling_log
assert.ok(!center.includes('gatewayResultText'), 'dead gateway-result renderer must be removed')
@@ -535,11 +539,15 @@ test('frontend renders the handling log as a rope-knot timeline', () => {
// 时间线样式:竖线穿节点、末项不收口,左列固定宽度、右列自适应
const css = read('assets/css/frontend/modal-runtime.css')
assert.match(css, /\.aksrt-after-sale-timeline__item \{ --as-accent: var\(--modal-muted\); display: grid; grid-template-columns: 88px minmax\(0, 1fr\)/)
assert.match(css, /\.aksrt-after-sale-timeline__aside::before \{ content: ""; position: absolute; top: 12px; bottom: -2px/)
assert.match(css, /\.aksrt-after-sale-timeline__item:last-child \.aksrt-after-sale-timeline__aside::before \{ display: none; \}/)
assert.match(css, /\.aksrt-after-sale-timeline__item \{ --as-accent: var\(--modal-muted\); position: relative; display: grid; grid-template-columns: 10px minmax\(0, 1fr\); gap: 10px; padding: 0 0 14px; \}/)
assert.match(css, /\.aksrt-after-sale-timeline__item::before \{ content: ""; position: absolute; top: 14px; bottom: -2px; left: 4px/)
assert.match(css, /\.aksrt-after-sale-timeline__item:last-child::before \{ display: none; \}/)
assert.match(css, /\.aksrt-after-sale-timeline__head \{ display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; \}/)
assert.match(css, /\.aksrt-after-sale-timeline__knot/)
assert.match(css, /\.aksrt-after-sale-timeline__note/)
// 旧的两列结构(aside / main)已移除
assert.ok(!css.includes('aksrt-after-sale-timeline__aside'), 'left-column aside must be removed')
assert.ok(!css.includes('aksrt-after-sale-timeline__main'), 'right-column main must be removed')
// 打包产物同步:public.css / public.min.css 都含时间线规则
assert.ok(read('assets/css/build/public.css').includes('.aksrt-after-sale-timeline__knot'))