Fix: 同步文件时顺便同步更新结构

This commit is contained in:
奇趣保罗 2026-01-30 18:00:03 +08:00
parent b51da785af
commit bf1a7dde48
1 changed files with 62 additions and 6 deletions

View File

@ -16,7 +16,7 @@ import {
} from "@/lib/db"; } from "@/lib/db";
import { FolderOpen, Settings } from "lucide-react"; import { FolderOpen, Settings } from "lucide-react";
import { useTranslationInlineEdit } from "@/hooks/biz/use-translation-inline-edit"; import { useTranslationInlineEdit } from "@/hooks/biz/use-translation-inline-edit";
import { buildStructureFromObject, flattenEntries, flattenValues, type FlatEntry, insertEntrySibling, removeEntryAtPath, renameEntryAtPath, moveEntryByOffset } from "@/lib/i18n-structure"; import { buildStructureFromObject, flattenEntries, flattenValues, unflattenValues, type FlatEntry, insertEntrySibling, removeEntryAtPath, renameEntryAtPath, moveEntryByOffset } from "@/lib/i18n-structure";
import { ImportLanguageModal } from "@/components/biz/import-language-modal"; import { ImportLanguageModal } from "@/components/biz/import-language-modal";
import { ExportLanguageModal } from "@/components/biz/export-language-modal"; import { ExportLanguageModal } from "@/components/biz/export-language-modal";
import { EntryNameModal } from "@/components/biz/entry-name-modal"; import { EntryNameModal } from "@/components/biz/entry-name-modal";
@ -215,18 +215,74 @@ export default function Editor({ projectId }: EditorProps) {
} }
}, [projectId, setSourcesMeta]); }, [projectId, setSourcesMeta]);
const updateStructureFromDefaultLanguage = useCallback(
async (opts?: { silent?: boolean }) => {
if (!projectId) return false;
// 获取默认语言
const defaultLang = sourcesState.defaultLanguage;
if (!defaultLang) {
if (!opts?.silent) {
toast.error("未配置默认语言,无法更新翻译结构");
}
return false;
}
// 获取默认语言的翻译内容
const translations = valuesByLang[defaultLang];
if (!translations || Object.keys(translations).length === 0) {
if (!opts?.silent) {
toast.error(`默认语言 ${defaultLang} 的翻译内容为空`);
}
return false;
}
try {
// 从扁平结构转换为嵌套对象
const nestedObj = unflattenValues(translations);
// 从嵌套对象构建结构树
const root = buildStructureFromObject(nestedObj);
// 保存到数据库
await upsertStructure({ projectId, root });
setStructure({ projectId, root });
if (!opts?.silent) {
toast.success("翻译结构已更新");
}
return true;
} catch (err) {
const message = (err as Error)?.message ?? "更新结构失败";
if (!opts?.silent) {
toast.error(message);
}
console.error("更新结构失败", err);
return false;
}
},
[projectId, sourcesState.defaultLanguage, valuesByLang]
);
const syncExternalSources = useCallback( const syncExternalSources = useCallback(
async (opts?: { silent?: boolean; reloadConfig?: boolean }) => { async (opts?: { silent?: boolean; reloadConfig?: boolean; updateStructure?: boolean }) => {
let preloaded: LoadedProjectSources | null = null; let preloaded: LoadedProjectSources | null = null;
if (opts?.reloadConfig) { if (opts?.reloadConfig) {
preloaded = await bootstrapSources(); preloaded = await bootstrapSources();
} }
let syncResult: boolean;
if (preloaded) { if (preloaded) {
return applyLoadedSources(preloaded, opts); syncResult = await applyLoadedSources(preloaded, opts);
} else {
syncResult = await syncFromAdapter(opts);
} }
return syncFromAdapter(opts);
// 如果同步成功且需要更新结构,则从默认语言更新结构
if (syncResult && opts?.updateStructure) {
await updateStructureFromDefaultLanguage({ silent: opts.silent });
}
return syncResult;
}, },
[applyLoadedSources, bootstrapSources, syncFromAdapter] [applyLoadedSources, bootstrapSources, syncFromAdapter, updateStructureFromDefaultLanguage]
); );
const refresh = useCallback( const refresh = useCallback(
@ -482,7 +538,7 @@ export default function Editor({ projectId }: EditorProps) {
void syncExternalSources({ silent: false }); void syncExternalSources({ silent: false });
break; break;
case "read-all": case "read-all":
void syncExternalSources({ silent: false, reloadConfig: true }); void syncExternalSources({ silent: false, reloadConfig: true, updateStructure: true });
break; break;
case "save": case "save":
void handleSaveAllConnected(); void handleSaveAllConnected();