diff --git a/frontend/src/pages/front/ChatPage.css b/frontend/src/pages/front/ChatPage.css index 294e026..f8bc2fd 100644 --- a/frontend/src/pages/front/ChatPage.css +++ b/frontend/src/pages/front/ChatPage.css @@ -1574,6 +1574,30 @@ del { border-color: color-mix(in srgb, var(--color-accent, #5B5FED) 35%, transparent); } +/* 新鲜出炉的思考面板 — 脉冲高亮动画 */ +.ai-process-fresh { + animation: aiProcessPulse 1.2s ease-out; +} +.ai-process-fresh .ai-process-summary { + color: var(--color-accent, #5B5FED); + font-weight: 700; +} + +@keyframes aiProcessPulse { + 0% { + box-shadow: 0 0 0 0 rgba(91, 95, 237, 0.4); + border-color: var(--color-accent, #5B5FED); + } + 50% { + box-shadow: 0 0 0 6px rgba(91, 95, 237, 0.08); + border-color: color-mix(in srgb, var(--color-accent, #5B5FED) 60%, transparent); + } + 100% { + box-shadow: 0 6px 22px rgba(91, 95, 237, 0.10); + border-color: color-mix(in srgb, var(--color-accent, #5B5FED) 35%, transparent); + } +} + .ai-process-summary { list-style: none; cursor: pointer; diff --git a/frontend/src/pages/front/ChatPage.tsx b/frontend/src/pages/front/ChatPage.tsx index 4abef3e..2da97c3 100644 --- a/frontend/src/pages/front/ChatPage.tsx +++ b/frontend/src/pages/front/ChatPage.tsx @@ -478,22 +478,35 @@ const Dropdown: React.FC = ({ trigger, children, className = '', // ===== AI 思考 / 执行过程面板(顶部展开 + 自动收拢) ===== // autoExpand=true 时(本轮刚产生的助手消息)首屏展开呈现思考链路, -// 2.6s 后若用户未手动干预则自动收拢为一行摘要,避免与回复内容冲突。 +// 6s 后若用户未手动干预则自动收拢为一行摘要,避免与回复内容冲突。 +// 展开时自动滚动到视图内,带脉冲动画提示用户注意。 const AiProcessBlock: React.FC<{ steps: any[]; autoExpand: boolean }> = ({ steps, autoExpand }) => { const [open, setOpen] = useState(autoExpand); + const [fresh, setFresh] = useState(autoExpand); const timerRef = useRef(null); const touchedRef = useRef(false); + const blockRef = useRef(null); useEffect(() => { if (!autoExpand) { setOpen(false); + setFresh(false); return; } setOpen(true); + setFresh(true); touchedRef.current = false; + // 自动滚动到视图内(上方留 60px 避免被顶部遮挡) + if (blockRef.current) { + blockRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } timerRef.current = window.setTimeout(() => { - if (!touchedRef.current) setOpen(false); - }, 2600); + if (!touchedRef.current) { + setOpen(false); + // 收拢后短暂保留 fresh 样式再移除 + setTimeout(() => setFresh(false), 500); + } + }, 6000); return () => { if (timerRef.current) window.clearTimeout(timerRef.current); }; @@ -503,6 +516,7 @@ const AiProcessBlock: React.FC<{ steps: any[]; autoExpand: boolean }> = ({ steps const toggle = () => { touchedRef.current = true; + setFresh(false); if (timerRef.current) { window.clearTimeout(timerRef.current); timerRef.current = null; @@ -511,10 +525,10 @@ const AiProcessBlock: React.FC<{ steps: any[]; autoExpand: boolean }> = ({ steps }; return ( -
+
{ e.preventDefault(); toggle(); }}> 🧠 - 思考 / 执行过程({steps.length} 步,{open ? '点击收起' : '点击展开'}) + AI 思考 / 执行过程({steps.length} 步 — {open ? '自动收拢中... 点击手动收起' : '点击展开查看'})
{steps.map((s: any, i: number) => (