optimize: remove redundant GET requests after updates
parent
0fb6c4d255
commit
aabeeb8e3b
|
|
@ -9,7 +9,7 @@ interface AvatarSelectorProps {
|
||||||
agent: Agent | null;
|
agent: Agent | null;
|
||||||
avatarUploading: boolean;
|
avatarUploading: boolean;
|
||||||
beforeUploadEditAvatar: (file: any) => Promise<boolean>;
|
beforeUploadEditAvatar: (file: any) => Promise<boolean>;
|
||||||
onAvatarChange: () => Promise<void>;
|
onAvatarSelect: (avatarUrl: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AvatarSelector({
|
export default function AvatarSelector({
|
||||||
|
|
@ -18,7 +18,7 @@ export default function AvatarSelector({
|
||||||
agent,
|
agent,
|
||||||
avatarUploading,
|
avatarUploading,
|
||||||
beforeUploadEditAvatar,
|
beforeUploadEditAvatar,
|
||||||
onAvatarChange,
|
onAvatarSelect,
|
||||||
}: AvatarSelectorProps) {
|
}: AvatarSelectorProps) {
|
||||||
return (
|
return (
|
||||||
<Modal title="选择头像形象" open={open} onCancel={onCancel} footer={null} width={600} centered>
|
<Modal title="选择头像形象" open={open} onCancel={onCancel} footer={null} width={600} centered>
|
||||||
|
|
@ -39,9 +39,8 @@ export default function AvatarSelector({
|
||||||
key={url}
|
key={url}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (!agent?.id) return;
|
if (!agent?.id) return;
|
||||||
await AgentAPI.updateAvatar(agent.id, url);
|
await onAvatarSelect(url);
|
||||||
onCancel();
|
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'}`}
|
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' }}
|
style={{ width: 80, height: 80, minWidth: 80, borderColor: agent?.avatar === url ? 'var(--color-brand)' : 'transparent' }}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ interface CapabilitySettingsProps {
|
||||||
selectedAvatar: string;
|
selectedAvatar: string;
|
||||||
setAvatarSelectorOpen: (open: boolean) => void;
|
setAvatarSelectorOpen: (open: boolean) => void;
|
||||||
beforeUploadKnowledge: (file: any) => Promise<boolean>;
|
beforeUploadKnowledge: (file: any) => Promise<boolean>;
|
||||||
|
onDeleteKnowledge: (fileId: string) => Promise<void>;
|
||||||
markDirty: () => void;
|
markDirty: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,6 +28,7 @@ export default function CapabilitySettings({
|
||||||
selectedAvatar,
|
selectedAvatar,
|
||||||
setAvatarSelectorOpen,
|
setAvatarSelectorOpen,
|
||||||
beforeUploadKnowledge,
|
beforeUploadKnowledge,
|
||||||
|
onDeleteKnowledge,
|
||||||
markDirty,
|
markDirty,
|
||||||
}: CapabilitySettingsProps) {
|
}: CapabilitySettingsProps) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -224,10 +226,10 @@ export default function CapabilitySettings({
|
||||||
className="bg-white mb-2 rounded-lg border border-gray-100 p-2"
|
className="bg-white mb-2 rounded-lg border border-gray-100 p-2"
|
||||||
actions={[
|
actions={[
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
key="del"
|
key="del"
|
||||||
title="确认删除?"
|
title="确认删除?"
|
||||||
onConfirm={() => agent && AgentAPI.deleteKnowledge(agent.id, item.id)}
|
onConfirm={() => onDeleteKnowledge(item.id)}
|
||||||
>
|
>
|
||||||
<Button type="text" danger size="small" style={{ borderRadius: 8 }}>
|
<Button type="text" danger size="small" style={{ borderRadius: 8 }}>
|
||||||
删除
|
删除
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -111,9 +111,10 @@ export function useAgentEditor({ id, isNew, form, message, navigate }: UseAgentE
|
||||||
if (!silent) setSaving(true);
|
if (!silent) setSaving(true);
|
||||||
setAutoSaveStatus('saving');
|
setAutoSaveStatus('saving');
|
||||||
try {
|
try {
|
||||||
await AgentAPI.update(id!, values);
|
const updatedAgent = await AgentAPI.update(id!, values);
|
||||||
|
setAgent(updatedAgent);
|
||||||
|
form.setFieldsValue(updatedAgent);
|
||||||
if (!silent) message.success('已保存');
|
if (!silent) message.success('已保存');
|
||||||
await refresh(true);
|
|
||||||
setAutoSaveStatus('saved');
|
setAutoSaveStatus('saved');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setAutoSaveStatus('error');
|
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) => {
|
const beforeUploadKnowledge = async (file: any) => {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
message.warning('请先保存智能体基础信息后再上传');
|
message.warning('请先保存智能体基础信息后再上传');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
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} 已上传,正在建索引…`);
|
message.success(`${file.name} 已上传,正在建索引…`);
|
||||||
refresh();
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
message.error('上传失败:' + (e?.message ?? e));
|
message.error('上传失败:' + (e?.message ?? e));
|
||||||
}
|
}
|
||||||
|
|
@ -163,14 +194,26 @@ export function useAgentEditor({ id, isNew, form, message, navigate }: UseAgentE
|
||||||
return false;
|
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) => {
|
const beforeUploadEditAvatar = async (file: any) => {
|
||||||
if (!id) return false;
|
if (!id) return false;
|
||||||
try {
|
try {
|
||||||
const url = await uploadAvatar(file as File);
|
const url = await uploadAvatar(file as File);
|
||||||
await AgentAPI.updateAvatar(id, url);
|
const updatedAgent = await AgentAPI.updateAvatar(id, url);
|
||||||
|
setAgent(updatedAgent);
|
||||||
message.success('头像已更新');
|
message.success('头像已更新');
|
||||||
setAvatarSelectorOpen(false);
|
setAvatarSelectorOpen(false);
|
||||||
refresh();
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
message.error('头像上传失败:' + (e?.message ?? e));
|
message.error('头像上传失败:' + (e?.message ?? e));
|
||||||
}
|
}
|
||||||
|
|
@ -211,6 +254,8 @@ export function useAgentEditor({ id, isNew, form, message, navigate }: UseAgentE
|
||||||
beforeUploadKnowledge,
|
beforeUploadKnowledge,
|
||||||
beforeUploadInitAvatar,
|
beforeUploadInitAvatar,
|
||||||
beforeUploadEditAvatar,
|
beforeUploadEditAvatar,
|
||||||
|
handleAvatarSelect,
|
||||||
|
handleDeleteKnowledge,
|
||||||
liveAgent,
|
liveAgent,
|
||||||
currentName,
|
currentName,
|
||||||
markDirty,
|
markDirty,
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ export default function AgentEditor() {
|
||||||
beforeUploadKnowledge,
|
beforeUploadKnowledge,
|
||||||
beforeUploadInitAvatar,
|
beforeUploadInitAvatar,
|
||||||
beforeUploadEditAvatar,
|
beforeUploadEditAvatar,
|
||||||
|
handleAvatarSelect,
|
||||||
|
handleDeleteKnowledge,
|
||||||
liveAgent,
|
liveAgent,
|
||||||
currentName,
|
currentName,
|
||||||
markDirty,
|
markDirty,
|
||||||
|
|
@ -82,6 +84,7 @@ export default function AgentEditor() {
|
||||||
selectedAvatar={agent?.avatar || selectedAvatar}
|
selectedAvatar={agent?.avatar || selectedAvatar}
|
||||||
setAvatarSelectorOpen={setAvatarSelectorOpen}
|
setAvatarSelectorOpen={setAvatarSelectorOpen}
|
||||||
beforeUploadKnowledge={beforeUploadKnowledge}
|
beforeUploadKnowledge={beforeUploadKnowledge}
|
||||||
|
onDeleteKnowledge={handleDeleteKnowledge}
|
||||||
markDirty={markDirty}
|
markDirty={markDirty}
|
||||||
/>
|
/>
|
||||||
<PreviewPane liveAgent={liveAgent} agentId={id} />
|
<PreviewPane liveAgent={liveAgent} agentId={id} />
|
||||||
|
|
@ -117,7 +120,7 @@ export default function AgentEditor() {
|
||||||
agent={agent}
|
agent={agent}
|
||||||
avatarUploading={avatarUploading}
|
avatarUploading={avatarUploading}
|
||||||
beforeUploadEditAvatar={beforeUploadEditAvatar}
|
beforeUploadEditAvatar={beforeUploadEditAvatar}
|
||||||
onAvatarChange={refresh}
|
onAvatarSelect={handleAvatarSelect}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue