前端给AI消息做日期分组与时间线

先说结论:把一长条 AI 对话消息变成清爽的时间线,核心就两步------按会话(session)分组 、再按日期(今天/昨天/更早)打标签 。数据层用 reduce 归并,渲染层做粘性日期头,不用引第三方库。下面是我前两周真踩过的活儿,代码能直接抄。

起因

我在给一个自己搭的 AI 小助手做 web 端聊天界面。后端把消息一股脑按时间正序吐回来,前端就一条接一条往下堆。测了两天,消息攒到三百多条的时候,整个面板糊成一坨------你根本分不清哪句是今早问的,哪句是上周那次会话留下的。产品同事(其实就是我自己兼)看了一眼说:太脏了。

行吧。

第一步:数据先分好组,别在 JSX 里硬塞

我见过有人直接在模板里 if (上一条日期 !== 这条日期) 插分隔线,能跑,但乱。先在数据层把扁平数组捏成分组结构。

scss 复制代码
// 假设每条 msg: { id, sessionId, content, role, createdAt }
function groupBySession(messages) {
  const map = new Map();
  for (const m of messages) {
    if (!map.has(m.sessionId)) map.set(m.sessionId, []);
    map.get(m.sessionId).push(m);
  }
  // Map 保插入顺序,会话天然按首次出现排好
  return [...map.entries()].map(([sessionId, list]) => ({
    sessionId,
    list,
    startAt: list[0].createdAt,
  }));
}

会话内再不用动,组与组之间按 startAt 倒序就是最近的会话在最上面。

第二步:日期标签,别去算"几天前"

这步是我栽过的坑。一开始我吭哧吭哧写 Math.floor((now - t) / 86400000) 去算差几天,结果跨午夜就错------晚上23:50和凌晨0:10明明隔了20分钟,算出来"0天",可它俩分属两天,得分到两组。

正解是比日历日,不是比时间差:

ini 复制代码
function dayLabel(ts) {
  const d = new Date(ts);
  const today = new Date();
  const ymd = x => x.getFullYear() * 10000 + (x.getMonth() + 1) * 100 + x.getDate();
  const diff = ymd(today) - ymd(d);
  if (diff === 0) return '今天';
  if (diff === 1) return '昨天';
  if (diff < 7) return d.toLocaleDateString('zh-CN', { weekday: 'long' }); // 周三
  return `${d.getMonth() + 1}月${d.getDate()}日`;
}

把日期戳压成 年*10000+月*100+日 这个整数再相减,天数差就稳了,不受具体几点几分干扰。

第三步:粘性日期头,滚动时吸顶

时间线的"清爽感"一大半来自滚动时那个日期标签会黏在顶上。纯 CSS 就够:

css 复制代码
.day-label {
  position: sticky;
  top: 0;
  z-index: 2;
  /* 别忘了背景色,不然下面的消息会透上来糊一起 */
  background: #f7f8fa;
}

background 那行我忘了写,调了十分钟以为是 z-index 的事,结果是文字和下面气泡叠透了。记一下。

一点真实的取舍

会话分组我没做"自动归并相近时间的消息"那种智能合并------比如隔了2小时的两次提问算不算一个会话。试过,阈值定多少都有人觉得不对,干脆老老实实信后端给的 sessionId,前端只管展示。少做一点反而稳。

另外说句实话,难看的不是布局,是内容本身。我那个 AI 小助手第一版回答又干又短,时间线做得再漂亮,点开每条都是两行废话也白搭。后来我给它配了点私有资料喂进去(RAG 那套),回答才有了血肉,时间线翻起来才像回事。

对了,搭这个小助手我基本没写后端------拖一拖配一配,挂个现成模型、传几份文档当知识库,发布成一个 API,前端直接调。我一个偏前端的人,零代码就把"智能体"那部分糊出来了,省下的精力全砸在这个时间线交互上了。

收尾

分组的活儿听着小,做到"一眼就清爽"挺费心思的------比 ymd 那个整数 trick 还琐碎的细节有七八处。但用户滑动时那个日期标签稳稳吸在顶上的瞬间,值。

你们做聊天记录的日期分组,是信后端 sessionId 还是前端自己按时间切?评论区聊聊,我那套阈值方案就是被同行劝退的。

(背后那个智能体我挂的是讯飞的 MaaS,现成大模型直接调 API,没自己部署算力,省心。)

相关推荐
tqs_123456 分钟前
AI后端服务高性能架构:GPU独立部署、算力解耦、弹性伸缩实战
人工智能·架构
MartinYeung512 分钟前
[论文学习]谄媚研究者驱动表演性错位:大语言模型“对齐伪装”成因的颠复性实证研究
人工智能·学习·语言模型
红色星际13 分钟前
新石器走进无人配送车下半场
大数据·人工智能
高远项目管理16 分钟前
技术实践:用高远-AI智能化缺陷管理应用把缺陷录入到派单全自动
人工智能·智能驾驶·缺陷管理·aspice·研发协同·飞书项目meego·高远科技
爱吃火鸡面呀19 分钟前
图片拼接与答题卡判断对错:从图像处理到自动判卷的完整实践
图像处理·人工智能
AI_AGENT_DEV_AI20 分钟前
原生 APP 开发的核心优势
人工智能
搭贝21 分钟前
国资报送责任制怎么建?三级责任矩阵设计
android·数据库·人工智能·线性代数·低代码·矩阵·制造
磁场转动100万匹22 分钟前
深度学习入门:从神经网络到反向传播的完整解析
人工智能·深度学习·神经网络
欧特克_Glodon22 分钟前
OpenCV计算机视觉开发入门与实践<二十四>:几何变换之平移、缩放、旋转
c++·人工智能·opencv·计算机视觉
AI服务老曹26 分钟前
水位识别算法接入AI视频分析平台全流程与误报优化指南(附接口字段与排查表)
人工智能·算法·音视频