修改一些

This commit is contained in:
yangyongju 2024-08-14 13:23:45 +08:00
parent 741a078c87
commit 69f931543f
10 changed files with 105 additions and 17 deletions

View File

@ -33,6 +33,7 @@ export async function handle(
try {
const response = await request(req);
console.log("我是从api这边进入的2", response);
return response;
} catch (e) {
console.error("[Deepseek] ", e);
@ -42,6 +43,7 @@ export async function handle(
async function request(req: NextRequest) {
const controller = new AbortController();
console.log("我是从api这边进入的", req.nextUrl.pathname);
// alibaba use base url or just remove the path
let path = `${req.nextUrl.pathname}`.replaceAll(ApiPath.Deepseek, "");
@ -57,8 +59,8 @@ async function request(req: NextRequest) {
baseUrl = baseUrl.slice(0, -1);
}
console.log("[Proxy] ", path);
console.log("[Base Url]", baseUrl);
console.log("[Deepseek Proxy] ", path);
console.log("[Deepseek Base Url]", baseUrl);
const timeoutId = setTimeout(
() => {

View File

@ -157,7 +157,7 @@ export class ClientApi {
{
from: "human",
value:
"Share from [NextChat]: https://github.com/Yidadaa/ChatGPT-Next-Web",
"Share from [清明上河图小助手]: https://github.com/Yidadaa/ChatGPT-Next-Web",
},
]);
// 敬告二开开发者们,为了开源大模型的发展,请不要修改上述消息,此消息用于后续数据清洗使用
@ -279,7 +279,7 @@ export function getHeaders() {
const bearerToken = getBearerToken(apiKey, isAzure || isAnthropic);
console.log("bearerToken", bearerToken);
// TODO: remove this 更换 Deepseek 的 api key
headers["Authorization"] = `Bearer sk-c8e0505e462f49068758ebcc4331c9ee`;
headers["Authorization"] = `Bearer sk-94ee98bc9bd14db495d49eb598b69ff0`;
if (bearerToken) {
headers[authHeader] = bearerToken;
} else if (isEnabledAccessControl && validString(accessStore.accessCode)) {

View File

@ -206,14 +206,14 @@ export class DeepseekApi implements LLMApi {
}
},
onmessage(msg) {
console.log("msg", msg);
// console.log("msg", msg);
if (msg.data === "[DONE]" || finished) {
return finish();
}
const text = msg.data;
try {
const json = JSON.parse(text);
console.log("json", json);
// console.log("json", json);
const choices = json.choices as Array<{
delta: { content: string };

View File

@ -1,8 +1,12 @@
// 导入必要的依赖
import { useEffect } from "react";
import { useSearchParams } from "react-router-dom";
import Locale from "./locales";
// 定义命令类型和命令接口
// Command 是一个接受字符串参数并返回 void 的函数类型
type Command = (param: string) => void;
// Commands 接口定义了可能的命令及其对应的处理函数
interface Commands {
fill?: Command;
submit?: Command;
@ -11,11 +15,18 @@ interface Commands {
settings?: Command;
}
/**
* HookuseCommand
* URL参数中的命令
* @param commands -
*/
export function useCommand(commands: Commands = {}) {
// 使用 useSearchParams 钩子获取和设置 URL 参数
const [searchParams, setSearchParams] = useSearchParams();
useEffect(() => {
let shouldUpdate = false;
// 遍历URL参数执行对应的命令
searchParams.forEach((param, name) => {
const commandName = name as keyof Commands;
if (typeof commands[commandName] === "function") {
@ -25,6 +36,7 @@ export function useCommand(commands: Commands = {}) {
}
});
// 如果有更新则设置新的URL参数
if (shouldUpdate) {
setSearchParams(searchParams);
}
@ -32,19 +44,30 @@ export function useCommand(commands: Commands = {}) {
}, [searchParams, commands]);
}
// 定义聊天命令接口
interface ChatCommands {
new?: Command;
newm?: Command;
next?: Command;
prev?: Command;
clear?: Command;
del?: Command;
new?: Command; // 新建聊天
newm?: Command; // 新建面具聊天
next?: Command; // 下一个聊天
prev?: Command; // 上一个聊天
clear?: Command; // 清除聊天历史
del?: Command; // 删除当前聊天
}
// Compatible with Chinese colon character ""
// 定义聊天命令前缀(兼容中文冒号和英文冒号)
export const ChatCommandPrefix = /^[:]/;
/**
* HookuseChatCommand
*
* @param commands -
*/
export function useChatCommand(commands: ChatCommands = {}) {
/**
*
* @param userInput -
* @returns
*/
function extract(userInput: string) {
const match = userInput.match(ChatCommandPrefix);
if (match) {
@ -53,6 +76,11 @@ export function useChatCommand(commands: ChatCommands = {}) {
return userInput as keyof ChatCommands;
}
/**
*
* @param userInput -
* @returns
*/
function search(userInput: string) {
const input = extract(userInput);
const desc = Locale.Chat.Commands;
@ -64,6 +92,11 @@ export function useChatCommand(commands: ChatCommands = {}) {
}));
}
/**
*
* @param userInput -
* @returns
*/
function match(userInput: string) {
const command = extract(userInput);
const matched = typeof commands[command] === "function";
@ -76,3 +109,9 @@ export function useChatCommand(commands: ChatCommands = {}) {
return { match, search };
}
// 参考资料:
// 1. React Router useSearchParams: https://reactrouter.com/web/api/Hooks/usesearchparams
// 2. React useEffect Hook: https://reactjs.org/docs/hooks-effect.html
// 3. TypeScript Interfaces: https://www.typescriptlang.org/docs/handbook/interfaces.html
// 4. JavaScript Regular Expressions: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

View File

@ -208,7 +208,7 @@ export function Artifacts() {
<a href={REPO_URL} target="_blank" rel="noopener noreferrer">
<IconButton bordered icon={<GithubIcon />} shadow />
</a>
<div className={styles["artifacts-title"]}>NextChat Artifacts</div>
<div className={styles["artifacts-title"]}></div>
<ArtifactsShareButton
id={id}
getCode={() => code}

View File

@ -539,7 +539,7 @@ export function ImagePreviewer(props: {
</div>
<div>
<div className={styles["main-title"]}>NextChat</div>
<div className={styles["main-title"]}></div>
<div className={styles["sub-title"]}>
github.com/ChatGPTNextWeb/ChatGPT-Next-Web
</div>

View File

@ -30,10 +30,14 @@ import { getClientConfig } from "../config/client";
import { type ClientApi, getClientApi } from "../client/api";
import { useAccessStore } from "../store";
// Loading组件用于显示加载状态
export function Loading(props: { noLogo?: boolean }) {
return (
// 使用styles["loading-content"]类名来应用样式,"no-dark"类用于防止暗色主题影响
<div className={styles["loading-content"] + " no-dark"}>
{/* 如果noLogo属性为false则显示BotIcon */}
{!props.noLogo && <BotIcon />}
{/* 显示LoadingIcon表示正在加载 */}
<LoadingIcon />
</div>
);
@ -105,13 +109,17 @@ function useHtmlLang() {
}, []);
}
// 定义一个自定义HookuseHasHydrated
const useHasHydrated = () => {
// 使用useState初始化hasHydrated状态为false
const [hasHydrated, setHasHydrated] = useState<boolean>(false);
// 使用useEffect在组件挂载后将hasHydrated设置为true
useEffect(() => {
setHasHydrated(true);
}, []);
// 返回hasHydrated的当前值
return hasHydrated;
};
@ -138,23 +146,31 @@ export function WindowContent(props: { children: React.ReactNode }) {
);
}
// Screen 组件:负责渲染应用的主要内容
function Screen() {
// 获取应用配置
const config = useAppConfig();
// 获取当前路由位置
const location = useLocation();
// 判断当前路径是否为特定页面
const isArtifact = location.pathname.includes(Path.Artifacts);
const isHome = location.pathname === Path.Home;
const isAuth = location.pathname === Path.Auth;
const isSd = location.pathname === Path.Sd;
const isSdNew = location.pathname === Path.SdNew;
// 检查是否为移动屏幕
const isMobileScreen = useMobileScreen();
// 决定是否使用紧凑边框
const shouldTightBorder =
getClientConfig()?.isApp || (config.tightBorder && !isMobileScreen);
// 加载Google字体
useEffect(() => {
loadAsyncGoogleFont();
}, []);
// 如果是Artifacts页面渲染特定路由
if (isArtifact) {
return (
<Routes>
@ -162,13 +178,17 @@ function Screen() {
</Routes>
);
}
// 渲染主要内容的函数
const renderContent = () => {
if (isAuth) return <AuthPage />;
if (isSd) return <Sd />;
if (isSdNew) return <Sd />;
return (
<>
{/* 侧边栏 */}
<SideBar className={isHome ? styles["sidebar-show"] : ""} />
{/* 主区域 */}
<WindowContent>
<Routes>
<Route path={Path.Home} element={<Chat />} />
@ -182,6 +202,7 @@ function Screen() {
);
};
// 返回最终的渲染结果
return (
<div
className={`${styles.container} ${
@ -193,14 +214,21 @@ function Screen() {
);
}
// 定义一个自定义HookuseLoadData
export function useLoadData() {
// 获取应用配置
const config = useAppConfig();
// 根据配置中的提供商名称获取客户端API
const api: ClientApi = getClientApi(config.modelConfig.providerName);
// 使用useEffect钩子在组件挂载时加载数据
useEffect(() => {
// 定义一个异步函数来获取模型
(async () => {
// 从API获取模型列表
const models = await api.llm.models();
// 将获取到的模型合并到配置中
config.mergeModels(models);
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
@ -208,19 +236,26 @@ export function useLoadData() {
}
export function Home() {
// 切换主题
useSwitchTheme();
// 加载数据
useLoadData();
// 设置HTML语言
useHtmlLang();
useEffect(() => {
// 从构建时获取配置并打印日志
console.log("[Config] got config from build time", getClientConfig());
// 获取访问权限
useAccessStore.getState().fetch();
}, []);
// 如果组件还未水合,显示加载中
if (!useHasHydrated()) {
return <Loading />;
}
// 渲染主要内容
return (
<ErrorBoundary>
<Router>

View File

@ -225,8 +225,8 @@ export function SideBar(props: { className?: string }) {
{...props}
>
<SideBarHeader
title="NextChat"
subTitle="Build your own AI assistant."
title="清明上河图小助手"
subTitle="清明上河图小助手."
logo={<ChatGptIcon />}
>
<div className={styles["sidebar-header-bar"]}>

View File

@ -157,11 +157,16 @@ export function selectOrCopy(el: HTMLElement, content: string) {
return true;
}
// 获取DOM元素的内容宽度
function getDomContentWidth(dom: HTMLElement) {
// 获取元素的计算样式
const style = window.getComputedStyle(dom);
// 计算左右内边距的总宽度
const paddingWidth =
parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
// 计算内容宽度:元素客户端宽度减去内边距宽度
const width = dom.clientWidth - paddingWidth;
// 返回计算得到的内容宽度
return width;
}

7
注意事项.md Normal file
View File

@ -0,0 +1,7 @@
# 路由相关
- 此项目不是使用nextjs的app路由方式而是使用react-router-dom 的路由方式,
- 定义路由的位置是在 `app/components/Home.tsx` 文件中
- 根路由 renderContent
- WindowContent下的Routes包裹是切换路由
- 路由映射是在 [text](app/constant.ts) 文件中定义的Path如下