optimize: remove redundant GET requests after updates

main
sp mac bookpro 2605 2026-06-01 16:03:15 +08:00
parent 0fb6c4d255
commit aabeeb8e3b
4 changed files with 64 additions and 15 deletions

View File

@ -9,7 +9,7 @@ interface AvatarSelectorProps {
agent: Agent | null;
avatarUploading: boolean;
beforeUploadEditAvatar: (file: any) => Promise<boolean>;
onAvatarChange: () => Promise<void>;
onAvatarSelect: (avatarUrl: string) => Promise<void>;
}
export default function AvatarSelector({
@ -18,7 +18,7 @@ export default function AvatarSelector({
agent,
avatarUploading,
beforeUploadEditAvatar,
onAvatarChange,
onAvatarSelect,
}: AvatarSelectorProps) {
return (
<Modal title="选择头像形象" open={open} onCancel={onCancel} footer={null} width={600} centered>
@ -39,9 +39,8 @@ export default function AvatarSelector({
key={url}
onClick={async () => {
if (!agent?.id) return;
await AgentAPI.updateAvatar(agent.id, url);
await onAvatarSelect(url);
onCancel();
await onAvatarChange();
}}
className={`relative rounded-full cursor-pointer transition-all duration-300 overflow-hidden border-2 mx-auto ${agent?.avatar === url ? 'scale-110 shadow-lg z-10' : 'border-transparent opacity-70 hover:opacity-100 hover:scale-105'}`}
style={{ width: 80, height: 80, minWidth: 80, borderColor: agent?.avatar === url ? 'var(--color-brand)' : 'transparent' }}

View File

@ -14,6 +14,7 @@ interface CapabilitySettingsProps {
selectedAvatar: string;
setAvatarSelectorOpen: (open: boolean) => void;
beforeUploadKnowledge: (file: any) => Promise<boolean>;
onDeleteKnowledge: (fileId: string) => Promise<void>;
markDirty: () => void;
}
@ -27,6 +28,7 @@ export default function CapabilitySettings({
selectedAvatar,
setAvatarSelectorOpen,
beforeUploadKnowledge,
onDeleteKnowledge,
markDirty,
}: CapabilitySettingsProps) {
return (
@ -224,10 +226,10 @@ export default function CapabilitySettings({
className="bg-white mb-2 rounded-lg border border-gray-100 p-2"
actions={[
<Popconfirm
key="del"
title="确认删除?"
onConfirm={() => agent && AgentAPI.deleteKnowledge(agent.id, item.id)}
>
key="del"
title="确认删除?"
onConfirm={() => onDeleteKnowledge(item.id)}
>
<Button type="text" danger size="small" style={{ borderRadius: 8 }}>
</Button>

View File

@ -111,9 +111,10 @@ export function useAgentEditor({ id, isNew, form, message, navigate }: UseAgentE
if (!silent) setSaving(true);
setAutoSaveStatus('saving');
try {
await AgentAPI.update(id!, values);
const updatedAgent = await AgentAPI.update(id!, values);
setAgent(updatedAgent);
form.setFieldsValue(updatedAgent);
if (!silent) message.success('已保存');
await refresh(true);
setAutoSaveStatus('saved');
} catch (e) {
setAutoSaveStatus('error');
@ -137,15 +138,45 @@ export function useAgentEditor({ id, isNew, form, message, navigate }: UseAgentE
}
};
const handleDeleteKnowledge = async (fileId: string) => {
if (!id) return;
try {
await AgentAPI.deleteKnowledge(id, fileId);
setAgent((prev) => {
if (!prev) return prev;
return {
...prev,
knowledge: (prev.knowledge || []).filter((k: any) => k.id !== fileId),
};
});
message.success('已删除');
} catch (e: any) {
message.error('删除失败:' + (e?.message ?? e));
}
};
const beforeUploadKnowledge = async (file: any) => {
if (!id) {
message.warning('请先保存智能体基础信息后再上传');
return false;
}
try {
await AgentAPI.uploadKnowledge(id, [file as File]);
const result = await AgentAPI.uploadKnowledge(id, [file as File]);
const newFiles = (result.files || []).map((f: any) => ({
...f,
status: 'indexing' as const,
size: file.size || 0,
}));
setAgent((prev) => {
if (!prev) return prev;
const existingIds = new Set((prev.knowledge || []).map((k: any) => k.id));
const uniqueNewFiles = newFiles.filter((f: any) => !existingIds.has(f.id));
return {
...prev,
knowledge: [...uniqueNewFiles, ...(prev.knowledge || [])],
};
});
message.success(`${file.name} 已上传,正在建索引…`);
refresh();
} catch (e: any) {
message.error('上传失败:' + (e?.message ?? e));
}
@ -163,14 +194,26 @@ export function useAgentEditor({ id, isNew, form, message, navigate }: UseAgentE
return false;
};
const handleAvatarSelect = async (avatarUrl: string) => {
if (!id) return;
try {
const updatedAgent = await AgentAPI.updateAvatar(id, avatarUrl);
setAgent(updatedAgent);
message.success('头像已更新');
setAvatarSelectorOpen(false);
} catch (e: any) {
message.error('头像更新失败:' + (e?.message ?? e));
}
};
const beforeUploadEditAvatar = async (file: any) => {
if (!id) return false;
try {
const url = await uploadAvatar(file as File);
await AgentAPI.updateAvatar(id, url);
const updatedAgent = await AgentAPI.updateAvatar(id, url);
setAgent(updatedAgent);
message.success('头像已更新');
setAvatarSelectorOpen(false);
refresh();
} catch (e: any) {
message.error('头像上传失败:' + (e?.message ?? e));
}
@ -211,6 +254,8 @@ export function useAgentEditor({ id, isNew, form, message, navigate }: UseAgentE
beforeUploadKnowledge,
beforeUploadInitAvatar,
beforeUploadEditAvatar,
handleAvatarSelect,
handleDeleteKnowledge,
liveAgent,
currentName,
markDirty,

View File

@ -44,6 +44,8 @@ export default function AgentEditor() {
beforeUploadKnowledge,
beforeUploadInitAvatar,
beforeUploadEditAvatar,
handleAvatarSelect,
handleDeleteKnowledge,
liveAgent,
currentName,
markDirty,
@ -82,6 +84,7 @@ export default function AgentEditor() {
selectedAvatar={agent?.avatar || selectedAvatar}
setAvatarSelectorOpen={setAvatarSelectorOpen}
beforeUploadKnowledge={beforeUploadKnowledge}
onDeleteKnowledge={handleDeleteKnowledge}
markDirty={markDirty}
/>
<PreviewPane liveAgent={liveAgent} agentId={id} />
@ -117,7 +120,7 @@ export default function AgentEditor() {
agent={agent}
avatarUploading={avatarUploading}
beforeUploadEditAvatar={beforeUploadEditAvatar}
onAvatarChange={refresh}
onAvatarSelect={handleAvatarSelect}
/>
</>
);