From b56cea0c8cbd27c55bf7053a0c79109c882d6315 Mon Sep 17 00:00:00 2001 From: wanghanlin <1533525126@qq.com> Date: Thu, 20 Aug 2026 09:31:02 +0800 Subject: [PATCH] =?UTF-8?q?fix(client):=20=E5=8E=86=E5=8F=B2=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E6=97=B6=E9=97=B4=E6=99=BA=E8=83=BD=E5=88=86=E6=A1=A3?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=B9=B6=E4=BF=AE=E5=A4=8D=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=A0=8F=E6=8C=89=E9=92=AE=20tooltip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 历史会话列表时间由原始 ISO 字符串改为智能分档:今天/昨天显示 HH:mm,同年显示 MM-DD HH:mm,跨年显示 YYYY-MM-DD HH:mm。 操作栏按钮(重新生成/复制/点赞/点踩)补齐 hover 文字说明:修复 tooltip 浮层 z-index 低于聊天窗(9999)被遮挡,及 .t-tooltip 深色背景样式在 light DOM 浮层缺失的问题(globalCSS 只对 shadow DOM 生效)。 --- client/src/dom.ts | 10 +++++++--- client/src/styles.ts | 20 ++++++++++++++++++++ client/src/utils.ts | 21 +++++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/client/src/dom.ts b/client/src/dom.ts index 0ae5860..5132366 100644 --- a/client/src/dom.ts +++ b/client/src/dom.ts @@ -8,7 +8,7 @@ * - 输入区采用圆角容器包裹文本框与发送按钮 */ import { ResolvedConfig, RagSource } from './types'; -import { debounce, formatTime } from './utils'; +import { debounce, formatTime, formatHistoryTime } from './utils'; import { t } from './i18n'; import { DialogPlugin } from 'tdesign-web-components/lib/dialog/index.js'; // omi 的 render/h 用于创建带 on* 函数回调的组件(见 createEventful 说明) @@ -915,8 +915,11 @@ function createChatAction(wrapper: HTMLElement, text: string, msgId?: string, fe const el = actionEl as unknown as { actionBar: string[]; handleAction: (action: string, data: { event?: Event; active?: boolean }) => void; + tooltipProps: Record; }; el.actionBar = ['replay', 'copy', 'good', 'bad']; + // 浮层 portal 到 body:zIndex 越过弹窗(9999)防遮挡,overlayClassName 加 SDK 私有类用于补样式 + el.tooltipProps = { overlayClassName: 'csk-tooltip', zIndex: 10000 }; // copyText/comment 为 String 简单类型,须用 setAttribute(property 赋值在 omi 下静默失效) actionEl.setAttribute('copyText', text); actionEl.setAttribute('comment', feedback === 'up' ? 'good' : feedback === 'down' ? 'bad' : ''); @@ -1160,8 +1163,9 @@ export function renderHistoryList( const metaParts: string[] = []; if (item.roleName) metaParts.push(item.roleName); if (item.messageCount !== undefined) metaParts.push(`${item.messageCount} 条消息`); - if (item.lastMessageTime) metaParts.push(item.lastMessageTime); - else if (item.createdAt) metaParts.push(item.createdAt); + const timeStr = item.lastMessageTime || item.createdAt; + const timeText = formatHistoryTime(timeStr); + if (timeText) metaParts.push(timeText); metaEl.textContent = metaParts.join(' · '); info.appendChild(idEl); diff --git a/client/src/styles.ts b/client/src/styles.ts index 051451a..38a30cc 100644 --- a/client/src/styles.ts +++ b/client/src/styles.ts @@ -624,6 +624,26 @@ function getStyles(config: ResolvedConfig): string { .csk-launcher, .csk-teaser { box-sizing: border-box; } .csk-launcher *, .csk-teaser * { box-sizing: border-box; } +/* ===== tooltip 浮层(t-popup portal 到 body,light DOM)样式补注入 ===== + * .t-tooltip 样式在 globalCSS(constructable stylesheet)里只对 shadow DOM 生效, + * 但浮层 portal 到 document.body 是 light DOM,故补注入;用 csk-tooltip 私有类避免污染宿主。 + * 来源:tdesign-web-components v1.2.10 的 _chunks/dep-a3fbe4be.js(css_248z)。 */ +.csk-tooltip .t-popup__content { + display: inline-block; + border: 0; + z-index: 5600; + margin-bottom: 1px; + max-width: 480px; + word-break: break-word; + box-sizing: border-box; + border-radius: var(--td-radius-medium); + color: var(--td-text-color-anti); + background: var(--td-gray-color-13); + box-shadow: inset 0 0.5px 0 var(--td-gray-color-9), inset 0.5px 0 0 var(--td-gray-color-9), inset 0 -0.5px 0 var(--td-gray-color-9), inset -0.5px 0 0 var(--td-gray-color-9); +} +.csk-tooltip .t-popup__arrow { background: inherit; height: auto; } +.csk-tooltip .t-popup__arrow::before { background: inherit; } + /* ===== t-tag(light DOM 组件)样式补注入 ===== * t-tag 是 tdesign-web-components 的 light DOM 组件(isLightDOM: true),其 .t-tag * 样式定义在 globalCSS 的 constructable stylesheet 里,但 globalCSS 只对 shadow DOM diff --git a/client/src/utils.ts b/client/src/utils.ts index 3d0d3d0..fb712a2 100644 --- a/client/src/utils.ts +++ b/client/src/utils.ts @@ -40,6 +40,27 @@ export function formatTime(timestamp: number): string { return `${hh}:${mm}`; } +/** 格式化历史会话时间:今天/昨天显示 HH:mm,同年显示 MM-DD HH:mm,跨年显示 YYYY-MM-DD HH:mm */ +export function formatHistoryTime(timeStr: string | undefined): string { + if (!timeStr) return ''; + const d = new Date(timeStr); + if (isNaN(d.getTime())) return timeStr; // 解析失败原样返回,避免破坏展示 + const pad = (n: number) => String(n).padStart(2, '0'); + const hh = pad(d.getHours()); + const mm = pad(d.getMinutes()); + const now = new Date(); + const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime(); + const yesterdayStart = todayStart - 86400000; + const ts = d.getTime(); + // 今天或昨天:只显示时分 + if (ts >= yesterdayStart) return `${hh}:${mm}`; + const md = `${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; + // 今年内:月-日 时分 + if (d.getFullYear() === now.getFullYear()) return `${md} ${hh}:${mm}`; + // 跨年:完整年月日 时分 + return `${d.getFullYear()}-${md} ${hh}:${mm}`; +} + /** 获取当前时间戳(毫秒) */ export function now(): number { return Date.now();