feat(ai-chat): 优化历史消息时间显示与搜索定位

- 时间显示人性化:昨天/前天/跨年日期
- 搜索上下导航修复 scroll-into-view 触发逻辑
This commit is contained in:
2026-05-19 09:28:29 +08:00
parent 861c43a428
commit 70fbdce641
3 changed files with 47 additions and 27 deletions

View File

@@ -8,6 +8,11 @@ export const lang = {
send: 'Send', send: 'Send',
retry: 'Retry', retry: 'Retry',
// ====== Time Format ======
timeFormatToday: 'Today',
timeFormatYesterday: 'Yesterday',
timeFormatBeforeYesterday: 'Day before yesterday',
// ====== ai-chat-message ====== // ====== ai-chat-message ======
aiNickname: 'AI Assistant', aiNickname: 'AI Assistant',
defaultNickname: 'Me', defaultNickname: 'Me',

View File

@@ -8,6 +8,11 @@ export const lang = {
send: '发送', send: '发送',
retry: '重试', retry: '重试',
// ====== 时间格式化 ======
timeFormatToday: '今天',
timeFormatYesterday: '昨天',
timeFormatBeforeYesterday: '前天',
// ====== ai-chat-message ====== // ====== ai-chat-message ======
aiNickname: '智能助手', aiNickname: '智能助手',
defaultNickname: '我', defaultNickname: '我',

View File

@@ -1291,52 +1291,62 @@ _handleStreamError(msg) {
return html return html
}, },
// 格式化时间 // 格式化时间(人性化显示)
formatTime(timestamp) { formatTime(timestamp) {
// 如果没有时间戳,就不显示时间 if (!timestamp) return '';
if (!timestamp) {
return '';
}
let date; let date;
// 如果是字符串格式,例如 "2026-04-16 03:56:20"
if (typeof timestamp === 'string') { if (typeof timestamp === 'string') {
// 手动解析格式 "YYYY-MM-DD HH:mm:ss"
const parts = timestamp.match(/(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})/); const parts = timestamp.match(/(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})/);
if (parts) { if (parts) {
const [, year, month, day, hour, minute, second] = parts; const [, year, month, day, hour, minute, second] = parts;
// 先解析成本地时间,然后加上8小时时区差
date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second)); date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second));
// 加上8小时
date.setHours(date.getHours() + 8); date.setHours(date.getHours() + 8);
} else { } else {
// 其他字符串格式直接解析
date = new Date(timestamp); date = new Date(timestamp);
} }
} } else {
// 如果是数字格式
else {
let timeValue = timestamp; let timeValue = timestamp;
// 如果时间戳小于10000000000,说明是秒,需要乘以1000转成毫秒
if (typeof timeValue === 'number' && timeValue < 10000000000) { if (typeof timeValue === 'number' && timeValue < 10000000000) {
timeValue = timeValue * 1000; timeValue = timeValue * 1000;
} }
date = new Date(timeValue); date = new Date(timeValue);
} }
if (isNaN(date.getTime())) return '';
// 如果时间无效,就不显示时间
if (isNaN(date.getTime())) { const now = new Date();
return ''; const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
} const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
const beforeYesterday = new Date(today.getTime() - 2 * 24 * 60 * 60 * 1000);
const msgDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
const hours = date.getHours().toString().padStart(2, '0'); const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0');
const result = hours + ':' + minutes; const timeStr = `${hours}:${minutes}`;
return result;
if (msgDate.getTime() === today.getTime()) {
return timeStr;
}
if (msgDate.getTime() === yesterday.getTime()) {
return `${this.$lang('timeFormatYesterday')} ${timeStr}`;
}
if (msgDate.getTime() === beforeYesterday.getTime()) {
return `${this.$lang('timeFormatBeforeYesterday')} ${timeStr}`;
}
const isCurrentYear = date.getFullYear() === now.getFullYear();
const monthStr = (date.getMonth() + 1).toString();
const dayStr = date.getDate().toString();
if (isCurrentYear) {
return `${monthStr}/${dayStr} ${timeStr}`;
}
const yearStr = date.getFullYear().toString();
return `${yearStr}/${monthStr}/${dayStr} ${timeStr}`;
}, },
// 格式化文件大小 // 格式化文件大小