From 0ec9fc39b8e94282379c5a8bc7e44a4959e110eb Mon Sep 17 00:00:00 2001 From: moux1024 <403053463@qq.com> Date: Wed, 24 Sep 2025 11:11:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20template=E5=BF=AB=E6=8D=B7?= =?UTF-8?q?=E5=85=A5=E5=8F=A3=E6=94=AF=E6=8C=81=E6=8B=96=E5=8A=A8,?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8=E8=B7=B3?= =?UTF-8?q?=E8=BD=AC=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/activate/page.tsx | 47 ++++++++++++++++++++---- components/ChatInputBox/ChatInputBox.tsx | 40 ++++++++++++++++++-- components/pages/work-flow.tsx | 2 +- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/app/activate/page.tsx b/app/activate/page.tsx index d342139..824beff 100644 --- a/app/activate/page.tsx +++ b/app/activate/page.tsx @@ -1,7 +1,8 @@ "use client"; + import { post } from "@/api/request"; -import { useSearchParams } from "next/navigation"; -import React, { useEffect, useState } from "react"; +import { useSearchParams, useRouter } from "next/navigation"; +import { useEffect, useState } from "react"; import { CheckCircle, XCircle, Loader2 } from "lucide-react"; export default function Activate() { @@ -21,10 +22,12 @@ export default function Activate() { * @param {string} t - Verification token */ function ConfirmEmail({ t }: { t: string }) { + const router = useRouter(); const [status, setStatus] = useState<"loading" | "success" | "error">( "loading" ); const [message, setMessage] = useState(""); + const [countdown, setCountdown] = useState(3); useEffect(() => { if (!t) { @@ -35,18 +38,36 @@ function ConfirmEmail({ t }: { t: string }) { post(`/auth/activate`, { t: t, }).then((res:any) => { - console.log('res', res) setStatus("success"); - setMessage( - "Your registration has been verified. Please return to the official website to log in." - ); + setMessage( + "Your registration has been verified. Redirecting to login page..." + ); }).catch((err:any) => { - console.log('err', err) setStatus("error"); setMessage("Verification failed. Please try again."); }); }, [t]); + /** + * Handle countdown and redirect to login page + */ + useEffect(() => { + if (status === "success") { + const timer = setInterval(() => { + setCountdown((prev: number) => { + if (prev <= 1) { + clearInterval(timer); + router.push("/login"); + return 0; + } + return prev - 1; + }); + }, 1000); + + return () => clearInterval(timer); + } + }, [status, router]); + const renderContent = () => { switch (status) { case "loading": @@ -77,6 +98,18 @@ function ConfirmEmail({ t }: { t: string }) { Verification Successful

{message}

+
+

+ Redirecting to login page in {countdown} seconds... +

+
+ ); diff --git a/components/ChatInputBox/ChatInputBox.tsx b/components/ChatInputBox/ChatInputBox.tsx index 763b7c1..64d0573 100644 --- a/components/ChatInputBox/ChatInputBox.tsx +++ b/components/ChatInputBox/ChatInputBox.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useEffect, useRef } from "react"; +import { useState, useEffect, useRef, useCallback } from "react"; import { ChevronDown, ChevronUp, @@ -103,6 +103,33 @@ const debounce = (func: Function, wait: number) => { */ export function ChatInputBox({ noData }: { noData: boolean }) { const { isMobile, isDesktop } = useDeviceType(); + + // 模板快捷入口拖动相关状态 + const templateScrollRef = useRef(null); + const [isTemplateDragging, setIsTemplateDragging] = useState(false); + const [templateStartX, setTemplateStartX] = useState(0); + const [templateScrollLeft, setTemplateScrollLeft] = useState(0); + + // 模板快捷入口拖动事件处理 + const handleTemplateMouseDown = useCallback((e: React.MouseEvent) => { + e.preventDefault(); + setIsTemplateDragging(true); + setTemplateStartX(e.pageX - templateScrollRef.current!.offsetLeft); + setTemplateScrollLeft(templateScrollRef.current!.scrollLeft); + }, []); + + const handleTemplateMouseMove = useCallback((e: React.MouseEvent) => { + if (!isTemplateDragging) return; + e.preventDefault(); + const x = e.pageX - templateScrollRef.current!.offsetLeft; + const walk = (x - templateStartX) * 2; + templateScrollRef.current!.scrollLeft = templateScrollLeft - walk; + }, [isTemplateDragging, templateStartX, templateScrollLeft]); + + const handleTemplateMouseUp = useCallback(() => { + setIsTemplateDragging(false); + }, []); + // 控制面板展开/收起状态 const [isExpanded, setIsExpanded] = useState(false); @@ -510,7 +537,14 @@ export function ChatInputBox({ noData }: { noData: boolean }) { {/* 第三行:模板快捷入口水平滚动 */}
-
+
{isTemplateLoading && (!templateStoryList || templateStoryList.length === 0) ? ( // 骨架屏:若正在加载且没有数据 Array.from({ length: 6 }).map((_, idx) => ( @@ -525,7 +559,7 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
) : (