Skip to content

Commit a034248

Browse files
committed
chore: fix some bug
1 parent ac9c5a2 commit a034248

File tree

21 files changed

+531
-356
lines changed

21 files changed

+531
-356
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ module.exports = {
1919
'no-console': 'warn',
2020
'prefer-const': 'error',
2121
'no-var': 'error',
22+
'@typescript-eslint/no-explicit-any': 'warn',
2223
},
2324
};

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"cSpell.words": ["upsert"]
3+
}

backend/src/app.module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { ChatModule } from './chat/chat.module';
1919
ConfigModule.forRoot({ isGlobal: true }),
2020
GraphQLModule.forRoot<ApolloDriverConfig>({
2121
driver: ApolloDriver,
22-
autoSchemaFile: join(process.cwd(), '../frontend/schema.gql'),
22+
autoSchemaFile: join(process.cwd(), '../frontend/src/graphql/schema.gql'),
2323
sortSchema: true,
2424
playground: true,
2525
installSubscriptionHandlers: true,

backend/src/chat/chat.model.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class ChatCompletionDelta {
55
@Field({ nullable: true })
66
content?: string;
77
}
8+
89
@ObjectType('ChatCompletionChunkType')
910
export class ChatCompletionChunk {
1011
@Field()
@@ -20,7 +21,7 @@ export class ChatCompletionChunk {
2021
model: string;
2122

2223
@Field({ nullable: true })
23-
system_fingerprint: string | null;
24+
systemFingerprint: string | null;
2425

2526
@Field(() => [ChatCompletionChoice])
2627
choices: ChatCompletionChoice[];
@@ -35,7 +36,7 @@ class ChatCompletionChoice {
3536
delta: ChatCompletionDelta;
3637

3738
@Field({ nullable: true })
38-
finish_reason: string | null;
39+
finishReason: string | null;
3940
}
4041

4142
@InputType('ChatInputType')

backend/src/database.sqlite

12 KB
Binary file not shown.

frontend/.eslintrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"extends": "next/core-web-vitals"
2+
"extends": "next/core-web-vitals",
3+
"ignorePatterns": ["src/graphql/type.ts","src/graphql/**/*"]
34
}

frontend/codegen.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { CodegenConfig } from '@graphql-codegen/cli';
2+
3+
const config: CodegenConfig = {
4+
schema: './src/graphql/schema.gql',
5+
generates: {
6+
'src/graphql/type.tsx': {
7+
plugins: [
8+
'typescript',
9+
'typescript-operations',
10+
'typescript-resolvers',
11+
'typescript-react-apollo',
12+
],
13+
config: {
14+
withHooks: true,
15+
useIndexSignature: true,
16+
enumsAsTypes: true,
17+
constEnums: true,
18+
skipTypename: false,
19+
dedupeOperationSuffix: true,
20+
nonOptionalTypename: true,
21+
preResolveTypes: true,
22+
namingConvention: {
23+
enumValues: 'keep',
24+
},
25+
scalars: {
26+
Date: 'Date',
27+
},
28+
},
29+
},
30+
},
31+
};
32+
33+
export default config;

frontend/codegen.yml

Lines changed: 0 additions & 24 deletions
This file was deleted.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"zustand": "^5.0.0-rc.2"
5858
},
5959
"devDependencies": {
60+
"@0no-co/graphqlsp": "^1.12.16",
6061
"@graphql-codegen/cli": "^5.0.3",
6162
"@graphql-codegen/typescript": "^4.1.0",
6263
"@graphql-codegen/typescript-operations": "^4.3.0",

frontend/src/app/[id]/page.tsx

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
'use client';
22

3-
import { ChatLayout } from "@/components/chat/chat-layout";
4-
import { getSelectedModel } from "@/lib/model-helper";
5-
import React, { useEffect, useRef, useState } from "react";
6-
import { toast } from "sonner";
7-
import useChatStore from "../hooks/useChatStore";
8-
import { Message } from "@/components/types";
3+
import { ChatLayout } from '@/components/chat/chat-layout';
4+
import { getSelectedModel } from '@/lib/model-helper';
5+
import React, { useEffect, useRef, useState } from 'react';
6+
import { toast } from 'sonner';
7+
import useChatStore from '../hooks/useChatStore';
8+
import { Message } from '@/components/types';
99

1010
interface ChatStreamResponse {
1111
chatStream: {
@@ -31,18 +31,17 @@ interface Attachment {
3131
export default function Page({ params }: { params: { id: string } }) {
3232
// 状态管理
3333
const [messages, setMessages] = useState<Message[]>([]);
34-
const [input, setInput] = useState("");
34+
const [input, setInput] = useState('');
3535
const [isLoading, setIsLoading] = useState(false);
3636
const [error, setError] = useState<Error | null>(null);
37-
const [selectedModel, setSelectedModel] = useState<string>(
38-
getSelectedModel()
39-
);
37+
const [selectedModel, setSelectedModel] =
38+
useState<string>(getSelectedModel());
4039
const [loadingSubmit, setLoadingSubmit] = useState(false);
4140
const formRef = useRef<HTMLFormElement>(null);
4241
const ws = useRef<WebSocket | null>(null);
4342
const base64Images = useChatStore((state) => state.base64Images);
4443
const setBase64Images = useChatStore((state) => state.setBase64Images);
45-
const [currentAssistantMessage, setCurrentAssistantMessage] = useState("");
44+
const [currentAssistantMessage, setCurrentAssistantMessage] = useState('');
4645

4746
// 初始化 WebSocket 连接
4847
useEffect(() => {
@@ -65,35 +64,35 @@ export default function Page({ params }: { params: { id: string } }) {
6564
useEffect(() => {
6665
if (!isLoading && !error && messages.length > 0) {
6766
localStorage.setItem(`chat_${params.id}`, JSON.stringify(messages));
68-
window.dispatchEvent(new Event("storage"));
67+
window.dispatchEvent(new Event('storage'));
6968
}
7069
}, [messages, isLoading, error, params.id]);
7170

7271
const initWebSocket = () => {
73-
ws.current = new WebSocket("ws://localhost:8080/graphql");
72+
ws.current = new WebSocket('ws://localhost:8080/graphql');
7473

7574
ws.current.onopen = () => {
76-
console.log("WebSocket connected");
75+
console.log('WebSocket connected');
7776
};
7877

7978
ws.current.onerror = (error) => {
80-
console.error("WebSocket error:", error);
81-
toast.error("Connection error. Retrying...");
79+
console.error('WebSocket error:', error);
80+
toast.error('Connection error. Retrying...');
8281
setTimeout(initWebSocket, 3000);
8382
};
8483

8584
ws.current.onclose = () => {
86-
console.log("WebSocket closed");
85+
console.log('WebSocket closed');
8786
setTimeout(initWebSocket, 3000);
8887
};
8988
};
9089

9190
const loadChatHistory = async (chatId: string) => {
9291
try {
93-
const response = await fetch("http://localhost:8080/graphql", {
94-
method: "POST",
92+
const response = await fetch('http://localhost:8080/graphql', {
93+
method: 'POST',
9594
headers: {
96-
"Content-Type": "application/json",
95+
'Content-Type': 'application/json',
9796
},
9897
body: JSON.stringify({
9998
query: `
@@ -120,7 +119,7 @@ export default function Page({ params }: { params: { id: string } }) {
120119
const savedMessages = data.data.getChatHistory || [];
121120
setMessages(savedMessages);
122121
} catch (error) {
123-
console.error("Error loading chat history:", error);
122+
console.error('Error loading chat history:', error);
124123
// 尝试从本地存储加载
125124
const localMessages = localStorage.getItem(`chat_${chatId}`);
126125
if (localMessages) {
@@ -137,7 +136,7 @@ export default function Page({ params }: { params: { id: string } }) {
137136
if (ws.current?.readyState === WebSocket.OPEN) {
138137
ws.current.send(
139138
JSON.stringify({
140-
type: "stop",
139+
type: 'stop',
141140
id: params.id,
142141
})
143142
);
@@ -152,7 +151,7 @@ export default function Page({ params }: { params: { id: string } }) {
152151
ws.current.readyState !== WebSocket.OPEN
153152
) {
154153
if (!ws.current || ws.current.readyState !== WebSocket.OPEN) {
155-
toast.error("Connection lost. Reconnecting...");
154+
toast.error('Connection lost. Reconnecting...');
156155
initWebSocket();
157156
}
158157
return;
@@ -162,25 +161,25 @@ export default function Page({ params }: { params: { id: string } }) {
162161

163162
const newMessage: Message = {
164163
id: params.id,
165-
role: "user",
164+
role: 'user',
166165
content: input,
167166
createdAt: new Date().toISOString(),
168167
};
169168

170169
setMessages((prev) => [...prev, newMessage]);
171-
setInput("");
172-
setCurrentAssistantMessage("");
170+
setInput('');
171+
setCurrentAssistantMessage('');
173172

174173
const attachments = base64Images
175174
? base64Images.map((image) => ({
176-
contentType: "image/base64",
175+
contentType: 'image/base64',
177176
url: image,
178177
}))
179178
: [];
180179

181180
// 发送 GraphQL subscription 请求
182181
const subscriptionMsg = {
183-
type: "start",
182+
type: 'start',
184183
id: Date.now().toString(),
185184
payload: {
186185
query: `
@@ -215,15 +214,15 @@ export default function Page({ params }: { params: { id: string } }) {
215214
ws.current.onmessage = (event) => {
216215
const response = JSON.parse(event.data);
217216

218-
if (response.type === "data" && response.payload.data) {
217+
if (response.type === 'data' && response.payload.data) {
219218
const chunk = response.payload.data.chatStream;
220219
const content = chunk.choices[0]?.delta?.content;
221220

222221
if (content) {
223222
setCurrentAssistantMessage((prev) => prev + content);
224223
setMessages((prev) => {
225224
const lastMsg = prev[prev.length - 1];
226-
if (lastMsg?.role === "assistant") {
225+
if (lastMsg?.role === 'assistant') {
227226
return [
228227
...prev.slice(0, -1),
229228
{
@@ -236,7 +235,7 @@ export default function Page({ params }: { params: { id: string } }) {
236235
...prev,
237236
{
238237
id: chunk.id,
239-
role: "assistant",
238+
role: 'assistant',
240239
content,
241240
createdAt: new Date(chunk.created * 1000).toISOString(),
242241
},
@@ -245,22 +244,22 @@ export default function Page({ params }: { params: { id: string } }) {
245244
});
246245
}
247246

248-
if (chunk.choices[0]?.finish_reason === "stop") {
247+
if (chunk.choices[0]?.finish_reason === 'stop') {
249248
setLoadingSubmit(false);
250-
setCurrentAssistantMessage("");
249+
setCurrentAssistantMessage('');
251250

252251
// 保存消息
253252
localStorage.setItem(`chat_${params.id}`, JSON.stringify(messages));
254-
window.dispatchEvent(new Event("storage"));
253+
window.dispatchEvent(new Event('storage'));
255254
}
256255
}
257256
};
258257

259258
ws.current.send(JSON.stringify(subscriptionMsg));
260259
setBase64Images(null);
261260
} catch (error) {
262-
console.error("Error:", error);
263-
toast.error("Failed to send message");
261+
console.error('Error:', error);
262+
toast.error('Failed to send message');
264263
setLoadingSubmit(false);
265264
}
266265
};

0 commit comments

Comments
 (0)