diff --git a/index.html b/index.html index 806588b..7896407 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - 六维填报师 + 六纬AI填报师 diff --git a/public/icons/loading.gif b/public/icons/loading.gif new file mode 100644 index 0000000..2ef3431 Binary files /dev/null and b/public/icons/loading.gif differ diff --git a/src/app/MainArea/Antechamber/index.tsx b/src/app/MainArea/Antechamber/index.tsx index e1084b8..9672d8b 100644 --- a/src/app/MainArea/Antechamber/index.tsx +++ b/src/app/MainArea/Antechamber/index.tsx @@ -8,22 +8,22 @@ import { useSearchParams } from "react-router-dom"; import { fetchUserToken } from "@/apis/user"; import { useToast } from "@/hooks/use-toast"; import { useAbortController } from "@/hooks/useAbortController"; -// import { ReportContext } from "@/components/Provider/ReportResolveProvider"; import AntechamberFile from "@/components/AntechamberFile"; import AntechamberReport from "@/components/AntechamberReport"; import AntechamberWishList from "@/components/AntechamberWishList"; +import { ReportContext } from "@/components/Provider/ReportResolveProvider"; export default function Antechamber() { - const { handleConnect } = useContext(RealtimeClientContext); + const { handleConnect} = useContext(RealtimeClientContext); + const { hasHandledReport } = useContext(ReportContext); const [searchParams] = useSearchParams(); const [disable,setDisable] = useState(true); + const [isLoading,setIsLoading] = useState(false); const token = searchParams.get("token") || ''; - // const reportId = searchParams.get("reportId") || ''; - // const reportType = searchParams.get("reportType") || ''; const { toast } = useToast(); const { getSignal } = useAbortController(); @@ -57,54 +57,35 @@ export default function Antechamber() { } }; - // const getReport = async () => { - // try { - // const { result, message } = await fetchReport({ - // params:{Type:reportType,Id:reportId}, - // options: { - // signal: getSignal(), - // headers: { - // "Authorization": `Bearer ${encodeURIComponent(token)}` - // } - // } - // }); - // if (message) { - // console.log(message); - // } else { - // handleConnect({initMessage:result as string}); - // setHasHandledReport(true) - // } - // } catch (error: any) { - // if (error.name !== 'AbortError') { - // console.error('获取报告失败:', error); - // } - // } - // } useEffect(() => { getUserToken(); }, [token]); - // useEffect(() => { - // if(reportId && reportType && !hasHandledReport){ - // getReport(); - // } - // }, [reportId, reportType,hasHandledReport]); const toRoom = (params:{initMessage?:string,fileUrl?:string}) => { - if(disable){ + if(!hasHandledReport && (disable || isLoading)){ return; } - handleConnect(params); + setIsLoading(true) + handleConnect(params).then(() => { + setIsLoading(false); + }); }; return ( -
+
- - + + toRoom({})} /> + { + isLoading ?
+ loading + 加载中 +
: <> + }
); } diff --git a/src/app/MainArea/index.tsx b/src/app/MainArea/index.tsx index 194a577..9e3cf14 100644 --- a/src/app/MainArea/index.tsx +++ b/src/app/MainArea/index.tsx @@ -7,11 +7,11 @@ import { } from "@/components/Provider/RealtimeClientProvider"; import { ReportProvider } from "@/components/Provider/ReportResolveProvider"; import { RealtimeUtils } from "@coze/realtime-api"; - - +import { useLocation } from "react-router-dom"; function MainContent() { - const { isConnected } = useContext(RealtimeClientContext); + const { isConnected, handleDisconnect } = useContext(RealtimeClientContext); + const location = useLocation(); const handlePromise = async() => { await RealtimeUtils.checkDevicePermission(false); @@ -21,11 +21,16 @@ function MainContent() { handlePromise(); }, []); + useEffect(() => { + if (isConnected) { + handleDisconnect(); + } + }, [location.pathname]); + return ( {isConnected ? : } - ); } diff --git a/src/components/AntechamberButton/index.module.css b/src/components/AntechamberButton/index.module.css index 0104440..8322951 100644 --- a/src/components/AntechamberButton/index.module.css +++ b/src/components/AntechamberButton/index.module.css @@ -1,6 +1,8 @@ .wrapper { width: 88px; height: 88px; + min-height: 88px; + min-width: 88px; background: linear-gradient(180deg, #64c7ff 0%, #0165ff 100%); display: flex; flex-direction: column; @@ -8,8 +10,6 @@ align-items: center; border-radius: 50%; position: relative; - margin-top: auto; - margin-bottom: 80px; overflow: hidden; } diff --git a/src/components/AntechamberButton/index.tsx b/src/components/AntechamberButton/index.tsx index a9d6733..8af0e96 100644 --- a/src/components/AntechamberButton/index.tsx +++ b/src/components/AntechamberButton/index.tsx @@ -15,9 +15,11 @@ export default function InvokeButton(props: IInvokeButtonProps) { return ( -
- call -
{disable ? '暂不可用':isConnecting?'连接中':'发起通话'}
+
+
+ call +
{disable ? '暂不可用':isConnecting?'连接中':'发起通话'}
+
); } \ No newline at end of file diff --git a/src/components/AntechamberFile/index.tsx b/src/components/AntechamberFile/index.tsx index 4c7ffb4..4f53f6e 100644 --- a/src/components/AntechamberFile/index.tsx +++ b/src/components/AntechamberFile/index.tsx @@ -6,9 +6,11 @@ import { useSearchParams } from "react-router-dom"; import { ReportContext } from "../Provider/ReportResolveProvider"; import { FileInfo, RealtimeClientContext } from "../Provider/RealtimeClientProvider"; +type Props = { + handleLoading:(val:boolean) => void +} - -export default function AntechamberFile() { +export default function AntechamberFile({handleLoading}:Props) { const [searchParams] = useSearchParams(); const fileId = searchParams.get("fileId") || ""; const locationCode = searchParams.get("locationCode") || ""; @@ -32,7 +34,7 @@ export default function AntechamberFile() { }); } let resp = result.result as FileInfo; - + handleLoading(true) handleConnect({ fileInfo: {type: resp.type,url: resp.url,tableName: resp.tableName,provinceName: resp.provinceName,subjectClaim: resp.subjectClaim}, }); diff --git a/src/components/AntechamberHeader/index.module.css b/src/components/AntechamberHeader/index.module.css index e6ccaf8..62c41b6 100644 --- a/src/components/AntechamberHeader/index.module.css +++ b/src/components/AntechamberHeader/index.module.css @@ -56,7 +56,6 @@ position: relative; z-index: 1; backdrop-filter:blur(10px); - min-height: 213px; box-sizing: border-box; } diff --git a/src/components/AntechamberHeader/index.tsx b/src/components/AntechamberHeader/index.tsx index 9fe0661..eba34b6 100644 --- a/src/components/AntechamberHeader/index.tsx +++ b/src/components/AntechamberHeader/index.tsx @@ -91,7 +91,7 @@ export default function HeaderGroup() { key={index} onClick={() => handleQuestion(item)} > -
{item}
+
{item}
right-icon void +} + +export default function AntechamberReport({handleLoading}:Props) { const [searchParams] = useSearchParams(); const token = searchParams.get("token") || ''; const reportId = searchParams.get("reportId") || ''; @@ -30,6 +34,7 @@ export default function AntechamberReport() { if (message) { console.log(message); } else { + handleLoading(true) handleConnect({initMessage:result as string}); setHasHandledReport(true) } diff --git a/src/components/AntechamberScore/index.module.css b/src/components/AntechamberScore/index.module.css index 2917553..842b358 100644 --- a/src/components/AntechamberScore/index.module.css +++ b/src/components/AntechamberScore/index.module.css @@ -5,7 +5,7 @@ } .innerWrapper { - padding: 15px; + padding: 12px 15px; width: 100%; background: rgba(255, 255, 255, 0.7); border-radius: 13px; @@ -21,14 +21,15 @@ align-items: center; gap: 10px; margin-top: 10px; - font-size: 16px; + font-size: 14px; + font-weight: 700; } .right{ - color: #1580FF; - display: flex; - align-items: center; - font-size: 13px; + color: #1580FF; + display: flex; + align-items: center; + font-size: 13px; } .imgIcon{ diff --git a/src/components/AntechamberWishList/index.tsx b/src/components/AntechamberWishList/index.tsx index 74bb0ab..194dfb6 100644 --- a/src/components/AntechamberWishList/index.tsx +++ b/src/components/AntechamberWishList/index.tsx @@ -54,7 +54,7 @@ export default function AntechamberWishList() { return ( <> {wishList.length > 0 ? ( -
+
@@ -95,7 +95,6 @@ export default function AntechamberWishList() {
{item.type}
-
@@ -118,7 +117,7 @@ export default function AntechamberWishList() {
@@ -163,7 +162,7 @@ export default function AntechamberWishList() { onClick={() => handleNavigate(wishList[0])} > 智能分析 - +
diff --git a/src/components/Provider/RealtimeClientProvider.tsx b/src/components/Provider/RealtimeClientProvider.tsx index 2a81649..8afca4f 100644 --- a/src/components/Provider/RealtimeClientProvider.tsx +++ b/src/components/Provider/RealtimeClientProvider.tsx @@ -91,6 +91,8 @@ export const RealtimeClientProvider = ({ const connectorId = "1024"; const clientRef = useRef(null); + // 添加连接锁 + const connectingLockRef = useRef(false); // 实时语音回复消息列表 const [messageList, setMessageList] = useState< { content: string; role: RoleType; event?: any }[] @@ -166,6 +168,18 @@ export const RealtimeClientProvider = ({ fileInfo?: FileInfo; }) => { try { + // 使用连接锁确保原子性 + if (connectingLockRef.current) { + return; + } + connectingLockRef.current = true; + + // 如果已经连接或正在连接中,直接返回 + if (isConnected || isConnecting) { + connectingLockRef.current = false; + return; + } + if (!clientRef.current) { await initClient({ initMessage, fileInfo }); } @@ -192,6 +206,9 @@ export const RealtimeClientProvider = ({ } else { console.error("连接错误:" + error); } + } finally { + // 确保在任何情况下都释放连接锁 + connectingLockRef.current = false; } };