feat: 如果请求失败不要写入localstorage,且不要展示失败的skill
This commit is contained in:
parent
d376d421fe
commit
f92444c722
|
|
@ -49,6 +49,12 @@ function parseStoredSkills(raw: string | null): SkillData[] {
|
|||
}
|
||||
}
|
||||
|
||||
function removeSkillsByIdsFromList(skills: SkillData[], skillIds: string[]): SkillData[] {
|
||||
if (skillIds.length === 0) return skills;
|
||||
const idSet = new Set(skillIds.map((id) => String(id)));
|
||||
return skills.filter((skill) => !idSet.has(String(skill.skill_id)));
|
||||
}
|
||||
|
||||
// Hook 返回类型
|
||||
interface UseIframeSkillReturn {
|
||||
selectedSkill: SkillData | null;
|
||||
|
|
@ -81,6 +87,45 @@ export function useIframeSkill(
|
|||
const [selectedSkills, setSelectedSkills] = useState<SkillData[]>([]);
|
||||
const [isBootstrapping, setIsBootstrapping] = useState(false);
|
||||
|
||||
const removeFailedSkills = useCallback(
|
||||
(skillIds: string[]) => {
|
||||
if (skillIds.length === 0) return;
|
||||
|
||||
// 1) 回滚内存状态:移除失败 skill,避免展示错误 tag
|
||||
setSelectedSkills((prev) => {
|
||||
const next = removeSkillsByIdsFromList(prev, skillIds);
|
||||
setSelectedSkill(next[0] ?? null);
|
||||
return next;
|
||||
});
|
||||
|
||||
// 2) 回滚 localStorage(latest + thread)
|
||||
const latestSkills = parseStoredSkills(
|
||||
window.localStorage.getItem(STORAGE_KEYS.latest),
|
||||
);
|
||||
const nextLatestSkills = removeSkillsByIdsFromList(latestSkills, skillIds);
|
||||
if (nextLatestSkills.length > 0) {
|
||||
window.localStorage.setItem(
|
||||
STORAGE_KEYS.latest,
|
||||
JSON.stringify(nextLatestSkills),
|
||||
);
|
||||
} else {
|
||||
window.localStorage.removeItem(STORAGE_KEYS.latest);
|
||||
}
|
||||
|
||||
const threadKey = getThreadStorageKey(threadId);
|
||||
if (threadKey) {
|
||||
const threadSkills = parseStoredSkills(window.localStorage.getItem(threadKey));
|
||||
const nextThreadSkills = removeSkillsByIdsFromList(threadSkills, skillIds);
|
||||
if (nextThreadSkills.length > 0) {
|
||||
window.localStorage.setItem(threadKey, JSON.stringify(nextThreadSkills));
|
||||
} else {
|
||||
window.localStorage.removeItem(threadKey);
|
||||
}
|
||||
}
|
||||
},
|
||||
[threadId],
|
||||
);
|
||||
|
||||
// 1. 监听 query 参数变化(临时禁用)
|
||||
// TODO: 当前 skill 仅通过 iframe postMessage 传递,暂不从 URL 读取 skill_id/title。
|
||||
// useEffect(() => {
|
||||
|
|
@ -223,6 +268,8 @@ export function useIframeSkill(
|
|||
toast.dismiss("suggest-skill-bootstrap");
|
||||
|
||||
if (!result.success) {
|
||||
const failedIds = selectedSkills.map((item) => String(item.id).trim());
|
||||
removeFailedSkills(failedIds);
|
||||
toast.error(`技能「${title}」加载失败`, {
|
||||
description: result.message || "未知错误",
|
||||
});
|
||||
|
|
@ -243,6 +290,8 @@ export function useIframeSkill(
|
|||
|
||||
return true;
|
||||
} catch (error) {
|
||||
const failedIds = selectedSkills.map((item) => String(item.id).trim());
|
||||
removeFailedSkills(failedIds);
|
||||
toast.dismiss("suggest-skill-bootstrap");
|
||||
const message =
|
||||
error instanceof Error ? error.message : "网络请求失败";
|
||||
|
|
@ -254,7 +303,7 @@ export function useIframeSkill(
|
|||
setIsBootstrapping(false);
|
||||
}
|
||||
},
|
||||
[searchParams, sendSelectSkill, threadId],
|
||||
[removeFailedSkills, searchParams, sendSelectSkill, threadId],
|
||||
);
|
||||
|
||||
// 打开 skill 选择对话框
|
||||
|
|
|
|||
Loading…
Reference in New Issue