diff --git a/packages/core/client/src/collection-manager/Configuration/ImportCollectionMetaAction.tsx b/packages/core/client/src/collection-manager/Configuration/ImportCollectionMetaAction.tsx index be37cd611..f570dd17e 100644 --- a/packages/core/client/src/collection-manager/Configuration/ImportCollectionMetaAction.tsx +++ b/packages/core/client/src/collection-manager/Configuration/ImportCollectionMetaAction.tsx @@ -75,8 +75,10 @@ const ImportUpload = (props: any) => { message.success(`${info.file.name} ` + t('file uploaded successfully')); refresh(); await refreshCM(); + window.location.reload(); } else if (status === 'error') { - // message.error(`${info.file.name} ` + t('file upload failed')); + message.error(`${info.file.name} ` + t('file upload failed')); + window.location.reload(); } }, onDrop(e) { @@ -137,7 +139,6 @@ export const ImportCollectionMetaAction = React.forwardRef((props, ref) => { const { t } = useTranslation(); const [dataTypes, setDataTypes] = useState(['required']); const [isModalOpen, setIsModalOpen] = useState(false); - // const [restoreData, setRestoreData] = useState(null); const [loading, setLoading] = useState(false); const showModal = () => { @@ -150,12 +151,10 @@ export const ImportCollectionMetaAction = React.forwardRef((props, ref) => { const handleCancel = () => { setIsModalOpen(false); - // setRestoreData(null); setDataTypes(['required']); }; return ( <> - {/* {t('Import')} */} { @@ -38,20 +35,34 @@ export const collectionImportExportMeta: ResourceOptions = { if (metaList.some((item) => item.name === name)) { return; } - const meta = await Collections.repository.findOne({ + const metaRecord = await Collections.repository.findOne({ filterByTk: name, context: ctx, appends: ['category', 'fields'], }); - if (!meta) { + if (!metaRecord) { return; } + const meta = metaRecord.toJSON(); + if (meta.inherits) { + for (const inherit of meta.inherits) { + await getAssociationCollection(inherit); + } + } + if (meta.view) { + const collection = ctx.db.getCollection(meta.viewName); + const viewDef = await ctx.db.queryInterface.viewDef(collection.getTableNameWithSchemaAsString()); + const viewSql = [ + `DROP VIEW IF EXISTS ${collection.getTableNameWithSchemaAsString()}`, + `CREATE VIEW ${collection.getTableNameWithSchemaAsString()} AS ${viewDef}`, + ]; + meta.viewSql = viewSql; + } metaList.push(meta); - const fields = meta.dataValues.fields; + const fields = meta.fields; for (const field of fields) { - ctx.logger.info('field.dataValues', field.dataValues); - if (field?.dataValues?.options?.target) { - await getAssociationCollection(field?.dataValues?.options?.target); + if (field?.options?.target) { + await getAssociationCollection(field?.options?.target); } } } @@ -76,49 +87,102 @@ export const collectionImportExportMeta: ResourceOptions = { } let createCount = 0; + const reverseKeys = []; + // 检查field是否已经存在 + const fieldRepo = ctx.db.getCollection('fields'); + + // old name => new name + const collectionNameMap = {}; + const completedCollections = new Set(); + const createList = []; + + const existCollections = await ctx.db.getCollection('collections').repository.find({ + filter: { + $or: { + name: { $in: metaList.map((item) => item.name) }, + key: { $in: metaList.map((item) => item.key) }, + }, + }, + context: ctx, + }); + + const allFieldKeys = []; + for (const meta of metaList) { + allFieldKeys.push(...meta.fields.map((item) => item.key)); + } + + const views = []; + const CollectionRepo = ctx.db.getCollection('collections'); async function importCollection(meta) { - const CollectionRepo = ctx.db.getCollection('collections'); - // 检查表是否存在 - let collection = await CollectionRepo.repository.findOne({ - filterByTk: meta.name, - context: ctx, - }); - if (collection) { + if (!meta) { return; - throw new Error('collection name already exists, please change the name'); } - collection = await CollectionRepo.repository.findOne({ - filter: { key: meta.key }, - context: ctx, - }); - if (collection) { + if (completedCollections.has(meta.name)) { + return; + } + if (meta.inherits && meta.inherits.length > 0) { + for (const inherit of meta.inherits) { + if (!completedCollections.has(inherit)) { + const inheritCollection = metaList.find((v) => v.name === inherit); + await importCollection(inheritCollection); + } + } + } + let collection = existCollections.find((v) => v.key === meta.key); + // key和name完全相同的两个collection, 出现重复 + if (collection && collection.name === meta.name) { + completedCollections.add(collection.name); return; - throw new Error('collection key already exists, please change the key'); } - // generate unique key - // meta.fields.forEach((field) => { - // field.key = uid(); - // }); - - // 检查field是否已经存在 - const fieldRepo = ctx.db.getCollection('fields'); - const fieldKeys = meta.fields.map((field) => field.key); - - const existFields = await fieldRepo.repository.findOne({ - filter: { key: { $in: fieldKeys } }, - context: ctx, - }); - if (existFields) { + // key一样 name不一样则需要生成新的key + if (collection && collection.name !== meta.name) { + meta.key = uid(); return; - throw new Error('field key already exists, please change the key'); + } else { + collection = existCollections.find((v) => v.name === meta.name); + if (collection) { + // 重复导入则放过 + collection.name = `t_${uid()}`; + collectionNameMap[meta.name] = collection.name; + meta.name = collection.name; + if (meta.category && meta.category.length) { + meta.category.forEach((v) => { + v.collectionCategory.collectionName = collection.name; + }); + } + } } + const normalFieldKeys = []; + if (meta.fields) { + for (const field of meta.fields) { + if (!field.reverseKey) { + if (field.collectionName && collectionNameMap[field.collectionName]) { + field.collectionName = collectionNameMap[field.collectionName]; + } + if (field.target && collectionNameMap[field.target]) { + field.target = collectionNameMap[field.target]; + } + normalFieldKeys.push(field); + } else if (!reverseKeys.some((v) => v === field.key || v === field.reverseKey)) { + reverseKeys.push({ ...field, collectionName: meta.key }); + } + } + meta.fields = normalFieldKeys; + } + + // 视图 + if (meta.view) { + views.push(meta); + return; + } await CollectionRepo.repository.create({ values: meta, context: ctx, }); + completedCollections.add(meta.name); createCount++; } @@ -126,8 +190,26 @@ export const collectionImportExportMeta: ResourceOptions = { await importCollection(meta); } + for (const meta of views) { + if (!meta.viewSql || !meta.viewSql.length) { + continue; + } + for (const sql of meta.viewSql) { + await ctx.db.sequelize.query(sql); + } + await CollectionRepo.repository.create({ + values: meta, + context: ctx, + }); + createCount++; + } + + for (const reverseKey of reverseKeys) { + await fieldRepo.repository.create(reverseKey); + } + if (!createCount) { - throw new Error('no collection created, please check the key or name'); + throw new Error('no collection created, please check the name'); } ctx.body = { count: createCount };