feat: 模板切换重置AI对话+Diff间距修复+API密钥DOM安全+模型切换(20260419_2344)

- 切换模板时同步清空 chatMessages/chatInput/aiUploadedImages/aiSelectedFrames
- 修复stripHtml双换行导致diff modal原始版本段落间距过大
- API密钥input改为ref非受控组件, DOM中不再出现value=sk-xxx属性
- 默认模型名改为 moonshot-v1-32k-vision-preview
This commit is contained in:
2026-04-19 23:50:51 +08:00
parent 18d81cb4a6
commit e549419a4c
6 changed files with 231 additions and 6 deletions

View File

@@ -833,7 +833,7 @@ export default function ReportEditor() {
const stripHtml = (html: string): string => {
const tmp = document.createElement('div');
tmp.innerHTML = html.replace(/<\/p>/gi, '</p>\n').replace(/<br\s*\/?>/gi, '\n');
tmp.innerHTML = html.replace(/<br\s*\/?>/gi, '\n');
return (tmp.innerText || tmp.textContent || '').trim();
};
@@ -898,7 +898,7 @@ export default function ReportEditor() {
const provider = settings.aiProviders?.[settings.activeAiProvider || 'kimi'];
const apiKey = provider?.apiKey || getDefaultApiKey();
const apiEndpoint = (provider?.endpoint || 'https://api.moonshot.cn/v1').replace(/\/+$/, '');
const modelName = provider?.modelName || 'moonshot-v1-auto';
const modelName = provider?.modelName || 'moonshot-v1-32k-vision-preview';
if (!apiKey) {
setChatMessages(prev => [...prev, { id: Date.now().toString(), role: 'model', content: '【系统提示】尚未配置 AI API Key请前往系统设置填写。' }]);
setIsGenerating(false);
@@ -1239,6 +1239,10 @@ export default function ReportEditor() {
setVideos([]);
setCapturedFrames([]);
setCurrentVideoIndex(-1);
setChatMessages([]);
setChatInput('');
setAiUploadedImages([]);
setAiSelectedFrames([]);
prevVideoCountRef.current = 0;
stateRef.current = {
...stateRef.current,
@@ -1246,6 +1250,8 @@ export default function ReportEditor() {
reportData: nextReportData,
videos: [],
capturedFrames: [],
chatMessages: [],
chatInput: '',
activeTab: stateRef.current.activeTab
};
updatePageHeight();

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import Sidebar from '../components/Sidebar';
import { Video, Globe, Layout, Check, Plus, X } from 'lucide-react';
@@ -21,6 +21,16 @@ export default function SystemSettings() {
const [pendingFrameCount, setPendingFrameCount] = useState<number | null>(null);
const [modeModalOpen, setModeModalOpen] = useState(false);
const [availableModels, setAvailableModels] = useState<string[]>([]);
const apiKeyInputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (apiKeyInputRef.current) {
const targetValue = settings.aiProviders[settings.activeAiProvider]?.apiKey || '';
if (apiKeyInputRef.current.value !== targetValue) {
apiKeyInputRef.current.value = targetValue;
}
}
}, [settings.aiProviders[settings.activeAiProvider]?.apiKey]);
useEffect(() => {
const user = storage.get<User | null>('currentUser', null);
@@ -38,7 +48,7 @@ export default function SystemSettings() {
providers.kimi = {
endpoint: (savedSettings as any).kimiApiEndpoint || providers.kimi.endpoint,
apiKey: (savedSettings as any).kimiApiKey || '',
modelName: 'moonshot-v1-auto'
modelName: 'moonshot-v1-32k-vision-preview'
};
}
savedSettings.aiProviders = providers;
@@ -362,8 +372,8 @@ export default function SystemSettings() {
<div className="space-y-1.5">
<label className="block text-xs font-bold text-text-main uppercase tracking-wider">API </label>
<input
ref={apiKeyInputRef}
type="password"
value={settings.aiProviders[settings.activeAiProvider]?.apiKey || ''}
onChange={(e) => {
const next = { ...settings.aiProviders };
next[settings.activeAiProvider] = { ...next[settings.activeAiProvider], apiKey: e.target.value };

View File

@@ -89,7 +89,7 @@ export interface SystemSettings {
}
export const DEFAULT_AI_PROVIDERS: Record<string, AiProviderConfig> = {
kimi: { endpoint: 'https://api.moonshot.cn/v1', apiKey: '', modelName: 'moonshot-v1-auto' },
kimi: { endpoint: 'https://api.moonshot.cn/v1', apiKey: '', modelName: 'moonshot-v1-32k-vision-preview' },
deepseek: { endpoint: 'https://api.deepseek.com/v1', apiKey: '', modelName: 'deepseek-chat' },
openai: { endpoint: 'https://api.openai.com/v1', apiKey: '', modelName: 'gpt-4o' },
custom: { endpoint: '', apiKey: '', modelName: '' }