2026-04-19-03-03-55 修复AI撰写体验:API endpoint斜杠净化、模型列表下拉栏、聊天记录持久化存储

This commit is contained in:
2026-04-19 03:09:46 +08:00
parent d5cbbf9137
commit 9173aa7733
6 changed files with 293 additions and 20 deletions

View File

@@ -20,6 +20,7 @@ export default function SystemSettings() {
const [isSaved, setIsSaved] = useState(false);
const [pendingFrameCount, setPendingFrameCount] = useState<number | null>(null);
const [modeModalOpen, setModeModalOpen] = useState(false);
const [availableModels, setAvailableModels] = useState<string[]>([]);
useEffect(() => {
const user = storage.get<User | null>('currentUser', null);
@@ -99,18 +100,27 @@ export default function SystemSettings() {
return;
}
try {
const res = await fetch(`${provider.endpoint}/models`, {
const res = await fetch(`${provider.endpoint.replace(/\/+$/, '')}/models`, {
method: 'GET',
headers: { 'Authorization': `Bearer ${provider.apiKey}`, 'Content-Type': 'application/json' }
});
if (res.ok) {
const data = await res.json();
alert(`连接成功!可用模型数: ${data.data?.length || '未知'}`);
const models = data.data?.map((m: any) => m.id).filter((id: string) => id) || [];
setAvailableModels(models);
if (models.length > 0 && !provider.modelName) {
const next = { ...settings.aiProviders };
next[settings.activeAiProvider] = { ...next[settings.activeAiProvider], modelName: models[0] };
setSettings({ ...settings, aiProviders: next });
}
alert(`连接成功!可用模型数: ${models.length}`);
} else {
alert(`连接失败: ${res.status} ${res.statusText}`);
setAvailableModels([]);
}
} catch (e: any) {
alert(`连接失败: ${e.message}`);
setAvailableModels([]);
}
};
@@ -361,18 +371,34 @@ export default function SystemSettings() {
<div className="space-y-1.5">
<label className="block text-xs font-bold text-text-main uppercase tracking-wider"> (Model Name)</label>
<input
type="text"
value={settings.aiProviders[settings.activeAiProvider]?.modelName || ''}
onChange={(e) => {
const next = { ...settings.aiProviders };
next[settings.activeAiProvider] = { ...next[settings.activeAiProvider], modelName: e.target.value };
setSettings({ ...settings, aiProviders: next });
}}
placeholder="kimi-k2-5"
className="input-minimal"
/>
<p className="text-[11px] text-text-muted">使</p>
{availableModels.length > 0 ? (
<select
value={settings.aiProviders[settings.activeAiProvider]?.modelName || ''}
onChange={(e) => {
const next = { ...settings.aiProviders };
next[settings.activeAiProvider] = { ...next[settings.activeAiProvider], modelName: e.target.value };
setSettings({ ...settings, aiProviders: next });
}}
className="input-minimal bg-white"
>
{availableModels.map(m => (
<option key={m} value={m}>{m}</option>
))}
</select>
) : (
<input
type="text"
value={settings.aiProviders[settings.activeAiProvider]?.modelName || ''}
onChange={(e) => {
const next = { ...settings.aiProviders };
next[settings.activeAiProvider] = { ...next[settings.activeAiProvider], modelName: e.target.value };
setSettings({ ...settings, aiProviders: next });
}}
placeholder="kimi-k2-5"
className="input-minimal"
/>
)}
<p className="text-[11px] text-text-muted">{availableModels.length > 0 ? '已从服务商获取可用模型列表' : '点击"测试连接"成功后,此处可下拉选择模型'}</p>
</div>
</div>
</div>