"use client"; import { Modal } from "antd"; require("../polyfill"); import { useState, useEffect } from "react"; import { HashRouter as Router, Routes, Route, useLocation, useNavigate } from "react-router-dom"; import styles from "./home.module.scss"; import BotIcon from "../icons/bot.svg"; import loadingIcon from "../icons/loading.gif"; import { getCSSVar, useMobileScreen } from "../utils"; import dynamic from "next/dynamic"; import { Path, SlotID } from "../constant"; import { ErrorBoundary } from "./error"; import { getISOLang, getLang } from "../locales"; import { SideBar } from "./sidebar"; import { useAppConfig } from "../store/config"; import { AuthPage } from "./auth"; import { getClientConfig } from "../config/client"; import { type ClientApi, getClientApi } from "../client/api"; import { useAccessStore } from "../store"; import api from "../api/api"; export function Loading() { /** second版本注释掉进度条 */ // const [progress, setProgress] = useState(1); // // useEffect(() => { // let isMounted = true; // // const intervalId = setInterval(() => { // if (isMounted && progress < 100) { // // 每隔一段时间增加1%进度 // setProgress(prevProgress => prevProgress + 1); // } // }, 30);// 每10毫秒更新1%进度 // // return () => { // isMounted = false; // clearInterval(intervalId); // }; // }, [progress]); return (
{/* seceond版本注释掉进度条 */} {/*
*/} {/*
*/} {/*
*/} {/* {progress}% */} {/*
*/} {/*
*/} {/*
*/}
); } // 延时器 export const delayer = (): Promise => { // 延时时间-秒 const time: number = 0.1; return new Promise((resolve, reject) => { setTimeout(() => { resolve({}); }, time * 1000); }); } const Artifacts = dynamic( async () => { await delayer(); return (await import("./artifacts")).Artifacts }, { loading: () => , } ); const Settings = dynamic( async () => { await delayer(); return (await import("./settings")).Settings }, { loading: () => , } ); const Chat = dynamic( async () => { await delayer(); return (await import("./chat")).Chat }, { loading: () => , } ); const DeepSeekChat = dynamic( async () => { await delayer(); return (await import("./DeepSeekChat")).Chat }, { loading: () => , } ); const Record = dynamic( async () => { await delayer(); return (await import("./Record")) }, { loading: () => , } ); const HomeApp = dynamic( async () => { return (await import("./DeekSeekHome")) }, { loading: () => , } ); const MaskChat = dynamic( async () => { await delayer(); return (await import("./mask-chat")).MaskChat }, { loading: () => , } ); const MaskPage = dynamic( async () => { await delayer(); return (await import("./mask")).MaskPage }, { loading: () => , } ); export function useSwitchTheme() { const config = useAppConfig(); useEffect(() => { document.body.classList.remove("light"); document.body.classList.remove("dark"); if (config.theme === "dark") { document.body.classList.add("dark"); } else if (config.theme === "light") { document.body.classList.add("light"); } const metaDescriptionDark = document.querySelector( 'meta[name="theme-color"][media*="dark"]', ); const metaDescriptionLight = document.querySelector( 'meta[name="theme-color"][media*="light"]', ); if (config.theme === "auto") { metaDescriptionDark?.setAttribute("content", "#151515"); metaDescriptionLight?.setAttribute("content", "#fafafa"); } else { const themeColor = getCSSVar("--theme-color"); metaDescriptionDark?.setAttribute("content", themeColor); metaDescriptionLight?.setAttribute("content", themeColor); } }, [config.theme]); } function useHtmlLang() { useEffect(() => { const lang = getISOLang(); const htmlLang = document.documentElement.lang; if (lang !== htmlLang) { document.documentElement.lang = lang; } }, []); } const useHasHydrated = () => { const [hasHydrated, setHasHydrated] = useState(false); useEffect(() => { setHasHydrated(true); }, []); return hasHydrated; }; const loadAsyncGoogleFont = () => { const linkEl = document.createElement("link"); const proxyFontUrl = "/google-fonts"; const remoteFontUrl = "https://fonts.googleapis.com"; const googleFontUrl = getClientConfig()?.buildMode === "export" ? remoteFontUrl : proxyFontUrl; linkEl.rel = "stylesheet"; linkEl.href = googleFontUrl + "/css2?family=" + encodeURIComponent("Noto Sans:wght@300;400;700;900") + "&display=swap"; document.head.appendChild(linkEl); }; export function WindowContent(props: { children: React.ReactNode }) { return (
{props?.children}
); } function Screen() { const config = useAppConfig(); const location = useLocation(); const isArtifact = location.pathname.includes(Path.Artifacts); const isAuth = location.pathname === Path.Auth; const isMobileScreen = useMobileScreen(); const shouldTightBorder = getClientConfig()?.isApp || (config.tightBorder && !isMobileScreen); useEffect(() => { loadAsyncGoogleFont(); }, []); if (isArtifact) { return ( } /> ); } const renderContent = () => { if (isAuth) return ; return ( <> { location.pathname !== '/' && } } /> } /> } /> } /> } /> {/* 关闭以下入口 后续有需求再开启*/} {/* } /> */} {/* } /> */} {/* } /> */} ); }; return (
{renderContent()}
); } export function useLoadData() { const config = useAppConfig(); const api: ClientApi = getClientApi(config.modelConfig.providerName); useEffect(() => { (async () => { const models = await api.llm.models(); config.mergeModels(models); })(); }, []); } export function Home() { useSwitchTheme(); useLoadData(); useHtmlLang(); useEffect(() => { useAccessStore.getState().fetch(); }, []); if (typeof window !== "undefined") { window.addEventListener("pageshow", (event) => { const perfEntries = performance.getEntriesByType("navigation"); if (perfEntries.length > 0) { const navEntry = perfEntries[0] as PerformanceNavigationTiming; if (navEntry.type === "back_forward") { window.location.reload(); } } }); } const jkLogin = async (data: { code: string, redirectUrl: string }, url: string) => { try { const res = await api.post('jk_code_login', data); localStorage.setItem('userInfo', JSON.stringify(res.data)); location.replace(url); } catch (error: any) { Modal.error({ title: '登录失败', content: error.msg, }) } } const frameLogin = async (data: { clientId: string, workspaceId: string, workspaceName: string, userName: string, timestamp: string, signature: string }, url: string, fullUrl: string) => { try { const res = await api.post('frame_login', data); localStorage.setItem('userInfo', JSON.stringify(res.data)); location.replace(url); } catch (error: any) { Modal.error({ title: '登录失败', content: error.msg, }); //停留5秒 setTimeout(() => { toUninLogin(url, fullUrl); }, 5000); } } const toUninLogin = async (originUrl: string, fullUrl: string) => { // return //测试环境 //const loginUrl = 'https://esctest.sribs.com.cn/esc-sso/oauth2.0/authorize?client_id=e97f94cf93761f4d69e8&response_type=code'; //生产环境 const loginUrl = 'http://esc.sribs.com.cn:8080/esc-sso/oauth2.0/authorize?client_id=e97f94cf93761f4d69e8&response_type=code'; const externalLoginUrl = loginUrl + `&redirect_uri=${encodeURIComponent(originUrl)}&state=${encodeURIComponent(fullUrl)}`; location.replace(externalLoginUrl); } useEffect(() => { // ============== // 环境开关:暂时屏蔽 toUninLogin 跳转验证 // 说明:设置 NEXT_PUBLIC_DISABLE_UNIN_LOGIN=1 时,跳过所有统一登录跳转 // 用法: // 1) 临时禁用:NEXT_PUBLIC_DISABLE_UNIN_LOGIN=1 yarn dev // 2) 或在 .env.local 中加入 NEXT_PUBLIC_DISABLE_UNIN_LOGIN=1 // ============== // const DISABLE_UNIN_LOGIN = typeof process !== 'undefined' && process.env.NEXT_PUBLIC_DISABLE_UNIN_LOGIN === '1'; // if (DISABLE_UNIN_LOGIN) { // console.log('[Home] 统一登录验证已禁用,跳过 toUninLogin 验证'); // return; // } // const loginRes = { "nickName": "建科咨询虚拟账号", "userId": "2222331845498970571", "token": "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjAyMDE4Mzg0LTFmNjctNDhkYi05NjNiLTJkOGNhMDMxNTkzMiJ9.zTkTv8gDgJN7tfyxJko_zG1VsESlZACeYkpdMbITqnIpIfvHkZo8l8_Kcv6zo77GnuDyzdpOEt-GzPufD2Ye8A" }; // if (loginRes) { // return localStorage.setItem('userInfo', JSON.stringify(loginRes)); // } // 如果有token就先去存数据 const hash = window.location.hash; const queryString = hash.includes("?") ? hash.split("?")[1] : ""; const urlHachParams = new URLSearchParams(queryString); const token = urlHachParams.get('token'); const nickName = urlHachParams.get('nickName'); const userId = urlHachParams.get('userId'); if(token) { localStorage.setItem('userInfo', JSON.stringify({ token, nickName, userId })); // 清除url中的token参数 if (window.history.replaceState) { const cleanUrl = window.location.href.split("#")[0]; // http://localhost:4000/#/knowledgeChat?showMenu=true&chatMode=LOCAL&appId=2965620717148049408&userId=8&nickName=test&token=eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjQ3M2QzOWI0LTVhOGYtNGYxZS1iOGY window.history.replaceState({}, document.title, `${cleanUrl}#/knowledgeChat?showMenu=true&chatMode=LOCAL&&appId=${urlHachParams.get('appId')}`); } } const originUrl = window.location.origin; const fullUrl = window.location.href; const urlParams = new URLSearchParams(new URL(fullUrl).search); const code = urlParams.get('code'); const state = urlParams.get('state'); const userInfo = localStorage.getItem('userInfo'); if (fullUrl.includes(originUrl + '/?code') && code && state) {// 通过code登陆 if (!userInfo) { jkLogin({ code: code, redirectUrl: encodeURIComponent(originUrl) }, state); } } else { //判断是否是frame方式联登/frame if (fullUrl.includes(originUrl + '/?frame=Y')) { const workspaceId = urlParams.get('workspace_id'); const workspaceName = urlParams.get('workspace_name'); const username = urlParams.get('username'); const clientId = urlParams.get('client_id'); const timestamp = urlParams.get('timestamp'); const signature = urlParams.get('signature'); if (!clientId || !workspaceId || !workspaceName || !username || !timestamp || !signature) { // 处理缺失参数的情况 Modal.error({ title: '参数错误', content: '缺少必要的参数', }); //停留5秒 setTimeout(() => { toUninLogin(originUrl, fullUrl); }, 5000); return; } frameLogin({ clientId: clientId, workspaceId: workspaceId, workspaceName: workspaceName, userName: username, timestamp: timestamp, signature: signature }, originUrl, fullUrl); } else { if (!userInfo) { toUninLogin(originUrl, fullUrl); } } } }, []); if (!useHasHydrated()) { return ; } return ( ); }