Skip to content

Commit 2b53e09

Browse files
committed
feat: 设置增加 ChatGPT 模型选择
1 parent c2505ad commit 2b53e09

File tree

8 files changed

+137
-29
lines changed

8 files changed

+137
-29
lines changed

src/app/core/setting/config.tsx

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,26 @@ export const config = [
2525
toast({ title: '当前版本' })
2626
}
2727
},
28-
{
29-
title: '自动更新',
30-
key: 'autoUpdate',
31-
value: true,
32-
desc: <>关闭后,NoteGen 将不会自动更新。</>,
33-
schema: z.boolean(),
34-
disabled: true,
35-
layout: 'horizontal',
36-
type: 'switch',
37-
},
38-
{
39-
title: '语言',
40-
key: 'language',
41-
value: '简体中文',
42-
desc: <>更改界面语言</>,
43-
type: 'select',
44-
schema: z.string(),
45-
disabled: true,
46-
layout: 'horizontal',
47-
}
28+
// {
29+
// title: '自动更新',
30+
// key: 'autoUpdate',
31+
// value: true,
32+
// desc: <>关闭后,NoteGen 将不会自动更新。</>,
33+
// schema: z.boolean(),
34+
// disabled: true,
35+
// layout: 'horizontal',
36+
// type: 'switch',
37+
// },
38+
// {
39+
// title: '语言',
40+
// key: 'language',
41+
// value: '简体中文',
42+
// desc: <>更改界面语言</>,
43+
// type: 'select',
44+
// schema: z.string(),
45+
// disabled: true,
46+
// layout: 'horizontal',
47+
// }
4848
]
4949
},
5050
{
@@ -66,6 +66,19 @@ export const config = [
6666
layout: 'vertical',
6767
type: 'input',
6868
},
69+
{
70+
title: '模型选择',
71+
key: 'model',
72+
value: 'gpt-4o-mini',
73+
desc: <>
74+
<span>选择 ChatGPT 模型,不同的模型对应不同的资费标准,请按实力选择。</span><br />
75+
<OpenBroswer title="费用标准参考" url="https://chatanywhere.apifox.cn/doc-2694962" />
76+
</>,
77+
schema: z.string(),
78+
disabled: false,
79+
layout: 'horizontal',
80+
type: 'select',
81+
},
6982
{
7083
title: '记录生成描述',
7184
key: 'markDescGen',
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
2+
import { ControllerRenderProps } from "react-hook-form";
3+
import { fetchAiModels } from "@/lib/ai";
4+
import { useEffect, useState } from "react";
5+
import { AiModel } from "@/lib/ai.types";
6+
import { Store } from "@tauri-apps/plugin-store";
7+
import useSettingStore from "@/stores/setting";
8+
9+
export function ModelSelect({ field }: { field: ControllerRenderProps }) {
10+
const [models, setModels] = useState<AiModel[]>([])
11+
const [defaultModel, setDefaultModel] = useState<string>('')
12+
const { apiKey } = useSettingStore()
13+
14+
async function init() {
15+
const store = await Store.load('store.json');
16+
const value = await store.get('model')
17+
if (value) {
18+
setDefaultModel(value as string)
19+
}
20+
21+
const res = (await fetchAiModels()) as {
22+
data: AiModel[]
23+
}
24+
res.data = res.data.filter((model, index, self) => {
25+
return index === self.findIndex((m) => {
26+
return m.id === model.id
27+
})
28+
})
29+
res.data.sort((a, b) => {
30+
// 按名称排序
31+
return a.id.localeCompare(b.id)
32+
})
33+
setModels(res.data)
34+
}
35+
36+
function changeHandler(value: string) {
37+
if (value) {
38+
field.onChange(value)
39+
}
40+
}
41+
42+
useEffect(() => {
43+
if (apiKey) {
44+
init()
45+
}
46+
}, [apiKey])
47+
48+
return (
49+
<Select onValueChange={changeHandler} value={field.value} defaultValue={defaultModel} disabled={field.disabled}>
50+
<SelectTrigger className="w-[180px]">
51+
<SelectValue placeholder="选择模型" />
52+
</SelectTrigger>
53+
<SelectContent>
54+
{
55+
models.map((model) => (
56+
<SelectItem key={model.id + model.created} value={model.id}>{model.id}</SelectItem>
57+
))
58+
}
59+
</SelectContent>
60+
</Select>
61+
)
62+
}

src/app/core/setting/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export default function Page() {
101101
<FormItem className={`${setting.layout === 'horizontal' ? 'flex-row items-center' : 'flex-col'} flex justify-between mt-4`}>
102102
<div>
103103
<FormLabel>{setting.title}</FormLabel>
104-
<FormDescription>{setting.desc}</FormDescription>
104+
<FormDescription className="my-1">{setting.desc}</FormDescription>
105105
</div>
106106
<FormControl>
107107
<SettingRender setting={setting} field={field} />

src/app/core/setting/setting-render.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { LanguageSelect } from "./lanage-select";
99
import { PreviewThemeSelect } from "./preview-theme-select";
1010
import { CodeThemeSelect } from "./code-theme-select";
1111
import { Badge } from "@/components/ui/badge";
12+
import { ModelSelect } from "./model-select";
1213

1314
export function SettingRender(
1415
{ setting, field }:
@@ -32,6 +33,8 @@ export function SettingRender(
3233
return <PreviewThemeSelect field={field} />
3334
case 'codeTheme':
3435
return <CodeThemeSelect field={field} />
36+
case 'model':
37+
return <ModelSelect field={field} />
3538
}
3639
case 'shortcut':
3740
return <Badge>{setting.value}</Badge>

src/components/local-image.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export function LocalImage({ onLoad, src, ...props }: React.ComponentProps<typeo
1111
setLocalSrc(src.toString())
1212
} else {
1313
const covertFileSrcPath = await convertImage(src as string)
14-
console.log(covertFileSrcPath);
1514
setLocalSrc(covertFileSrcPath)
1615
}
1716
}

src/lib/ai.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ const url = 'https://api.chatanywhere.tech/v1/chat/completions'
77
async function createAi(text: string, isStream = true) {
88
const store = await Store.load('store.json')
99
const apiKey = await store.get('apiKey')
10+
const model = await store.get('model')
1011

1112
const headers = new Headers();
1213
headers.append("Authorization", `Bearer ${apiKey}`);
1314
headers.append("Content-Type", "application/json");
1415

1516
const body = JSON.stringify({
16-
model: 'gpt-4o-mini',
17+
model,
1718
stream: isStream,
1819
messages: [
1920
{
@@ -32,6 +33,19 @@ async function createAi(text: string, isStream = true) {
3233
return requestOptions;
3334
}
3435

36+
// 获取模型
37+
export async function fetchAiModels() {
38+
const store = await Store.load('store.json')
39+
const apiKey = await store.get('apiKey')
40+
const headers = new Headers();
41+
headers.append("Authorization", `Bearer ${apiKey}`);
42+
const requestOptions = {
43+
method: 'GET',
44+
headers,
45+
};
46+
return (await fetch('https://api.chatanywhere.tech/v1/models', requestOptions)).json()
47+
}
48+
3549
export async function fetchAiStream(text: string, callback: (text: string) => void) {
3650
const requestOptions = await createAi(text, true)
3751

src/lib/ai.types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,11 @@ interface Choice {
2424
interface Message {
2525
role: string;
2626
content: string;
27+
}
28+
29+
export interface AiModel {
30+
id: string;
31+
object: string;
32+
created: number;
33+
owned_by: string;
2734
}

src/stores/setting.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ interface SettingState {
1717
apiKey: string
1818
setApiKey: (apiKey: string) => void
1919

20+
model: string
21+
setModel: (language: string) => void
22+
2023
markDescGen: boolean
2124
setMarkDescGen: (markDescGen: boolean) => void
2225

@@ -29,14 +32,14 @@ interface SettingState {
2932
codeTheme: string
3033
setCodeTheme: (codeTheme: string) => void
3134

32-
tesseractList: string[]
33-
setTesseractList: (tesseractList: string[]) => void
35+
tesseractList: string
36+
setTesseractList: (tesseractList: string) => void
3437

3538
screenshotShortcut: string
3639
setScreenshotShortcut: (screenshotShortcut: string) => void
3740

3841
githubUsername: string
39-
setGithubUsername: (githubUsername: string) => void
42+
setGithubUsername: (githubUsername: string) => Promise<void>
4043

4144
accessToken: string
4245
setAccessToken: (accessToken: string) => void
@@ -73,6 +76,9 @@ const useSettingStore = create<SettingState>((set, get) => ({
7376
apiKey: '',
7477
setApiKey: (apiKey: string) => set({ apiKey }),
7578

79+
model: 'gpt-4o-mini',
80+
setModel: (model: string) => set({ model }),
81+
7682
markDescGen: true,
7783
setMarkDescGen: (markDescGen: boolean) => set({ markDescGen }),
7884

@@ -85,14 +91,18 @@ const useSettingStore = create<SettingState>((set, get) => ({
8591
codeTheme: 'atom',
8692
setCodeTheme: (codeTheme: string) => set({ codeTheme }),
8793

88-
tesseractList: [],
89-
setTesseractList: (tesseractList: string[]) => set({ tesseractList }),
94+
tesseractList: 'eng,chi_sim',
95+
setTesseractList: (tesseractList: string) => set({ tesseractList }),
9096

9197
screenshotShortcut: 'Command+Shift+R',
9298
setScreenshotShortcut: (screenshotShortcut: string) => set({ screenshotShortcut }),
9399

94100
githubUsername: '',
95-
setGithubUsername: (githubUsername: string) => set({ githubUsername }),
101+
setGithubUsername: async(githubUsername: string) => {
102+
set({ githubUsername })
103+
const store = await Store.load('store.json');
104+
store.set('githubUsername', githubUsername)
105+
},
96106

97107
accessToken: '',
98108
setAccessToken: (accessToken: string) => set({ accessToken }),

0 commit comments

Comments
 (0)