- 添加账号管理详情页(基本信息、提示词、CapCut、参考图标签页) - 重构资产页面,按项目组分开展示图片/视频 - 聊天界面支持深度思考内容折叠展示、复制、删除消息 - 设置页面支持Agent配置(Anthropic/OpenAI协议)和工具配置 - 后端支持OpenAI兼容协议流式输出和DeepSeek思考模式 - 添加对话置顶/删除功能、数据库迁移、资产清单API - 添加账号参考图上传/删除、技能配置持久化、连接测试API
116 lines
4.9 KiB
TypeScript
116 lines
4.9 KiB
TypeScript
import { useState } from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Input } from '@/components/ui/input';
|
|
import type { Account } from '@/types';
|
|
|
|
interface Props {
|
|
account: Account;
|
|
onSave: (data: Partial<Account>) => void;
|
|
}
|
|
|
|
export function AccountBasicTab({ account, onSave }: Props) {
|
|
const [form, setForm] = useState({
|
|
name: account.name || '',
|
|
description: account.description || '',
|
|
pipeline: account.pipeline || 'image-video',
|
|
defaultFormat: account.defaultFormat || '9:16',
|
|
imageModel: account.imageModel || 'gemini',
|
|
videoModel: account.videoModel || 'veo3-fast',
|
|
batchSize: account.batchSize || 30,
|
|
ttsVoice: account.ttsVoice || '',
|
|
ttsInstruction: account.ttsInstruction || '',
|
|
});
|
|
const [saved, setSaved] = useState(false);
|
|
|
|
const handleChange = (key: string, value: string | number) => {
|
|
setForm((f) => ({ ...f, [key]: value }));
|
|
setSaved(false);
|
|
};
|
|
|
|
const handleSave = () => {
|
|
onSave(form);
|
|
setSaved(true);
|
|
setTimeout(() => setSaved(false), 2000);
|
|
};
|
|
|
|
return (
|
|
<div className="max-w-lg space-y-4">
|
|
<div>
|
|
<label className="text-xs font-medium text-zinc-500">名称</label>
|
|
<Input value={form.name} onChange={(e) => handleChange('name', e.target.value)}
|
|
className="mt-1 bg-zinc-50 border-zinc-200" />
|
|
</div>
|
|
<div>
|
|
<label className="text-xs font-medium text-zinc-500">描述</label>
|
|
<Input value={form.description} onChange={(e) => handleChange('description', e.target.value)}
|
|
placeholder="账号描述..." className="mt-1 bg-zinc-50 border-zinc-200" />
|
|
</div>
|
|
|
|
<div className="grid grid-cols-3 gap-3">
|
|
<div>
|
|
<label className="text-xs font-medium text-zinc-500">画幅</label>
|
|
<select value={form.defaultFormat} onChange={(e) => handleChange('defaultFormat', e.target.value)}
|
|
className="mt-1 w-full h-10 rounded-md border border-zinc-200 bg-zinc-50 px-3 text-sm">
|
|
<option value="9:16">9:16 竖屏</option>
|
|
<option value="16:9">16:9 横屏</option>
|
|
<option value="1:1">1:1 方形</option>
|
|
<option value="4:3">4:3</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label className="text-xs font-medium text-zinc-500">生图模型</label>
|
|
<select value={form.imageModel} onChange={(e) => handleChange('imageModel', e.target.value)}
|
|
className="mt-1 w-full h-10 rounded-md border border-zinc-200 bg-zinc-50 px-3 text-sm">
|
|
<option value="gemini">Gemini</option>
|
|
<option value="mj">Midjourney</option>
|
|
<option value="gpt">GPT Image</option>
|
|
<option value="kling">Kling</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label className="text-xs font-medium text-zinc-500">视频模型</label>
|
|
<select value={form.videoModel} onChange={(e) => handleChange('videoModel', e.target.value)}
|
|
className="mt-1 w-full h-10 rounded-md border border-zinc-200 bg-zinc-50 px-3 text-sm">
|
|
<option value="veo3-fast">Veo3 Fast</option>
|
|
<option value="veo3-fast-frames">Veo3 Frames</option>
|
|
<option value="kling">Kling</option>
|
|
<option value="grok">Grok</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 gap-3">
|
|
<div>
|
|
<label className="text-xs font-medium text-zinc-500">Pipeline</label>
|
|
<select value={form.pipeline} onChange={(e) => handleChange('pipeline', e.target.value)}
|
|
className="mt-1 w-full h-10 rounded-md border border-zinc-200 bg-zinc-50 px-3 text-sm">
|
|
<option value="image-video">图片+视频</option>
|
|
<option value="single">单图模式</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label className="text-xs font-medium text-zinc-500">批量数量</label>
|
|
<Input type="number" value={form.batchSize} onChange={(e) => handleChange('batchSize', parseInt(e.target.value) || 30)}
|
|
className="mt-1 bg-zinc-50 border-zinc-200" />
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-xs font-medium text-zinc-500">TTS 语音 ID</label>
|
|
<Input value={form.ttsVoice} onChange={(e) => handleChange('ttsVoice', e.target.value)}
|
|
placeholder="cosyvoice-xxx" className="mt-1 bg-zinc-50 border-zinc-200 font-mono text-xs" />
|
|
</div>
|
|
<div>
|
|
<label className="text-xs font-medium text-zinc-500">TTS 指令</label>
|
|
<textarea value={form.ttsInstruction} onChange={(e) => handleChange('ttsInstruction', e.target.value)}
|
|
rows={3} placeholder="用沉稳有力的男性声音朗读..."
|
|
className="mt-1 w-full rounded-md border border-zinc-200 bg-zinc-50 px-3 py-2 text-sm resize-y" />
|
|
</div>
|
|
|
|
<Button onClick={handleSave}>
|
|
{saved ? '已保存' : '保存基本信息'}
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|